old_test.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  1. // Old tests ported to Go1. This is a mess. Want to drop it one day.
  2. // Copyright 2011 Gorilla Authors. All rights reserved.
  3. // Use of this source code is governed by a BSD-style
  4. // license that can be found in the LICENSE file.
  5. package mux
  6. import (
  7. "bytes"
  8. "net/http"
  9. "testing"
  10. )
  11. // ----------------------------------------------------------------------------
  12. // ResponseRecorder
  13. // ----------------------------------------------------------------------------
  14. // Copyright 2009 The Go Authors. All rights reserved.
  15. // Use of this source code is governed by a BSD-style
  16. // license that can be found in the LICENSE file.
  17. // ResponseRecorder is an implementation of http.ResponseWriter that
  18. // records its mutations for later inspection in tests.
  19. type ResponseRecorder struct {
  20. Code int // the HTTP response code from WriteHeader
  21. HeaderMap http.Header // the HTTP response headers
  22. Body *bytes.Buffer // if non-nil, the bytes.Buffer to append written data to
  23. Flushed bool
  24. }
  25. // NewRecorder returns an initialized ResponseRecorder.
  26. func NewRecorder() *ResponseRecorder {
  27. return &ResponseRecorder{
  28. HeaderMap: make(http.Header),
  29. Body: new(bytes.Buffer),
  30. }
  31. }
  32. // DefaultRemoteAddr is the default remote address to return in RemoteAddr if
  33. // an explicit DefaultRemoteAddr isn't set on ResponseRecorder.
  34. const DefaultRemoteAddr = "1.2.3.4"
  35. // Header returns the response headers.
  36. func (rw *ResponseRecorder) Header() http.Header {
  37. return rw.HeaderMap
  38. }
  39. // Write always succeeds and writes to rw.Body, if not nil.
  40. func (rw *ResponseRecorder) Write(buf []byte) (int, error) {
  41. if rw.Body != nil {
  42. rw.Body.Write(buf)
  43. }
  44. if rw.Code == 0 {
  45. rw.Code = http.StatusOK
  46. }
  47. return len(buf), nil
  48. }
  49. // WriteHeader sets rw.Code.
  50. func (rw *ResponseRecorder) WriteHeader(code int) {
  51. rw.Code = code
  52. }
  53. // Flush sets rw.Flushed to true.
  54. func (rw *ResponseRecorder) Flush() {
  55. rw.Flushed = true
  56. }
  57. // ----------------------------------------------------------------------------
  58. func TestRouteMatchers(t *testing.T) {
  59. var scheme, host, path, query, method string
  60. var headers map[string]string
  61. var resultVars map[bool]map[string]string
  62. router := NewRouter()
  63. router.NewRoute().Host("{var1}.google.com").
  64. Path("/{var2:[a-z]+}/{var3:[0-9]+}").
  65. Queries("foo", "bar").
  66. Methods("GET").
  67. Schemes("https").
  68. Headers("x-requested-with", "XMLHttpRequest")
  69. router.NewRoute().Host("www.{var4}.com").
  70. PathPrefix("/foo/{var5:[a-z]+}/{var6:[0-9]+}").
  71. Queries("baz", "ding").
  72. Methods("POST").
  73. Schemes("http").
  74. Headers("Content-Type", "application/json")
  75. reset := func() {
  76. // Everything match.
  77. scheme = "https"
  78. host = "www.google.com"
  79. path = "/product/42"
  80. query = "?foo=bar"
  81. method = "GET"
  82. headers = map[string]string{"X-Requested-With": "XMLHttpRequest"}
  83. resultVars = map[bool]map[string]string{
  84. true: {"var1": "www", "var2": "product", "var3": "42"},
  85. false: {},
  86. }
  87. }
  88. reset2 := func() {
  89. // Everything match.
  90. scheme = "http"
  91. host = "www.google.com"
  92. path = "/foo/product/42/path/that/is/ignored"
  93. query = "?baz=ding"
  94. method = "POST"
  95. headers = map[string]string{"Content-Type": "application/json"}
  96. resultVars = map[bool]map[string]string{
  97. true: {"var4": "google", "var5": "product", "var6": "42"},
  98. false: {},
  99. }
  100. }
  101. match := func(shouldMatch bool) {
  102. url := scheme + "://" + host + path + query
  103. request, _ := http.NewRequest(method, url, nil)
  104. for key, value := range headers {
  105. request.Header.Add(key, value)
  106. }
  107. var routeMatch RouteMatch
  108. matched := router.Match(request, &routeMatch)
  109. if matched != shouldMatch {
  110. // Need better messages. :)
  111. if matched {
  112. t.Errorf("Should match.")
  113. } else {
  114. t.Errorf("Should not match.")
  115. }
  116. }
  117. if matched {
  118. currentRoute := routeMatch.Route
  119. if currentRoute == nil {
  120. t.Errorf("Expected a current route.")
  121. }
  122. vars := routeMatch.Vars
  123. expectedVars := resultVars[shouldMatch]
  124. if len(vars) != len(expectedVars) {
  125. t.Errorf("Expected vars: %v Got: %v.", expectedVars, vars)
  126. }
  127. for name, value := range vars {
  128. if expectedVars[name] != value {
  129. t.Errorf("Expected vars: %v Got: %v.", expectedVars, vars)
  130. }
  131. }
  132. }
  133. }
  134. // 1st route --------------------------------------------------------------
  135. // Everything match.
  136. reset()
  137. match(true)
  138. // Scheme doesn't match.
  139. reset()
  140. scheme = "http"
  141. match(false)
  142. // Host doesn't match.
  143. reset()
  144. host = "www.mygoogle.com"
  145. match(false)
  146. // Path doesn't match.
  147. reset()
  148. path = "/product/notdigits"
  149. match(false)
  150. // Query doesn't match.
  151. reset()
  152. query = "?foo=baz"
  153. match(false)
  154. // Method doesn't match.
  155. reset()
  156. method = "POST"
  157. match(false)
  158. // Header doesn't match.
  159. reset()
  160. headers = map[string]string{}
  161. match(false)
  162. // Everything match, again.
  163. reset()
  164. match(true)
  165. // 2nd route --------------------------------------------------------------
  166. // Everything match.
  167. reset2()
  168. match(true)
  169. // Scheme doesn't match.
  170. reset2()
  171. scheme = "https"
  172. match(false)
  173. // Host doesn't match.
  174. reset2()
  175. host = "sub.google.com"
  176. match(false)
  177. // Path doesn't match.
  178. reset2()
  179. path = "/bar/product/42"
  180. match(false)
  181. // Query doesn't match.
  182. reset2()
  183. query = "?foo=baz"
  184. match(false)
  185. // Method doesn't match.
  186. reset2()
  187. method = "GET"
  188. match(false)
  189. // Header doesn't match.
  190. reset2()
  191. headers = map[string]string{}
  192. match(false)
  193. // Everything match, again.
  194. reset2()
  195. match(true)
  196. }
  197. type headerMatcherTest struct {
  198. matcher headerMatcher
  199. headers map[string]string
  200. result bool
  201. }
  202. var headerMatcherTests = []headerMatcherTest{
  203. {
  204. matcher: headerMatcher(map[string]string{"x-requested-with": "XMLHttpRequest"}),
  205. headers: map[string]string{"X-Requested-With": "XMLHttpRequest"},
  206. result: true,
  207. },
  208. {
  209. matcher: headerMatcher(map[string]string{"x-requested-with": ""}),
  210. headers: map[string]string{"X-Requested-With": "anything"},
  211. result: true,
  212. },
  213. {
  214. matcher: headerMatcher(map[string]string{"x-requested-with": "XMLHttpRequest"}),
  215. headers: map[string]string{},
  216. result: false,
  217. },
  218. }
  219. type hostMatcherTest struct {
  220. matcher *Route
  221. url string
  222. vars map[string]string
  223. result bool
  224. }
  225. var hostMatcherTests = []hostMatcherTest{
  226. {
  227. matcher: NewRouter().NewRoute().Host("{foo:[a-z][a-z][a-z]}.{bar:[a-z][a-z][a-z]}.{baz:[a-z][a-z][a-z]}"),
  228. url: "http://abc.def.ghi/",
  229. vars: map[string]string{"foo": "abc", "bar": "def", "baz": "ghi"},
  230. result: true,
  231. },
  232. {
  233. matcher: NewRouter().NewRoute().Host("{foo:[a-z][a-z][a-z]}.{bar:[a-z][a-z][a-z]}.{baz:[a-z][a-z][a-z]}"),
  234. url: "http://a.b.c/",
  235. vars: map[string]string{"foo": "abc", "bar": "def", "baz": "ghi"},
  236. result: false,
  237. },
  238. }
  239. type methodMatcherTest struct {
  240. matcher methodMatcher
  241. method string
  242. result bool
  243. }
  244. var methodMatcherTests = []methodMatcherTest{
  245. {
  246. matcher: methodMatcher([]string{"GET", "POST", "PUT"}),
  247. method: "GET",
  248. result: true,
  249. },
  250. {
  251. matcher: methodMatcher([]string{"GET", "POST", "PUT"}),
  252. method: "POST",
  253. result: true,
  254. },
  255. {
  256. matcher: methodMatcher([]string{"GET", "POST", "PUT"}),
  257. method: "PUT",
  258. result: true,
  259. },
  260. {
  261. matcher: methodMatcher([]string{"GET", "POST", "PUT"}),
  262. method: "DELETE",
  263. result: false,
  264. },
  265. }
  266. type pathMatcherTest struct {
  267. matcher *Route
  268. url string
  269. vars map[string]string
  270. result bool
  271. }
  272. var pathMatcherTests = []pathMatcherTest{
  273. {
  274. matcher: NewRouter().NewRoute().Path("/{foo:[0-9][0-9][0-9]}/{bar:[0-9][0-9][0-9]}/{baz:[0-9][0-9][0-9]}"),
  275. url: "http://localhost:8080/123/456/789",
  276. vars: map[string]string{"foo": "123", "bar": "456", "baz": "789"},
  277. result: true,
  278. },
  279. {
  280. matcher: NewRouter().NewRoute().Path("/{foo:[0-9][0-9][0-9]}/{bar:[0-9][0-9][0-9]}/{baz:[0-9][0-9][0-9]}"),
  281. url: "http://localhost:8080/1/2/3",
  282. vars: map[string]string{"foo": "123", "bar": "456", "baz": "789"},
  283. result: false,
  284. },
  285. }
  286. type queryMatcherTest struct {
  287. matcher queryMatcher
  288. url string
  289. result bool
  290. }
  291. var queryMatcherTests = []queryMatcherTest{
  292. {
  293. matcher: queryMatcher(map[string]string{"foo": "bar", "baz": "ding"}),
  294. url: "http://localhost:8080/?foo=bar&baz=ding",
  295. result: true,
  296. },
  297. {
  298. matcher: queryMatcher(map[string]string{"foo": "", "baz": ""}),
  299. url: "http://localhost:8080/?foo=anything&baz=anything",
  300. result: true,
  301. },
  302. {
  303. matcher: queryMatcher(map[string]string{"foo": "ding", "baz": "bar"}),
  304. url: "http://localhost:8080/?foo=bar&baz=ding",
  305. result: false,
  306. },
  307. {
  308. matcher: queryMatcher(map[string]string{"bar": "foo", "ding": "baz"}),
  309. url: "http://localhost:8080/?foo=bar&baz=ding",
  310. result: false,
  311. },
  312. }
  313. type schemeMatcherTest struct {
  314. matcher schemeMatcher
  315. url string
  316. result bool
  317. }
  318. var schemeMatcherTests = []schemeMatcherTest{
  319. {
  320. matcher: schemeMatcher([]string{"http", "https"}),
  321. url: "http://localhost:8080/",
  322. result: true,
  323. },
  324. {
  325. matcher: schemeMatcher([]string{"http", "https"}),
  326. url: "https://localhost:8080/",
  327. result: true,
  328. },
  329. {
  330. matcher: schemeMatcher([]string{"https"}),
  331. url: "http://localhost:8080/",
  332. result: false,
  333. },
  334. {
  335. matcher: schemeMatcher([]string{"http"}),
  336. url: "https://localhost:8080/",
  337. result: false,
  338. },
  339. }
  340. type urlBuildingTest struct {
  341. route *Route
  342. vars []string
  343. url string
  344. }
  345. var urlBuildingTests = []urlBuildingTest{
  346. {
  347. route: new(Route).Host("foo.domain.com"),
  348. vars: []string{},
  349. url: "http://foo.domain.com",
  350. },
  351. {
  352. route: new(Route).Host("{subdomain}.domain.com"),
  353. vars: []string{"subdomain", "bar"},
  354. url: "http://bar.domain.com",
  355. },
  356. {
  357. route: new(Route).Host("foo.domain.com").Path("/articles"),
  358. vars: []string{},
  359. url: "http://foo.domain.com/articles",
  360. },
  361. {
  362. route: new(Route).Path("/articles"),
  363. vars: []string{},
  364. url: "/articles",
  365. },
  366. {
  367. route: new(Route).Path("/articles/{category}/{id:[0-9]+}"),
  368. vars: []string{"category", "technology", "id", "42"},
  369. url: "/articles/technology/42",
  370. },
  371. {
  372. route: new(Route).Host("{subdomain}.domain.com").Path("/articles/{category}/{id:[0-9]+}"),
  373. vars: []string{"subdomain", "foo", "category", "technology", "id", "42"},
  374. url: "http://foo.domain.com/articles/technology/42",
  375. },
  376. }
  377. func TestHeaderMatcher(t *testing.T) {
  378. for _, v := range headerMatcherTests {
  379. request, _ := http.NewRequest("GET", "http://localhost:8080/", nil)
  380. for key, value := range v.headers {
  381. request.Header.Add(key, value)
  382. }
  383. var routeMatch RouteMatch
  384. result := v.matcher.Match(request, &routeMatch)
  385. if result != v.result {
  386. if v.result {
  387. t.Errorf("%#v: should match %v.", v.matcher, request.Header)
  388. } else {
  389. t.Errorf("%#v: should not match %v.", v.matcher, request.Header)
  390. }
  391. }
  392. }
  393. }
  394. func TestHostMatcher(t *testing.T) {
  395. for _, v := range hostMatcherTests {
  396. request, _ := http.NewRequest("GET", v.url, nil)
  397. var routeMatch RouteMatch
  398. result := v.matcher.Match(request, &routeMatch)
  399. vars := routeMatch.Vars
  400. if result != v.result {
  401. if v.result {
  402. t.Errorf("%#v: should match %v.", v.matcher, v.url)
  403. } else {
  404. t.Errorf("%#v: should not match %v.", v.matcher, v.url)
  405. }
  406. }
  407. if result {
  408. if len(vars) != len(v.vars) {
  409. t.Errorf("%#v: vars length should be %v, got %v.", v.matcher, len(v.vars), len(vars))
  410. }
  411. for name, value := range vars {
  412. if v.vars[name] != value {
  413. t.Errorf("%#v: expected value %v for key %v, got %v.", v.matcher, v.vars[name], name, value)
  414. }
  415. }
  416. } else {
  417. if len(vars) != 0 {
  418. t.Errorf("%#v: vars length should be 0, got %v.", v.matcher, len(vars))
  419. }
  420. }
  421. }
  422. }
  423. func TestMethodMatcher(t *testing.T) {
  424. for _, v := range methodMatcherTests {
  425. request, _ := http.NewRequest(v.method, "http://localhost:8080/", nil)
  426. var routeMatch RouteMatch
  427. result := v.matcher.Match(request, &routeMatch)
  428. if result != v.result {
  429. if v.result {
  430. t.Errorf("%#v: should match %v.", v.matcher, v.method)
  431. } else {
  432. t.Errorf("%#v: should not match %v.", v.matcher, v.method)
  433. }
  434. }
  435. }
  436. }
  437. func TestPathMatcher(t *testing.T) {
  438. for _, v := range pathMatcherTests {
  439. request, _ := http.NewRequest("GET", v.url, nil)
  440. var routeMatch RouteMatch
  441. result := v.matcher.Match(request, &routeMatch)
  442. vars := routeMatch.Vars
  443. if result != v.result {
  444. if v.result {
  445. t.Errorf("%#v: should match %v.", v.matcher, v.url)
  446. } else {
  447. t.Errorf("%#v: should not match %v.", v.matcher, v.url)
  448. }
  449. }
  450. if result {
  451. if len(vars) != len(v.vars) {
  452. t.Errorf("%#v: vars length should be %v, got %v.", v.matcher, len(v.vars), len(vars))
  453. }
  454. for name, value := range vars {
  455. if v.vars[name] != value {
  456. t.Errorf("%#v: expected value %v for key %v, got %v.", v.matcher, v.vars[name], name, value)
  457. }
  458. }
  459. } else {
  460. if len(vars) != 0 {
  461. t.Errorf("%#v: vars length should be 0, got %v.", v.matcher, len(vars))
  462. }
  463. }
  464. }
  465. }
  466. func TestQueryMatcher(t *testing.T) {
  467. for _, v := range queryMatcherTests {
  468. request, _ := http.NewRequest("GET", v.url, nil)
  469. var routeMatch RouteMatch
  470. result := v.matcher.Match(request, &routeMatch)
  471. if result != v.result {
  472. if v.result {
  473. t.Errorf("%#v: should match %v.", v.matcher, v.url)
  474. } else {
  475. t.Errorf("%#v: should not match %v.", v.matcher, v.url)
  476. }
  477. }
  478. }
  479. }
  480. func TestSchemeMatcher(t *testing.T) {
  481. for _, v := range queryMatcherTests {
  482. request, _ := http.NewRequest("GET", v.url, nil)
  483. var routeMatch RouteMatch
  484. result := v.matcher.Match(request, &routeMatch)
  485. if result != v.result {
  486. if v.result {
  487. t.Errorf("%#v: should match %v.", v.matcher, v.url)
  488. } else {
  489. t.Errorf("%#v: should not match %v.", v.matcher, v.url)
  490. }
  491. }
  492. }
  493. }
  494. func TestUrlBuilding(t *testing.T) {
  495. for _, v := range urlBuildingTests {
  496. u, _ := v.route.URL(v.vars...)
  497. url := u.String()
  498. if url != v.url {
  499. t.Errorf("expected %v, got %v", v.url, url)
  500. /*
  501. reversePath := ""
  502. reverseHost := ""
  503. if v.route.pathTemplate != nil {
  504. reversePath = v.route.pathTemplate.Reverse
  505. }
  506. if v.route.hostTemplate != nil {
  507. reverseHost = v.route.hostTemplate.Reverse
  508. }
  509. t.Errorf("%#v:\nexpected: %q\ngot: %q\nreverse path: %q\nreverse host: %q", v.route, v.url, url, reversePath, reverseHost)
  510. */
  511. }
  512. }
  513. ArticleHandler := func(w http.ResponseWriter, r *http.Request) {
  514. }
  515. router := NewRouter()
  516. router.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).Name("article")
  517. url, _ := router.Get("article").URL("category", "technology", "id", "42")
  518. expected := "/articles/technology/42"
  519. if url.String() != expected {
  520. t.Errorf("Expected %v, got %v", expected, url.String())
  521. }
  522. }
  523. func TestMatchedRouteName(t *testing.T) {
  524. routeName := "stock"
  525. router := NewRouter()
  526. route := router.NewRoute().Path("/products/").Name(routeName)
  527. url := "http://www.domain.com/products/"
  528. request, _ := http.NewRequest("GET", url, nil)
  529. var rv RouteMatch
  530. ok := router.Match(request, &rv)
  531. if !ok || rv.Route != route {
  532. t.Errorf("Expected same route, got %+v.", rv.Route)
  533. }
  534. retName := rv.Route.GetName()
  535. if retName != routeName {
  536. t.Errorf("Expected %q, got %q.", routeName, retName)
  537. }
  538. }
  539. func TestSubRouting(t *testing.T) {
  540. // Example from docs.
  541. router := NewRouter()
  542. subrouter := router.NewRoute().Host("www.domain.com").Subrouter()
  543. route := subrouter.NewRoute().Path("/products/").Name("products")
  544. url := "http://www.domain.com/products/"
  545. request, _ := http.NewRequest("GET", url, nil)
  546. var rv RouteMatch
  547. ok := router.Match(request, &rv)
  548. if !ok || rv.Route != route {
  549. t.Errorf("Expected same route, got %+v.", rv.Route)
  550. }
  551. u, _ := router.Get("products").URL()
  552. builtUrl := u.String()
  553. // Yay, subroute aware of the domain when building!
  554. if builtUrl != url {
  555. t.Errorf("Expected %q, got %q.", url, builtUrl)
  556. }
  557. }
  558. func TestVariableNames(t *testing.T) {
  559. route := new(Route).Host("{arg1}.domain.com").Path("/{arg1}/{arg2:[0-9]+}")
  560. if route.err == nil {
  561. t.Errorf("Expected error for duplicated variable names")
  562. }
  563. }
  564. func TestRedirectSlash(t *testing.T) {
  565. var route *Route
  566. var routeMatch RouteMatch
  567. r := NewRouter()
  568. r.StrictSlash(false)
  569. route = r.NewRoute()
  570. if route.strictSlash != false {
  571. t.Errorf("Expected false redirectSlash.")
  572. }
  573. r.StrictSlash(true)
  574. route = r.NewRoute()
  575. if route.strictSlash != true {
  576. t.Errorf("Expected true redirectSlash.")
  577. }
  578. route = new(Route)
  579. route.strictSlash = true
  580. route.Path("/{arg1}/{arg2:[0-9]+}/")
  581. request, _ := http.NewRequest("GET", "http://localhost/foo/123", nil)
  582. routeMatch = RouteMatch{}
  583. _ = route.Match(request, &routeMatch)
  584. vars := routeMatch.Vars
  585. if vars["arg1"] != "foo" {
  586. t.Errorf("Expected foo.")
  587. }
  588. if vars["arg2"] != "123" {
  589. t.Errorf("Expected 123.")
  590. }
  591. rsp := NewRecorder()
  592. routeMatch.Handler.ServeHTTP(rsp, request)
  593. if rsp.HeaderMap.Get("Location") != "http://localhost/foo/123/" {
  594. t.Errorf("Expected redirect header.")
  595. }
  596. route = new(Route)
  597. route.strictSlash = true
  598. route.Path("/{arg1}/{arg2:[0-9]+}")
  599. request, _ = http.NewRequest("GET", "http://localhost/foo/123/", nil)
  600. routeMatch = RouteMatch{}
  601. _ = route.Match(request, &routeMatch)
  602. vars = routeMatch.Vars
  603. if vars["arg1"] != "foo" {
  604. t.Errorf("Expected foo.")
  605. }
  606. if vars["arg2"] != "123" {
  607. t.Errorf("Expected 123.")
  608. }
  609. rsp = NewRecorder()
  610. routeMatch.Handler.ServeHTTP(rsp, request)
  611. if rsp.HeaderMap.Get("Location") != "http://localhost/foo/123" {
  612. t.Errorf("Expected redirect header.")
  613. }
  614. }
  615. // Test for the new regexp library, still not available in stable Go.
  616. func TestNewRegexp(t *testing.T) {
  617. var p *routeRegexp
  618. var matches []string
  619. tests := map[string]map[string][]string{
  620. "/{foo:a{2}}": {
  621. "/a": nil,
  622. "/aa": {"aa"},
  623. "/aaa": nil,
  624. "/aaaa": nil,
  625. },
  626. "/{foo:a{2,}}": {
  627. "/a": nil,
  628. "/aa": {"aa"},
  629. "/aaa": {"aaa"},
  630. "/aaaa": {"aaaa"},
  631. },
  632. "/{foo:a{2,3}}": {
  633. "/a": nil,
  634. "/aa": {"aa"},
  635. "/aaa": {"aaa"},
  636. "/aaaa": nil,
  637. },
  638. "/{foo:[a-z]{3}}/{bar:[a-z]{2}}": {
  639. "/a": nil,
  640. "/ab": nil,
  641. "/abc": nil,
  642. "/abcd": nil,
  643. "/abc/ab": {"abc", "ab"},
  644. "/abc/abc": nil,
  645. "/abcd/ab": nil,
  646. },
  647. `/{foo:\w{3,}}/{bar:\d{2,}}`: {
  648. "/a": nil,
  649. "/ab": nil,
  650. "/abc": nil,
  651. "/abc/1": nil,
  652. "/abc/12": {"abc", "12"},
  653. "/abcd/12": {"abcd", "12"},
  654. "/abcd/123": {"abcd", "123"},
  655. },
  656. }
  657. for pattern, paths := range tests {
  658. p, _ = newRouteRegexp(pattern, false, false, false)
  659. for path, result := range paths {
  660. matches = p.regexp.FindStringSubmatch(path)
  661. if result == nil {
  662. if matches != nil {
  663. t.Errorf("%v should not match %v.", pattern, path)
  664. }
  665. } else {
  666. if len(matches) != len(result)+1 {
  667. t.Errorf("Expected %v matches, got %v.", len(result)+1, len(matches))
  668. } else {
  669. for k, v := range result {
  670. if matches[k+1] != v {
  671. t.Errorf("Expected %v, got %v.", v, matches[k+1])
  672. }
  673. }
  674. }
  675. }
  676. }
  677. }
  678. }