func TestAddHandlerWithInvalidPathCausesPanic(t *testing.T) {
	tbl := []struct {
		Path    string
		Pattern string
	}{
		{"test", "model.$id.type.$id"},
		{"test", "model..foo"},
		{"test", "model.$"},
		{"test", "model.$.foo"},
		{"test", "model.>.foo"},
		{"test", "model.foo.>bar"},
		{"$id", "model"},
		{">", "model"},
		{"test.>", "model"},
		{"test.", "model"},
		{"test.$id", "model"},
		{"test..foo", "model"},
	}
	for i, l := range tbl {
		restest.AssertPanic(t, func() {
			m := res.NewMux(l.Path)
			m.Handle(l.Pattern, res.GetResource(func(r res.GetRequest) { r.NotFound() }))
		}, "test ", i)
	}
}
Test adding handler with an invalid route handler path causes panic.
package test
import (
	"encoding/json"
	"fmt"
	"testing"
	res "github.com/jirenius/go-res"
	"github.com/jirenius/go-res/restest"
)
var getMatchingPathTestSets = []struct {
	Path         string
	Pattern      string
	ResourceName string
}{
	{"", "model", "model"},
	{"", "model.foo", "model.foo"},
	{"", "model.$id", "model.42"},
	{"", "model.$id.foo", "model.42.foo"},
	{"", "model.>", "model.foo"},
	{"", "model.>", "model.foo.bar"},
	{"", "model.$id.>", "model.42.foo"},
	{"", "model.$id.>", "model.42.foo.bar"},
	{"", "$id", "model"},
	{"", ">", "model.foo"},
	{"", "$id.>", "model.foo.bar"},
	{"", "$id.$foo", "model.foo"},
	{"test", "model", "test.model"},
	{"test", "model.foo", "test.model.foo"},
	{"test", "model.$id", "test.model.42"},
	{"test", "model.$id.foo", "test.model.42.foo"},
	{"test", "model.>", "test.model.foo"},
	{"test", "model.>", "test.model.foo.bar"},
	{"test", "model.$id.>", "test.model.42.foo"},
	{"test", "model.$id.>", "test.model.42.foo.bar"},
	{"test", "$id", "test.model"},
	{"test", ">", "test.model.foo"},
	{"test", "$id.>", "test.model.foo.bar"},
	{"test", "$id.$foo", "test.model.foo"},
}
var getMatchingMountedPathTestSets = []struct {
	Path         string
	Pattern      string
	ResourceName string
}{
	{"", "model", "sub.model"},
	{"", "model.foo", "sub.model.foo"},
	{"", "model.$id", "sub.model.42"},
	{"", "model.$id.foo", "sub.model.42.foo"},
	{"", "model.>", "sub.model.foo"},
	{"", "model.>", "sub.model.foo.bar"},
	{"", "model.$id.>", "sub.model.42.foo"},
	{"", "model.$id.>", "sub.model.42.foo.bar"},
	{"", "$id", "sub.model"},
	{"", ">", "sub.model.foo"},
	{"", "$id.>", "sub.model.foo.bar"},
	{"", "$id.$foo", "sub.model.foo"},
	{"test", "model", "test.sub.model"},
	{"test", "model.foo", "test.sub.model.foo"},
	{"test", "model.$id", "test.sub.model.42"},
	{"test", "model.$id.foo", "test.sub.model.42.foo"},
	{"test", "model.>", "test.sub.model.foo"},
	{"test", "model.>", "test.sub.model.foo.bar"},
	{"test", "model.$id.>", "test.sub.model.42.foo"},
	{"test", "model.$id.>", "test.sub.model.42.foo.bar"},
	{"test", "$id", "test.sub.model"},
	{"test", ">", "test.sub.model.foo"},
	{"test", "$id.>", "test.sub.model.foo.bar"},
	{"test", "$id.$foo", "test.sub.model.foo"},
}
func TestRoute(t *testing.T) {
	runTest(t, func(s *res.Service) {
		s.Route("foo", func(m *res.Mux) {
			m.Handle("model",
				res.GetModel(func(r res.ModelRequest) {
					r.Model(mock.Model)
				}),
			)
		})
	}, func(s *restest.Session) {
		s.Get("test.foo.model").
			Response().
			AssertModel(mock.Model)
	})
}
func TestMount(t *testing.T) {
	runTest(t, func(s *res.Service) {
		m := res.NewMux("")
		m.Handle("model",
			res.GetModel(func(r res.ModelRequest) {
				r.Model(mock.Model)
			}),
		)
		s.Mount("foo", m)
	}, func(s *restest.Session) {
		s.Get("test.foo.model").
			Response().
			AssertModel(mock.Model)
	})
}
func TestMountToRoot(t *testing.T) {
	runTest(t, func(s *res.Service) {
		m := res.NewMux("foo")
		m.Handle("model",
			res.GetModel(func(r res.ModelRequest) {
				r.Model(mock.Model)
			}),
		)
		s.Mount("", m)
	}, func(s *restest.Session) {
		s.Get("test.foo.model").
			Response().
			AssertModel(mock.Model)
	})
}
func TestMountRootMux(t *testing.T) {
	runTest(t, func(s *res.Service) {
		m := res.NewMux("")
		m.Handle("model",
			res.GetModel(func(r res.ModelRequest) {
				r.Model(mock.Model)
			}),
		)
		s.Mount("foo", m)
	}, func(s *restest.Session) {
		s.Get("test.foo.model").
			Response().
			AssertModel(mock.Model)
	})
}
func TestMountRootMuxToRoot(t *testing.T) {
	runTest(t, func(s *res.Service) {
		restest.AssertPanic(t, func() {
			m := res.NewMux("")
			m.Handle("model",
				res.GetModel(func(r res.ModelRequest) {
					r.Model(mock.Model)
				}),
			)
			s.Mount("", m)
		})
	}, nil, restest.WithoutReset)
}
func TestMountMuxTwice(t *testing.T) {
	runTest(t, func(s *res.Service) {
		restest.AssertPanic(t, func() {
			m := res.NewMux("")
			m.Handle("model",
				res.GetModel(func(r res.ModelRequest) {
					r.Model(mock.Model)
				}),
			)
			s.Mount("foo", m)
			s.Mount("bar", m)
		})
	}, nil, restest.WithoutReset)
}
func TestAddHandlerWithValidPath(t *testing.T) {
	tbl := []struct {
		Pattern string
		Path    string
	}{
		{"", "model"},
		{"", "model.foo"},
		{"", "model.$id"},
		{"", "model.$id.foo"},
		{"", "model.>"},
		{"", "model.$id.>"},
		{"test", "model"},
		{"test", "model.foo"},
		{"test", "model.$id"},
		{"test", "model.$id.foo"},
		{"test", "model.>"},
		{"test", "model.$id.>"},
	}
	for _, l := range tbl {
		m := res.NewMux(l.Pattern)
		m.Handle(l.Path, res.GetResource(func(r res.GetRequest) { r.NotFound() }))
	}
}