Skip to content

Commit

Permalink
fix(47299): allow testing pages with metadata in jsdom test environment
Browse files Browse the repository at this point in the history
  • Loading branch information
feugy committed Aug 14, 2023
1 parent fa88095 commit 8e39538
Show file tree
Hide file tree
Showing 9 changed files with 43 additions and 77 deletions.
1 change: 0 additions & 1 deletion packages/next/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,6 @@
"image-size": "1.0.0",
"is-docker": "2.0.0",
"is-wsl": "2.2.0",
"jest-docblock": "29.4.3",
"jest-worker": "27.0.0-next.5",
"json5": "2.2.3",
"jsonwebtoken": "9.0.0",
Expand Down
19 changes: 2 additions & 17 deletions packages/next/src/build/swc/jest-transformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ DEALINGS IN THE SOFTWARE.
import vm from 'vm'
import { transformSync } from './index'
import { getJestSWCOptions } from './options'
import * as docblock from 'next/dist/compiled/jest-docblock'
import type {
TransformerCreator,
TransformOptions,
Expand Down Expand Up @@ -77,30 +76,16 @@ function isEsm(
)
}

function getTestEnvironment(
src: string,
jestConfig: Config.ProjectConfig
): string {
const docblockPragmas = docblock.parse(docblock.extract(src))
const pragma = docblockPragmas['jest-environment']
const environment =
(Array.isArray(pragma) ? pragma[0] : pragma) ?? jestConfig.testEnvironment
return environment
}

const createTransformer: TransformerCreator<
SyncTransformer<JestTransformerConfig>,
JestTransformerConfig
> = (inputOptions) => ({
process(src, filename, jestOptions) {
const jestConfig = getJestConfig(jestOptions)
const testEnvironment = getTestEnvironment(src, jestConfig)

const swcTransformOpts = getJestSWCOptions({
// When target is node it's similar to the server option set in SWC.
isServer:
testEnvironment === 'node' ||
testEnvironment.includes('jest-environment-node'),
// Always target server when compiling during test, to pass server-only validations and allow testing pages with metadatas
isServer: true,
filename,
jsConfig: inputOptions?.jsConfig,
resolvedBaseUrl: inputOptions?.resolvedBaseUrl,
Expand Down
21 changes: 0 additions & 21 deletions packages/next/src/compiled/jest-docblock/LICENSE

This file was deleted.

1 change: 0 additions & 1 deletion packages/next/src/compiled/jest-docblock/index.js

This file was deleted.

1 change: 0 additions & 1 deletion packages/next/src/compiled/jest-docblock/package.json

This file was deleted.

10 changes: 0 additions & 10 deletions packages/next/taskfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -2179,15 +2179,6 @@ export async function ncc_https_proxy_agent(task, opts) {
.target('src/compiled/https-proxy-agent')
}

// eslint-disable-next-line camelcase
externals['jest-docblock'] = 'next/dist/compiled/jest-docblock'
export async function ncc_jest_docblock(task, opts) {
await task
.source(relative(__dirname, require.resolve('jest-docblock')))
.ncc({ packageName: 'jest-docblock', externals })
.target('src/compiled/jest-docblock')
}

export async function precompile(task, opts) {
await task.parallel(
[
Expand Down Expand Up @@ -2322,7 +2313,6 @@ export async function ncc(task, opts) {
'ncc_opentelemetry_api',
'ncc_http_proxy_agent',
'ncc_https_proxy_agent',
'ncc_jest_docblock',
'ncc_mini_css_extract_plugin',
],
opts
Expand Down
5 changes: 0 additions & 5 deletions packages/next/types/misc.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -454,8 +454,3 @@ declare module 'next/dist/compiled/@opentelemetry/api' {
import * as m from '@opentelemetry/api'
export = m
}

declare module 'next/dist/compiled/jest-docblock' {
import m from 'jest-docblock'
export = m
}
15 changes: 2 additions & 13 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

47 changes: 39 additions & 8 deletions test/production/jest/server-only.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,19 @@ describe('next/jest', () => {
next = await createNext({
skipStart: true,
files: {
'app/page.jsx': `import { PI } from '../lib/util'
export default function Home() {
return <h1>{PI}</h1>
}`,
'app/layout.jsx': `export default function RootLayout({ children }) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}`,

'app/page.jsx': `import { PI } from '../lib/util'
export default function Home() {
return <h1>{PI}</h1>
}`,

'app/page.test.jsx': `import { render, screen } from '@testing-library/react'
import '@testing-library/jest-dom'
import Page from './page'
Expand All @@ -27,13 +29,42 @@ describe('next/jest', () => {
render(<Page />)
expect(screen.getByRole('heading')).toHaveTextContent('3.14')
})`,
'lib/util.js': `/** @jest-environment node */

'app/[blog]/page.jsx': `import { Metadata } from 'next'
export async function generateMetadata({
params: { blog: title },
}) {
return { title, description: 'A blog post about ' + title }
}
export default function Page({ params }) {
return <h1>All about {params.blog}</h1>
}
`,

'app/[blog]/page.test.jsx': `import { render, screen } from '@testing-library/react'
import '@testing-library/jest-dom'
import Page from './page'
describe('Blog Page', () => {
it('has the appropriate title', () => {
render(<Page params={{ blog: 'Jane' }} />)
expect(screen.getByRole('heading')).toHaveTextContent('All about Jane')
})
})
`,

'lib/util.js': `
import 'server-only'
export const PI = 3.14;`,
'lib/utils.test.ts': `import { PI } from './util'

'lib/utils.test.ts': `
import { PI } from './util'
it('works from server-side code', () => {
expect(PI).toEqual(3.14)
})`,

'jest.config.js': `module.exports = require('next/jest')({ dir: './' })({ testEnvironment: 'jsdom' })`,
},
buildCommand: `yarn jest`,
Expand All @@ -48,11 +79,11 @@ describe('next/jest', () => {

afterAll(() => next.destroy())

it('can run test against server side components', async () => {
it('can run test against server server only code', async () => {
try {
await next.start()
} finally {
expect(next.cliOutput).toInclude('Tests: 2 passed, 2 total')
expect(next.cliOutput).toInclude('Tests: 3 passed, 3 total')
}
})
})

0 comments on commit 8e39538

Please sign in to comment.