コード例 #1
0
ファイル: fetch_test.go プロジェクト: porty/react-in-go
func TestFetchCallback(t *testing.T) {
	m := http.NewServeMux()
	m.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("hello"))
	})
	s := httptest.NewServer(m)
	defer s.Close()

	vm := otto.New()
	l := loop.New(vm)

	if err := Define(vm, l); err != nil {
		panic(err)
	}

	ch := make(chan bool, 1)

	if err := vm.Set("__capture", func(s string) {
		defer func() { ch <- true }()

		if !strings.Contains(s, "hello") {
			panic(fmt.Errorf("expected to find `hello' in response"))
		}
	}); err != nil {
		panic(err)
	}

	must(l.EvalAndRun(`fetch('` + s.URL + `').then(function(r) {
    return r.text();
  }).then(__capture)`))

	<-ch
}
コード例 #2
0
ファイル: fetch_test.go プロジェクト: porty/react-in-go
func TestFetchWithHandler(t *testing.T) {
	m := http.NewServeMux()
	m.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		// these spaces are here so we can disambiguate between this and the
		// re-encoded data the javascript below spits out
		w.Write([]byte("[ 1 , 2 , 3 ]"))
	})

	vm := otto.New()
	l := loop.New(vm)

	if err := DefineWithHandler(vm, l, m); err != nil {
		panic(err)
	}

	ch := make(chan bool, 1)

	if err := vm.Set("__capture", func(s string) {
		defer func() { ch <- true }()

		if s != `[1,2,3]` {
			panic(fmt.Errorf("expected data to be json, and for that json to be parsed"))
		}
	}); err != nil {
		panic(err)
	}

	must(l.EvalAndRun(`fetch('/').then(function(r) { return r.json(); }).then(function(d) {
    return setTimeout(__capture, 4, JSON.stringify(d));
  })`))

	<-ch
}
コード例 #3
0
ファイル: fetch_test.go プロジェクト: deoxxa/ottoext
func TestFetchWithHandlerParallel(t *testing.T) {
	m := http.NewServeMux()
	m.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("hello"))
	})

	vm := otto.New()
	l := loop.New(vm)

	if err := DefineWithHandler(vm, l, m); err != nil {
		panic(err)
	}

	ch := make(chan bool, 1)

	if err := vm.Set("__capture", func(c otto.FunctionCall) otto.Value {
		defer func() { ch <- true }()

		return otto.UndefinedValue()
	}); err != nil {
		panic(err)
	}

	must(l.EvalAndRun(`Promise.all([1,2,3,4,5].map(function(i) { return fetch('/' + i); })).then(__capture)`))

	<-ch
}
コード例 #4
0
ファイル: fetch_test.go プロジェクト: porty/react-in-go
func TestFetchHeaders(t *testing.T) {
	m := http.NewServeMux()
	m.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("header-one", "1")
		w.Header().Add("header-two", "2a")
		w.Header().Add("header-two", "2b")

		w.Write([]byte("hello"))
	})
	s := httptest.NewServer(m)
	defer s.Close()

	vm := otto.New()
	l := loop.New(vm)

	if err := Define(vm, l); err != nil {
		panic(err)
	}

	ch := make(chan bool, 1)

	if err := vm.Set("__capture", func(s string) {
		defer func() { ch <- true }()

		if s != `{"header-one":["1"],"header-two":["2a","2b"]}` {
			panic(fmt.Errorf("expected headers to contain 1, 2a, and 2b"))
		}
	}); err != nil {
		panic(err)
	}

	must(l.EvalAndRun(`fetch('` + s.URL + `').then(function(r) {
    return __capture(JSON.stringify({
      'header-one': r.headers.getAll('header-one'),
      'header-two': r.headers.getAll('header-two'),
    }));
  })`))

	<-ch
}
コード例 #5
0
ファイル: fetch_test.go プロジェクト: porty/react-in-go
func TestFetch(t *testing.T) {
	m := http.NewServeMux()
	m.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("hello"))
	})
	s := httptest.NewServer(m)
	defer s.Close()

	vm := otto.New()
	l := loop.New(vm)

	if err := Define(vm, l); err != nil {
		panic(err)
	}

	must(l.EvalAndRun(`fetch('` + s.URL + `').then(function(r) {
    return r.text();
  }).then(function(d) {
    if (d.indexOf('hellox') === -1) {
      throw new Error('what');
    }
  });`))
}
コード例 #6
0
ファイル: main.go プロジェクト: porty/react-in-go
func main() {
	logrus.StandardLogger().Level = logrus.DebugLevel

	logrus.Debug("starting up")

	baseVM := otto.New()

	smRead := logDuration("read sourcemap")
	smData, err := ioutil.ReadFile("../client/public/bundle.server.js.map")
	if err != nil {
		panic(err)
	}
	smRead()

	smParse := logDuration("parse sourcemap")
	sm, err := sourcemap.Read(bytes.NewReader(smData))
	if err != nil {
		panic(err)
	}
	smParse()

	jsRead := logDuration("read javascript")
	jsData, err := ioutil.ReadFile("../client/public/bundle.server.js")
	if err != nil {
		panic(err)
	}
	jsRead()

	jsCompiled := logDuration("compile javascript")
	s, err := baseVM.CompileWithSourceMap("bundle.js", string(jsData), &sm)
	if err != nil {
		panic(err)
	}
	jsCompiled()

	jsInitialised := logDuration("initialise javascript")
	if _, err := baseVM.Run(s); err != nil {
		panic(err)
	}
	jsInitialised()

	tpl, err := template.ParseFiles("./index.template")
	if err != nil {
		panic(err)
	}

	apiRouter := mux.NewRouter()

	apiRouter.Path("/api/v1/posts").Methods("GET").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		posts := `[
			{"id":1,"title":"hello1 ","content":"hi there one!"},
			{"id":2,"title":"hello 2","content":"hi there two!"}
		]`

		w.Header().Set("content-type", "application/json")
		if _, err := w.Write([]byte(posts)); err != nil {
			panic(err)
		}
	})

	m := mux.NewRouter()

	m.PathPrefix("/api/v1").Handler(apiRouter)

	m.PathPrefix("/").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		vmCopied := logDuration("copy vm")
		vm := baseVM.Copy()
		vmCopied()

		l := loop.New(vm)
		if err := fetch.DefineWithHandler(vm, l, apiRouter); err != nil {
			panic(err)
		}

		fn, err := vm.Get("renderApplication")
		if err != nil {
			panic(err)
		}

		m := map[string]interface{}{
			"redirect": func(u string) {
				http.Redirect(w, r, u, 301)
			},
			"error": func(e string) {
				http.Error(w, e, http.StatusInternalServerError)
			},
			"notFound": func() {
				http.NotFound(w, r)
			},
			"success": func(d string) {
				w.Header().Set("content-type", "text/html")

				tpl.Execute(w, map[string]string{
					"html": d,
				})
			},
		}

		v, err := vm.ToValue(m)
		if err != nil {
			panic(err)
		}

		jsRun := logDuration("run javascript")
		if _, err := fn.Call(otto.UndefinedValue(), r.URL.String(), otto.NullValue(), v); err != nil {
			panic(err)
		}
		jsRun()

		jsFinished := logDuration("wait for js")
		if err := l.Run(); err != nil {
			panic(err)
		}
		jsFinished()
	})

	n := negroni.New()

	n.Use(negroni.NewRecovery())
	n.Use(negronilogrus.NewMiddleware())
	st := negroni.NewStatic(http.Dir("../client/public"))
	st.IndexFile = "NOT_USED_I_HOPE"
	n.Use(st)
	n.UseHandler(m)

	logrus.Info("listening")
	if err := http.ListenAndServe(":3000", n); err != nil {
		panic(err)
	}
}
コード例 #7
0
ファイル: main.go プロジェクト: deoxxa/react-in-go
func main() {
	logrus.StandardLogger().Level = logrus.DebugLevel

	logrus.Debug("starting up")

	baseVM := otto.New()

	smRead := logDuration("read sourcemap")
	smData, err := ioutil.ReadFile("../client/public/bundle.server.js.map")
	if err != nil {
		panic(err)
	}
	smRead()

	smParse := logDuration("parse sourcemap")
	sm, err := sourcemap.Read(bytes.NewReader(smData))
	if err != nil {
		panic(err)
	}
	smParse()

	jsRead := logDuration("read javascript")
	jsData, err := ioutil.ReadFile("../client/public/bundle.server.js")
	if err != nil {
		panic(err)
	}
	jsRead()

	// lodash has a lookahead regex that we don't care about, and it makes otto
	// unhappy. this is a hack to get rid of it.
	jsData = bytes.Replace(jsData, []byte(`(?=`), []byte(`(`), -1)

	jsCompiled := logDuration("compile javascript")
	s, err := baseVM.CompileWithSourceMap("bundle.js", string(jsData), &sm)
	if err != nil {
		if st := dumpDebugError(err); st != "" {
			fmt.Println(st)
		}
		panic(err)
	}
	jsCompiled()

	jsInitialised := logDuration("initialise javascript")
	if _, err := baseVM.Run(s); err != nil {
		if st := dumpDebugError(err); st != "" {
			fmt.Println(st)
		}
		panic(err)
	}
	jsInitialised()

	vmChan := make(chan *otto.Otto)
	go vmCopier(baseVM, vmChan)

	tpl, err := template.ParseFiles("./index.template")
	if err != nil {
		panic(err)
	}

	apiRouter := mux.NewRouter()

	var cats = []Cat{
		Cat{Name: "fluffy", FavouriteFood: "marshmallows"},
		Cat{Name: "beans", FavouriteFood: "legume"},
		Cat{Name: "misty", FavouriteFood: "meat"},
		Cat{Name: "sara", FavouriteFood: "fish"},
	}

	apiRouter.Path("/api/v1/cats").Methods("GET").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.URL.Query().Get("search") == "" {
			w.Header().Set("content-type", "application/json")
			if err := json.NewEncoder(w).Encode(cats); err != nil {
				panic(err)
			}

			return
		}

		var d []Cat
		for _, c := range cats {
			if strings.Contains(strings.ToLower(c.Name), strings.ToLower(r.URL.Query().Get("search"))) {
				d = append(d, c)
			}
		}

		w.Header().Set("content-type", "application/json")
		if err := json.NewEncoder(w).Encode(d); err != nil {
			panic(err)
		}
	})

	apiRouter.Path("/api/v1/cats/{name}").Methods("GET").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		vars := mux.Vars(r)

		for _, c := range cats {
			if strings.ToLower(c.Name) == vars["name"] {
				w.Header().Set("content-type", "application/json")
				if err := json.NewEncoder(w).Encode(c); err != nil {
					panic(err)
				}

				return
			}
		}

		http.NotFound(w, r)
	})

	m := mux.NewRouter()

	m.PathPrefix("/api/v1").Handler(apiRouter)

	m.PathPrefix("/").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		vmCopied := logDuration("copy vm")
		vm := <-vmChan
		vmCopied()

		l := loop.New(vm)
		if err := fetch.DefineWithHandler(vm, l, apiRouter); err != nil {
			panic(err)
		}

		fn, err := vm.Get("renderApplication")
		if err != nil {
			panic(err)
		}

		m := map[string]interface{}{
			"redirect": func(u string) {
				http.Redirect(w, r, u, 301)
			},
			"error": func(e string) {
				http.Error(w, e, http.StatusInternalServerError)
			},
			"notFound": func() {
				http.NotFound(w, r)
			},
			"success": func(initialState, html string) {
				w.Header().Set("content-type", "text/html")

				tpl.Execute(w, map[string]string{
					"initialState": initialState,
					"html":         html,
				})
			},
		}

		v, err := vm.ToValue(m)
		if err != nil {
			panic(err)
		}

		jsRun := logDuration("run javascript")
		if _, err := fn.Call(otto.UndefinedValue(), r.URL.String(), otto.NullValue(), v); err != nil {
			if st := dumpDebugError(err); st != "" {
				panic(fmt.Errorf("%s", st))
			}
			panic(err)
		}
		jsRun()

		jsFinished := logDuration("wait for js")
		if err := l.Run(); err != nil {
			if st := dumpDebugError(err); st != "" {
				panic(fmt.Errorf("%s", st))
			}
			panic(err)
		}
		jsFinished()
	})

	n := negroni.New()

	n.Use(negroni.NewRecovery())
	n.Use(negronilogrus.NewMiddleware())
	st := negroni.NewStatic(http.Dir("../client/public"))
	st.IndexFile = "NOT_USED_I_HOPE"
	n.Use(st)
	n.UseHandler(m)

	logrus.Info("listening")
	if err := http.ListenAndServe(":3000", n); err != nil {
		panic(err)
	}
}
コード例 #8
0
ファイル: main.go プロジェクト: deoxxa/ottoext
func main() {
	flag.Parse()

	vm := otto.New()

	if *debugger {
		vm.SetDebuggerHandler(repl.DebuggerHandler)
	}

	l := loop.New(vm)

	if err := timers.Define(vm, l); err != nil {
		panic(err)
	}
	if err := promise.Define(vm, l); err != nil {
		panic(err)
	}
	if err := fetch.Define(vm, l); err != nil {
		panic(err)
	}
	if err := process.Define(vm, flag.Args()); err != nil {
		panic(err)
	}

	blockingTask := looptask.NewEvalTask("")

	if len(flag.Args()) == 0 || *openRepl {
		l.Add(blockingTask)
	}

	if len(flag.Args()) > 0 {
		d, err := ioutil.ReadFile(flag.Arg(0))
		if err != nil {
			panic(err)
		}

		// this is a very cheap way of "supporting" shebang lines
		if d[0] == '#' {
			d = []byte("// " + string(d))
		}

		s, err := vm.Compile(flag.Arg(0), string(d))
		if err != nil {
			panic(err)
		}

		if err := l.Eval(s); err != nil {
			panic(err)
		}
	}

	if len(flag.Args()) == 0 || *openRepl {
		go func() {
			if err := erepl.Run(l); err != nil && err != io.EOF {
				panic(err)
			}

			l.Ready(blockingTask)
		}()
	}

	if err := l.Run(); err != nil {
		panic(err)
	}
}