Skip to content

Commit

Permalink
Create an Integration Test for the default Gatsby Wrappers
Browse files Browse the repository at this point in the history
* Add `npm run setup` to setup symlinks for the test suite.
* Add a note about `npm run setup` in CONTRIBUTING
* Add `npm run test-integration` to run the slower tests.
  • Loading branch information
benstepp committed Apr 11, 2016
1 parent 2a696e0 commit b5afd66
Show file tree
Hide file tree
Showing 15 changed files with 192 additions and 13 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,6 @@ examples/blog/public/
*.un~
dist
bin/published.js

# Build Path of Test Fixtures
test/**/public
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,5 @@ addons:
# script needed to test, because defaults don't work on osx
script:
- npm install
- npm run setup
- npm run test
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ simple steps:

* Clone the repo, navigate to its directory.
* Execute `npm install` to install packages.
* Execute `npm run setup` to set up the test suite.
* Execute `npm uninstall -g gatsby && npm link`
* Use `git pull` to update to latest Gatsby.

Expand Down
10 changes: 6 additions & 4 deletions lib/isomorphic/wrappers/html.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@ import React, { PropTypes } from 'react'

module.exports = React.createClass({
propTypes: {
page: PropTypes.shape({
data: PropTypes.shape({
body: PropTypes.string.isRequired,
route: PropTypes.shape({
page: PropTypes.shape({
data: PropTypes.shape({
body: PropTypes.string.isRequired,
}),
}),
}),
},

render () {
const html = this.props.page.data.body
const html = this.props.route.page.data.body
return (
<div dangerouslySetInnerHTML={{ __html: html }} />
)
Expand Down
12 changes: 7 additions & 5 deletions lib/isomorphic/wrappers/md.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import React, { PropTypes } from 'react'

export default React.createClass({
module.exports = React.createClass({
propTypes: {
page: PropTypes.shape({
data: PropTypes.shape({
body: PropTypes.string.isRequired,
route: PropTypes.shape({
page: PropTypes.shape({
data: PropTypes.shape({
body: PropTypes.string.isRequired,
}),
}),
}),
},

render () {
const post = this.props.page.data
const post = this.props.route.page.data
return (
<div className="markdown">
<h1>{post.title}</h1>
Expand Down
12 changes: 8 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,12 @@
"babel-cli": "^6.7.5",
"babel-eslint": "^6.0.2",
"babel-register": "^6.7.2",
"bluebird": "^3.3.4",
"eslint": "^2.7.0",
"eslint-config-airbnb": "^6.1.0",
"eslint-plugin-ava": "^2.0.1",
"eslint-plugin-react": "^4.3.0"
"eslint-plugin-react": "^4.3.0",
"jsdom": "^8.3.0"
},
"engines": {
"node": ">0.12.0"
Expand All @@ -110,9 +112,11 @@
},
"scripts": {
"build": "babel lib --out-dir dist/",
"lint": "eslint --ext .js,.jsx --ignore-pattern dist .",
"test": "npm run lint && npm run test-node",
"test-node": "node_modules/.bin/ava",
"lint": "eslint --ext .js,.jsx --ignore-pattern dist --ignore-pattern public .",
"test": "npm run lint && npm run test-node && npm run test-integration",
"test-integration": "npm run build && node_modules/.bin/ava test/integration",
"test-node": "node_modules/.bin/ava test/utils",
"setup": "npm run build && scripts/setup.sh",
"watch": "babel -w lib --out-dir dist/"
},
"ava": {
Expand Down
41 changes: 41 additions & 0 deletions scripts/setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/usr/bin/env node

var path = require('path')
var fs = require('fs-extra')
var Promise = require('bluebird')

var mkdir = Promise.promisify(fs.mkdir)
var symlink = Promise.promisify(fs.symlink)
var readdir = Promise.promisify(fs.readdir)
var remove = Promise.promisify(fs.remove)

var nodeModulesDirectory = path.join(process.cwd(), 'node_modules')
var gatsbyDirectory = path.join(nodeModulesDirectory, 'gatsby')
var fixturesDirectory = path.join(process.cwd(), 'test', 'fixtures')

function linkNodeModules (directory) {
var fixtureNodeModules = path.join(fixturesDirectory, directory, 'node_modules')

return remove(fixtureNodeModules)
.then(() => symlink(nodeModulesDirectory, fixtureNodeModules))
}

function linkGatsby () {
var gatsbyPackagePath = path.join(process.cwd(), 'package.json')
var gatsbyDistPath = path.join(process.cwd(), 'dist')
var fixturePackagePath = path.join(gatsbyDirectory, 'package.json')
var fixtureDistPath = path.join(gatsbyDirectory, 'dist')

return remove(gatsbyDirectory)
.then(() => mkdir(gatsbyDirectory))
.then(() => {
return Promise.all([
symlink(gatsbyPackagePath, fixturePackagePath),
symlink(gatsbyDistPath, fixtureDistPath)
])
})
}

linkGatsby()
.then(() => readdir(fixturesDirectory))
.then(fixtures => fixtures.map(linkNodeModules))
14 changes: 14 additions & 0 deletions test/fixtures/starter-wrappers/.gatsby-context.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
'use strict';

// This file is auto-written and used by Gatsby to require
// files from your pages directory.
module.exports = function (callback) {
var context = require.context('./pages', true);
if (module.hot) {
module.hot.accept(context.id, function () {
context = require.context('./pages', true);
return callback(context);
});
}
return callback(context);
};
Empty file.
29 changes: 29 additions & 0 deletions test/fixtures/starter-wrappers/html.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react'
import { prefixLink } from 'gatsby-helpers'

module.exports = React.createClass({
displayName: 'HTML',
propTypes: {
body: React.PropTypes.string,
},
render () {
const { body } = this.props

return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta httpEquiv="X-UA-Compatible" content="IE=edge" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0 maximum-scale=5.0"
/>
</head>
<body className="landing-page">
<div id="react-mount" dangerouslySetInnerHTML={{ __html: body }} />
<script src={prefixLink('/bundle.js')} />
</body>
</html>
)
},
})
15 changes: 15 additions & 0 deletions test/fixtures/starter-wrappers/pages/_template.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react'

export default class Template extends React.Component {
static get propTypes () {
return { children: React.PropTypes.any }
}

render () {
return (
<main>
{this.props.children}
</main>
)
}
}
2 changes: 2 additions & 0 deletions test/fixtures/starter-wrappers/pages/html.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<h1>html</h1>
<p>This is a page with the .html extension.</p>
5 changes: 5 additions & 0 deletions test/fixtures/starter-wrappers/pages/md.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
---
# md

This is a page with the .md extension.
42 changes: 42 additions & 0 deletions test/integration/static-html-wrappers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import test from 'ava'
import path from 'path'
import Promise from 'bluebird'
import fsExtra from 'fs-extra'
import { exec, jsdom } from '../support'
const fs = Promise.promisifyAll(fsExtra)

const starterPath = path.resolve('../', 'fixtures', 'starter-wrappers')
const buildPath = path.join(starterPath, 'public')

test.serial('can build the starter', async t => {
await fs.remove(buildPath)

const exitCode = await exec('gatsby', ['build'], { cwd: starterPath })
const bundle = await fs.statAsync(path.join(buildPath, 'bundle.js'))

t.is(exitCode, 0)
t.truthy(bundle)
})

test('html/index.html has an h1 that states file extention', async t => {
const { document } = await jsdom(path.join(buildPath, 'html/index.html'))
t.truthy(document)

const heading = document.querySelector('h1')
t.truthy(heading)

const headingText = heading.textContent
t.is(headingText, 'html')
})

test('md/index.html has an h1 that states file extention', async t => {
const { document } = await jsdom(path.join(buildPath, 'md/index.html'))
t.truthy(document)

// MD wrapper spits out an h1 tag. Shouldn't it be consistent with HTML
const heading = document.querySelectorAll('h1')[1]
t.truthy(heading)

const headingText = heading.textContent
t.is(headingText, 'md')
})
18 changes: 18 additions & 0 deletions test/support.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import jsdomlib from 'jsdom'
import Promise from 'bluebird'
import { spawn } from 'child_process'

export function exec (command, args, options) {
return new Promise((resolve, reject) => {
const child = spawn(command, args, options)
child.on('exit', code => resolve(code))
child.on('error', error => reject(error))
child.stdout.on('data', data => { console.log(data.toString()) })
child.stderr.on('data', data => { console.error(data.toString()) })
})
}

export function jsdom (html) {
const env = Promise.promisify(jsdomlib.env)
return env(html)
}

0 comments on commit b5afd66

Please sign in to comment.