PageRenderTime 54ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/modules/__tests__/PathUtils-test.js

https://gitlab.com/kevintcoughlin/react-router
JavaScript | 321 lines | 23 code | 4 blank | 294 comment | 0 complexity | e1ba1208d604daafcf1649ac43436fcd MD5 | raw file
  1. var expect = require('expect');
  2. var PathUtils = require('../PathUtils');
  3. describe('PathUtils.extractParamNames', function () {
  4. describe('when a pattern contains no dynamic segments', function () {
  5. it('returns an empty array', function () {
  6. expect(PathUtils.extractParamNames('a/b/c')).toEqual([]);
  7. });
  8. });
  9. describe('when a pattern contains :a and :b dynamic segments', function () {
  10. it('returns the correct names', function () {
  11. expect(PathUtils.extractParamNames('/comments/:a/:b/edit')).toEqual([ 'a', 'b' ]);
  12. });
  13. });
  14. describe('when a pattern has a *', function () {
  15. it('uses the name "splat"', function () {
  16. expect(PathUtils.extractParamNames('/files/*.jpg')).toEqual([ 'splat' ]);
  17. });
  18. });
  19. });
  20. describe('PathUtils.extractParams', function () {
  21. describe('when a pattern does not have dynamic segments', function () {
  22. var pattern = 'a/b/c';
  23. describe('and the path matches', function () {
  24. it('returns an empty object', function () {
  25. expect(PathUtils.extractParams(pattern, pattern)).toEqual({});
  26. });
  27. });
  28. describe('and the path does not match', function () {
  29. it('returns null', function () {
  30. expect(PathUtils.extractParams(pattern, 'd/e/f')).toBe(null);
  31. });
  32. });
  33. });
  34. describe('when a pattern has dynamic segments', function () {
  35. var pattern = 'comments/:id.:ext/edit';
  36. describe('and the path matches', function () {
  37. it('returns an object with the params', function () {
  38. expect(PathUtils.extractParams(pattern, 'comments/abc.js/edit')).toEqual({ id: 'abc', ext: 'js' });
  39. });
  40. });
  41. describe('and the pattern is optional', function () {
  42. var pattern = 'comments/(:id)/edit';
  43. describe('and the path matches with supplied param', function () {
  44. it('returns an object with the params', function () {
  45. expect(PathUtils.extractParams(pattern, 'comments/123/edit')).toEqual({ id: '123' });
  46. });
  47. });
  48. describe('and the path matches without supplied param', function () {
  49. it('returns an object with an undefined param', function () {
  50. expect(PathUtils.extractParams(pattern, 'comments//edit')).toEqual({ id: undefined });
  51. });
  52. });
  53. });
  54. describe('and the pattern and forward slash are optional', function () {
  55. var pattern = 'comments(/:id)/edit';
  56. describe('and the path matches with supplied param', function () {
  57. it('returns an object with the params', function () {
  58. expect(PathUtils.extractParams(pattern, 'comments/123/edit')).toEqual({ id: '123' });
  59. });
  60. });
  61. describe('and the path matches without supplied param', function () {
  62. it('returns an object with an undefined param', function () {
  63. expect(PathUtils.extractParams(pattern, 'comments/edit')).toEqual({ id: undefined });
  64. });
  65. });
  66. });
  67. describe('and the path does not match', function () {
  68. it('returns null', function () {
  69. expect(PathUtils.extractParams(pattern, 'users/123')).toBe(null);
  70. });
  71. });
  72. describe('and the path matches with a segment containing a .', function () {
  73. it('returns an object with the params', function () {
  74. expect(PathUtils.extractParams(pattern, 'comments/foo.bar/edit')).toEqual({ id: 'foo', ext: 'bar' });
  75. });
  76. });
  77. });
  78. describe('when a pattern has characters that have special URL encoding', function () {
  79. var pattern = 'one, two';
  80. describe('and the path matches', function () {
  81. it('returns an empty object', function () {
  82. expect(PathUtils.extractParams(pattern, 'one, two')).toEqual({});
  83. });
  84. });
  85. describe('and the path does not match', function () {
  86. it('returns null', function () {
  87. expect(PathUtils.extractParams(pattern, 'one two')).toBe(null);
  88. });
  89. });
  90. });
  91. describe('when a pattern has dynamic segments and characters that have special URL encoding', function () {
  92. var pattern = '/comments/:id/edit now';
  93. describe('and the path matches', function () {
  94. it('returns an object with the params', function () {
  95. expect(PathUtils.extractParams(pattern, '/comments/abc/edit now')).toEqual({ id: 'abc' });
  96. });
  97. });
  98. describe('and the path does not match', function () {
  99. it('returns null', function () {
  100. expect(PathUtils.extractParams(pattern, '/users/123')).toBe(null);
  101. });
  102. });
  103. });
  104. describe('when a pattern has a *', function () {
  105. describe('and the path matches', function () {
  106. it('returns an object with the params', function () {
  107. expect(PathUtils.extractParams('/files/*', '/files/my/photo.jpg')).toEqual({ splat: 'my/photo.jpg' });
  108. expect(PathUtils.extractParams('/files/*', '/files/my/photo.jpg.zip')).toEqual({ splat: 'my/photo.jpg.zip' });
  109. expect(PathUtils.extractParams('/files/*.jpg', '/files/my/photo.jpg')).toEqual({ splat: 'my/photo' });
  110. });
  111. });
  112. describe('and the path does not match', function () {
  113. it('returns null', function () {
  114. expect(PathUtils.extractParams('/files/*.jpg', '/files/my/photo.png')).toBe(null);
  115. });
  116. });
  117. });
  118. describe('when a pattern has an optional group', function () {
  119. var pattern = '/archive(/:name)';
  120. describe('and the path matches', function () {
  121. it('returns an object with the params', function () {
  122. expect(PathUtils.extractParams(pattern, '/archive/foo')).toEqual({ name: 'foo' });
  123. expect(PathUtils.extractParams(pattern, '/archive')).toEqual({ name: undefined });
  124. });
  125. });
  126. describe('and the path does not match', function () {
  127. it('returns null', function () {
  128. expect(PathUtils.extractParams(pattern, '/archiv')).toBe(null);
  129. });
  130. });
  131. });
  132. describe('when a param has dots', function () {
  133. var pattern = '/:query/with/:domain';
  134. describe('and the path matches', function () {
  135. it('returns an object with the params', function () {
  136. expect(PathUtils.extractParams(pattern, '/foo/with/foo.app')).toEqual({ query: 'foo', domain: 'foo.app' });
  137. expect(PathUtils.extractParams(pattern, '/foo.ap/with/foo')).toEqual({ query: 'foo.ap', domain: 'foo' });
  138. expect(PathUtils.extractParams(pattern, '/foo.ap/with/foo.app')).toEqual({ query: 'foo.ap', domain: 'foo.app' });
  139. });
  140. });
  141. describe('and the path does not match', function () {
  142. it('returns null', function () {
  143. expect(PathUtils.extractParams(pattern, '/foo.ap')).toBe(null);
  144. });
  145. });
  146. });
  147. });
  148. describe('PathUtils.injectParams', function () {
  149. describe('when a pattern does not have dynamic segments', function () {
  150. var pattern = 'a/b/c';
  151. it('returns the pattern', function () {
  152. expect(PathUtils.injectParams(pattern, {})).toEqual(pattern);
  153. });
  154. });
  155. describe('when a pattern has dynamic segments', function () {
  156. var pattern = 'comments/:id/edit';
  157. describe('and a param is missing', function () {
  158. it('throws an Error', function () {
  159. expect(function () {
  160. PathUtils.injectParams(pattern, {});
  161. }).toThrow(Error);
  162. });
  163. });
  164. describe('and a param is optional', function () {
  165. var pattern = 'comments/(:id)/edit';
  166. it('returns the correct path when param is supplied', function () {
  167. expect(PathUtils.injectParams(pattern, { id:'123' })).toEqual('comments/123/edit');
  168. });
  169. it('returns the correct path when param is not supplied', function () {
  170. expect(PathUtils.injectParams(pattern, {})).toEqual('comments/edit');
  171. });
  172. });
  173. describe('and a param and forward slash are optional', function () {
  174. var pattern = 'comments(/:id)/edit';
  175. it('returns the correct path when param is supplied', function () {
  176. expect(PathUtils.injectParams(pattern, { id:'123' })).toEqual('comments/123/edit');
  177. });
  178. it('returns the correct path when param is not supplied', function () {
  179. expect(PathUtils.injectParams(pattern, {})).toEqual('comments/edit');
  180. });
  181. });
  182. describe('and all params are present', function () {
  183. it('returns the correct path', function () {
  184. expect(PathUtils.injectParams(pattern, { id: 'abc' })).toEqual('comments/abc/edit');
  185. });
  186. it('returns the correct path when the value is 0', function () {
  187. expect(PathUtils.injectParams(pattern, { id: 0 })).toEqual('comments/0/edit');
  188. });
  189. });
  190. describe('and some params have special URL encoding', function () {
  191. it('returns the correct path', function () {
  192. expect(PathUtils.injectParams(pattern, { id: 'one, two' })).toEqual('comments/one, two/edit');
  193. });
  194. });
  195. describe('and a param has a forward slash', function () {
  196. it('preserves the forward slash', function () {
  197. expect(PathUtils.injectParams(pattern, { id: 'the/id' })).toEqual('comments/the/id/edit');
  198. });
  199. });
  200. describe('and some params contain dots', function () {
  201. it('returns the correct path', function () {
  202. expect(PathUtils.injectParams(pattern, { id: 'alt.black.helicopter' })).toEqual('comments/alt.black.helicopter/edit');
  203. });
  204. });
  205. });
  206. describe('when a pattern has one splat', function () {
  207. it('returns the correct path', function () {
  208. expect(PathUtils.injectParams('/a/*/d', { splat: 'b/c' })).toEqual('/a/b/c/d');
  209. });
  210. });
  211. describe('when a pattern has multiple splats', function () {
  212. it('returns the correct path', function () {
  213. expect(PathUtils.injectParams('/a/*/c/*', { splat: [ 'b', 'd' ] })).toEqual('/a/b/c/d');
  214. });
  215. it('complains if not given enough splat values', function () {
  216. expect(function () {
  217. PathUtils.injectParams('/a/*/c/*', { splat: [ 'b' ] });
  218. }).toThrow(Error);
  219. });
  220. });
  221. describe('when a pattern has dots', function () {
  222. it('returns the correct path', function () {
  223. expect(PathUtils.injectParams('/foo.bar.baz')).toEqual('/foo.bar.baz');
  224. });
  225. });
  226. });
  227. describe('PathUtils.extractQuery', function () {
  228. describe('when the path contains a query string', function () {
  229. it('returns the parsed query object', function () {
  230. expect(PathUtils.extractQuery('/?id=def&show=true')).toEqual({ id: 'def', show: 'true' });
  231. });
  232. it('properly handles arrays', function () {
  233. expect(PathUtils.extractQuery('/?id%5B%5D=a&id%5B%5D=b')).toEqual({ id: [ 'a', 'b' ] });
  234. });
  235. it('properly handles encoded ampersands', function () {
  236. expect(PathUtils.extractQuery('/?id=a%26b')).toEqual({ id: 'a&b' });
  237. });
  238. });
  239. describe('when the path does not contain a query string', function () {
  240. it('returns null', function () {
  241. expect(PathUtils.extractQuery('/a/b/c')).toBe(null);
  242. });
  243. });
  244. });
  245. describe('PathUtils.withoutQuery', function () {
  246. it('removes the query string', function () {
  247. expect(PathUtils.withoutQuery('/a/b/c?id=def')).toEqual('/a/b/c');
  248. });
  249. });
  250. describe('PathUtils.withQuery', function () {
  251. it('appends the query string', function () {
  252. expect(PathUtils.withQuery('/a/b/c', { id: 'def' })).toEqual('/a/b/c?id=def');
  253. });
  254. it('merges two query strings', function () {
  255. expect(PathUtils.withQuery('/path?a=b', { c: [ 'd', 'e' ] })).toEqual('/path?a=b&c%5B%5D=d&c%5B%5D=e');
  256. });
  257. it('removes query string', function () {
  258. expect(PathUtils.withQuery('/a/b/c?a=b', { a: undefined })).toEqual('/a/b/c');
  259. });
  260. it('handles special characters', function () {
  261. expect(PathUtils.withQuery('/path?a=b', { c: [ 'd#e', 'f&a=i#j+k' ] })).toEqual('/path?a=b&c%5B%5D=d%23e&c%5B%5D=f%26a%3Di%23j%2Bk');
  262. });
  263. });