From b59bdb17b26c1a00442965fe288e6caa61c0a53f Mon Sep 17 00:00:00 2001 From: Nicolas Gallagher Date: Sat, 17 Oct 2015 17:25:12 -0700 Subject: [PATCH] [change] Unit test setup and reporter --- .eslintrc | 3 - .travis.yml | 2 +- CONTRIBUTING.md | 2 +- config/constants.js | 3 +- config/karma.config.js | 49 ++++++++------- package.json | 8 ++- .../index-test.js} | 18 +++--- .../index-test.js} | 4 +- .../index-test.js} | 4 +- .../index-test.js} | 10 ++-- .../index-test.js} | 60 +++++++++---------- .../index-test.js} | 8 ++- .../index-test.js} | 8 ++- .../index-test.js} | 4 +- src/modules/specHelpers/index.js | 21 ++++--- src/{specs.context.js => tests.webpack.js} | 5 +- 16 files changed, 114 insertions(+), 95 deletions(-) rename src/components/Image/{index.spec.js => __tests__/index-test.js} (79%) rename src/components/ListView/{index.spec.js => __tests__/index-test.js} (88%) rename src/components/ScrollView/{index.spec.js => __tests__/index-test.js} (65%) rename src/components/Text/{index.spec.js => __tests__/index-test.js} (81%) rename src/components/TextInput/{index.spec.js => __tests__/index-test.js} (83%) rename src/components/Touchable/{index.spec.js => __tests__/index-test.js} (79%) rename src/components/View/{index.spec.js => __tests__/index-test.js} (86%) rename src/modules/filterObjectProps/{index.spec.js => __tests__/index-test.js} (89%) rename src/{specs.context.js => tests.webpack.js} (60%) diff --git a/.eslintrc b/.eslintrc index ee307322..e325acd2 100644 --- a/.eslintrc +++ b/.eslintrc @@ -3,9 +3,6 @@ "parser": "babel-eslint", // based on https://github.com/feross/standard "extends": [ "standard", "standard-react" ], - "env": { - "mocha": true - }, "rules": { // overrides of the standard style "space-before-function-paren": [ 2, { "anonymous": "always", "named": "never" } ], diff --git a/.travis.yml b/.travis.yml index 201ca059..763195c6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: node_js node_js: - - "0.12" + - "4.1" before_script: - export DISPLAY=:99.0 - sh -e /etc/init.d/xvfb start diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2d8b8aa4..6d43d0ac 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -70,7 +70,7 @@ Development commands: * `npm run build` – build the library * `npm run dev` – start the dev server and develop against live examples * `npm run lint` – run the linter -* `npm run test:specs` – run and watch the unit tests +* `npm run test` – run the linter and unit tests Please follow this process for submitting a patch: diff --git a/config/constants.js b/config/constants.js index 7c7cfd93..33687b09 100644 --- a/config/constants.js +++ b/config/constants.js @@ -5,5 +5,6 @@ var ROOT = path.join(__dirname, '..') module.exports = { DIST_DIRECTORY: path.join(ROOT, 'dist'), SRC_DIRECTORY: path.join(ROOT, 'src'), - ROOT_DIRECTORY: ROOT + ROOT_DIRECTORY: ROOT, + TEST_ENTRY: path.join(ROOT, 'src/tests.webpack.js') } diff --git a/config/karma.config.js b/config/karma.config.js index f52eb8f7..2ffbe533 100644 --- a/config/karma.config.js +++ b/config/karma.config.js @@ -1,6 +1,5 @@ -var assign = require('object-assign') var constants = require('./constants') -var webpackConfig = require('./webpack.config.base') +var webpack = require('webpack') module.exports = function (config) { config.set({ @@ -9,38 +8,48 @@ module.exports = function (config) { browserNoActivityTimeout: 60000, client: { captureConsole: true, - mocha: { - ui: 'tdd' - }, + mocha: { ui: 'tdd' }, useIframe: true }, files: [ - 'src/specs.context.js' - ], - frameworks: [ - 'mocha' + constants.TEST_ENTRY ], + frameworks: [ 'mocha' ], plugins: [ 'karma-chrome-launcher', 'karma-firefox-launcher', 'karma-mocha', + 'karma-mocha-reporter', 'karma-sourcemap-loader', 'karma-webpack' ], preprocessors: { - 'src/specs.context.js': [ 'webpack', 'sourcemap' ] + [constants.TEST_ENTRY]: [ 'webpack', 'sourcemap' ] }, - reporters: [ 'dots' ], + reporters: process.env.TRAVIS ? [ 'dots' ] : [ 'mocha' ], singleRun: true, - webpack: assign({}, webpackConfig, { devtool: 'inline' }), - webpackMiddleware: { - stats: { - assetsSort: 'name', - colors: true, - children: false, - chunks: false, - modules: false - } + webpack: { + devtool: 'inline-source-map', + module: { + loaders: [ + { + test: /\.js$/, + exclude: /node_modules/, + loader: 'babel', + query: { cacheDirectory: true } + } + ] + }, + plugins: [ + new webpack.DefinePlugin({ + 'process.env': { + NODE_ENV: JSON.stringify('test') + } + }) + ] + }, + webpackServer: { + noInfo: true } }) } diff --git a/package.json b/package.json index 15ea54a9..9cf96450 100644 --- a/package.json +++ b/package.json @@ -11,9 +11,9 @@ "dev": "webpack-dev-server --config config/webpack.config.example.js --inline --colors --quiet", "lint": "eslint config src", "prepublish": "NODE_ENV=publish npm run build", - "test:specs": "NODE_ENV=test karma start config/karma.config.js", - "test:specs:watch": "npm run test:specs -- --no-single-run", - "test": "npm run test:specs && npm run lint" + "test": "npm run lint && npm run test:unit", + "test:unit": "karma start config/karma.config.js", + "test:watch": "npm run test:unit -- --no-single-run" }, "dependencies": { "react": ">=0.13.3", @@ -35,9 +35,11 @@ "eslint-plugin-standard": "^1.3.0", "extract-text-webpack-plugin": "^0.8.2", "karma": "^0.13.9", + "karma-browserstack-launcher": "^0.1.5", "karma-chrome-launcher": "^0.2.0", "karma-firefox-launcher": "^0.1.6", "karma-mocha": "^0.2.0", + "karma-mocha-reporter": "^1.1.1", "karma-sourcemap-loader": "^0.3.5", "karma-webpack": "^1.7.0", "mocha": "^2.3.0", diff --git a/src/components/Image/index.spec.js b/src/components/Image/__tests__/index-test.js similarity index 79% rename from src/components/Image/index.spec.js rename to src/components/Image/__tests__/index-test.js index a576094f..505e9b77 100644 --- a/src/components/Image/index.spec.js +++ b/src/components/Image/__tests__/index-test.js @@ -1,10 +1,12 @@ -import { assertProps, render, renderToDOM } from '../../modules/specHelpers' +/* eslint-env mocha */ + +import { assertProps, render, renderToDOM } from '../../../modules/specHelpers' import assert from 'assert' import React from 'react/addons' -import Image from '.' +import Image from '../' -suite('Image', () => { +suite('components/Image', () => { test('default accessibility', () => { const dom = renderToDOM() assert.equal(dom.getAttribute('role'), 'img') @@ -18,7 +20,7 @@ suite('Image', () => { assertProps.accessible(Image) }) - test.skip('prop "children"', () => { }) + test('prop "children"') test('prop "defaultSource"', () => { const defaultSource = { uri: 'https://google.com/favicon.ico' } @@ -51,13 +53,13 @@ suite('Image', () => { } }) - test.skip('prop "onLoadEnd"', () => { }) + test('prop "onLoadEnd"') - test.skip('prop "onLoadStart"', () => { }) + test('prop "onLoadStart"') - test.skip('prop "resizeMode"', () => { }) + test('prop "resizeMode"') - test.skip('prop "source"', () => { }) + test('prop "source"') test('prop "style"', () => { assertProps.style(Image) diff --git a/src/components/ListView/index.spec.js b/src/components/ListView/__tests__/index-test.js similarity index 88% rename from src/components/ListView/index.spec.js rename to src/components/ListView/__tests__/index-test.js index 2cfb8b75..0fe4a477 100644 --- a/src/components/ListView/index.spec.js +++ b/src/components/ListView/__tests__/index-test.js @@ -1,8 +1,10 @@ +/* eslint-env mocha */ + /* import assert from 'assert' import React from 'react/addons' -import ListView from '.' +import ListView from '../' const ReactTestUtils = React.addons.TestUtils diff --git a/src/components/ScrollView/index.spec.js b/src/components/ScrollView/__tests__/index-test.js similarity index 65% rename from src/components/ScrollView/index.spec.js rename to src/components/ScrollView/__tests__/index-test.js index 3fb97fb7..6052bbea 100644 --- a/src/components/ScrollView/index.spec.js +++ b/src/components/ScrollView/__tests__/index-test.js @@ -1,5 +1,7 @@ +/* eslint-env mocha */ + /* -import { assertProps, renderToDOM, shallowRender } from '../../modules/specHelpers' +import { assertProps, renderToDOM, shallowRender } from '../../../modules/specHelpers' import assert from 'assert' import React from 'react/addons' diff --git a/src/components/Text/index.spec.js b/src/components/Text/__tests__/index-test.js similarity index 81% rename from src/components/Text/index.spec.js rename to src/components/Text/__tests__/index-test.js index b4e02435..8a83a8a8 100644 --- a/src/components/Text/index.spec.js +++ b/src/components/Text/__tests__/index-test.js @@ -1,12 +1,14 @@ -import { assertProps, renderToDOM, shallowRender } from '../../modules/specHelpers' +/* eslint-env mocha */ + +import { assertProps, renderToDOM, shallowRender } from '../../../modules/specHelpers' import assert from 'assert' import React from 'react/addons' -import Text from '.' +import Text from '../' const ReactTestUtils = React.addons.TestUtils -suite('Text', () => { +suite('components/Text', () => { test('prop "accessibilityLabel"', () => { assertProps.accessibilityLabel(Text) }) @@ -25,7 +27,7 @@ suite('Text', () => { assertProps.component(Text, 'span') }) - test.skip('prop "numberOfLines"', () => {}) + test('prop "numberOfLines"') test('prop "onPress"', (done) => { const dom = renderToDOM() diff --git a/src/components/TextInput/index.spec.js b/src/components/TextInput/__tests__/index-test.js similarity index 83% rename from src/components/TextInput/index.spec.js rename to src/components/TextInput/__tests__/index-test.js index 4dfdbf49..345646a6 100644 --- a/src/components/TextInput/index.spec.js +++ b/src/components/TextInput/__tests__/index-test.js @@ -1,12 +1,14 @@ -import * as utils from '../../modules/specHelpers' +/* eslint-env mocha */ + +import * as utils from '../../../modules/specHelpers' import assert from 'assert' import React from 'react/addons' -import TextInput from '.' +import TextInput from '../' const ReactTestUtils = React.addons.TestUtils -suite('TextInput', () => { +suite('components/TextInput', () => { test('prop "accessibilityLabel"', () => { utils.assertProps.accessibilityLabel(TextInput) }) @@ -29,18 +31,16 @@ suite('TextInput', () => { assert.deepEqual(document.activeElement, dom) }) - test('prop "clearTextOnFocus"', () => { + utils.testIfDocumentFocused('prop "clearTextOnFocus"', () => { const defaultValue = 'defaultValue' - utils.requiresFocus(() => { - // false - let dom = utils.renderAndInject() - dom.focus() - assert.equal(dom.value, defaultValue) - // true - dom = utils.renderAndInject() - dom.focus() - assert.equal(dom.value, '') - }) + // false + let dom = utils.renderAndInject() + dom.focus() + assert.equal(dom.value, defaultValue) + // true + dom = utils.renderAndInject() + dom.focus() + assert.equal(dom.value, '') }) test('prop "defaultValue"', () => { @@ -126,7 +126,7 @@ suite('TextInput', () => { const height = dom.getBoundingClientRect().height // need a range because of cross-browser differences assert.ok(height >= 40) - assert.ok(height <= 45) + assert.ok(height <= 46) }) test('prop "onBlur"', (done) => { @@ -166,7 +166,7 @@ suite('TextInput', () => { } }) - test.skip('prop "onLayout"', () => {}) + test('prop "onLayout"') test('prop "onSelectionChange"', (done) => { const input = utils.renderAndInject() @@ -178,9 +178,9 @@ suite('TextInput', () => { } }) - test.skip('prop "placeholder"', () => {}) + test('prop "placeholder"') - test.skip('prop "placeholderTextColor"', () => {}) + test('prop "placeholderTextColor"') test('prop "secureTextEntry"', () => { let dom = utils.renderToDOM() @@ -190,20 +190,18 @@ suite('TextInput', () => { assert.equal(dom.getAttribute('type'), undefined) }) - test('prop "selectTextOnFocus"', () => { + utils.testIfDocumentFocused('prop "selectTextOnFocus"', () => { const text = 'Text' - utils.requiresFocus(() => { - // false - let dom = utils.renderAndInject() - dom.focus() - assert.equal(dom.selectionEnd, 0) - assert.equal(dom.selectionStart, 0) - // true - dom = utils.renderAndInject() - dom.focus() - assert.equal(dom.selectionEnd, 4) - assert.equal(dom.selectionStart, 0) - }) + // false + let dom = utils.renderAndInject() + dom.focus() + assert.equal(dom.selectionEnd, 0) + assert.equal(dom.selectionStart, 0) + // true + dom = utils.renderAndInject() + dom.focus() + assert.equal(dom.selectionEnd, 4) + assert.equal(dom.selectionStart, 0) }) test('prop "style"', () => { diff --git a/src/components/Touchable/index.spec.js b/src/components/Touchable/__tests__/index-test.js similarity index 79% rename from src/components/Touchable/index.spec.js rename to src/components/Touchable/__tests__/index-test.js index 53797ec8..73172553 100644 --- a/src/components/Touchable/index.spec.js +++ b/src/components/Touchable/__tests__/index-test.js @@ -1,13 +1,15 @@ -import { assertProps, shallowRender } from '../../modules/specHelpers' +/* eslint-env mocha */ + +import { assertProps, shallowRender } from '../../../modules/specHelpers' import assert from 'assert' import React from 'react/addons' -import Touchable from '.' +import Touchable from '../' const children = children const requiredProps = { children } -suite('Touchable', () => { +suite('components/Touchable', () => { test('prop "accessibilityLabel"', () => { assertProps.accessibilityLabel(Touchable, requiredProps) }) diff --git a/src/components/View/index.spec.js b/src/components/View/__tests__/index-test.js similarity index 86% rename from src/components/View/index.spec.js rename to src/components/View/__tests__/index-test.js index 1141010f..2c752501 100644 --- a/src/components/View/index.spec.js +++ b/src/components/View/__tests__/index-test.js @@ -1,10 +1,12 @@ -import { assertProps, shallowRender } from '../../modules/specHelpers' +/* eslint-env mocha */ + +import { assertProps, shallowRender } from '../../../modules/specHelpers' import assert from 'assert' import React from 'react/addons' -import View from '.' +import View from '../' -suite('View', () => { +suite('components/View', () => { test('prop "accessibilityLabel"', () => { assertProps.accessibilityLabel(View) }) diff --git a/src/modules/filterObjectProps/index.spec.js b/src/modules/filterObjectProps/__tests__/index-test.js similarity index 89% rename from src/modules/filterObjectProps/index.spec.js rename to src/modules/filterObjectProps/__tests__/index-test.js index 95aebeeb..f70dd06a 100644 --- a/src/modules/filterObjectProps/index.spec.js +++ b/src/modules/filterObjectProps/__tests__/index-test.js @@ -1,4 +1,6 @@ -import { omitProps, pickProps } from '.' +/* eslint-env mocha */ + +import { omitProps, pickProps } from '..' import assert from 'assert' suite('pickProps', () => { diff --git a/src/modules/specHelpers/index.js b/src/modules/specHelpers/index.js index 87a9b9d2..80059ec8 100644 --- a/src/modules/specHelpers/index.js +++ b/src/modules/specHelpers/index.js @@ -1,3 +1,5 @@ +/* eslint-env mocha */ + import assert from 'assert' import React from 'react/addons' @@ -105,19 +107,16 @@ export function renderToDOM(element, container) { return React.findDOMNode(result) } -export function requiresFocus(test, fallback) { - if (document.hasFocus && document.hasFocus()) { - test() - } else { - console.warn('Test was skipped as the document is not focused') - if (fallback) { - fallback() - } - } -} - export function shallowRender(component, context = {}) { const shallowRenderer = React.addons.TestUtils.createRenderer() shallowRenderer.render(component, context) return shallowRenderer.getRenderOutput() } + +export function testIfDocumentFocused(message, fn) { + if (document.hasFocus && document.hasFocus()) { + test(message, fn) + } else { + test.skip(`${message} – WARNING: document is not focused`) + } +} diff --git a/src/specs.context.js b/src/tests.webpack.js similarity index 60% rename from src/specs.context.js rename to src/tests.webpack.js index cbd88299..ab3a4de7 100644 --- a/src/specs.context.js +++ b/src/tests.webpack.js @@ -4,6 +4,5 @@ * * See: https://github.com/webpack/docs/wiki/context */ -const specContext = require.context('.', true, /.+\.spec\.jsx?$/) -specContext.keys().forEach(specContext) -module.exports = specContext +var context = require.context('.', true, /-test\.js$/) +context.keys().forEach(context)