|
| 1 | +// Test suite for markdown link path normalization |
| 2 | +// This can be run with: npx tsx src/components/test-normalize-path.ts |
| 3 | + |
| 4 | +import { normalizeMarkdownPath } from '../utils/normalize-markdown-path' |
| 5 | + |
| 6 | +// Test cases |
| 7 | +const testCases: Array<[string, string, string]> = [ |
| 8 | + // [input, expected, description] |
| 9 | + |
| 10 | + // Paths that should be modified |
| 11 | + ['./foo', '../foo', 'Same directory with ./'], |
| 12 | + ['./guides/foo', '../guides/foo', 'Subdirectory with ./'], |
| 13 | + ['./overview.md#api-reference', '../overview.md#api-reference', 'Same directory with ./ and hash'], |
| 14 | + ['./installation.md', '../installation.md', 'Real example from quick-start.md'], |
| 15 | + ['./overview.md', '../overview.md', 'Real example from quick-start.md'], |
| 16 | + ['./live-queries.md', '../live-queries.md', 'Real example from quick-start.md'], |
| 17 | + ['foo', '../foo', 'Bare filename (same directory)'], |
| 18 | + ['guides/foo', '../guides/foo', 'Bare subdirectory path'], |
| 19 | + ['guides/subfolder/foo', '../guides/subfolder/foo', 'Nested bare path'], |
| 20 | + ['live-queries.md', '../live-queries.md', 'Real bare filename from overview.md'], |
| 21 | + |
| 22 | + // Paths that should NOT be modified (from real DB docs) |
| 23 | + ['../foo', '../foo', 'Already has ../'], |
| 24 | + ['../classes/foo', '../classes/foo', 'Already has ../ with subdirectory'], |
| 25 | + ['../classes/aggregatefunctionnotinselecterror.md', '../classes/aggregatefunctionnotinselecterror.md', 'Real example from reference docs'], |
| 26 | + ['../interfaces/btreeindexoptions.md', '../interfaces/btreeindexoptions.md', 'Real example from reference docs'], |
| 27 | + ['../type-aliases/changelistener.md', '../type-aliases/changelistener.md', 'Real example from reference docs'], |
| 28 | + ['../../foo', '../../foo', 'Multiple ../'], |
| 29 | + ['/absolute/path', '/absolute/path', 'Absolute path'], |
| 30 | + ['http://example.com', 'http://example.com', 'HTTP URL'], |
| 31 | + ['https://example.com', 'https://example.com', 'HTTPS URL'], |
| 32 | + ['https://github.com/TanStack/db/blob/main/packages/db/src/types.ts#L228', 'https://github.com/TanStack/db/blob/main/packages/db/src/types.ts#L228', 'GitHub source link'], |
| 33 | + |
| 34 | + // Real examples from TanStack Router docs |
| 35 | + ['../learn-the-basics.md', '../learn-the-basics.md', 'Router: Parent directory link'], |
| 36 | + ['../hosting.md', '../hosting.md', 'Router: Parent directory hosting guide'], |
| 37 | + ['../server-functions.md', '../server-functions.md', 'Router: Parent directory server functions'], |
| 38 | + ['../server-routes.md', '../server-routes.md', 'Router: Parent directory server routes'], |
| 39 | + ['../middleware.md', '../middleware.md', 'Router: Parent directory middleware'], |
| 40 | +] |
| 41 | + |
| 42 | +// Run tests |
| 43 | +console.log('Running path normalization tests:\n') |
| 44 | +let passed = 0 |
| 45 | +let failed = 0 |
| 46 | + |
| 47 | +for (const [input, expected, description] of testCases) { |
| 48 | + const result = normalizeMarkdownPath(input) |
| 49 | + const isPass = result === expected |
| 50 | + |
| 51 | + if (isPass) { |
| 52 | + console.log(`✅ PASS: ${description}`) |
| 53 | + console.log(` Input: "${input}" → Output: "${result}"`) |
| 54 | + passed++ |
| 55 | + } else { |
| 56 | + console.log(`❌ FAIL: ${description}`) |
| 57 | + console.log(` Input: "${input}"`) |
| 58 | + console.log(` Expected: "${expected}"`) |
| 59 | + console.log(` Got: "${result}"`) |
| 60 | + failed++ |
| 61 | + } |
| 62 | + console.log('') |
| 63 | +} |
| 64 | + |
| 65 | +console.log(`\nResults: ${passed} passed, ${failed} failed`) |
| 66 | + |
| 67 | +// Edge cases to consider |
| 68 | +console.log('\n--- Edge Cases to Consider ---') |
| 69 | +console.log('1. Hash fragments: "foo#section" should become "../foo#section"') |
| 70 | +console.log('2. Query params: "foo?param=value" should become "../foo?param=value"') |
| 71 | +console.log('3. Special protocols: "mailto:", "javascript:", etc. should not be modified') |
| 72 | +console.log('4. Empty string or undefined should return as-is') |
| 73 | + |
| 74 | +// Test edge cases |
| 75 | +console.log('\n--- Testing Edge Cases ---\n') |
| 76 | + |
| 77 | +const edgeCases: Array<[string | undefined, string | undefined, string]> = [ |
| 78 | + ['foo#section', '../foo#section', 'Hash fragment'], |
| 79 | + ['./foo#section', '../foo#section', 'With ./ and hash'], |
| 80 | + ['../foo#section', '../foo#section', 'Already ../ with hash'], |
| 81 | + [undefined, undefined, 'Undefined input'], |
| 82 | + ['', '', 'Empty string'], |
| 83 | + ['#section', '#section', 'Hash only (should not be modified)'], |
| 84 | + ['mailto:[email protected]', 'mailto:[email protected]', 'Mailto protocol'], |
| 85 | + ['javascript:void(0)', 'javascript:void(0)', 'Javascript protocol'], |
| 86 | +] |
| 87 | + |
| 88 | +for (const [input, expected, description] of edgeCases) { |
| 89 | + const result = normalizeMarkdownPath(input) |
| 90 | + const isPass = result === expected |
| 91 | + |
| 92 | + if (isPass) { |
| 93 | + console.log(`✅ PASS: ${description}`) |
| 94 | + console.log(` Input: "${input}" → Output: "${result}"`) |
| 95 | + } else { |
| 96 | + console.log(`❌ FAIL: ${description}`) |
| 97 | + console.log(` Input: "${input}"`) |
| 98 | + console.log(` Expected: "${expected}"`) |
| 99 | + console.log(` Got: "${result}"`) |
| 100 | + } |
| 101 | + console.log('') |
| 102 | +} |
| 103 | + |
0 commit comments