Skip to content

Commit

Permalink
New test setup (#640)
Browse files Browse the repository at this point in the history
* Use jest-cli instead of gulp plugin.

* Use jest-cli instead of gulp plugin.

* Move fixtures into the examples dir.

* Move test code of example app to the basic example.

* Add isolated tests for server/resolve

* Allow tests to use cheerio.

* Use portfinder to get a unique port.

* Move back integration tests into the example dir.

* Introduce next-test-utils.

* Remove gulp-jest

* Add coveralls support.

* Use transpiled version of code in dist.
This is to make sure same file gets covered
by both unit/isolated tests and integration tests.

* Add support for source maps.

* Use code from dist always.

* Use nyc to stop instrument.

* Add integration test suite for production usage.

* Use jest-cli.

* Add support for running e2e tests.

* Check gzipPath with fs.stat before serving
Otherwise, serve package might throw issues other than ENOENT

* Install chromedriver with npm install.

* Install chrome on travis-ci.

* Add --forceExit to Jest.

* Run tests only on Node v6.
That's because selenium-webdriver only supports
Node 6 LTS.

* Use chromedriver NPM module to install chromedriver.

* Use wd as the webdriver client.

* Run chromedriver before tests.

* Run travis for both node 4 and 6

* Remove unwanted npm install script.

* Move some common text utilities to next-test-utils

* Add lint checks and testing in npm prepublish hook.

* Use npm on travis-ci.
We are having some caching issues with yarn and chromedriver.

* Make tests work on windows.\n But chromedriver doesn't work.

* Clean up dependencies.

* Run chromedriver in background without any tools.

* Fix a typo in the code.

* Use ES6 features used in node4 inside the gulpfile.

* Add some comments.

* Add support for running in windows.

* Stop chromedriver properly on windows.

* Fix typos.
  • Loading branch information
arunoda authored and nkzawa committed Jan 12, 2017
1 parent 4c32dd9 commit 1dc52db
Show file tree
Hide file tree
Showing 41 changed files with 895 additions and 309 deletions.
7 changes: 6 additions & 1 deletion .babelrc
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,10 @@
"transform-object-rest-spread",
"transform-class-properties",
"transform-runtime"
]
],
"env": {
"test": {
"plugins": ["istanbul"]
}
}
}
23 changes: 16 additions & 7 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
sudo: required
dist: trusty
addons:
apt:
sources:
- google-chrome
packages:
- google-chrome-stable
language: node_js
node_js:
- "node"
- "6"
- "4"
- "6"
cache:
yarn: true
directories:
- node_modules
install:
- curl -o- -L https://yarnpkg.com/install.sh | bash
- export PATH=$HOME/.yarn/bin:$PATH
- yarn --ignore-engines
before_install:
- rm yarn.lock
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
- sleep 3
script:
- echo "No need to use npm test since it's done in the install section via 'npm prepublish'"
after_script: npm run coveralls
47 changes: 29 additions & 18 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ const sequence = require('run-sequence')
const webpack = require('webpack')
const webpackStream = require('webpack-stream')
const del = require('del')
const jest = require('gulp-jest')
const childProcess = require('child_process')

const isWindows = /^win/.test(process.platform)
const babelOptions = JSON.parse(fs.readFileSync('.babelrc', 'utf-8'))

