From 9ce36930212359a8d357d8285a79ff1103cfa9a3 Mon Sep 17 00:00:00 2001 From: Evan You Date: Sat, 23 Apr 2016 20:00:38 -0400 Subject: [PATCH] setup unit test --- .gitignore | 1 + build/alias.js | 1 + build/karma.base.config.js | 42 ++++++++++ build/karma.cover.config.js | 27 +++++++ build/karma.dev.config.js | 8 ++ build/karma.sauce.config.js | 81 +++++++++++++++++++ build/karma.unit.config.js | 9 +++ build/nightwatch.config.js | 52 ++++++------ ...ebpack.config.js => webpack.dev.config.js} | 8 ++ package.json | 24 +++++- test/unit/index.js | 47 +++++++++++ test/unit/specs/test.spec.js | 7 ++ 12 files changed, 277 insertions(+), 30 deletions(-) create mode 100644 build/karma.base.config.js create mode 100644 build/karma.cover.config.js create mode 100644 build/karma.dev.config.js create mode 100644 build/karma.sauce.config.js create mode 100644 build/karma.unit.config.js rename build/{webpack.config.js => webpack.dev.config.js} (76%) create mode 100644 test/unit/index.js create mode 100644 test/unit/specs/test.spec.js diff --git a/.gitignore b/.gitignore index 0595b28bf..e9e5b4682 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ dist/*.map dist/vue.common.min.js selenium-debug.log test/e2e/reports +coverage diff --git a/build/alias.js b/build/alias.js index 01515db43..7a5d3fb93 100644 --- a/build/alias.js +++ b/build/alias.js @@ -1,6 +1,7 @@ var path = require('path') module.exports = { + vue: path.resolve(__dirname, '../src/entries/web-runtime-with-compiler'), compiler: path.resolve(__dirname, '../src/compiler'), core: path.resolve(__dirname, '../src/core'), shared: path.resolve(__dirname, '../src/shared'), diff --git a/build/karma.base.config.js b/build/karma.base.config.js new file mode 100644 index 000000000..a97dc88f8 --- /dev/null +++ b/build/karma.base.config.js @@ -0,0 +1,42 @@ +var alias = require('./alias') +var webpack = require('webpack') + +var webpackConfig = { + resolve: { + alias: Object.assign({}, alias, { + entities: './entity-decoder' + }) + }, + module: { + loaders: [ + { + test: /\.js$/, + loader: 'babel', + exclude: /node_modules/ + } + ] + }, + plugins: [ + new webpack.DefinePlugin({ + 'process.env': { + NODE_ENV: '"development"' + } + }) + ], + devtool: '#inline-source-map' +} + +// shared config for all unit tests +module.exports = { + frameworks: ['jasmine'], + files: [ + '../test/unit/index.js' + ], + preprocessors: { + '../test/unit/index.js': ['webpack', 'sourcemap'] + }, + webpack: webpackConfig, + webpackMiddleware: { + noInfo: true + } +} diff --git a/build/karma.cover.config.js b/build/karma.cover.config.js new file mode 100644 index 000000000..b887b5f1e --- /dev/null +++ b/build/karma.cover.config.js @@ -0,0 +1,27 @@ +var path = require('path') +var base = require('./karma.base.config.js') + +module.exports = function (config) { + var options = Object.assign(base, { + browsers: ['PhantomJS'], + reporters: ['progress', 'coverage'], + coverageReporter: { + reporters: [ + { type: 'lcov', dir: '../coverage', subdir: '.' }, + { type: 'text-summary', dir: '../coverage', subdir: '.' } + ] + }, + singleRun: true + }) + + // add coverage loader + options.webpack.module.preLoaders = [ + { + test: /\.js$/, + include: path.resolve(__dirname, '../src'), + loader: 'isparta' + } + ] + + config.set(options) +} diff --git a/build/karma.dev.config.js b/build/karma.dev.config.js new file mode 100644 index 000000000..756ca1d79 --- /dev/null +++ b/build/karma.dev.config.js @@ -0,0 +1,8 @@ +var base = require('./karma.base.config.js') + +module.exports = function (config) { + config.set(Object.assign(base, { + browsers: ['Chrome'], + reporters: ['progress'] + })) +} diff --git a/build/karma.sauce.config.js b/build/karma.sauce.config.js new file mode 100644 index 000000000..a2dec4bd5 --- /dev/null +++ b/build/karma.sauce.config.js @@ -0,0 +1,81 @@ +var base = require('./karma.base.config.js') + +/** + * Having too many tests running concurrently on saucelabs + * causes timeouts and errors, so we have to run them in + * smaller batches. + */ + +var batches = [ + // the cool kids + { + sl_chrome: { + base: 'SauceLabs', + browserName: 'chrome', + platform: 'Windows 7' + }, + sl_firefox: { + base: 'SauceLabs', + browserName: 'firefox' + }, + sl_mac_safari: { + base: 'SauceLabs', + browserName: 'safari', + platform: 'OS X 10.10' + } + }, + // ie family + { + sl_ie_9: { + base: 'SauceLabs', + browserName: 'internet explorer', + platform: 'Windows 7', + version: '9' + }, + sl_ie_10: { + base: 'SauceLabs', + browserName: 'internet explorer', + platform: 'Windows 8', + version: '10' + }, + sl_ie_11: { + base: 'SauceLabs', + browserName: 'internet explorer', + platform: 'Windows 8.1', + version: '11' + } + }, + // mobile + { + sl_ios_safari: { + base: 'SauceLabs', + browserName: 'iphone', + platform: 'OS X 10.9', + version: '7.1' + }, + sl_android: { + base: 'SauceLabs', + browserName: 'android', + platform: 'Linux', + version: '4.2' + } + } +] + +module.exports = function (config) { + var batch = batches[process.argv[4] || 0] + + config.set(Object.assign(base, { + browsers: Object.keys(batch), + customLaunchers: batch, + reporters: ['progress', 'saucelabs'], + sauceLabs: { + testName: 'Vue.js unit tests', + recordScreenshots: false, + build: process.env.CIRCLE_BUILD_NUM || process.env.SAUCE_BUILD_ID || Date.now() + }, + // mobile emulators are really slow + captureTimeout: 300000, + browserNoActivityTimeout: 300000 + })) +} diff --git a/build/karma.unit.config.js b/build/karma.unit.config.js new file mode 100644 index 000000000..1cf6859fb --- /dev/null +++ b/build/karma.unit.config.js @@ -0,0 +1,9 @@ +var base = require('./karma.base.config.js') + +module.exports = function (config) { + config.set(Object.assign(base, { + browsers: ['Chrome', 'Firefox', 'Safari'], + reporters: ['progress'], + singleRun: true + })) +} diff --git a/build/nightwatch.config.js b/build/nightwatch.config.js index 868c2ac0f..07697a50c 100644 --- a/build/nightwatch.config.js +++ b/build/nightwatch.config.js @@ -1,40 +1,40 @@ // http://nightwatchjs.org/guide#settings-file module.exports = { - "src_folders": ["test/e2e/specs"], - "output_folder": "test/e2e/reports", - "custom_commands_path": ["test/e2e/custom-commands"], - "custom_assertions_path": ["test/e2e/custom-assertions"], + 'src_folders': ['test/e2e/specs'], + 'output_folder': 'test/e2e/reports', + 'custom_commands_path': ['test/e2e/custom-commands'], + 'custom_assertions_path': ['test/e2e/custom-assertions'], - "selenium": { - "start_process": true, - "server_path": "node_modules/selenium-server/lib/runner/selenium-server-standalone-2.53.0.jar", - "host": "127.0.0.1", - "port": 4444, - "cli_args": { - "webdriver.chrome.driver": require('chromedriver').path + 'selenium': { + 'start_process': true, + 'server_path': 'node_modules/selenium-server/lib/runner/selenium-server-standalone-2.53.0.jar', + 'host': '127.0.0.1', + 'port': 4444, + 'cli_args': { + 'webdriver.chrome.driver': require('chromedriver').path } }, - "test_settings": { - "default": { - "selenium_port": 4444, - "selenium_host": "localhost", - "silent": true + 'test_settings': { + 'default': { + 'selenium_port': 4444, + 'selenium_host': 'localhost', + 'silent': true }, - "chrome": { - "desiredCapabilities": { - "browserName": "chrome", - "javascriptEnabled": true, - "acceptSslCerts": true + 'chrome': { + 'desiredCapabilities': { + 'browserName': 'chrome', + 'javascriptEnabled': true, + 'acceptSslCerts': true } }, - "firefox": { - "desiredCapabilities": { - "browserName": "firefox", - "javascriptEnabled": true, - "acceptSslCerts": true + 'firefox': { + 'desiredCapabilities': { + 'browserName': 'firefox', + 'javascriptEnabled': true, + 'acceptSslCerts': true } } } diff --git a/build/webpack.config.js b/build/webpack.dev.config.js similarity index 76% rename from build/webpack.config.js rename to build/webpack.dev.config.js index a8fef7d42..a56dc7590 100644 --- a/build/webpack.config.js +++ b/build/webpack.dev.config.js @@ -1,5 +1,6 @@ var path = require('path') var alias = require('./alias') +var webpack = require('webpack') module.exports = { entry: path.resolve(__dirname, 'dev-entry.js'), @@ -19,5 +20,12 @@ module.exports = { { test: /\.js/, loader: 'babel!eslint', exclude: /node_modules/ } ] }, + plugins: [ + new webpack.DefinePlugin({ + 'process.env': { + NODE_ENV: '"development"' + } + }) + ], devtool: '#source-map' } diff --git a/package.json b/package.json index ff1fa580c..d77c5e336 100644 --- a/package.json +++ b/package.json @@ -10,11 +10,14 @@ "src" ], "scripts": { - "dev": "webpack --config build/webpack.config.js --watch", - "test": "npm run e2e", + "dev": "webpack --watch --config build/webpack.dev.config.js", + "dev-with-test": "npm run dev & karma start build/karma.dev.config.js", + "test": "npm run unit && npm run e2e", "build": "NODE_ENV=production node build/build.js", - "lint": "eslint src", - "e2e": "node test/e2e/runner.js" + "lint": "eslint src build", + "unit": "karma start build/karma.unit.config.js", + "cover": "karma start build/karma.cover.config.js", + "e2e": "npm run build && node test/e2e/runner.js" }, "repository": { "type": "git", @@ -42,7 +45,20 @@ "eslint-plugin-promise": "^1.1.0", "eslint-plugin-standard": "^1.3.2", "http-server": "^0.9.0", + "isparta-loader": "^2.0.0", + "jasmine-core": "^2.4.1", + "karma": "^0.13.15", + "karma-chrome-launcher": "^0.2.3", + "karma-coverage": "^0.5.5", + "karma-firefox-launcher": "^0.1.7", + "karma-jasmine": "^0.3.8", + "karma-phantomjs-launcher": "^1.0.0", + "karma-safari-launcher": "^0.1.1", + "karma-sourcemap-loader": "^0.3.7", + "karma-spec-reporter": "0.0.24", + "karma-webpack": "^1.7.0", "nightwatch": "^0.8.18", + "phantomjs-prebuilt": "^2.1.3", "rollup": "^0.25.8", "rollup-plugin-alias": "^1.0.2", "rollup-plugin-babel": "^2.4.0", diff --git a/test/unit/index.js b/test/unit/index.js new file mode 100644 index 000000000..d06beb9d0 --- /dev/null +++ b/test/unit/index.js @@ -0,0 +1,47 @@ +if (typeof console === 'undefined') { + window.console = { + error: function () {} + } +} + +function hasWarned (msg) { + var count = console.error.calls.count() + var args + while (count--) { + args = console.error.calls.argsFor(count) + if (args.some(containsMsg)) { + return true + } + } + + function containsMsg (arg) { + if (arg instanceof Error) throw arg + return typeof arg === 'string' && arg.indexOf(msg) > -1 + } +} + +// define custom matcher for warnings +beforeEach(function () { + spyOn(console, 'error') + jasmine.addMatchers({ + toHaveBeenWarned: function () { + return { + compare: function (msg) { + var warned = Array.isArray(msg) + ? msg.some(hasWarned) + : hasWarned(msg) + return { + pass: warned, + message: warned + ? 'Expected message "' + msg + '" not to have been warned' + : 'Expected message "' + msg + '" to have been warned' + } + } + } + } + }) +}) + +// require all test files +var testsContext = require.context('./specs', true, /\.spec$/) +testsContext.keys().forEach(testsContext) diff --git a/test/unit/specs/test.spec.js b/test/unit/specs/test.spec.js new file mode 100644 index 000000000..ac118a55b --- /dev/null +++ b/test/unit/specs/test.spec.js @@ -0,0 +1,7 @@ +import Vue from 'vue' + +describe('test', function () { + it('should pass', function () { + expect(Vue.config.replace).toBeUndefined() + }) +})