Skip to content

Commit

Permalink
add tests, fix bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
jescalan committed Apr 30, 2020
1 parent e2c8209 commit 63d26c2
Show file tree
Hide file tree
Showing 8 changed files with 12,262 additions and 584 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
.DS_Store
node_modules
node_modules
__tests__/fixtures/*/.next
__tests__/fixtures/*/out
9 changes: 9 additions & 0 deletions __tests__/fixtures/basic/components/test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export default function Test({ name }) {
const [count, setCount] = React.useState(0)
return (
<>
<p>hello {name}</p>
<button onClick={() => setCount(count + 1)}>Count: {count}</button>
</>
)
}
9 changes: 9 additions & 0 deletions __tests__/fixtures/basic/mdx/test.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
title: 'foo'
---

# Headline

<Test name="jeff" />

Some **markdown** content
24 changes: 24 additions & 0 deletions __tests__/fixtures/basic/pages/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import fs from 'fs'
import path from 'path'
import matter from 'gray-matter'
import renderToString from '../../../../render-to-string'
import hydrate from '../../../../hydrate'
import Test from '../components/test'

const MDX_COMPONENTS = { Test }

export default function TestPage({ data, mdxSource }) {
return (
<>
<h1>{data.title}</h1>
{hydrate(mdxSource, MDX_COMPONENTS)}
</>
)
}

export async function getStaticProps() {
const fixturePath = path.join(process.cwd(), 'mdx/test.mdx')
const { data, content } = matter(fs.readFileSync(fixturePath, 'utf8'))
const mdxSource = await renderToString(content, MDX_COMPONENTS)
return { props: { mdxSource, data } }
}
76 changes: 76 additions & 0 deletions __tests__/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
const spawn = require('cross-spawn')
const path = require('path')
const fs = require('fs')
const puppeteer = require('puppeteer')
const handler = require('serve-handler')
const http = require('http')

jest.setTimeout(30000)

test('it works', () => {
buildFixture('basic')
const result = readOutputFile('basic', 'index')

// server renders correctly
expect(result).toMatch(
'<h1>foo</h1><span><h1>Headline</h1><p>hello <!-- -->jeff</p><button>Count: <!-- -->0</button><p>Some <strong>markdown</strong> content</p></span>'
)
// hydrates correctly
let browser, server
return new Promise(async (resolve) => {
browser = await puppeteer.launch()
const page = await browser.newPage()
page.on('console', (msg) => console.log(msg.text()))
server = await serveStatic('basic')
await page.exposeFunction('__NEXT_HYDRATED_CB', async () => {
// click the button, flakes with one click for some reason
await page.click('button')
await page.click('button')
// wait for react to render
await page.waitFor(() => {
return document.querySelector('button').innerText !== 'Count: 0'
})
// pull the text for a test confirm
const buttonCount = page.$eval('button', (el) => el.innerText)
resolve(buttonCount)
})
await page.goto('http://localhost:1235', { waitUntil: 'domcontentloaded' })
}).then(async (buttonText) => {
expect(buttonText).not.toEqual('Count: 0')

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

function buildFixture(fixture) {
spawn.sync('next', ['build'], {
stdio: 'inherit',
cwd: path.join(__dirname, 'fixtures', fixture),
env: { ...process.env, NODE_ENV: undefined, __NEXT_TEST_MODE: true },
})
spawn.sync('next', ['export'], {
stdio: 'inherit',
cwd: path.join(__dirname, 'fixtures', fixture),
env: { ...process.env, NODE_ENV: undefined, __NEXT_TEST_MODE: true },
})
}

function readOutputFile(fixture, name) {
return fs.readFileSync(
path.join(__dirname, 'fixtures', fixture, 'out', `${name}.html`),
'utf8'
)
}

function serveStatic(fixture) {
return new Promise((resolve) => {
const server = http.createServer((req, res) =>
handler(req, res, {
public: path.join(__dirname, 'fixtures', fixture, 'out'),
})
)
server.listen(1235, () => resolve(server))
})
}
6 changes: 5 additions & 1 deletion hydrate.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ module.exports = function hydrate({ source, renderedOutput }, components) {
// our default result is the server-rendered output
// we get this in front of users as quickly as possible
const [result, setResult] = React.useState(
<span dangerouslySetInnerHTML={{ __html: renderedOutput }} />
React.createElement('span', {
dangerouslySetInnerHTML: {
__html: renderedOutput,
},
})
)

// if we're on the client side and have not yet hydrated, we hydrate
Expand Down
Loading

0 comments on commit 63d26c2

Please sign in to comment.