Skip to content

Commit

Permalink
[after] duplicate test pages for edge instead of next.patch (#69477)
Browse files Browse the repository at this point in the history
`unstable_after` needs to be tested in both nodejs and edge runtimes.
Previously, we set the runtime via `next.patch()`, but this proved
error-prone (e.g. because `sandbox()` call would override this patch,
and not actually run anything in edge...)

This PR makes this more static by splitting the test pages for
`unstable_after` into `/nodejs` and `/edge`, each with a corresponding
`export const runtime = "..."` in its root layout. The pages in `/edge`
mirror the structure of `/nodejs` and reexport components from it (which
makes the tests easier to update than simply duplicating everything).
note that "use client" directives and route segment configs cannot be
reexported and need to be duplicated.
  • Loading branch information
lubieowoce authored Aug 30, 2024
1 parent ae1efa4 commit 53201b1
Show file tree
Hide file tree
Showing 42 changed files with 213 additions and 174 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// 'use client'
'use client'

import { unstable_after as after } from 'next/server'
import { cliLog } from '../../utils/log'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { unstable_after as after } from 'next/server'
import { cliLog } from '../../utils/log'

// (patched in tests)
// export const dynamic = 'REPLACE_ME'
export const dynamic = 'error'

export default function Index() {
after(async () => {
cliLog({ source: '[page] /static' })
cliLog({ source: '[page] /invalid-in-dynamic-error' })
})
return <div>Page with after()</div>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { unstable_after as after } from 'next/server'
import { cliLog } from '../../utils/log'

export const dynamic = 'force-static'

export default function Index() {
after(async () => {
cliLog({ source: '[page] /invalid-in-dynamic-force-static' })
})
return <div>Page with after()</div>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export default function AppLayout({ children }) {
return (
<html>
<head>
<title>after</title>
</head>
<body>{children}</body>
</html>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/* eslint-env jest */
import { nextTestSetup } from 'e2e-utils'
import * as Log from './utils/log'
import {
assertHasRedbox,
getRedboxDescription,
getRedboxSource,
} from '../../../lib/next-test-utils'

describe('unstable_after() - invalid usages', () => {
const { next } = nextTestSetup({
files: __dirname,
})

let currentCliOutputIndex = 0
beforeEach(() => {
currentCliOutputIndex = next.cliOutput.length
})

const getLogs = () => {
if (next.cliOutput.length < currentCliOutputIndex) {
// cliOutput shrank since we started the test, so something (like a `sandbox`) reset the logs
currentCliOutputIndex = 0
}
return Log.readCliLogs(next.cliOutput.slice(currentCliOutputIndex))
}

it.each(['error', 'force-static'])(
`errors at compile time with dynamic = "%s"`,
async (dynamicValue) => {
const pathname = '/invalid-in-dynamic-' + dynamicValue
const session = await next.browser(pathname)

await assertHasRedbox(session)
expect(await getRedboxDescription(session)).toContain(
`Route ${pathname} with \`dynamic = "${dynamicValue}"\` couldn't be rendered statically because it used \`unstable_after\``
)
expect(getLogs()).toHaveLength(0)
}
)
it('errors at compile time when used in a client module', async () => {
const session = await next.browser('/invalid-in-client')

await assertHasRedbox(session)
expect(await getRedboxSource(session)).toMatch(
/You're importing a component that needs "?unstable_after"?\. That only works in a Server Component but one of its parents is marked with "use client", so it's a Client Component\./
)
expect(getLogs()).toHaveLength(0)
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/** @type {import('next').NextConfig} */
module.exports = {
experimental: {
after: true,
},
}
16 changes: 16 additions & 0 deletions test/development/app-dir/next-after-app-invalid-usage/utils/log.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export function cliLog(/** @type {string | Record<string, any>} */ data) {
console.log('<test-log>' + JSON.stringify(data) + '</test-log>')
}

export function readCliLogs(/** @type {string} */ output) {
return output
.split('\n')
.map((line) => {
const match = line.match(/^<test-log>(?<value>.+?)<\/test-log>$/)
if (!match) {
return null
}
return JSON.parse(match.groups.value)
})
.filter(Boolean)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '../../../nodejs/[id]/dynamic/page'
1 change: 1 addition & 0 deletions test/e2e/app-dir/next-after-app/app/edge/[id]/layout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '../../nodejs/[id]/layout'
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '../../../nodejs/[id]/setting-cookies/page'
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '../../../nodejs/[id]/with-action/page'
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export {
default,
generateMetadata,
} from '../../../nodejs/[id]/with-metadata/page'
3 changes: 3 additions & 0 deletions test/e2e/app-dir/next-after-app/app/edge/delay/page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { default } from '../../nodejs/delay/page'

export const dynamic = 'force-dynamic'
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '../../../nodejs/interrupted/calls-not-found/page'
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { createPage } from '../../../nodejs/interrupted/calls-redirect/page'

// NOTE: this page is forked from /nodejs

export default createPage('/edge')
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '../../../nodejs/interrupted/redirect-target/page'
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '../../../nodejs/interrupted/throws-error/page'
3 changes: 3 additions & 0 deletions test/e2e/app-dir/next-after-app/app/edge/layout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { default } from '../nodejs/layout'

export const runtime = 'edge'
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '../../../nodejs/middleware/redirect/page'
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '../../nodejs/nested-after/page'
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '../../nodejs/provided-request-context/page'
4 changes: 4 additions & 0 deletions test/e2e/app-dir/next-after-app/app/edge/route/route.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export { GET } from '../../nodejs/route/route'

export const runtime = 'edge'
export const dynamic = 'force-dynamic'

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { unstable_after as after } from 'next/server'
import { cache } from 'react'
import { cliLog } from '../../../utils/log'
import { cliLog } from '../../../../utils/log'
import { headers } from 'next/headers'

const thing = cache(() => Symbol('cache me please'))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { unstable_after as after } from 'next/server'
import { cliLog } from '../../utils/log'
import { cliLog } from '../../../utils/log'

export default function Layout({ children }) {
after(async () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { unstable_after as after } from 'next/server'
import { cache } from 'react'
import { cliLog } from '../../../utils/log'
import { cliLog } from '../../../../utils/log'
import { headers } from 'next/headers'

const thing = cache(() => Symbol('cache me please'))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { unstable_after as after } from 'next/server'
import { cliLog } from '../../../utils/log'
import { cliLog } from '../../../../utils/log'

export function generateMetadata({ params }) {
after(() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Suspense } from 'react'
import { unstable_after as after } from 'next/server'
import { cliLog } from '../../utils/log'
import { cliLog } from '../../../utils/log'

export const dynamic = 'force-dynamic'

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { notFound } from 'next/navigation'
import { unstable_after as after } from 'next/server'
import { cliLog } from '../../../utils/log'
import { cliLog } from '../../../../utils/log'

export default function Page() {
after(() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { unstable_after as after } from 'next/server'
import { redirect } from 'next/navigation'
import { cliLog } from '../../../../utils/log'

// NOTE: this page is forked in /edge

export function createPage(pathPrefix) {
return function Page() {
after(() => {
cliLog({
source: '[page] /interrupted/calls-redirect',
})
})

redirect(pathPrefix + '/interrupted/redirect-target')
}
}

export default createPage('/nodejs')
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { unstable_after as after } from 'next/server'
import { cliLog } from '../../../utils/log'
import { cliLog } from '../../../../utils/log'

export default function Page() {
after(() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { unstable_after as after } from 'next/server'
import { cliLog } from '../../../utils/log'
import { cliLog } from '../../../../utils/log'

export default function Page() {
after(() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// (patched in tests)
// export const runtime = 'REPLACE_ME'
export const runtime = 'nodejs'

export default function AppLayout({ children }) {
return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { unstable_after as after } from 'next/server'
import { cache } from 'react'
import { cliLog } from '../../utils/log'
import { cliLog } from '../../../utils/log'
import { headers } from 'next/headers'

const thing = cache(() => Symbol('cache me please'))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { unstable_after as after } from 'next/server'
import { cliLog } from '../../utils/log'
import { cliLog } from '../../../utils/log'

export default function Page() {
after(() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { unstable_after as after } from 'next/server'
import { cliLog } from '../../utils/log'

// (patched in tests)
// export const runtime = 'REPLACE_ME'
import { cliLog } from '../../../utils/log'

export const runtime = 'nodejs'
export const dynamic = 'force-dynamic'

export async function GET() {
Expand Down
Loading

0 comments on commit 53201b1

Please sign in to comment.