Add additional tests for @next/mdx (#45585)Co-authored-by: Shu Ding <g@shud.in>

Adds additional integration tests for `@next/mdx`.

- Test mdx-rs
- Test `mdx-components.tsx`
- Tests development and production. Previously it only checked
development.

<!--
Thanks for opening a PR! Your contribution is much appreciated.
To make sure your PR is handled as smoothly as possible we request that
you follow the checklist sections below.
Choose the right checklist for the change(s) that you're making:
-->

## Bug

- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have a helpful link attached, see
[`contributing.md`](https://github.com/vercel/next.js/blob/canary/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`
- [ ]
[e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs)
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`](https://github.com/vercel/next.js/blob/canary/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)

---------

Co-authored-by: Shu Ding <g@shud.in>
This commit is contained in:
Tim Neutkens 2023-02-11 13:37:00 +01:00 committed by GitHub
parent d4df2bf2da
commit 1faa599568
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 876 additions and 271 deletions

View file

@ -60,8 +60,8 @@
"@babel/preset-react": "7.14.5",
"@edge-runtime/jest-environment": "2.0.0",
"@fullhuman/postcss-purgecss": "1.3.0",
"@mdx-js/loader": "^1.5.1",
"@mdx-js/react": "^1.6.18",
"@mdx-js/loader": "2.2.1",
"@mdx-js/react": "2.2.1",
"@next/bundle-analyzer": "workspace:*",
"@next/env": "workspace:*",
"@next/eslint-plugin-next": "workspace:*",

View file

@ -12,7 +12,15 @@
},
"peerDependencies": {
"@mdx-js/loader": ">=0.15.0",
"@mdx-js/react": "*"
"@mdx-js/react": ">=0.15.0"
},
"peerDependenciesMeta": {
"@mdx-js/loader": {
"optional": true
},
"@mdx-js/react": {
"optional": true
}
},
"peerDependenciesMeta": {
"@mdx-js/loader": {

View file

@ -136,7 +136,6 @@ const nextConfig = {
pageExtensions: ['ts', 'tsx', 'js', 'jsx', 'md', 'mdx'],
experimental: {
appDir: true,
mdxRs: true
}
// Optionally, add any other Next.js config below
reactStrictMode: true,

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,3 @@
# This is a title
This is a paragraph

View file

@ -0,0 +1,8 @@
import MDXContent from './mdx-file.mdx'
export default function Page() {
return (
<>
<MDXContent />
</>
)
}

View file

@ -0,0 +1,7 @@
export default function Root({ children }: { children: React.ReactNode }) {
return (
<html>
<body>{children}</body>
</html>
)
}

View file

@ -0,0 +1,3 @@
# Hello World
This is MDX!

View file

@ -0,0 +1,5 @@
export function useMDXComponents() {
return {
h1: (props) => <h1 style={{ color: 'red' }} {...props} />,
}
}

View file

@ -0,0 +1,94 @@
import { createNextDescribe } from 'e2e-utils'
for (const type of ['with-mdx-rs', 'without-mdx-rs']) {
createNextDescribe(
`mdx ${type}`,
{
files: __dirname,
dependencies: {
'@next/mdx': 'canary',
'@mdx-js/loader': '^2.2.1',
'@mdx-js/react': '^2.2.1',
},
env: {
WITH_MDX_RS: type === 'with-mdx-rs' ? 'true' : 'false',
},
},
({ next }) => {
describe('app directory', () => {
it('should work in initial html', async () => {
const $ = await next.render$('/')
expect($('h1').text()).toBe('Hello World')
expect($('p').text()).toBe('This is MDX!')
})
it('should work using browser', async () => {
const browser = await next.browser('/')
expect(await browser.elementByCss('h1').text()).toBe('Hello World')
expect(await browser.elementByCss('p').text()).toBe('This is MDX!')
})
it('should work in initial html with mdx import', async () => {
const $ = await next.render$('/import')
expect($('h1').text()).toBe('This is a title')
expect($('p').text()).toBe('This is a paragraph')
})
it('should work using browser with mdx import', async () => {
const browser = await next.browser('/import')
expect(await browser.elementByCss('h1').text()).toBe(
'This is a title'
)
expect(await browser.elementByCss('p').text()).toBe(
'This is a paragraph'
)
})
it('should allow overriding components', async () => {
const browser = await next.browser('/')
expect(await browser.elementByCss('h1').getComputedCss('color')).toBe(
'rgb(255, 0, 0)'
)
})
})
describe('pages directory', () => {
it('should work in initial html', async () => {
const $ = await next.render$('/pages')
expect($('h1').text()).toBe('Hello World')
expect($('p').text()).toBe('This is MDX!')
})
// Recommended for tests that need a full browser
it('should work using browser', async () => {
const browser = await next.browser('/pages')
expect(await browser.elementByCss('h1').text()).toBe('Hello World')
expect(await browser.elementByCss('p').text()).toBe('This is MDX!')
})
it('should work in initial html with mdx import', async () => {
const $ = await next.render$('/pages/import')
expect($('h1').text()).toBe('This is a title')
expect($('p').text()).toBe('This is a paragraph')
})
it('should work using browser with mdx import', async () => {
const browser = await next.browser('/pages/import')
expect(await browser.elementByCss('h1').text()).toBe(
'This is a title'
)
expect(await browser.elementByCss('p').text()).toBe(
'This is a paragraph'
)
})
it('should allow overriding components', async () => {
const browser = await next.browser('/pages')
expect(await browser.elementByCss('h1').getComputedCss('color')).toBe(
'rgb(255, 0, 0)'
)
})
})
}
)
}

View file

@ -0,0 +1,16 @@
const withMDX = require('@next/mdx')({
extension: /\.mdx?$/,
})
/**
* @type {import('next').NextConfig}
*/
const nextConfig = {
pageExtensions: ['js', 'jsx', 'ts', 'tsx', 'mdx'],
experimental: {
appDir: true,
mdxRs: process.env.WITH_MDX_RS === 'true',
},
}
module.exports = withMDX(nextConfig)

View file

@ -0,0 +1,8 @@
import MDXContent from './mdx-file.mdx'
export default function Page() {
return (
<>
<MDXContent />
</>
)
}

View file

@ -0,0 +1,3 @@
# This is a title
This is a paragraph

View file

@ -0,0 +1,3 @@
# Hello World
This is MDX!

5
test/e2e/app-dir/mdx/types/mdx.d.ts vendored Normal file
View file

@ -0,0 +1,5 @@
// types/mdx.d.ts
declare module '*.mdx' {
let MDXComponent: (props) => JSX.Element
export default MDXComponent
}

View file

@ -1,3 +1,8 @@
module.exports = {
/**
* @type {import('next').NextConfig}
*/
const nextConfig = {
experimental: { appDir: true },
}
module.exports = nextConfig

View file

@ -1,14 +0,0 @@
export default ({ children }) => (
<button
style={{
borderRadius: '3px',
border: '1px solid black',
color: 'black',
padding: '0.5em 1em',
cursor: 'pointer',
fontSize: '1.1em',
}}
>
{children}
</button>
)

View file

@ -1,6 +0,0 @@
const withMDX = require('@next/mdx')({
extension: /\.mdx?$/,
})
module.exports = withMDX({
pageExtensions: ['js', 'jsx', 'mdx'],
})

View file

@ -1,7 +0,0 @@
import Button from '../components/button.js'
# MDX + Next.js
Look, a button! 👇
<Button>👋 Hello</Button>

View file

@ -1,5 +0,0 @@
## Hello MDX
Here's a simple mdx file!!
<p>Have p tag!</p>

View file

@ -1,28 +0,0 @@
/* eslint-env jest */
import { join } from 'path'
import { renderViaHTTP, findPort, launchApp, killApp } from 'next-test-utils'
const context = {}
describe('Configuration', () => {
beforeAll(async () => {
context.appPort = await findPort()
context.server = await launchApp(join(__dirname, '../'), context.appPort)
})
afterAll(() => {
killApp(context.server)
})
describe('MDX Plugin support', () => {
it('should render an MDX page correctly', async () => {
expect(await renderViaHTTP(context.appPort, '/')).toMatch(/Hello MDX/)
})
it('should render an MDX page with component correctly', async () => {
expect(await renderViaHTTP(context.appPort, '/button')).toMatch(
/Look, a button!/
)
})
})
})