func loadDenco(routes []route) http.Handler {
	handler := &dencoHandler{routerMap: map[string]*denco.Router{
		"GET":    denco.New(),
		"POST":   denco.New(),
		"PUT":    denco.New(),
		"PATCH":  denco.New(),
		"DELETE": denco.New(),
	}}
	recordMap := make(map[string][]denco.Record)
	for _, route := range routes {
		var f http.HandlerFunc
		switch route.method {
		case "GET":
			f = handler.Get
		case "POST":
			f = handler.Post
		case "PUT":
			f = handler.Put
		case "PATCH":
			f = handler.Patch
		case "DELETE":
			f = handler.Delete
		}
		recordMap[route.method] = append(recordMap[route.method], denco.NewRecord(route.path, f))
	}
	for method, records := range recordMap {
		if err := handler.routerMap[method].Build(records); err != nil {
			panic(err)
		}
	}
	return handler
}
Example #2
0
func TestRouter_Build_withSizeHint(t *testing.T) {
	for _, v := range []struct {
		key      string
		sizeHint int
		expect   int
	}{
		{"/user", 0, 0},
		{"/user", 1, 1},
		{"/user", 2, 2},
		{"/user/:id", 3, 3},
		{"/user/:id/:group", 0, 0},
		{"/user/:id/:group", 1, 1},
	} {
		r := denco.New()
		r.SizeHint = v.sizeHint
		records := []denco.Record{
			{v.key, "value"},
		}
		if err := r.Build(records); err != nil {
			t.Fatal(err)
		}
		actual := r.SizeHint
		expect := v.expect
		if !reflect.DeepEqual(actual, expect) {
			t.Errorf(`Router.Build(%#v); Router.SizeHint => (%[2]T=%#[2]v); want (%[3]T=%#[3]v)`, records, actual, expect)
		}
	}
}
Example #3
0
func TestRouter_Build_withoutSizeHint(t *testing.T) {
	for _, v := range []struct {
		keys     []string
		sizeHint int
	}{
		{[]string{"/user"}, 0},
		{[]string{"/user/:id"}, 1},
		{[]string{"/user/:id/post"}, 1},
		{[]string{"/user/:id/:group"}, 2},
		{[]string{"/user/:id/post/:cid"}, 2},
		{[]string{"/user/:id/post/:cid", "/admin/:id/post/:cid"}, 2},
		{[]string{"/user/:id", "/admin/:id/post/:cid"}, 2},
		{[]string{"/user/:id/post/:cid", "/admin/:id/post/:cid/:type"}, 3},
	} {
		r := denco.New()
		actual := r.SizeHint
		expect := -1
		if !reflect.DeepEqual(actual, expect) {
			t.Errorf(`before Build; Router.SizeHint => (%[1]T=%#[1]v); want (%[2]T=%#[2]v)`, actual, expect)
		}
		records := make([]denco.Record, len(v.keys))
		for i, k := range v.keys {
			records[i] = denco.Record{k, "value"}
		}
		if err := r.Build(records); err != nil {
			t.Fatal(err)
		}
		actual = r.SizeHint
		expect = v.sizeHint
		if !reflect.DeepEqual(actual, expect) {
			t.Errorf(`Router.Build(%#v); Router.SizeHint => (%[2]T=%#[2]v); want (%[3]T=%#[3]v)`, records, actual, expect)
		}
	}
}
Example #4
0
// buildForward builds forward router.
func (router *Router) buildForward() error {
	records := make([]denco.Record, len(router.routeTable))
	for i, route := range router.routeTable {
		records[i] = denco.NewRecord(route.Path, route)
	}
	router.forward = denco.New()
	return router.forward.Build(records)
}
func benchmarkRouterBuild(b *testing.B, records []denco.Record) {
	for i := 0; i < b.N; i++ {
		router := denco.New()
		if err := router.Build(records); err != nil {
			b.Fatal(err)
		}
	}
}
func loadDencoSingle(method, path string, handler *dencoHandler, hfunc http.HandlerFunc) http.Handler {
	handler.routerMap = map[string]*denco.Router{
		method: denco.New(),
	}

	if err := handler.routerMap[method].Build([]denco.Record{
		denco.NewRecord(path, hfunc),
	}); err != nil {
		panic(err)
	}
	return handler
}
Example #7
0
func (d *defaultRouteBuilder) Build() *defaultRouter {
	routers := make(map[string]*denco.Router)
	for method, records := range d.records {
		router := denco.New()
		router.Build(records)
		routers[method] = router
	}
	return &defaultRouter{
		spec:    d.spec,
		routers: routers,
	}
}
Example #8
0
func TestRouter_Build(t *testing.T) {
	// test for duplicate name of path parameters.
	func() {
		r := denco.New()
		if err := r.Build([]denco.Record{
			{"/:user/:id/:id", "testroute0"},
			{"/:user/:user/:id", "testroute0"},
		}); err == nil {
			t.Errorf("no error returned by duplicate name of path parameters")
		}
	}()
}
Example #9
0
func runLookupTest(t *testing.T, records []denco.Record, testcases []testcase) {
	r := denco.New()
	if err := r.Build(records); err != nil {
		t.Fatal(err)
	}
	for _, testcase := range testcases {
		data, params, found := r.Lookup(testcase.path)
		if !reflect.DeepEqual(data, testcase.value) || !reflect.DeepEqual(params, denco.Params(testcase.params)) || !reflect.DeepEqual(found, testcase.found) {
			t.Errorf("Router.Lookup(%q) => (%#v, %#v, %#v), want (%#v, %#v, %#v)", testcase.path, data, params, found, testcase.value, denco.Params(testcase.params), testcase.found)
		}
	}
}
func benchmarkRouterLookupSingleParam(b *testing.B, records []denco.Record) {
	router := denco.New()
	if err := router.Build(records); err != nil {
		b.Fatal(err)
	}
	record := pickTestRecord(records)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		if _, _, found := router.Lookup(record.Key); !found {
			b.Fail()
		}
	}
}
func benchmarkRouterLookupStatic(b *testing.B, n int) {
	b.StopTimer()
	router := denco.New()
	records := makeTestStaticRecords(n)
	if err := router.Build(records); err != nil {
		b.Fatal(err)
	}
	record := pickTestRecord(records)
	b.StartTimer()
	for i := 0; i < b.N; i++ {
		if r, _, _ := router.Lookup(record.Key); r != record.Value {
			b.Fail()
		}
	}
}
Example #12
0
func TestRouter_Lookup_withManyRoutes(t *testing.T) {
	n := 1000
	rand.Seed(time.Now().UnixNano())
	records := make([]denco.Record, n)
	for i := 0; i < n; i++ {
		records[i] = denco.Record{Key: "/" + randomString(rand.Intn(50)+10), Value: fmt.Sprintf("route%d", i)}
	}
	router := denco.New()
	if err := router.Build(records); err != nil {
		t.Fatal(err)
	}
	for _, r := range records {
		data, params, found := router.Lookup(r.Key)
		if !reflect.DeepEqual(data, r.Value) || len(params) != 0 || !reflect.DeepEqual(found, true) {
			t.Errorf("Router.Lookup(%q) => (%#v, %#v, %#v), want (%#v, %#v, %#v)", r.Key, data, len(params), found, r.Value, 0, true)
		}
	}
}
Example #13
0
// Build compiles registered routes. Routes that are added after building will not
// be handled. A new call to build will be required.
func (t *Router) Build() error {
	t.data = denco.New()
	return t.data.Build(t.records)
}