Skip to content

Commit 1a0beeb

Browse files
committed
WIP testing
1 parent 91c03a1 commit 1a0beeb

File tree

2 files changed

+79
-59
lines changed

2 files changed

+79
-59
lines changed

test/production/app-dir/actions-tree-shaking/_testing/utils.ts

Lines changed: 56 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,89 @@
1-
// @ts-ignore avoid ts errors during manual testing
2-
import { type NextInstance } from 'e2e-utils'
1+
import { nextTestSetup, type NextInstance } from 'e2e-utils'
2+
3+
// This is from 'next/dist/build/webpack/plugins/flight-client-entry-plugin', but unfortunately
4+
// Typescript breaks when importing it directly.
5+
type Actions = {
6+
[actionId: string]: {
7+
exportedName?: string
8+
filename?: string
9+
workers: {
10+
[name: string]: {
11+
moduleId: string | number
12+
async: boolean
13+
}
14+
}
15+
layer: {
16+
[name: string]: string
17+
}
18+
}
19+
}
320

421
async function getActionsMappingByRuntime(
522
next: NextInstance,
623
runtime: 'node' | 'edge'
7-
) {
24+
): Promise<Actions> {
825
const manifest = JSON.parse(
926
await next.readFile('.next/server/server-reference-manifest.json')
1027
)
1128

1229
return manifest[runtime]
1330
}
1431

15-
export function markLayoutAsEdge(next: NextInstance) {
16-
beforeAll(async () => {
17-
await next.stop()
18-
const layoutContent = await next.readFile('app/layout.js')
19-
await next.patchFile(
20-
'app/layout.js',
21-
layoutContent + `\nexport const runtime = 'edge'`
22-
)
23-
await next.start()
32+
export function nextTestSetupActionTreeShaking(opts) {
33+
let result = nextTestSetup({
34+
...opts,
35+
skipStart: !!process.env.TEST_EDGE,
2436
})
25-
}
2637

27-
/*
28-
{
29-
[route path]: { [layer]: Set<workerId> ]
30-
}
31-
*/
32-
type ActionsMappingOfRuntime = {
33-
[actionId: string]: {
34-
workers: {
35-
[route: string]: string
36-
}
37-
layer: {
38-
[route: string]: string
39-
}
38+
if (process.env.TEST_EDGE) {
39+
beforeAll(async () => {
40+
const layoutContent = await result.next.readFile('app/layout.js')
41+
await result.next.patchFile(
42+
'app/layout.js',
43+
layoutContent + `\nexport const runtime = 'edge'`
44+
)
45+
await result.next.start()
46+
})
4047
}
48+
49+
return result
4150
}
51+
4252
type ActionState = {
4353
[route: string]: {
44-
[layer: string]: number
54+
[layer: string]: string[]
4555
}
4656
}
4757

48-
function getActionsRoutesState(
49-
actionsMappingOfRuntime: ActionsMappingOfRuntime
50-
): ActionState {
58+
function getActionsRoutesState(actionsMappingOfRuntime: Actions): ActionState {
5159
const state: ActionState = {}
52-
Object.keys(actionsMappingOfRuntime).forEach((actionId) => {
60+
for (const actionId in actionsMappingOfRuntime) {
5361
const action = actionsMappingOfRuntime[actionId]
54-
const routePaths = Object.keys(action.workers)
55-
56-
routePaths.forEach((routePath) => {
62+
for (const routePath in action.workers) {
5763
if (!state[routePath]) {
5864
state[routePath] = {}
5965
}
6066
const layer = action.layer[routePath]
6167

6268
if (!state[routePath][layer]) {
63-
state[routePath][layer] = 0
69+
state[routePath][layer] = []
6470
}
6571

66-
state[routePath][layer]++
67-
})
68-
})
72+
// Normalize when NEXT_SKIP_ISOLATE=1
73+
const filename = action.filename.startsWith('test/tmp/next-test-')
74+
? action.filename.slice(
75+
action.filename.indexOf('/', 'test/tmp/next-test-'.length) + 1
76+
)
77+
: action.filename
78+
state[routePath][layer].push(`${filename}#${action.exportedName}`)
79+
}
80+
}
81+
82+
for (const layer of Object.values(state)) {
83+
for (const list of Object.values(layer)) {
84+
list.sort()
85+
}
86+
}
6987

7088
return state
7189
}
Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,39 @@
1-
import { nextTestSetup } from 'e2e-utils'
21
import {
2+
nextTestSetupActionTreeShaking,
33
getActionsRoutesStateByRuntime,
4-
markLayoutAsEdge,
54
} from '../_testing/utils'
65

76
// TODO: revisit when we have a better side-effect free transform approach for server action
87
;(process.env.IS_TURBOPACK_TEST ? describe : describe.skip)(
98
'actions-tree-shaking - basic',
109
() => {
11-
const { next } = nextTestSetup({
10+
const { next } = nextTestSetupActionTreeShaking({
1211
files: __dirname,
1312
})
1413

15-
if (process.env.TEST_EDGE) {
16-
markLayoutAsEdge(next)
17-
}
18-
1914
it('should not have the unused action in the manifest', async () => {
2015
const actionsRoutesState = await getActionsRoutesStateByRuntime(next)
21-
22-
expect(actionsRoutesState).toMatchObject({
23-
// only one server layer action
24-
'app/server/page': {
25-
rsc: 3,
26-
},
27-
// only one browser layer action
28-
'app/client/page': {
29-
'action-browser': 1,
30-
},
31-
'app/inline/page': {
32-
rsc: 1,
33-
},
34-
})
16+
expect(actionsRoutesState).toMatchInlineSnapshot(`
17+
{
18+
"app/client/page": {
19+
"action-browser": [
20+
"app/actions.js#clientComponentAction",
21+
],
22+
},
23+
"app/inline/page": {
24+
"rsc": [
25+
"app/inline/page.js#$$RSC_SERVER_ACTION_0",
26+
],
27+
},
28+
"app/server/page": {
29+
"rsc": [
30+
"app/actions.js#clientComponentAction",
31+
"app/actions.js#serverComponentAction",
32+
"app/actions.js#unusedExportedAction",
33+
],
34+
},
35+
}
36+
`)
3537
})
3638
}
3739
)

0 commit comments

Comments
 (0)