Skip to content

Commit f6f12ab

Browse files
committed
chore: add tests
1 parent af5fa9d commit f6f12ab

File tree

4 files changed

+78
-2
lines changed

4 files changed

+78
-2
lines changed

demos/middleware/next.config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ const nextConfig = {
77
ignoreDuringBuilds: true,
88
},
99
generateBuildId: () => 'build-id',
10+
i18n: {
11+
defaultLocale: 'en',
12+
locales: ['en'],
13+
},
1014
}
1115

1216
module.exports = nextConfig

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/runtime/src/helpers/matchers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export const stripLookahead = (regex: string) => {
2525
}
2626

2727
const LOCALIZED_REGEX_PREFIX = '(?:\\/(_next\\/data\\/[^/]{1,}))?(?:\\/([^/.]{1,}))'
28-
const OPTIONAL_REGEX_PREFIX = '(?:\\/(_next\\/data\\/[^/]{1,}))?(?:\\/([^/.]*))'
28+
const OPTIONAL_REGEX_PREFIX = '(?:\\/(_next\\/data\\/[^/]{1,}))?(?:\\/([^/.]{1,}))?'
2929

3030
// Make the locale section of the matcher regex optional
3131
export const makeLocaleOptional = (regex: string) => regex.replace(LOCALIZED_REGEX_PREFIX, OPTIONAL_REGEX_PREFIX)

test/matchers.spec.ts

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { makeLocaleOptional, stripLookahead } from '../packages/runtime/src/helpers/matchers'
2+
3+
const makeDataPath = (path: string) => `/_next/data/build-id${path === '/' ? '/index' : path}.json`
4+
5+
function checkPath(path: string, regex: string) {
6+
const re = new RegExp(regex)
7+
const dataPath = makeDataPath(path)
8+
const testPath = re.test(path)
9+
const testData = re.test(dataPath)
10+
// For easier debugging
11+
// console.log({ path, regex, dataPath, testPath, testData })
12+
return testPath && testData
13+
}
14+
15+
describe('the middleware path matcher', () => {
16+
it('makes the locale slug optional in the regex for the root', () => {
17+
// The regex generated by Next for the path "/" with i18n enabled
18+
const regex =
19+
'^(?:\\/(_next\\/data\\/[^/]{1,}))?(?:\\/([^/.]{1,}))(|\\.json|\\/?index|\\/?index\\.json)?[\\/#\\?]?$'
20+
expect(checkPath('/', regex)).toBe(false)
21+
expect(checkPath('/', makeLocaleOptional(regex))).toBe(true)
22+
expect(checkPath('/en', makeLocaleOptional(regex))).toBe(true)
23+
})
24+
25+
it('makes the locale slug optional in the regex for a subpath', () => {
26+
// The regex generated by Next for the path "/static" with i18n enabled
27+
const regex = '^(?:\\/(_next\\/data\\/[^/]{1,}))?(?:\\/([^/.]{1,}))\\/static(.json)?[\\/#\\?]?$'
28+
expect(checkPath('/static', regex)).toBe(false)
29+
expect(checkPath('/static', makeLocaleOptional(regex))).toBe(true)
30+
expect(checkPath('/en/static', makeLocaleOptional(regex))).toBe(true)
31+
})
32+
33+
it('does not change the regex when calling makeLocaleOptional with a regex that has no locale', () => {
34+
const regexes = [
35+
'^(?:\\/(_next\\/data\\/[^/]{1,}))?(?:\\/(\\/?index|\\/?index\\.json))?[\\/#\\?]?$',
36+
'^(?:\\/(_next\\/data\\/[^/]{1,}))?\\/api(?:\\/((?:[^\\/#\\?]+?)(?:\\/(?:[^\\/#\\?]+?))*))?(.json)?[\\/#\\?]?$',
37+
'^(?:\\/(_next\\/data\\/[^/]{1,}))?\\/shows(?:\\/((?!99|88).*))(.json)?[\\/#\\?]?$',
38+
]
39+
for (const regex of regexes) {
40+
expect(makeLocaleOptional(regex)).toBe(regex)
41+
}
42+
})
43+
44+
it('removes lookaheads from the regex', () => {
45+
const regexes = [
46+
'^(?:\\/(_next\\/data\\/[^/]{1,}))?(?:\\/([^/.]{1,}))\\/shows(?:\\/((?!99|88).*))(.json)?[\\/#\\?]?$',
47+
'^(?:\\/(_next\\/data\\/[^/]{1,}))?\\/shows(?:\\/((?!99|88).*))(.json)?[\\/#\\?]?$',
48+
]
49+
for (const regex of regexes) {
50+
const stripped = stripLookahead(regex)
51+
expect(regex).toMatch(/\(\?!/)
52+
expect(stripped).not.toMatch(/\(\?!/)
53+
}
54+
})
55+
it('converts regexes with lookaheads to stripped ones that still match at least the same paths', () => {
56+
const regex = '^(?:\\/(_next\\/data\\/[^/]{1,}))?\\/shows(?:\\/((?!99|88).*))(.json)?[\\/#\\?]?$'
57+
expect(checkPath('/shows', regex)).toBe(false)
58+
expect(checkPath('/shows/11', regex)).toBe(true)
59+
expect(checkPath('/shows/99', regex)).toBe(false)
60+
expect(checkPath('/shows/888', regex)).toBe(false)
61+
62+
const stripped = stripLookahead(regex)
63+
expect(checkPath('/shows', stripped)).toBe(false)
64+
expect(checkPath('/shows/11', stripped)).toBe(true)
65+
// These will be true because the regex is not as strict as the original one
66+
// The strict test will be done in the JS entrypoint
67+
expect(checkPath('/shows/99', stripped)).toBe(true)
68+
expect(checkPath('/shows/888', stripped)).toBe(true)
69+
})
70+
})
71+
72+
// "regexp": "^(?:\\/(_next\\/data\\/[^/]{1,}))?(?:\\/([^/.]{1,}))\\/shows(?:\\/((?!99|88).*))(.json)?[\\/#\\?]?$"

0 commit comments

Comments
 (0)