File size: 7,487 Bytes
b91e262
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
import { nextTestSetup } from 'e2e-utils'

describe('debug-build-paths', () => {
  const { next, skipped } = nextTestSetup({
    files: __dirname,
    skipDeployment: true,
    skipStart: true,
  })

  if (skipped) return

  describe('explicit path formats', () => {
    it('should build single page with pages/ prefix', async () => {
      const buildResult = await next.build({
        args: ['--debug-build-paths', 'pages/foo.tsx'],
      })
      expect(buildResult.exitCode).toBe(0)
      expect(buildResult.cliOutput).toBeDefined()

      // Should only build the specified page
      expect(buildResult.cliOutput).toContain('Route (pages)')
      expect(buildResult.cliOutput).toContain('β—‹ /foo')
      // Should not build other pages
      expect(buildResult.cliOutput).not.toContain('β—‹ /bar')
      // Should not build app routes
      expect(buildResult.cliOutput).not.toContain('Route (app)')
    })

    it('should build multiple pages routes', async () => {
      const buildResult = await next.build({
        args: ['--debug-build-paths', 'pages/foo.tsx,pages/bar.tsx'],
      })
      expect(buildResult.exitCode).toBe(0)
      expect(buildResult.cliOutput).toBeDefined()

      // Should build both specified pages
      expect(buildResult.cliOutput).toContain('Route (pages)')
      expect(buildResult.cliOutput).toContain('β—‹ /foo')
      expect(buildResult.cliOutput).toContain('β—‹ /bar')
      // Should not build app routes
      expect(buildResult.cliOutput).not.toContain('Route (app)')
    })

    it('should build dynamic route with literal [slug] path', async () => {
      // Test that literal paths with brackets work without escaping
      // The path is checked for file existence before being treated as glob
      const buildResult = await next.build({
        args: ['--debug-build-paths', 'app/blog/[slug]/page.tsx'],
      })
      expect(buildResult.exitCode).toBe(0)
      expect(buildResult.cliOutput).toBeDefined()

      // Should build only the blog/[slug] route
      expect(buildResult.cliOutput).toContain('Route (app)')
      expect(buildResult.cliOutput).toContain('/blog/[slug]')
      // Should not build other app routes
      expect(buildResult.cliOutput).not.toMatch(/β—‹ \/\n/)
      expect(buildResult.cliOutput).not.toContain('β—‹ /about')
      expect(buildResult.cliOutput).not.toContain('β—‹ /dashboard')
      // Should not build pages routes
      expect(buildResult.cliOutput).not.toContain('Route (pages)')
    })
  })

  describe('glob pattern matching', () => {
    it('should match app and pages routes with glob patterns', async () => {
      const buildResult = await next.build({
        args: ['--debug-build-paths', 'pages/*.tsx,app/page.tsx'],
      })
      expect(buildResult.exitCode).toBe(0)
      expect(buildResult.cliOutput).toBeDefined()

      // Should build pages matching the glob
      expect(buildResult.cliOutput).toContain('Route (pages)')
      expect(buildResult.cliOutput).toContain('β—‹ /foo')
      expect(buildResult.cliOutput).toContain('β—‹ /bar')

      // Should build the specified app route
      expect(buildResult.cliOutput).toContain('Route (app)')
      expect(buildResult.cliOutput).toContain('β—‹ /')
      // Should not build other app routes
      expect(buildResult.cliOutput).not.toContain('β—‹ /about')
      expect(buildResult.cliOutput).not.toContain('β—‹ /dashboard')
    })

    it('should match nested routes with app/blog/**/page.tsx pattern', async () => {
      const buildResult = await next.build({
        args: ['--debug-build-paths', 'app/blog/**/page.tsx'],
      })
      expect(buildResult.exitCode).toBe(0)
      expect(buildResult.cliOutput).toBeDefined()

      // Should build the blog route
      expect(buildResult.cliOutput).toContain('Route (app)')
      expect(buildResult.cliOutput).toContain('/blog/[slug]')
      // Should not build other app routes (check for exact route, not substring)
      expect(buildResult.cliOutput).not.toMatch(/β—‹ \/\n/)
      expect(buildResult.cliOutput).not.toContain('β—‹ /about')
      expect(buildResult.cliOutput).not.toContain('β—‹ /dashboard')
      // Should not build pages routes
      expect(buildResult.cliOutput).not.toContain('Route (pages)')
    })

    it('should match hybrid pattern with literal [slug] and glob **', async () => {
      // Test pattern: app/blog/[slug]/**/page.tsx
      // [slug] should be treated as literal directory (exists on disk)
      // ** should be treated as glob (match any depth)
      const buildResult = await next.build({
        args: ['--debug-build-paths', 'app/blog/[slug]/**/page.tsx'],
      })
      expect(buildResult.exitCode).toBe(0)
      expect(buildResult.cliOutput).toBeDefined()

      // Should build both blog/[slug] and blog/[slug]/comments routes
      expect(buildResult.cliOutput).toContain('Route (app)')
      expect(buildResult.cliOutput).toContain('/blog/[slug]')
      expect(buildResult.cliOutput).toContain('/blog/[slug]/comments')
      // Should not build other app routes
      expect(buildResult.cliOutput).not.toMatch(/β—‹ \/\n/)
      expect(buildResult.cliOutput).not.toContain('β—‹ /about')
      expect(buildResult.cliOutput).not.toContain('β—‹ /dashboard')
      // Should not build pages routes
      expect(buildResult.cliOutput).not.toContain('Route (pages)')
    })

    it('should match multiple app routes with explicit patterns', async () => {
      const buildResult = await next.build({
        args: [
          '--debug-build-paths',
          'app/page.tsx,app/about/page.tsx,app/dashboard/page.tsx,app/blog/**/page.tsx',
        ],
      })
      expect(buildResult.exitCode).toBe(0)
      expect(buildResult.cliOutput).toBeDefined()

      // Should build specified app routes
      expect(buildResult.cliOutput).toContain('Route (app)')
      expect(buildResult.cliOutput).toContain('β—‹ /')
      expect(buildResult.cliOutput).toContain('β—‹ /about')
      expect(buildResult.cliOutput).toContain('β—‹ /dashboard')
      expect(buildResult.cliOutput).toContain('/blog/[slug]')
      // Should not build routes not specified
      expect(buildResult.cliOutput).not.toContain('/with-type-error')
      // Should not build pages routes
      expect(buildResult.cliOutput).not.toContain('Route (pages)')
    })
  })

  describe('typechecking with debug-build-paths', () => {
    it('should skip typechecking for excluded app routes', async () => {
      // Build only pages routes, excluding app routes with type error
      const buildResult = await next.build({
        args: ['--debug-build-paths', 'pages/foo.tsx'],
      })
      // Build should succeed because the file with type error is not checked
      expect(buildResult.exitCode).toBe(0)
      expect(buildResult.cliOutput).toContain('Route (pages)')
      expect(buildResult.cliOutput).toContain('β—‹ /foo')
      // Should not include app routes
      expect(buildResult.cliOutput).not.toContain('Route (app)')
    })

    it('should fail typechecking when route with type error is included', async () => {
      // Build all app routes including the one with type error
      const buildResult = await next.build({
        args: ['--debug-build-paths', 'app/**/page.tsx'],
      })
      // Build should fail due to type error in with-type-error/page.tsx
      expect(buildResult.exitCode).toBe(1)
      expect(buildResult.cliOutput).toContain('Type error')
      expect(buildResult.cliOutput).toContain('with-type-error/page.tsx')
    })
  })
})