|
1 | | -import { highlightText } from '../../../tests/highlight-text'; |
2 | 1 | import { hasParams, isEqualPath, removeParams, isExternalLink, removeLastSlash } from './url'; |
3 | 2 |
|
4 | 3 | // ---------------------------------------------------------------------- |
5 | 4 |
|
6 | | -describe('hasParams()', () => { |
7 | | - it(`1. Should return ${highlightText.val('true')} if URL has query parameters`, () => { |
8 | | - expect(hasParams('https://example.com?page=1')).toBe(true); |
9 | | - }); |
| 5 | +const mapWithIndex = <T extends readonly any[][]>(cases: T) => |
| 6 | + cases.map((testCase, index) => [index + 1, ...testCase] as const); |
10 | 7 |
|
11 | | - it(`2. Should return ${highlightText.val('false')} if URL does not have query parameters`, () => { |
12 | | - expect(hasParams('https://example.com')).toBe(false); |
13 | | - }); |
| 8 | +describe('hasParams()', () => { |
| 9 | + const cases = [ |
| 10 | + ['Should return true with single param', '/dashboard?page=1', true], |
| 11 | + ['Should return true with multiple params', '/dashboard?x=1&y=2', true], |
| 12 | + ['Should return false with no params', '/dashboard', false], |
| 13 | + ['Should return false with trailing "?"', '/dashboard?', false], |
| 14 | + ['Should return false for empty string', '', false], |
| 15 | + ]; |
14 | 16 |
|
15 | | - it(`3. Should return ${highlightText.val('false')} if URL has empty query parameters`, () => { |
16 | | - expect(hasParams('https://example.com?')).toBe(false); |
| 17 | + test.each(mapWithIndex(cases))('%i. %s', (_i, _desc, input, expected) => { |
| 18 | + expect(hasParams(input)).toBe(expected); |
17 | 19 | }); |
18 | 20 | }); |
19 | 21 |
|
20 | 22 | describe('removeLastSlash()', () => { |
21 | | - it(`1. Should remove trailing slash from pathname`, () => { |
22 | | - expect(removeLastSlash('/dashboard/calendar/')).toBe('/dashboard/calendar'); |
23 | | - }); |
| 23 | + const cases = [ |
| 24 | + ['Removes trailing slash', '/dashboard/', '/dashboard'], |
| 25 | + ['Keeps path without slash', '/dashboard', '/dashboard'], |
| 26 | + ['Removes slash from nested path', '/dashboard/user/', '/dashboard/user'], |
| 27 | + ['Preserves root slash', '/', '/'], |
| 28 | + ['Removes extra trailing slashes', '/test//', '/test/'], |
| 29 | + ]; |
24 | 30 |
|
25 | | - it(`2. Should return the same pathname if there is no trailing slash`, () => { |
26 | | - expect(removeLastSlash('/dashboard/calendar')).toBe('/dashboard/calendar'); |
27 | | - }); |
28 | | - |
29 | | - it(`3. Should not remove the slash if pathname is just "/"`, () => { |
30 | | - expect(removeLastSlash('/')).toBe('/'); |
| 31 | + test.each(mapWithIndex(cases))('%i. %s', (_i, _desc, input, expected) => { |
| 32 | + expect(removeLastSlash(input)).toBe(expected); |
31 | 33 | }); |
32 | 34 | }); |
33 | 35 |
|
34 | 36 | describe('isEqualPath()', () => { |
35 | | - it(`1. Should return true if both paths are equal after removing trailing slashes`, () => { |
36 | | - expect(isEqualPath('/dashboard/calendar/', '/dashboard/calendar/')).toBe(true); |
37 | | - }); |
| 37 | + const cases = [ |
| 38 | + ['Exact match', '/dashboard', '/dashboard', true], |
| 39 | + ['Match with trailing slash', '/dashboard/', '/dashboard', true], |
| 40 | + ['Both paths have trailing slashes', '/dashboard/', '/dashboard/', true], |
| 41 | + ['Different paths', '/dashboard', '/settings', false], |
| 42 | + ]; |
38 | 43 |
|
39 | | - it(`2. Should return true if both paths are equal after removing trailing slashes`, () => { |
40 | | - expect(isEqualPath('/dashboard/calendar', '/dashboard/calendar/')).toBe(true); |
| 44 | + test.each(mapWithIndex(cases))('%i. %s', (_i, _desc, a, b, expected) => { |
| 45 | + expect(isEqualPath(a, b)).toBe(expected); |
41 | 46 | }); |
42 | 47 | }); |
43 | 48 |
|
44 | 49 | describe('removeParams()', () => { |
45 | | - it(`1. Should remove query parameters from URL`, () => { |
46 | | - expect(removeParams('https://example.com/page?param=value')).toBe('/page'); |
47 | | - }); |
| 50 | + const cases = [ |
| 51 | + ['Removes simple query', '/dashboard?page=1', '/dashboard'], |
| 52 | + ['Removes complex query', '/dashboard/user?id=123&filter=active', '/dashboard/user'], |
| 53 | + ['Ignores when no query', '/dashboard/user', '/dashboard/user'], |
| 54 | + ['Removes query with trailing slash', '/dashboard/user/?id=1', '/dashboard/user'], |
| 55 | + ['Removes query from full URL', 'https://example.com/page?id=1', '/page'], |
| 56 | + ]; |
48 | 57 |
|
49 | | - it(`2. Should return the same URL if there are no query parameters`, () => { |
50 | | - expect(removeParams('https://example.com/page')).toBe('/page'); |
51 | | - }); |
52 | | - |
53 | | - it(`3. Should return the same URL if there are no query parameters`, () => { |
54 | | - expect(removeParams('https://example.com/')).toBe('/'); |
55 | | - }); |
56 | | - |
57 | | - it(`4. Should return the same URL if there are no query parameters`, () => { |
58 | | - expect(removeParams('https://example.com')).toBe('/'); |
59 | | - }); |
60 | | - |
61 | | - it(`5. Should return the same URL if it is invalid`, () => { |
62 | | - expect(removeParams('invalid-url')).toBe('/invalid-url'); |
| 58 | + test.each(mapWithIndex(cases))('%i. %s', (_i, _desc, input, expected) => { |
| 59 | + expect(removeParams(input)).toBe(expected); |
63 | 60 | }); |
64 | 61 | }); |
65 | 62 |
|
66 | 63 | describe('isExternalLink()', () => { |
67 | | - it(`1. Should return ${highlightText.val('true')} if URL is an external link`, () => { |
68 | | - expect(isExternalLink('https://example.com')).toBe(true); |
69 | | - }); |
70 | | - |
71 | | - it(`2. Should return ${highlightText.val('false')} if URL is not an external link`, () => { |
72 | | - expect(isExternalLink('/internal/page')).toBe(false); |
73 | | - }); |
74 | | - |
75 | | - it(`3. Should return ${highlightText.val('true')} if URL starts with http`, () => { |
76 | | - expect(isExternalLink('http://example.com')).toBe(true); |
| 64 | + const cases = [ |
| 65 | + ['Detects http link', 'http://example.com', true], |
| 66 | + ['Detects https link', 'https://example.com', true], |
| 67 | + ['Returns false for local path', '/dashboard', false], |
| 68 | + ['Returns false for anchor', '#section', false], |
| 69 | + ['Does not false-positive on "http123"', 'http123', false], |
| 70 | + ]; |
| 71 | + |
| 72 | + test.each(mapWithIndex(cases))('%i. %s', (_i, _desc, input, expected) => { |
| 73 | + expect(isExternalLink(input)).toBe(expected); |
77 | 74 | }); |
78 | 75 | }); |
0 commit comments