Skip to content

Commit

Permalink
Mock @next/font when using next/jest (#42413)
Browse files Browse the repository at this point in the history
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)
  • Loading branch information
Hannes Bornö committed Nov 3, 2022
1 parent 73c5b77 commit 539769d
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 11 deletions.
2 changes: 1 addition & 1 deletion docs/testing.md
Expand Up @@ -293,7 +293,7 @@ module.exports = createJestConfig(customJestConfig)
Under the hood, `next/jest` is automatically configuring Jest for you, including:

- 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`
- Ignoring `node_modules` from test resolving and transforms
- Ignoring `.next` from test resolving
Expand Down
3 changes: 3 additions & 0 deletions jest.config.js
Expand Up @@ -14,6 +14,9 @@ const customJestConfig = {
globals: {
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
Expand Down
12 changes: 12 additions & 0 deletions packages/next/build/jest/__mocks__/nextFontMock.js
@@ -0,0 +1,12 @@
module.exports = new Proxy(
{},
{
get: function getter() {
return () => ({
className: 'className',
variable: 'variable',
style: { fontFamily: 'fontFamily' },
})
},
}
)
3 changes: 3 additions & 0 deletions packages/next/build/jest/jest.ts
Expand Up @@ -115,6 +115,9 @@ export default function nextJest(options: { dir?: string } = {}) {
// Keep .svg to it's own rule to make overriding easy
'^.+\\.(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,
// fixes the case where @pages/(.*) -> src/pages/$! doesn't break
// CSS/image mocks
Expand Down
19 changes: 9 additions & 10 deletions packages/next/build/swc/options.js
Expand Up @@ -33,7 +33,6 @@ function getBaseSWCOptions({
jsConfig,
swcCacheDir,
isServerLayer,
relativeFilePathFromRoot,
hasServerComponents,
}) {
const parserConfig = getParserOptions({ filename, jsConfig })
Expand Down Expand Up @@ -131,15 +130,6 @@ function getBaseSWCOptions({
isServer: !!isServerLayer,
}
: false,
fontLoaders:
nextConfig?.experimental?.fontLoaders && relativeFilePathFromRoot
? {
fontLoaders: nextConfig.experimental.fontLoaders.map(
({ loader }) => loader
),
relativeFilePathFromRoot,
}
: null,
}
}

Expand Down Expand Up @@ -255,6 +245,15 @@ export function getLoaderSWCOptions({
hasServerComponents,
})

if (nextConfig?.experimental?.fontLoaders && relativeFilePathFromRoot) {
baseOptions.fontLoaders = {
fontLoaders: nextConfig.experimental.fontLoaders.map(
({ loader }) => loader
),
relativeFilePathFromRoot,
}
}

const isNextDist = nextDistPath.test(filename)

if (isServer) {
Expand Down
8 changes: 8 additions & 0 deletions test/production/jest/index.test.ts
Expand Up @@ -21,6 +21,11 @@ describe('next/jest', () => {
import Image from "next/image";
import img from "../public/vercel.svg";
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"), {
loading: () => <h1>Loading...</h1>,
Expand All @@ -32,6 +37,7 @@ describe('next/jest', () => {
<Image src={img} alt="logo" placeholder="blur"/>
<Image src={img} alt="logo 2"/>
<p className={styles.home}>hello world</p>
<p style={{ fontFamily: inter.style.fontFamily }} className={myFont.className}>hello world</p>
</>
}
`,
Expand Down Expand Up @@ -118,8 +124,10 @@ describe('next/jest', () => {
expect(router.push._isMockFunction).toBeTruthy()
})
`,
'pages/my-font.woff2': 'fake font',
},
dependencies: {
'@next/font': 'canary',
jest: '27.4.7',
'@testing-library/jest-dom': '5.16.1',
'@testing-library/react': '12.1.2',
Expand Down

0 comments on commit 539769d

Please sign in to comment.