Mock @next/font when using next/jest (#42413)
Mock `@next/font` when using `next/jest`. fixes #42379 ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see `contributing.md` ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see `contributing.md` ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm build && pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
This commit is contained in:
parent
73c5b77a84
commit
539769dddc
6 changed files with 36 additions and 11 deletions
|
@ -293,7 +293,7 @@ module.exports = createJestConfig(customJestConfig)
|
||||||
Under the hood, `next/jest` is automatically configuring Jest for you, including:
|
Under the hood, `next/jest` is automatically configuring Jest for you, including:
|
||||||
|
|
||||||
- Setting up `transform` using [SWC](https://nextjs.org/docs/advanced-features/compiler)
|
- Setting up `transform` using [SWC](https://nextjs.org/docs/advanced-features/compiler)
|
||||||
- Auto mocking stylesheets (`.css`, `.module.css`, and their scss variants) and image imports
|
- Auto mocking stylesheets (`.css`, `.module.css`, and their scss variants), image imports and [`@next/font`](https://nextjs.org/docs/basic-features/font-optimization)
|
||||||
- Loading `.env` (and all variants) into `process.env`
|
- Loading `.env` (and all variants) into `process.env`
|
||||||
- Ignoring `node_modules` from test resolving and transforms
|
- Ignoring `node_modules` from test resolving and transforms
|
||||||
- Ignoring `.next` from test resolving
|
- Ignoring `.next` from test resolving
|
||||||
|
|
|
@ -14,6 +14,9 @@ const customJestConfig = {
|
||||||
globals: {
|
globals: {
|
||||||
AbortSignal: global.AbortSignal,
|
AbortSignal: global.AbortSignal,
|
||||||
},
|
},
|
||||||
|
moduleNameMapper: {
|
||||||
|
'@next/font/(.*)': '@next/font/$1',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// createJestConfig is exported in this way to ensure that next/jest can load the Next.js config which is async
|
// createJestConfig is exported in this way to ensure that next/jest can load the Next.js config which is async
|
||||||
|
|
12
packages/next/build/jest/__mocks__/nextFontMock.js
Normal file
12
packages/next/build/jest/__mocks__/nextFontMock.js
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
module.exports = new Proxy(
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
get: function getter() {
|
||||||
|
return () => ({
|
||||||
|
className: 'className',
|
||||||
|
variable: 'variable',
|
||||||
|
style: { fontFamily: 'fontFamily' },
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
|
@ -115,6 +115,9 @@ export default function nextJest(options: { dir?: string } = {}) {
|
||||||
// Keep .svg to it's own rule to make overriding easy
|
// Keep .svg to it's own rule to make overriding easy
|
||||||
'^.+\\.(svg)$': require.resolve(`./__mocks__/fileMock.js`),
|
'^.+\\.(svg)$': require.resolve(`./__mocks__/fileMock.js`),
|
||||||
|
|
||||||
|
// Handle @next/font
|
||||||
|
'@next/font/(.*)': require.resolve('./__mocks__/nextFontMock.js'),
|
||||||
|
|
||||||
// custom config comes last to ensure the above rules are matched,
|
// custom config comes last to ensure the above rules are matched,
|
||||||
// fixes the case where @pages/(.*) -> src/pages/$! doesn't break
|
// fixes the case where @pages/(.*) -> src/pages/$! doesn't break
|
||||||
// CSS/image mocks
|
// CSS/image mocks
|
||||||
|
|
|
@ -33,7 +33,6 @@ function getBaseSWCOptions({
|
||||||
jsConfig,
|
jsConfig,
|
||||||
swcCacheDir,
|
swcCacheDir,
|
||||||
isServerLayer,
|
isServerLayer,
|
||||||
relativeFilePathFromRoot,
|
|
||||||
hasServerComponents,
|
hasServerComponents,
|
||||||
}) {
|
}) {
|
||||||
const parserConfig = getParserOptions({ filename, jsConfig })
|
const parserConfig = getParserOptions({ filename, jsConfig })
|
||||||
|
@ -131,15 +130,6 @@ function getBaseSWCOptions({
|
||||||
isServer: !!isServerLayer,
|
isServer: !!isServerLayer,
|
||||||
}
|
}
|
||||||
: false,
|
: false,
|
||||||
fontLoaders:
|
|
||||||
nextConfig?.experimental?.fontLoaders && relativeFilePathFromRoot
|
|
||||||
? {
|
|
||||||
fontLoaders: nextConfig.experimental.fontLoaders.map(
|
|
||||||
({ loader }) => loader
|
|
||||||
),
|
|
||||||
relativeFilePathFromRoot,
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,6 +245,15 @@ export function getLoaderSWCOptions({
|
||||||
hasServerComponents,
|
hasServerComponents,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (nextConfig?.experimental?.fontLoaders && relativeFilePathFromRoot) {
|
||||||
|
baseOptions.fontLoaders = {
|
||||||
|
fontLoaders: nextConfig.experimental.fontLoaders.map(
|
||||||
|
({ loader }) => loader
|
||||||
|
),
|
||||||
|
relativeFilePathFromRoot,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const isNextDist = nextDistPath.test(filename)
|
const isNextDist = nextDistPath.test(filename)
|
||||||
|
|
||||||
if (isServer) {
|
if (isServer) {
|
||||||
|
|
|
@ -21,6 +21,11 @@ describe('next/jest', () => {
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import img from "../public/vercel.svg";
|
import img from "../public/vercel.svg";
|
||||||
import styles from "../styles/index.module.css";
|
import styles from "../styles/index.module.css";
|
||||||
|
import localFont from "@next/font/local";
|
||||||
|
import { Inter } from "@next/font/google";
|
||||||
|
|
||||||
|
const inter = Inter();
|
||||||
|
const myFont = localFont({ src: "./my-font.woff2" });
|
||||||
|
|
||||||
const Comp = dynamic(() => import("../components/comp"), {
|
const Comp = dynamic(() => import("../components/comp"), {
|
||||||
loading: () => <h1>Loading...</h1>,
|
loading: () => <h1>Loading...</h1>,
|
||||||
|
@ -32,6 +37,7 @@ describe('next/jest', () => {
|
||||||
<Image src={img} alt="logo" placeholder="blur"/>
|
<Image src={img} alt="logo" placeholder="blur"/>
|
||||||
<Image src={img} alt="logo 2"/>
|
<Image src={img} alt="logo 2"/>
|
||||||
<p className={styles.home}>hello world</p>
|
<p className={styles.home}>hello world</p>
|
||||||
|
<p style={{ fontFamily: inter.style.fontFamily }} className={myFont.className}>hello world</p>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
@ -118,8 +124,10 @@ describe('next/jest', () => {
|
||||||
expect(router.push._isMockFunction).toBeTruthy()
|
expect(router.push._isMockFunction).toBeTruthy()
|
||||||
})
|
})
|
||||||
`,
|
`,
|
||||||
|
'pages/my-font.woff2': 'fake font',
|
||||||
},
|
},
|
||||||
dependencies: {
|
dependencies: {
|
||||||
|
'@next/font': 'canary',
|
||||||
jest: '27.4.7',
|
jest: '27.4.7',
|
||||||
'@testing-library/jest-dom': '5.16.1',
|
'@testing-library/jest-dom': '5.16.1',
|
||||||
'@testing-library/react': '12.1.2',
|
'@testing-library/react': '12.1.2',
|
||||||
|
|
Loading…
Reference in a new issue