gulp.task('compile', [
Expand Down Expand Up @@ -123,21 +124,6 @@ gulp.task('build-prefetcher', ['compile-lib', 'compile-client'], () => {
.pipe(notify('Built release prefetcher'))
})

gulp.task('test', ['compile'], () => {
return gulp.src('./test')
.pipe(jest.default({
coverage: true,
verbose: true,
config: {
rootDir: './test',
testEnvironment: 'node',
coveragePathIgnorePatterns: [
'test/.*'
]
}
}))
})

gulp.task('bench', ['compile', 'copy', 'compile-bench', 'copy-bench-fixtures'], () => {
return gulp.src('dist/bench/*.js', {read: false})
.pipe(benchmark({
Expand Down Expand Up @@ -193,7 +179,6 @@ gulp.task('default', [
'compile',
'build',
'copy',
'test',
'watch'
])

Expand All @@ -202,10 +187,36 @@ gulp.task('release', (cb) => {
'compile',
'build',
'copy',
'test'
], cb)
})

// We run following task inside a NPM script chain and it runs chromedriver
// inside a child process tree.
// Even though we kill this task's process, chromedriver exists throughout
// the lifetime of the original npm script.

gulp.task('start-chromedriver', ['stop-chromedriver'], (cb) => {
const processName = isWindows? 'chromedriver.cmd' : 'chromedriver'
const chromedriver = childProcess.spawn(processName, { stdio: 'inherit' })

const timeoutHandler = setTimeout(() => {
// We need to do this, otherwise this task's process will keep waiting.
process.exit(0)
}, 2000)
})

gulp.task('stop-chromedriver', () => {
try {
if (isWindows) {
childProcess.execSync('taskkill /im chromedriver* /t /f', { stdio: 'ignore' })
} else {
childProcess.execSync('pkill chromedriver', { stdio: 'ignore' })
}
} catch(ex) {
// Do nothing
}
})

// avoid logging to the console
// that we created a notification
notify_.logLevel(0)
Expand Down
32 changes: 22 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@
},
"scripts": {
"build": "gulp",
"pretest": "npm run lint",
"test": "gulp test",
"html-report": "nyc report --temp-directory=./coverage --reporter=html",
"jest": "jest --coverage",
"coveralls": "nyc report --temp-directory=./coverage --reporter=text-lcov | coveralls",
"release": "gulp release",
"pretestonly": "gulp start-chromedriver",
"testonly": "cross-env NODE_PATH=test/lib jest \\.test.js",
"posttestonly": "gulp stop-chromedriver",
"pretest": "npm run lint && cross-env NODE_ENV=test npm run release",
"test": "npm run testonly -- --coverage --forceExit",
"coveralls": "nyc --instrument=false --source-map=false report --temp-directory=./coverage --reporter=text-lcov | coveralls",
"lint": "standard 'bin/*' 'client/**/*.js' 'examples/**/*.js' 'lib/**/*.js' 'pages/**/*.js' 'server/**/*.js' 'test/**/*.js'",
"prepublish": "gulp release",
"prepublish": "npm run test && npm run release",
"precommit": "npm run lint"
},
"standard": {
Expand Down Expand Up @@ -84,24 +86,34 @@
},
"devDependencies": {
"babel-eslint": "7.1.1",
"babel-jest": "^18.0.0",
"babel-plugin-istanbul": "^3.0.0",
"babel-plugin-transform-remove-strict-mode": "0.0.2",
"babel-preset-env": "1.1.8",
"benchmark": "2.1.3",
"cheerio": "^0.22.0",
"chromedriver": "^2.26.1",
"coveralls": "2.11.15",
"gulp": "3.9.1",
"gulp-babel": "6.1.2",
"gulp-benchmark": "1.1.1",
"gulp-cached": "1.1.1",
"gulp-jest": "^1.0.0",
"gulp-notify": "2.2.0",
"husky": "0.12.0",
"jest": "^18.0.0",
"jest-cli": "^18.0.0",
"node-fetch": "^1.6.3",
"nyc": "^10.0.0",
"portfinder": "^1.0.10",
"run-sequence": "1.2.2",
"standard": "8.6.0",
"webpack-stream": "3.2.0"
"wd": "^1.1.1",
"webpack-stream": "3.2.0",
"cross-env": "^3.1.4"
},
"jest": {
"testEnvironment": "node"
"testEnvironment": "node",
"testPathDirs": [
"test/"
]
}
}
9 changes: 9 additions & 0 deletions server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ export default class Server {
if (this.hotReloader) {
await this.hotReloader.stop()
}

if (this.http) {
await new Promise((resolve, reject) => {
this.http.close((err) => {
if (err) return reject(err)
return resolve()
})
})
}
}

defineRoutes () {
Expand Down
1 change: 1 addition & 0 deletions server/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ export async function serveStaticWithGzip (req, res, path) {
// we don't add gzipped files at runtime.
await fs.stat(gzipPath)
} catch (ex) {
// Handles the error thrown by fs.stat
if (ex.code === 'ENOENT') {
// Seems like there's no gzipped file. Let's serve the uncompressed file.
return serveStatic(req, res, path)
Expand Down
4 changes: 2 additions & 2 deletions server/resolve.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ function getPaths (id) {

if (i[i.length - 1] === sep) {
return [
i + 'index.json',
i + 'index.js'
i + 'index.js',
i + 'index.json'
]
}

Expand Down
18 changes: 0 additions & 18 deletions test/fixtures/basic/pages/async-props.js

This file was deleted.

1 change: 0 additions & 1 deletion test/fixtures/basic/pages/error.js

This file was deleted.

122 changes: 0 additions & 122 deletions test/integration.test.js

This file was deleted.

18 changes: 18 additions & 0 deletions test/integration/basic/pages/async-props.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react'

export default class AsyncProps extends React.Component {
static async getInitialProps () {
return await fetchData()
}

render () {
return <p>{this.props.name}</p>
}
}

function fetchData () {
const p = new Promise(resolve => {
setTimeout(() => resolve({ name: 'Diego Milito' }), 10)
})
return p
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react'
import style from 'next/css'

export default () => <div className={styles}>This is red</div>
export default () => <div id='red-box' className={styles}>This is red</div>

const styles = style({ color: 'red' })
3 changes: 3 additions & 0 deletions test/integration/basic/pages/error.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default () => {
throw new Error('This is an expected error')
}
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit 1dc52db

Please sign in to comment.