Skip to content

Commit

Permalink
feat: replace jest with vitest
Browse files Browse the repository at this point in the history
  • Loading branch information
dstaley committed Mar 13, 2024
1 parent acdc597 commit 525d7dc
Show file tree
Hide file tree
Showing 9 changed files with 12,004 additions and 22,085 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@ jobs:
- name: Install and build
run: |
npm ci
- name: Run Jest
- name: Run Tests
run: npm run test
1 change: 0 additions & 1 deletion .jest/dirname.cjs

This file was deleted.

236 changes: 123 additions & 113 deletions __tests__/integration.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,153 +3,163 @@
* SPDX-License-Identifier: MPL-2.0
*/

import { jest } from '@jest/globals'
import { Server } from 'http'
import * as cheerio from 'cheerio'

import {
buildFixture,
createDescribe,
readOutputFile,
serveStatic,
startDevServer,
stopDevServer,
} from '../.jest/utils'
createTmpTestDir,
cleanupTmpTestDir,
} from './utils'
import { ChildProcess } from 'child_process'
import { vi, describe, test, expect, beforeAll } from 'vitest'
import puppeteer, { type Browser } from 'puppeteer'

vi.setConfig({ testTimeout: 30000, hookTimeout: 30000 })

describe('hydration - production', () => {
let tmpDir: string
let browser: Browser

beforeAll(async () => {
tmpDir = await createTmpTestDir('basic')
browser = await puppeteer.launch()
buildFixture(tmpDir)

return async () => {
await browser.close()
await cleanupTmpTestDir(tmpDir)
}
})

test('server rendered output', async () => {
const result = await readOutputFile(tmpDir, 'index')
const $ = cheerio.load(result)

const htmlOutput = $('#__next').html()

// server renders correctly
expect(htmlOutput).toContain(`<h1>foo</h1>`)
expect(htmlOutput).toContain(`<h2>Headline</h2>`)
expect(htmlOutput).toContain(`<p>hello <!-- -->jeff</p>`)
expect(htmlOutput).toContain(`<button>Count: <!-- -->0</button>`)
expect($('.context').text()).toBe('Context value: "foo"')
expect(htmlOutput).toContain(
`<p>Some <strong class=\"custom-strong\">markdown</strong> content</p>`
)
expect(htmlOutput).toContain(
`<div class=\"alert alert-warning g-type-body\"><p>Alert</p></div>`
)
})

jest.setTimeout(30000)

createDescribe(
'hydration - production',
{ fixture: 'basic' },
({ dir, browser }) => {
beforeAll(() => {
buildFixture(dir())
})

test('server rendered output', () => {
const result = readOutputFile(dir(), 'index')
const $ = cheerio.load(result)

const htmlOutput = $('#__next').html()

// server renders correctly
expect(htmlOutput).toContain(`<h1>foo</h1>`)
expect(htmlOutput).toContain(`<h2>Headline</h2>`)
expect(htmlOutput).toContain(`<p>hello <!-- -->jeff</p>`)
expect(htmlOutput).toContain(`<button>Count: <!-- -->0</button>`)
expect($('.context').text()).toBe('Context value: "foo"')
expect(htmlOutput).toContain(
`<p>Some <strong class=\"custom-strong\">markdown</strong> content</p>`
)
expect(htmlOutput).toContain(
`<div class=\"alert alert-warning g-type-body\"><p>Alert</p></div>`
)
})

test('rehydrates correctly in browser', async () => {
// hydrates correctly
let server: Server
const page = await browser().newPage()
page.on('console', (msg) => console.log(msg.text()))
server = await serveStatic(dir())
test('rehydrates correctly in browser', async () => {
// hydrates correctly
let server: Server
const page = await browser.newPage()
page.on('console', (msg) => console.log(msg.text()))
server = await serveStatic(tmpDir)

await page.goto('http://localhost:1235')
await page.goto('http://localhost:1235')

// @ts-expect-error
await page.waitForFunction(() => Boolean(window.__NEXT_HYDRATED))
// @ts-expect-error
await page.waitForFunction(() => Boolean(window.__NEXT_HYDRATED))

await page.waitForSelector('button')
await page.waitForSelector('button')

// click the button
await page.click('button')
// click the button
await page.click('button')

// wait for react to render
await page.waitForFunction(() => {
return document.querySelector('button')?.innerText === 'Count: 1'
})
// wait for react to render
await page.waitForFunction(() => {
return document.querySelector('button')?.innerText === 'Count: 1'
})

// pull text for elements we're testing hydrate on
const contextElementText = await page.$eval(
'.context',
// @ts-expect-error -- el is typed as Element, but reasonable to assume it is an HTMLElement at this point
(el) => el.innerText
)
// pull text for elements we're testing hydrate on
const contextElementText = await page.$eval(
'.context',
// @ts-expect-error -- el is typed as Element, but reasonable to assume it is an HTMLElement at this point
const buttonText = await page.$eval('button', (el) => el.innerText)
(el) => el.innerText
)
// @ts-expect-error -- el is typed as Element, but reasonable to assume it is an HTMLElement at this point
const buttonText = await page.$eval('button', (el) => el.innerText)

expect(buttonText).toEqual('Count: 1')
expect(contextElementText).toEqual('Context value: "bar"')
expect(buttonText).toEqual('Count: 1')
expect(contextElementText).toEqual('Context value: "bar"')

// close the browser and dev server
await new Promise((resolve) => server.close(resolve))
})
}
)
// close the browser and dev server
await new Promise((resolve) => server.close(resolve))
})
})

createDescribe(
'hydration - dev server',
{ fixture: 'basic' },
({ dir, browser }) => {
let childProcess: ChildProcess
describe('hydration - dev server', () => {
let tmpDir: string
let browser: Browser
let childProcess: ChildProcess

beforeAll(async () => {
childProcess = await startDevServer(dir())
})
beforeAll(async () => {
tmpDir = await createTmpTestDir('basic')
browser = await puppeteer.launch()
childProcess = await startDevServer(tmpDir)

afterAll(async () => {
// close the browser and dev server
return async () => {
await browser.close()
await stopDevServer(childProcess)
})
await cleanupTmpTestDir(tmpDir)
}
})

test('loads in development', async () => {
const page = await browser().newPage()
page.on('console', (msg) => console.log(msg.text()))
test('loads in development', async () => {
const page = await browser.newPage()
page.on('console', (msg) => console.log(msg.text()))

await page.goto('http://localhost:12333')
await page.goto('http://localhost:12333')

// @ts-expect-error
await page.waitForFunction(() => Boolean(window.__NEXT_HYDRATED))
// @ts-expect-error
await page.waitForFunction(() => Boolean(window.__NEXT_HYDRATED))

// @ts-expect-error -- el is typed as Element, but reasonable to assume it is an HTMLElement at this point
const headingText = await page.$eval('h1', (el) => el.innerText)
// @ts-expect-error -- el is typed as Element, but reasonable to assume it is an HTMLElement at this point
const headingText = await page.$eval('h1', (el) => el.innerText)

expect(headingText).toEqual('foo')
})
}
)
expect(headingText).toEqual('foo')
})
})

createDescribe(
'hydration - dev server - rsc',
{ fixture: 'rsc' },
({ dir, browser }) => {
let childProcess: ChildProcess
describe('hydration - dev server - rsc', () => {
let tmpDir: string
let browser: Browser
let childProcess: ChildProcess

beforeAll(async () => {
childProcess = await startDevServer(dir())
})
beforeAll(async () => {
tmpDir = await createTmpTestDir('rsc')
browser = await puppeteer.launch()
childProcess = await startDevServer(tmpDir)

afterAll(async () => {
// close the browser and dev server
return async () => {
await browser.close()
await stopDevServer(childProcess)
})

test.each(['/app-dir-mdx/mdxremote', '/app-dir-mdx/compile-mdx'])(
'%s',
async (path) => {
const page = await browser().newPage()
page.on('console', (msg) => console.log(msg.text()))
await cleanupTmpTestDir(tmpDir)
}
})

test.each(['/app-dir-mdx/mdxremote', '/app-dir-mdx/compile-mdx'])(
'%s',
async (path) => {
const page = await browser.newPage()
page.on('console', (msg) => console.log(msg.text()))

await page.goto(`http://localhost:12333${path}`)
await page.goto(`http://localhost:12333${path}`)

// @ts-expect-error
await page.waitForFunction(() => Boolean(window.__NEXT_HYDRATED))
// @ts-expect-error
await page.waitForFunction(() => Boolean(window.__NEXT_HYDRATED))

// @ts-expect-error -- el is typed as Element, but reasonable to assume it is an HTMLElement at this point
const headingText = await page.$eval('h1', (el) => el.innerText)
// @ts-expect-error -- el is typed as Element, but reasonable to assume it is an HTMLElement at this point
const headingText = await page.$eval('h1', (el) => el.innerText)

expect(headingText).toEqual('foo')
}
)
}
)
expect(headingText).toEqual('foo')
}
)
})
2 changes: 2 additions & 0 deletions __tests__/rsc.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

import { compileMDX } from '../rsc'

import { describe, test, expect } from 'vitest'

describe('compileMDX', () => {
test('frontmatter types', async () => {
const { frontmatter } = await compileMDX<{ title: string }>({
Expand Down
4 changes: 3 additions & 1 deletion __tests__/serialize.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import { VFile } from 'vfile'

import { MDXRemote } from '../'
import { serialize } from '../serialize'
import { renderStatic } from '../.jest/utils'
import { renderStatic } from './utils'

import { describe, test, expect } from 'vitest'

interface Frontmatter {
hello: string
Expand Down
Loading

0 comments on commit 525d7dc

Please sign in to comment.