From a7d582580159b97307042f9ed6ba12567bfc6d21 Mon Sep 17 00:00:00 2001 From: d3viant0ne Date: Sat, 30 Jul 2016 18:03:33 -0500 Subject: [PATCH 1/2] chore(test): Unit & Integration Test Tools - Adds Babel and supporting libs - Adds Mocha for karma/mocha integration tests - Adds cross-env for setting ENV cross platform. - Increments versions on all Karma devDependencies. - Adds npm scripts for execution of the above. - Updates eslintrc to something sane - Updates style based on eslintrc. chore(ci): Adds base travis.yml Update .eslintrc fix(style): Updates with final eslint rules --- .editorconfig | 16 +- .eslintrc | 160 ++++++++++-- .gitignore | 1 + .travis.yml | 12 + example/fixtures/file.coffee | 2 - example/fixtures/file.js | 1 - example/karma-complex.conf.js | 115 --------- example/karma.conf.js | 107 -------- example/test/aTest.js | 24 -- example/test/bTest.coffee | 10 - example/test/index.js | 2 - example/test/separate.js | 5 - index.js | 415 ++++++++++++++++--------------- mocha-env-loader.js | 64 ++--- package.json | 39 ++- test/integration/karma.config.js | 108 ++++++++ test/unit/es2015Demo.test.js | 10 + 17 files changed, 567 insertions(+), 524 deletions(-) create mode 100644 .travis.yml delete mode 100644 example/fixtures/file.coffee delete mode 100644 example/fixtures/file.js delete mode 100644 example/karma-complex.conf.js delete mode 100644 example/karma.conf.js delete mode 100644 example/test/aTest.js delete mode 100644 example/test/bTest.coffee delete mode 100644 example/test/index.js delete mode 100644 example/test/separate.js create mode 100644 test/integration/karma.config.js create mode 100644 test/unit/es2015Demo.test.js diff --git a/.editorconfig b/.editorconfig index 636843b..f1cc3ad 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,5 +1,15 @@ +# http://editorconfig.org + root = true -[*.js] -indent_style=tab -trim_trailing_whitespace=true \ No newline at end of file +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +insert_final_newline = false +trim_trailing_whitespace = false diff --git a/.eslintrc b/.eslintrc index 4a6159c..fb0c5ec 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,24 +1,138 @@ { - "env": { - "node": true - }, - "rules": { - "strict": 0, - "camelcase": 0, - "curly": 0, - "indent": [2, "tab", { "SwitchCase": 1 }], - "eol-last": 1, - "no-shadow": 0, - "no-redeclare": 2, - "no-extra-bind": 1, - "no-empty": 0, - "no-process-exit": 1, - "no-underscore-dangle": 0, - "no-use-before-define": 0, - "no-unused-vars": 0, - "consistent-return": 0, - "no-inner-declarations": 1, - "no-loop-func": 1, - "space-before-function-paren": [2, "never"] - } -} \ No newline at end of file + "root": true, + "parserOptions": { + "ecmaVersion": "7", + "sourceType": "module", + "ecmaFeatures": { + "impliedStrict": true, + "experimentalObjectRestSpread": true + }, + }, + "env": { + "es6": true, + "node": true, + "mocha": true + }, + "rules": { + "strict": [2, "global"], + "no-constant-condition": [2, {"checkLoops": false}], + "no-undef": 2, + "no-use-before-define": 2, + "new-cap": 0, + "no-const-assign": 2, + "key-spacing": 0, + "block-spacing": [2, "never"], + "array-bracket-spacing": [2, "never"], + "brace-style": [2, "1tbs", {"allowSingleLine": true}], + "camelcase": [2, {"properties": "always"}], + "comma-spacing": [2, {"before": false, "after": true}], + "max-statements-per-line": [2, {"max": 1}], + "no-debugger": 1, + "no-trailing-spaces": 1, + "eol-last": 0, + "no-dupe-keys": 2, + "no-dupe-args": 2, + "no-dupe-class-members": 2, + "max-len": [1, {"code": 110, "ignoreUrls": true}], + "newline-before-return": 1, + "newline-after-var": 1, + "newline-per-chained-call": ["error", {"ignoreChainWithDepth":2 }], + "prefer-rest-params": 2, + "func-style": [1, "expression"], + "no-useless-rename": 1, + "prefer-spread": 1, + "template-curly-spacing": [2, "never"], + "no-useless-constructor": 1, + "no-useless-computed-key": 2, + "no-this-before-super": 2, + "no-class-assign": 2, + "no-duplicate-imports": 2, + "no-duplicate-case": 2, + "no-empty-character-class": 2, + "no-ex-assign": 2, + "no-empty": 2, + "no-extra-boolean-cast": 1, + "quote-props": [2, "as-needed"], + "no-return-assign": 0, + "one-var-declaration-per-line": [2, "always"], + "no-whitespace-before-property": 1, + "no-underscore-dangle": 0, + "max-nested-callbacks": [2, 4], + "space-unary-ops": [1, { + "words": true, + "nonwords": false + }], + "space-infix-ops": 2, + "keyword-spacing": [2, {"before": true, "after": true}], + "space-in-parens": [2, "never"], + "space-before-function-paren": [1, "never"], + "max-depth": [2, 6], + "linebreak-style": [2, "unix"], + "space-before-blocks": [1, "always"], + "arrow-spacing": [2, {"before": true, "after": true}], + "generator-star-spacing": [2, {"before": true, "after": false}], + "constructor-super": 2, + "object-shorthand": [1, "always"], + "no-unused-vars": 2, + "no-multi-spaces": 0, + "no-multi-str": 2, + "no-native-reassign": 2, + "no-redeclare": 2, + "no-self-compare": 2, + "no-throw-literal": 2, + "wrap-iife": [2, "inside"], + "operator-linebreak": [2, "after"], + "operator-assignment": [2, "always"], + "object-curly-spacing": [2, "never"], + "no-spaced-func": 2, + "no-unneeded-ternary": 1, + "padded-blocks": [2, "never"], + "prefer-template": 1, + "no-func-assign": 2, + "no-inner-declarations": 2, + "no-invalid-regexp": 2, + "no-regex-spaces": 1, + "no-unreachable": 1, + "no-proto": 2, + "no-sparse-arrays": 2, + "valid-typeof": 2, + "block-scoped-var": 2, + "dot-location": [2, "property"], + "dot-notation": 2, + "eqeqeq": 2, + "no-alert": 2, + "no-case-declarations": 2, + "no-empty-pattern": 2, + "no-eval": 2, + "no-extra-bind": 1, + "no-labels": 2, + "no-lone-blocks": 2, + "no-lonely-if": 2, + "no-multiple-empty-lines": 1, + "no-nested-ternary": 2, + "no-restricted-syntax": ["error", "WithStatement"], + "no-mixed-spaces-and-tabs": 1, + "no-loop-func": 2, + "use-isnan": 2, + "no-irregular-whitespace": 1, + "no-negated-in-lhs": 2, + "no-obj-calls": 2, + "prefer-const": 0, + "one-var": [2, {"uninitialized": "always"}], + "curly": 0, + "computed-property-spacing": [2, "never"], + "comma-style": [2, "last"], + "no-console": 1, + "indent": [2, 2, { + "SwitchCase": 1, + "VariableDeclarator": { + "var": 2, + "let": 2, + "const": 3 + } + }], + "quotes": [2, "single"], + "semi": [2, "never"], + "no-extra-semi": 0 + } +} diff --git a/.gitignore b/.gitignore index 3c3629e..ba2a97b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ node_modules +coverage diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..fe0161d --- /dev/null +++ b/.travis.yml @@ -0,0 +1,12 @@ +sudo: false +language: node_js +os: + - linux + - osx +node_js: + - node + - "6" + - "5" + - "4" + +script: npm test diff --git a/example/fixtures/file.coffee b/example/fixtures/file.coffee deleted file mode 100644 index 363df1c..0000000 --- a/example/fixtures/file.coffee +++ /dev/null @@ -1,2 +0,0 @@ -module.exports = - ok: true \ No newline at end of file diff --git a/example/fixtures/file.js b/example/fixtures/file.js deleted file mode 100644 index e12f1fe..0000000 --- a/example/fixtures/file.js +++ /dev/null @@ -1 +0,0 @@ -exports.ok = true; diff --git a/example/karma-complex.conf.js b/example/karma-complex.conf.js deleted file mode 100644 index b7bc623..0000000 --- a/example/karma-complex.conf.js +++ /dev/null @@ -1,115 +0,0 @@ -// Karma configuration - -var webpack = require("webpack"); - -var configSettings = { - "normal": {}, - "uglified": { - plugins: [ - new webpack.optimize.UglifyJsPlugin() - ] - } -}; - -module.exports = function(config) { - config.set({ - - // base path, that will be used to resolve files and exclude - basePath: '', - - - // frameworks to use - frameworks: ['mocha'], - - - // list of files / patterns to load in the browser - files: [ - 'test/index.js', - 'test/separate.js', - ], - - - // list of preprocessors - preprocessors: { - 'test/*': ['webpack'] - }, - - - webpack: Object.keys(configSettings).map(function(name) { - var config = { - name: name, - resolve: { - extensions: ["", ".js", ".coffee"] - }, - module: { - loaders: [ - { test: /\.coffee$/, loader: "coffee-loader" } - ] - } - }; - Object.keys(configSettings[name]).forEach(function(key) { - config[key] = configSettings[name][key] - }); - return config; - }), - - - webpackMiddleware: { - stats: { - colors: true - } - }, - - - // test results reporter to use - // possible values: 'dots', 'progress', 'junit', 'growl', 'coverage' - reporters: ['spec'], - - - // web server port - port: 9876, - - - // enable / disable colors in the output (reporters and logs) - colors: true, - - - // level of logging - // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG - logLevel: config.LOG_INFO, - - - // enable / disable watching file and executing tests whenever any file changes - autoWatch: true, - - - // Start these browsers, currently available: - // - Chrome - // - ChromeCanary - // - Firefox - // - Opera (has to be installed with `npm install karma-opera-launcher`) - // - Safari (only Mac; has to be installed with `npm install karma-safari-launcher`) - // - PhantomJS - // - IE (only Windows; has to be installed with `npm install karma-ie-launcher`) - browsers: ['Chrome'], - - - // If browser does not capture in given timeout [ms], kill it - captureTimeout: 60000, - - - // Continuous Integration mode - // if true, it capture browsers, run tests and exit - singleRun: true, - - - // List plugins explicitly, since autoloading karma-webpack - // won't work here - plugins: [ - require("karma-mocha"), - require("karma-spec-reporter"), - require("karma-chrome-launcher"), - require("../") - ] - }); -}; diff --git a/example/karma.conf.js b/example/karma.conf.js deleted file mode 100644 index 373274c..0000000 --- a/example/karma.conf.js +++ /dev/null @@ -1,107 +0,0 @@ -// Karma configuration - -var webpack = require("webpack"); - -var configSettings = { - "normal": {}, - "uglified": { - plugins: [ - new webpack.optimize.UglifyJsPlugin() - ] - } -}; - -module.exports = function(config) { - config.set({ - - // base path, that will be used to resolve files and exclude - basePath: '', - - - // frameworks to use - frameworks: ['mocha'], - - - // list of files / patterns to load in the browser - files: [ - 'test/index.js' - ], - - - // list of preprocessors - preprocessors: { - 'test/*': ['webpack'] - }, - - - webpack: { - resolve: { - extensions: ["", ".js", ".coffee"] - }, - module: { - loaders: [ - { test: /\.coffee$/, loader: "coffee-loader" } - ] - } - }, - - - webpackMiddleware: { - stats: { - colors: true - } - }, - - - // test results reporter to use - // possible values: 'dots', 'progress', 'junit', 'growl', 'coverage' - reporters: ['spec'], - - - // web server port - port: 9876, - - - // enable / disable colors in the output (reporters and logs) - colors: true, - - - // level of logging - // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG - logLevel: config.LOG_INFO, - - - // enable / disable watching file and executing tests whenever any file changes - autoWatch: true, - - - // Start these browsers, currently available: - // - Chrome - // - ChromeCanary - // - Firefox - // - Opera (has to be installed with `npm install karma-opera-launcher`) - // - Safari (only Mac; has to be installed with `npm install karma-safari-launcher`) - // - PhantomJS - // - IE (only Windows; has to be installed with `npm install karma-ie-launcher`) - browsers: ['Chrome'], - - - // If browser does not capture in given timeout [ms], kill it - captureTimeout: 60000, - - - // Continuous Integration mode - // if true, it capture browsers, run tests and exit - singleRun: false, - - - // List plugins explicitly, since autoloading karma-webpack - // won't work here - plugins: [ - require("karma-mocha"), - require("karma-spec-reporter"), - require("karma-chrome-launcher"), - require("../") - ] - }); -}; diff --git a/example/test/aTest.js b/example/test/aTest.js deleted file mode 100644 index e32e2a7..0000000 --- a/example/test/aTest.js +++ /dev/null @@ -1,24 +0,0 @@ -describe("a-test", function() { - it("should run a test", function() { - var ok = 1; - }); - - it("should require a file", function() { - var module = require("../fixtures/file.js"); - if(!module.ok) throw new Error("module didn't export ok"); - }); - - it("should use loaders", function() { - var module = require("../fixtures/file.coffee"); - if(!module.ok) throw new Error("module didn't export ok"); - }); - - it("should allow chunks", function(done) { - var test = true; - require.ensure(["../fixtures/file.js?1"], function(require) { - test = false; - done(); - }); - if(!test) throw new Error("Chunk should be async"); - }); -}); diff --git a/example/test/bTest.coffee b/example/test/bTest.coffee deleted file mode 100644 index d1466e1..0000000 --- a/example/test/bTest.coffee +++ /dev/null @@ -1,10 +0,0 @@ -describe "b-test", -> - it "should run another test", -> - ok = 1 - - it "should allow more chunks", (done) -> - test = true - require.ensure ["../fixtures/file.js?1"], (require) -> - test = false - done() - throw new Error("Chunk should be async") unless test diff --git a/example/test/index.js b/example/test/index.js deleted file mode 100644 index 1740381..0000000 --- a/example/test/index.js +++ /dev/null @@ -1,2 +0,0 @@ -var testsContext = require.context(".", true, /Test$/); -testsContext.keys().forEach(testsContext); diff --git a/example/test/separate.js b/example/test/separate.js deleted file mode 100644 index e2cd89d..0000000 --- a/example/test/separate.js +++ /dev/null @@ -1,5 +0,0 @@ -describe("separate-test", function() { - it("should run the test", function() { - var ok = 1; - }); -}); diff --git a/index.js b/index.js index ae8e85e..115b85b 100644 --- a/index.js +++ b/index.js @@ -1,9 +1,9 @@ -var _ = require("lodash"); -var path = require("path"); -var async = require("async"); -var webpackDevMiddleware = require("webpack-dev-middleware"); -var webpack = require("webpack"); -var SingleEntryDependency = require("webpack/lib/dependencies/SingleEntryDependency"); +var _ = require('lodash') +var path = require('path') +var async = require('async') +var webpackDevMiddleware = require('webpack-dev-middleware') +var webpack = require('webpack') +var SingleEntryDependency = require('webpack/lib/dependencies/SingleEntryDependency') var blocked = [] var isBlocked = false @@ -17,208 +17,231 @@ function Plugin( /* config.frameworks */ frameworks, customFileHandlers, emitter) { - webpackOptions = _.clone(webpackOptions) || {}; - webpackMiddlewareOptions = _.clone(webpackMiddlewareOptions || webpackServerOptions) || {}; - - var applyOptions = Array.isArray(webpackOptions) ? webpackOptions : [webpackOptions]; - var includeIndex = applyOptions.length > 1; - - applyOptions.forEach(function(webpackOptions, index) { - // The webpack tier owns the watch behavior so we want to force it in the config - webpackOptions.watch = true; - - // Webpack 2.1.0-beta.7+ will throw in error if both entry and plugins are not specified in options - // https://github.com/webpack/webpack/commit/b3bc5427969e15fd3663d9a1c57dbd1eb2c94805 - if(!webpackOptions.entry) webpackOptions.entry = {}; - - if(!webpackOptions.output) webpackOptions.output = {}; - - // When using an array, even of length 1, we want to include the index value for the build. - // This is due to the way that the dev server exposes commonPath for build output. - var indexPath = includeIndex ? index + "/" : ""; - var publicPath = indexPath !== "" ? indexPath + '/' : ""; - - // Must have the common _karma_webpack_ prefix on path here to avoid - // https://github.com/webpack/webpack/issues/645 - webpackOptions.output.path = "/_karma_webpack_/" + indexPath; - webpackOptions.output.publicPath = "/_karma_webpack_/" + publicPath; - webpackOptions.output.filename = "[name]"; - if(includeIndex) - webpackOptions.output.jsonpFunction = "webpackJsonp" + index; - webpackOptions.output.chunkFilename = "[id].bundle.js"; - }); - - this.emitter = emitter; - this.wrapMocha = frameworks.indexOf('mocha') >= 0 && includeIndex; - this.optionsCount = applyOptions.length; - this.files = []; - this.basePath = basePath; - this.waiting = []; - - var compiler = webpack(webpackOptions); - var applyPlugins = compiler.compilers || [compiler]; - applyPlugins.forEach(function(compiler) { - compiler.plugin("this-compilation", function(compilation, params) { - compilation.dependencyFactories.set(SingleEntryDependency, params.normalModuleFactory); - }); - compiler.plugin("make", this.make.bind(this)); - }, this); - - ["invalid", "watch-run", "run"].forEach(function(name) { - compiler.plugin(name, function(_, callback) { - isBlocked = true; - - if (typeof callback === 'function') { - callback(); - } - }) - }) - - compiler.plugin("done", function(stats) { - var applyStats = Array.isArray(stats.stats) ? stats.stats : [stats]; - var assets = []; - var noAssets = false; - applyStats.forEach(function(stats) { - stats = stats.toJson(); - - assets.push.apply(assets, stats.assets); - if(stats.assets.length === 0) - noAssets = true; - }); - - if(!this.waiting || this.waiting.length === 0) { - this.notifyKarmaAboutChanges(); - } - - if(this.waiting && !noAssets) { - var w = this.waiting; - this.waiting = null; - w.forEach(function(cb) { - cb(); - }); - } - - isBlocked = false - for (var i = 0; i < blocked.length; i++) { - blocked[i](); - } - blocked = [] - }.bind(this)); - compiler.plugin("invalid", function() { - if(!this.waiting) this.waiting = []; - }.bind(this)); - - webpackMiddlewareOptions.publicPath = "/_karma_webpack_/"; - var middleware = this.middleware = new webpackDevMiddleware(compiler, webpackMiddlewareOptions); - - customFileHandlers.push({ - urlRegex: /^\/_karma_webpack_\/.*/, - handler: function(req, res) { - middleware(req, res, function() { - res.statusCode = 404; - res.end('Not found'); - }); - } - }); - - emitter.on("exit", function(done) { - middleware.close(); - done(); - }); + webpackOptions = _.clone(webpackOptions) || {} + webpackMiddlewareOptions = _.clone(webpackMiddlewareOptions || webpackServerOptions) || {} + + var applyOptions = Array.isArray(webpackOptions) ? webpackOptions : [webpackOptions] + var includeIndex = applyOptions.length > 1 + + applyOptions.forEach(function(webpackOptions, index) { + // The webpack tier owns the watch behavior so we want to force it in the config + webpackOptions.watch = true + + // Webpack 2.1.0-beta.7+ will throw in error if both entry and plugins are not specified in options + // https://github.com/webpack/webpack/commit/b3bc5427969e15fd3663d9a1c57dbd1eb2c94805 + if (!webpackOptions.entry) { + webpackOptions.entry = {} + }; + + if (!webpackOptions.output) { + webpackOptions.output = {} + }; + + // When using an array, even of length 1, we want to include the index value for the build. + // This is due to the way that the dev server exposes commonPath for build output. + var indexPath = includeIndex ? index + '/' : '' + var publicPath = indexPath !== '' ? indexPath + '/' : '' + + // Must have the common _karma_webpack_ prefix on path here to avoid + // https://github.com/webpack/webpack/issues/645 + webpackOptions.output.path = '/_karma_webpack_/' + indexPath + webpackOptions.output.publicPath = '/_karma_webpack_/' + publicPath + webpackOptions.output.filename = '[name]' + if (includeIndex) { + webpackOptions.output.jsonpFunction = 'webpackJsonp' + index + } + webpackOptions.output.chunkFilename = '[id].bundle.js' + }) + + this.emitter = emitter + this.wrapMocha = frameworks.indexOf('mocha') >= 0 && includeIndex + this.optionsCount = applyOptions.length + this.files = [] + this.basePath = basePath + this.waiting = [] + + var compiler = webpack(webpackOptions) + var applyPlugins = compiler.compilers || [compiler] + + applyPlugins.forEach(function(compiler) { + compiler.plugin('this-compilation', function(compilation, params) { + compilation.dependencyFactories.set(SingleEntryDependency, params.normalModuleFactory) + }) + compiler.plugin('make', this.make.bind(this)) + }, this); + + ['invalid', 'watch-run', 'run'].forEach(function(name) { + compiler.plugin(name, function(_, callback) { + isBlocked = true + + if (typeof callback === 'function') { + callback() + } + }) + }) + + compiler.plugin('done', function(stats) { + var applyStats = Array.isArray(stats.stats) ? stats.stats : [stats] + var assets = [] + var noAssets = false + + applyStats.forEach(function(stats) { + stats = stats.toJson() + + assets.push.apply(assets, stats.assets) + if (stats.assets.length === 0) { + noAssets = true + } + }) + + if (!this.waiting || this.waiting.length === 0) { + this.notifyKarmaAboutChanges() + } + + if (this.waiting && !noAssets) { + var w = this.waiting + + this.waiting = null + w.forEach(function(cb) { + cb() + }) + } + + isBlocked = false + for (var i = 0; i < blocked.length; i++) { + blocked[i]() + } + blocked = [] + }.bind(this)) + compiler.plugin('invalid', function() { + if (!this.waiting) { + this.waiting = [] + } + }.bind(this)) + + webpackMiddlewareOptions.publicPath = '/_karma_webpack_/' + var middleware = this.middleware = new webpackDevMiddleware(compiler, webpackMiddlewareOptions) + + customFileHandlers.push({ + urlRegex: /^\/_karma_webpack_\/.*/, + handler: function(req, res) { + middleware(req, res, function() { + res.statusCode = 404 + res.end('Not found') + }) + } + }) + + emitter.on('exit', function(done) { + middleware.close() + done() + }) } Plugin.prototype.notifyKarmaAboutChanges = function() { - // Force a rebuild - this.emitter.refreshFiles(); -}; + // Force a rebuild + this.emitter.refreshFiles() +} Plugin.prototype.addFile = function(entry) { - if(this.files.indexOf(entry) >= 0) return; - this.files.push(entry); - return true; -}; + if (this.files.indexOf(entry) >= 0) { + return + } + this.files.push(entry) + + return true +} Plugin.prototype.make = function(compilation, callback) { - async.forEach(this.files.slice(), function(file, callback) { - var entry = file; - if(this.wrapMocha) { - entry = require.resolve("./mocha-env-loader") + "!" + entry; - } - - var dep = new SingleEntryDependency(entry); - compilation.addEntry("", dep, path.relative(this.basePath, file).replace(/\\/g, "/"), function() { - // If the module fails because of an File not found error, remove the test file - if(dep.module && dep.module.error && dep.module.error.error && dep.module.error.error.code === "ENOENT") { - this.files = this.files.filter(function(f) { - return file !== f; - }); - this.middleware.invalidate(); - } - callback(); - }.bind(this)); - }.bind(this), callback); -}; + async.forEach(this.files.slice(), function(file, callback) { + var entry = file + + if (this.wrapMocha) { + entry = require.resolve('./mocha-env-loader') + '!' + entry + } + + var dep = new SingleEntryDependency(entry) + + compilation.addEntry('', dep, path.relative(this.basePath, file).replace(/\\/g, '/'), function() { + // If the module fails because of an File not found error, remove the test file + if (dep.module && dep.module.error && + dep.module.error.error && + dep.module.error.error.code === 'ENOENT') { + this.files = this.files.filter(function(f) { + return file !== f + }) + this.middleware.invalidate() + } + callback() + }.bind(this)) + }.bind(this), callback) +} Plugin.prototype.readFile = function(file, callback) { - var middleware = this.middleware; - var optionsCount = this.optionsCount; - - function doRead() { - if(optionsCount > 1) { - async.times(optionsCount, function(idx, callback) { - middleware.fileSystem.readFile("/_karma_webpack_/" + idx + "/" + file.replace(/\\/g, "/"), callback); - }, function(err, contents) { - if(err) return callback(err); - contents = contents.reduce(function(arr, x) { - if(!arr) return [x]; - arr.push(new Buffer("\n"), x); - return arr; - }, null); - callback(null, Buffer.concat(contents)); - }); - } else { - middleware.fileSystem.readFile("/_karma_webpack_/" + file.replace(/\\/g, "/"), callback); - } - } - if(!this.waiting) - doRead(); - else - // Retry to read once a build is finished - // do it on process.nextTick to catch changes while building - this.waiting.push(process.nextTick.bind(process, this.readFile.bind(this, file, callback))); -}; - -function createPreprocesor( /* config.basePath */ basePath, webpackPlugin) { - return function(content, file, done) { - - if(webpackPlugin.addFile(file.path)) { - // recompile as we have an asset that we have not seen before - webpackPlugin.middleware.invalidate(); - } - - // read blocks until bundle is done - webpackPlugin.readFile(path.relative(basePath, file.path), function(err, content) { - if(err) { - throw err; - } - - done(err, content && content.toString()); - }); - }; + var middleware = this.middleware + var optionsCount = this.optionsCount + + function doRead() { + if (optionsCount > 1) { + async.times(optionsCount, function(idx, callback) { + middleware.fileSystem.readFile('/_karma_webpack_/' + idx + '/' + file.replace(/\\/g, '/'), callback) + }, function(err, contents) { + if (err) { + return callback(err) + }; + contents = contents.reduce(function(arr, x) { + if (!arr) { + return [x] + }; + arr.push(new Buffer('\n'), x) + + return arr + }, null) + callback(null, Buffer.concat(contents)) + }) + } else { + middleware.fileSystem.readFile('/_karma_webpack_/' + file.replace(/\\/g, '/'), callback) + } + } + if (!this.waiting) { + doRead() + } else { + // Retry to read once a build is finished + // do it on process.nextTick to catch changes while building + this.waiting.push(process.nextTick.bind(process, this.readFile.bind(this, file, callback))) + } +} + +function createPreprocesor(/* config.basePath */ basePath, webpackPlugin) { + return function(content, file, done) { + if (webpackPlugin.addFile(file.path)) { + // recompile as we have an asset that we have not seen before + webpackPlugin.middleware.invalidate() + } + + // read blocks until bundle is done + webpackPlugin.readFile(path.relative(basePath, file.path), function(err, content) { + if (err) { + throw err + } + + done(err, content && content.toString()) + }) + } } function createWebpackBlocker() { - return function(request, response, next) { - if (isBlocked) { - blocked.push(next) - } else { - next() - } - } + return function(request, response, next) { + if (isBlocked) { + blocked.push(next) + } else { + next() + } + } } module.exports = { - "webpackPlugin": ["type", Plugin], - "preprocessor:webpack": ["factory", createPreprocesor], - "middleware:webpackBlocker": ["factory", createWebpackBlocker] -}; + webpackPlugin: ['type', Plugin], + 'preprocessor:webpack': ['factory', createPreprocesor], + 'middleware:webpackBlocker': ['factory', createWebpackBlocker] +} diff --git a/mocha-env-loader.js b/mocha-env-loader.js index 6545cf1..d2524e0 100644 --- a/mocha-env-loader.js +++ b/mocha-env-loader.js @@ -1,32 +1,36 @@ -var path = require("path"); -var SourceNode = require("source-map").SourceNode; -var loaderUtils = require("loader-utils"); +//var path = require('path') +var SourceNode = require('source-map').SourceNode +var loaderUtils = require('loader-utils') module.exports = function(content, map) { - this.cacheable(); - - var sourceNode; - var id = this.options.name; - if(!id) this.callback(null, content, map); - - if(map) { - sourceNode = SourceNode.fromSourceWithMap(content, map); - } else { - var fileName = loaderUtils.getRemainingRequest(this); - sourceNode = new SourceNode(null, null, null); - content.split("\n").forEach(function(line, idx) { - sourceNode.add(new SourceNode(idx + 1, 0, fileName, line + "\n")); - }) - sourceNode.setSourceContent(fileName, content); - } - - var concatSrc = new SourceNode(); - concatSrc.add([ - "describe(" + JSON.stringify(id) + ", function() {\n", - sourceNode, - "\n});" - ]); - - var result = concatSrc.toStringWithSourceMap(); - this.callback(undefined, result.code, result.map.toString()); -}; + this.cacheable() + + var sourceNode + var id = this.options.name + + if (!id) { + this.callback(null, content, map) + } + + if (map) { + sourceNode = SourceNode.fromSourceWithMap(content, map) + } else { + var fileName = loaderUtils.getRemainingRequest(this) + + sourceNode = new SourceNode(null, null, null) + content.split('\n').forEach(function(line, idx) { + sourceNode.add(new SourceNode(idx + 1, 0, fileName, line + '\n')) + }) + sourceNode.setSourceContent(fileName, content) + } + + var concatSrc = new SourceNode() + + concatSrc.add([ + 'describe(' + JSON.stringify(id) + ', function() {\n', sourceNode, '\n});' + ]) + + var result = concatSrc.toStringWithSourceMap() + + this.callback(undefined, result.code, result.map.toString()) +} diff --git a/package.json b/package.json index 4aab200..cd19485 100644 --- a/package.json +++ b/package.json @@ -14,16 +14,43 @@ "webpack-dev-middleware": "^1.0.11" }, "devDependencies": { - "coffee-loader": "~0.7.2", + "babel-cli": "^6.11.4", + "babel-core": "^6.11.4", + "babel-eslint": "^6.1.2", + "babel-register": "^6.11.6", + "chai": "^3.5.0", + "chai-as-promised": "^5.3.0", + "cross-env": "^2.0.0", "eslint": "^3.1.1", - "karma": ">=0.13.2 < 1", - "karma-chrome-launcher": "~0.1.5", - "karma-mocha": "~0.1.9", - "karma-spec-reporter": "~0.0.16" + "eslint-plugin-babel": "^3.3.0", + "istanbul": "^0.4.4", + "karma": "^1.x", + "karma-chrome-launcher": "~1.0.1", + "karma-mocha": "~1.1.1", + "karma-spec-reporter": "~0.0.22", + "mocha": "^2.5.3" }, "scripts": { + "lint": "eslint test index.js mocha-env-loader.js", "pretest": "npm run lint", - "lint": "eslint example index.js mocha-env-loader.js" + "test": "npm run test.unit", + "test.unit": "mocha --harmony --full-trace --check-leaks test/unit", + "test.integration": "karma start --single-run", + "travis": "npm run test.unit && npm run test.integration" + }, + "babel": { + "presets": [ + "es2015" + ], + "plugins": [ + "transform-runtime" + ], + "ignore": "**/*.test.js", + "env": { + "development": { + "sourceMaps": "inline" + } + } }, "license": "MIT", "homepage": "http://github.com/webpack/karma-webpack", diff --git a/test/integration/karma.config.js b/test/integration/karma.config.js new file mode 100644 index 0000000..f8c2f61 --- /dev/null +++ b/test/integration/karma.config.js @@ -0,0 +1,108 @@ +// Karma configuration + +var webpack = require('webpack') + +var configSettings = { // eslint-disable-line no-unused-vars + normal: {}, + uglified: { + plugins: [ + new webpack.optimize.UglifyJsPlugin() + ] + } +} + +module.exports = function(config) { + config.set({ + + // base path, that will be used to resolve files and exclude + basePath: '', + + + // frameworks to use + frameworks: ['mocha'], + + + // list of files / patterns to load in the browser + files: [ + 'test/index.js' + ], + + + // list of preprocessors + preprocessors: { + 'test/*': ['webpack'] + }, + + + webpack: { + resolve: { + extensions: ['', '.js'] + }, + module: {} + }, + + + webpackMiddleware: { + stats: { + colors: true + } + }, + + + // test results reporter to use + // possible values: 'dots', 'progress', 'junit', 'growl', 'coverage' + reporters: ['spec'], + + + // web server port + port: 9876, + + + // enable / disable colors in the output (reporters and logs) + colors: true, + + + /** + * level of logging + * + * possible values: + * config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN + * config.LOG_INFO || config.LOG_DEBUG + */ + logLevel: config.LOG_INFO, + + + // enable / disable watching file and executing tests whenever any file changes + autoWatch: true, + + + // Start these browsers, currently available: + // - Chrome + // - ChromeCanary + // - Firefox + // - Opera (has to be installed with `npm install karma-opera-launcher`) + // - Safari (only Mac; has to be installed with `npm install karma-safari-launcher`) + // - PhantomJS + // - IE (only Windows; has to be installed with `npm install karma-ie-launcher`) + browsers: ['Chrome'], + + + // If browser does not capture in given timeout [ms], kill it + captureTimeout: 60000, + + + // Continuous Integration mode + // if true, it capture browsers, run tests and exit + singleRun: false, + + + // List plugins explicitly, since autoloading karma-webpack + // won't work here + plugins: [ + require('karma-mocha'), + require('karma-spec-reporter'), + require('karma-chrome-launcher'), + require('../../') + ] + }) +} diff --git a/test/unit/es2015Demo.test.js b/test/unit/es2015Demo.test.js new file mode 100644 index 0000000..faeb72d --- /dev/null +++ b/test/unit/es2015Demo.test.js @@ -0,0 +1,10 @@ +var assert = require('chai').assert + +describe('Array', function() { + describe('#indexOf()', function() { + it('should return -1 when the value is not present', function() { + assert.equal(-1, [1, 2, 3].indexOf(5)) + assert.equal(-1, [1, 2, 3].indexOf(0)) + }) + }) +}) From bfd660342f9a47bad0d422b800b6fc902ad629c9 Mon Sep 17 00:00:00 2001 From: MikaAK Date: Mon, 25 Jul 2016 20:59:57 -0700 Subject: [PATCH 2/2] chore(build): Create build system with webpack and babel --- .babelrc | 11 + .eslintignore | 1 + .gitignore | 1 + dist/karma-webpack.js | 305 ++++++++++++++++++ package.json | 57 ++-- index.js => src/karma-webpack.js | 0 .../mocha-env-loader.js | 0 test/integration/karma.config.js | 4 +- test/unit/es2015Demo.test.js | 2 +- webpack.config.babel.js | 35 ++ 10 files changed, 381 insertions(+), 35 deletions(-) create mode 100644 .babelrc create mode 100644 .eslintignore create mode 100644 dist/karma-webpack.js rename index.js => src/karma-webpack.js (100%) rename mocha-env-loader.js => src/mocha-env-loader.js (100%) create mode 100644 webpack.config.babel.js diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..35051ce --- /dev/null +++ b/.babelrc @@ -0,0 +1,11 @@ +{ + "env": { + "development": { + "sourceMaps": "inline" + } + }, + "presets": ["es2015", "stage-2"], + "plugins": [ + "transform-runtime" + ] +} diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..a261f29 --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +dist/* diff --git a/.gitignore b/.gitignore index ba2a97b..9c62828 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules coverage +dist diff --git a/dist/karma-webpack.js b/dist/karma-webpack.js new file mode 100644 index 0000000..8341187 --- /dev/null +++ b/dist/karma-webpack.js @@ -0,0 +1,305 @@ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(require("async"), require("loader-utils"), require("lodash"), require("path"), require("source-map"), require("webpack"), require("webpack-dev-middleware")); + else if(typeof define === 'function' && define.amd) + define(["async", "loader-utils", "lodash", "path", "source-map", "webpack", "webpack-dev-middleware"], factory); + else if(typeof exports === 'object') + exports["karma-webpack"] = factory(require("async"), require("loader-utils"), require("lodash"), require("path"), require("source-map"), require("webpack"), require("webpack-dev-middleware")); + else + root["karma-webpack"] = factory(root["async"], root["loader-utils"], root["lodash"], root["path"], root["source-map"], root["webpack"], root["webpack-dev-middleware"]); +})(this, function(__WEBPACK_EXTERNAL_MODULE_2__, __WEBPACK_EXTERNAL_MODULE_13__, __WEBPACK_EXTERNAL_MODULE_3__, __WEBPACK_EXTERNAL_MODULE_4__, __WEBPACK_EXTERNAL_MODULE_14__, __WEBPACK_EXTERNAL_MODULE_5__, __WEBPACK_EXTERNAL_MODULE_6__) { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; + +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; + +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; + +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + +/******/ // Flag the module as loaded +/******/ module.l = true; + +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } + + +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; + +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; + +/******/ // identity function for calling harmory imports with the correct context +/******/ __webpack_require__.i = function(value) { return value; }; + +/******/ // define getter function for harmory exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ }; + +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; + +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; + +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; + +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 15); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; +'use strict';var _stringify=__webpack_require__(7);var _stringify2=_interopRequireDefault(_stringify);function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}//var path = require('path') +var SourceNode=__webpack_require__(14).SourceNode;var loaderUtils=__webpack_require__(13);module.exports=function(content,map){this.cacheable();var sourceNode;var id=this.options.name;if(!id){this.callback(null,content,map);}if(map){sourceNode=SourceNode.fromSourceWithMap(content,map);}else{var fileName=loaderUtils.getRemainingRequest(this);sourceNode=new SourceNode(null,null,null);content.split('\n').forEach(function(line,idx){sourceNode.add(new SourceNode(idx+1,0,fileName,line+'\n'));});sourceNode.setSourceContent(fileName,content);}var concatSrc=new SourceNode();concatSrc.add(['describe('+(0,_stringify2.default)(id)+', function() {\n',sourceNode,'\n});']);var result=concatSrc.toStringWithSourceMap();this.callback(undefined,result.code,result.map.toString());}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNyYy9tb2NoYS1lbnYtbG9hZGVyLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJrTkFBQTtBQUNBLEdBQUksWUFBYSxRQUFRLFlBQVIsRUFBc0IsVUFBdkMsQ0FDQSxHQUFJLGFBQWMsUUFBUSxjQUFSLENBQWxCLENBRUEsT0FBTyxPQUFQLENBQWlCLFNBQVMsT0FBVCxDQUFrQixHQUFsQixDQUF1QixDQUN0QyxLQUFLLFNBQUwsR0FFQSxHQUFJLFdBQUosQ0FDQSxHQUFJLElBQUssS0FBSyxPQUFMLENBQWEsSUFBdEIsQ0FFQSxHQUFJLENBQUMsRUFBTCxDQUFTLENBQ1AsS0FBSyxRQUFMLENBQWMsSUFBZCxDQUFvQixPQUFwQixDQUE2QixHQUE3QixFQUNELENBRUQsR0FBSSxHQUFKLENBQVMsQ0FDUCxXQUFhLFdBQVcsaUJBQVgsQ0FBNkIsT0FBN0IsQ0FBc0MsR0FBdEMsQ0FBYixDQUNELENBRkQsSUFFTyxDQUNMLEdBQUksVUFBVyxZQUFZLG1CQUFaLENBQWdDLElBQWhDLENBQWYsQ0FFQSxXQUFhLEdBQUksV0FBSixDQUFlLElBQWYsQ0FBcUIsSUFBckIsQ0FBMkIsSUFBM0IsQ0FBYixDQUNBLFFBQVEsS0FBUixDQUFjLElBQWQsRUFBb0IsT0FBcEIsQ0FBNEIsU0FBUyxJQUFULENBQWUsR0FBZixDQUFvQixDQUM5QyxXQUFXLEdBQVgsQ0FBZSxHQUFJLFdBQUosQ0FBZSxJQUFNLENBQXJCLENBQXdCLENBQXhCLENBQTJCLFFBQTNCLENBQXFDLEtBQU8sSUFBNUMsQ0FBZixFQUNELENBRkQsRUFHQSxXQUFXLGdCQUFYLENBQTRCLFFBQTVCLENBQXNDLE9BQXRDLEVBQ0QsQ0FFRCxHQUFJLFdBQVksR0FBSSxXQUFKLEVBQWhCLENBRUEsVUFBVSxHQUFWLENBQWMsQ0FDWixZQUFjLHdCQUFlLEVBQWYsQ0FBZCxDQUFtQyxrQkFEdkIsQ0FDMkMsVUFEM0MsQ0FDdUQsT0FEdkQsQ0FBZCxFQUlBLEdBQUksUUFBUyxVQUFVLHFCQUFWLEVBQWIsQ0FFQSxLQUFLLFFBQUwsQ0FBYyxTQUFkLENBQXlCLE9BQU8sSUFBaEMsQ0FBc0MsT0FBTyxHQUFQLENBQVcsUUFBWCxFQUF0QyxFQUNELENBL0JEIiwiZmlsZSI6Im1vY2hhLWVudi1sb2FkZXIuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL21pa2EvRG9jdW1lbnRzL3NpZGUva2FybWEtd2VicGFjayIsInNvdXJjZXNDb250ZW50IjpbIi8vdmFyIHBhdGggPSByZXF1aXJlKCdwYXRoJylcbnZhciBTb3VyY2VOb2RlID0gcmVxdWlyZSgnc291cmNlLW1hcCcpLlNvdXJjZU5vZGVcbnZhciBsb2FkZXJVdGlscyA9IHJlcXVpcmUoJ2xvYWRlci11dGlscycpXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oY29udGVudCwgbWFwKSB7XG4gIHRoaXMuY2FjaGVhYmxlKClcblxuICB2YXIgc291cmNlTm9kZVxuICB2YXIgaWQgPSB0aGlzLm9wdGlvbnMubmFtZVxuXG4gIGlmICghaWQpIHtcbiAgICB0aGlzLmNhbGxiYWNrKG51bGwsIGNvbnRlbnQsIG1hcClcbiAgfVxuXG4gIGlmIChtYXApIHtcbiAgICBzb3VyY2VOb2RlID0gU291cmNlTm9kZS5mcm9tU291cmNlV2l0aE1hcChjb250ZW50LCBtYXApXG4gIH0gZWxzZSB7XG4gICAgdmFyIGZpbGVOYW1lID0gbG9hZGVyVXRpbHMuZ2V0UmVtYWluaW5nUmVxdWVzdCh0aGlzKVxuXG4gICAgc291cmNlTm9kZSA9IG5ldyBTb3VyY2VOb2RlKG51bGwsIG51bGwsIG51bGwpXG4gICAgY29udGVudC5zcGxpdCgnXFxuJykuZm9yRWFjaChmdW5jdGlvbihsaW5lLCBpZHgpIHtcbiAgICAgIHNvdXJjZU5vZGUuYWRkKG5ldyBTb3VyY2VOb2RlKGlkeCArIDEsIDAsIGZpbGVOYW1lLCBsaW5lICsgJ1xcbicpKVxuICAgIH0pXG4gICAgc291cmNlTm9kZS5zZXRTb3VyY2VDb250ZW50KGZpbGVOYW1lLCBjb250ZW50KVxuICB9XG5cbiAgdmFyIGNvbmNhdFNyYyA9IG5ldyBTb3VyY2VOb2RlKClcblxuICBjb25jYXRTcmMuYWRkKFtcbiAgICAnZGVzY3JpYmUoJyArIEpTT04uc3RyaW5naWZ5KGlkKSArICcsIGZ1bmN0aW9uKCkge1xcbicsIHNvdXJjZU5vZGUsICdcXG59KTsnXG4gIF0pXG5cbiAgdmFyIHJlc3VsdCA9IGNvbmNhdFNyYy50b1N0cmluZ1dpdGhTb3VyY2VNYXAoKVxuXG4gIHRoaXMuY2FsbGJhY2sodW5kZWZpbmVkLCByZXN1bHQuY29kZSwgcmVzdWx0Lm1hcC50b1N0cmluZygpKVxufVxuIl19 + +/***/ }, +/* 1 */ +/***/ function(module, exports, __webpack_require__) { + +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +var ModuleDependency = __webpack_require__(12); + +function SingleEntryDependency(request) { + ModuleDependency.call(this, request); +} +module.exports = SingleEntryDependency; + +SingleEntryDependency.prototype = Object.create(ModuleDependency.prototype); +SingleEntryDependency.prototype.constructor = SingleEntryDependency; +SingleEntryDependency.prototype.type = "single entry"; + + +/***/ }, +/* 2 */ +/***/ function(module, exports) { + +module.exports = __WEBPACK_EXTERNAL_MODULE_2__; + +/***/ }, +/* 3 */ +/***/ function(module, exports) { + +module.exports = __WEBPACK_EXTERNAL_MODULE_3__; + +/***/ }, +/* 4 */ +/***/ function(module, exports) { + +module.exports = require("path"); + +/***/ }, +/* 5 */ +/***/ function(module, exports) { + +module.exports = __WEBPACK_EXTERNAL_MODULE_5__; + +/***/ }, +/* 6 */ +/***/ function(module, exports) { + +module.exports = __WEBPACK_EXTERNAL_MODULE_6__; + +/***/ }, +/* 7 */ +/***/ function(module, exports, __webpack_require__) { + +module.exports = { "default": __webpack_require__(8), __esModule: true }; + +/***/ }, +/* 8 */ +/***/ function(module, exports, __webpack_require__) { + +var core = __webpack_require__(9) + , $JSON = core.JSON || (core.JSON = {stringify: JSON.stringify}); +module.exports = function stringify(it){ // eslint-disable-line no-unused-vars + return $JSON.stringify.apply($JSON, arguments); +}; + +/***/ }, +/* 9 */ +/***/ function(module, exports) { + +var core = module.exports = {version: '2.4.0'}; +if(typeof __e == 'number')__e = core; // eslint-disable-line no-undef + +/***/ }, +/* 10 */ +/***/ function(module, exports, __webpack_require__) { + +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +function Dependency() { + this.module = null; +} +module.exports = Dependency; + +Dependency.prototype.isEqualResource = function( /* other */ ) { + return false; +}; + +// Returns the referenced module and export +Dependency.prototype.getReference = function() { + if(!this.module) return null; + return { + module: this.module, + importedNames: true, // true: full object, false: only sideeffects/no export, array of strings: the exports with this names + } +}; + +Dependency.prototype.getWarnings = function() { + return null; +}; + +Dependency.prototype.updateHash = function(hash) { + hash.update((this.module && this.module.id) + ""); +}; + +Dependency.prototype.disconnect = function() { + this.module = null; +}; + +Dependency.compare = function(a, b) { + return Dependency.compareLocations(a.loc, b.loc); +}; + +Dependency.compareLocations = __webpack_require__(11); + + +/***/ }, +/* 11 */ +/***/ function(module, exports) { + +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +module.exports = function compareLocations(a, b) { + if(typeof a === "string") { + if(typeof b === "string") { + if(a < b) return -1; + if(a > b) return 1; + return 0; + } else if(typeof b === "object") { + return 1; + } else { + return 0; + } + } else if(typeof a === "object") { + if(typeof b === "string") { + return -1; + } else if(typeof b === "object") { + if(a.start) a = a.start; + if(b.start) b = b.start; + if(a.line < b.line) return -1; + if(a.line > b.line) return 1; + if(a.column < b.column) return -1; + if(a.column > b.column) return 1; + if(a.index < b.index) return -1; + if(a.index > b.index) return 1; + return 0; + } else { + return 0; + } + } +}; + + +/***/ }, +/* 12 */ +/***/ function(module, exports, __webpack_require__) { + +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +var Dependency = __webpack_require__(10); + +function ModuleDependency(request) { + Dependency.call(this); + this.request = request; + this.userRequest = request; +} +module.exports = ModuleDependency; + +ModuleDependency.prototype = Object.create(Dependency.prototype); +ModuleDependency.prototype.constructor = ModuleDependency; +ModuleDependency.prototype.isEqualResource = function isEqualResource(other) { + if(!(other instanceof ModuleDependency)) + return false; + return this.request === other.request; +}; + + +/***/ }, +/* 13 */ +/***/ function(module, exports) { + +module.exports = __WEBPACK_EXTERNAL_MODULE_13__; + +/***/ }, +/* 14 */ +/***/ function(module, exports) { + +module.exports = __WEBPACK_EXTERNAL_MODULE_14__; + +/***/ }, +/* 15 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; +'use strict';var _=__webpack_require__(3);var path=__webpack_require__(4);var async=__webpack_require__(2);var webpackDevMiddleware=__webpack_require__(6);var webpack=__webpack_require__(5);var SingleEntryDependency=__webpack_require__(1);var blocked=[];var isBlocked=false;function Plugin(/* config.webpack */webpackOptions,/* config.webpackServer */webpackServerOptions,/* config.webpackMiddleware */webpackMiddlewareOptions,/* config.basePath */basePath,/* config.files */files,/* config.frameworks */frameworks,customFileHandlers,emitter){webpackOptions=_.clone(webpackOptions)||{};webpackMiddlewareOptions=_.clone(webpackMiddlewareOptions||webpackServerOptions)||{};var applyOptions=Array.isArray(webpackOptions)?webpackOptions:[webpackOptions];var includeIndex=applyOptions.length>1;applyOptions.forEach(function(webpackOptions,index){// The webpack tier owns the watch behavior so we want to force it in the config +webpackOptions.watch=true;// Webpack 2.1.0-beta.7+ will throw in error if both entry and plugins are not specified in options +// https://github.com/webpack/webpack/commit/b3bc5427969e15fd3663d9a1c57dbd1eb2c94805 +if(!webpackOptions.entry){webpackOptions.entry={};};if(!webpackOptions.output){webpackOptions.output={};};// When using an array, even of length 1, we want to include the index value for the build. +// This is due to the way that the dev server exposes commonPath for build output. +var indexPath=includeIndex?index+'/':'';var publicPath=indexPath!==''?indexPath+'/':'';// Must have the common _karma_webpack_ prefix on path here to avoid +// https://github.com/webpack/webpack/issues/645 +webpackOptions.output.path='/_karma_webpack_/'+indexPath;webpackOptions.output.publicPath='/_karma_webpack_/'+publicPath;webpackOptions.output.filename='[name]';if(includeIndex){webpackOptions.output.jsonpFunction='webpackJsonp'+index;}webpackOptions.output.chunkFilename='[id].bundle.js';});this.emitter=emitter;this.wrapMocha=frameworks.indexOf('mocha')>=0&&includeIndex;this.optionsCount=applyOptions.length;this.files=[];this.basePath=basePath;this.waiting=[];var compiler=webpack(webpackOptions);var applyPlugins=compiler.compilers||[compiler];applyPlugins.forEach(function(compiler){compiler.plugin('this-compilation',function(compilation,params){compilation.dependencyFactories.set(SingleEntryDependency,params.normalModuleFactory);});compiler.plugin('make',this.make.bind(this));},this);['invalid','watch-run','run'].forEach(function(name){compiler.plugin(name,function(_,callback){isBlocked=true;if(typeof callback==='function'){callback();}});});compiler.plugin('done',function(stats){var applyStats=Array.isArray(stats.stats)?stats.stats:[stats];var assets=[];var noAssets=false;applyStats.forEach(function(stats){stats=stats.toJson();assets.push.apply(assets,stats.assets);if(stats.assets.length===0){noAssets=true;}});if(!this.waiting||this.waiting.length===0){this.notifyKarmaAboutChanges();}if(this.waiting&&!noAssets){var w=this.waiting;this.waiting=null;w.forEach(function(cb){cb();});}isBlocked=false;for(var i=0;i=0){return;}this.files.push(entry);return true;};Plugin.prototype.make=function(compilation,callback){async.forEach(this.files.slice(),function(file,callback){var entry=file;if(this.wrapMocha){entry=/*require.resolve*/(0)+'!'+entry;}var dep=new SingleEntryDependency(entry);compilation.addEntry('',dep,path.relative(this.basePath,file).replace(/\\/g,'/'),function(){// If the module fails because of an File not found error, remove the test file +if(dep.module&&dep.module.error&&dep.module.error.error&&dep.module.error.error.code==='ENOENT'){this.files=this.files.filter(function(f){return file!==f;});this.middleware.invalidate();}callback();}.bind(this));}.bind(this),callback);};Plugin.prototype.readFile=function(file,callback){var middleware=this.middleware;var optionsCount=this.optionsCount;function doRead(){if(optionsCount>1){async.times(optionsCount,function(idx,callback){middleware.fileSystem.readFile('/_karma_webpack_/'+idx+'/'+file.replace(/\\/g,'/'),callback);},function(err,contents){if(err){return callback(err);};contents=contents.reduce(function(arr,x){if(!arr){return[x];};arr.push(new Buffer('\n'),x);return arr;},null);callback(null,Buffer.concat(contents));});}else{middleware.fileSystem.readFile('/_karma_webpack_/'+file.replace(/\\/g,'/'),callback);}}if(!this.waiting){doRead();}else{// Retry to read once a build is finished +// do it on process.nextTick to catch changes while building +this.waiting.push(process.nextTick.bind(process,this.readFile.bind(this,file,callback)));}};function createPreprocesor(/* config.basePath */basePath,webpackPlugin){return function(content,file,done){if(webpackPlugin.addFile(file.path)){// recompile as we have an asset that we have not seen before +webpackPlugin.middleware.invalidate();}// read blocks until bundle is done +webpackPlugin.readFile(path.relative(basePath,file.path),function(err,content){if(err){throw err;}done(err,content&&content.toString());});};}function createWebpackBlocker(){return function(request,response,next){if(isBlocked){blocked.push(next);}else{next();}};}module.exports={webpackPlugin:['type',Plugin],'preprocessor:webpack':['factory',createPreprocesor],'middleware:webpackBlocker':['factory',createWebpackBlocker]}; +//# sourceMappingURL=data:application/json;base64,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QUNGLENBakNELENBbUNBLFFBQVMsa0JBQVQsQ0FBMkIscUJBQXNCLFFBQWpELENBQTJELGFBQTNELENBQTBFLENBQ3hFLE1BQU8sVUFBUyxPQUFULENBQWtCLElBQWxCLENBQXdCLElBQXhCLENBQThCLENBQ25DLEdBQUksY0FBYyxPQUFkLENBQXNCLEtBQUssSUFBM0IsQ0FBSixDQUFzQyxDQUNwQztBQUNBLGNBQWMsVUFBZCxDQUF5QixVQUF6QixHQUNELENBRUQ7QUFDQSxjQUFjLFFBQWQsQ0FBdUIsS0FBSyxRQUFMLENBQWMsUUFBZCxDQUF3QixLQUFLLElBQTdCLENBQXZCLENBQTJELFNBQVMsR0FBVCxDQUFjLE9BQWQsQ0FBdUIsQ0FDaEYsR0FBSSxHQUFKLENBQVMsQ0FDUCxLQUFNLElBQU4sQ0FDRCxDQUVELEtBQUssR0FBTCxDQUFVLFNBQVcsUUFBUSxRQUFSLEVBQXJCLEVBQ0QsQ0FORCxFQU9ELENBZEQsQ0FlRCxDQUVELFFBQVMscUJBQVQsRUFBZ0MsQ0FDOUIsTUFBTyxVQUFTLE9BQVQsQ0FBa0IsUUFBbEIsQ0FBNEIsSUFBNUIsQ0FBa0MsQ0FDdkMsR0FBSSxTQUFKLENBQWUsQ0FDYixRQUFRLElBQVIsQ0FBYSxJQUFiLEVBQ0QsQ0FGRCxJQUVPLENBQ0wsT0FDRCxDQUNGLENBTkQsQ0FPRCxDQUVELE9BQU8sT0FBUCxDQUFpQixDQUNmLGNBQWUsQ0FBQyxNQUFELENBQVMsTUFBVCxDQURBLENBRWYsdUJBQXdCLENBQUMsU0FBRCxDQUFZLGlCQUFaLENBRlQsQ0FHZiw0QkFBNkIsQ0FBQyxTQUFELENBQVksb0JBQVosQ0FIZCxDQUFqQiIsImZpbGUiOiJrYXJtYS13ZWJwYWNrLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9taWthL0RvY3VtZW50cy9zaWRlL2thcm1hLXdlYnBhY2siLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgXyA9IHJlcXVpcmUoJ2xvZGFzaCcpXG52YXIgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKVxudmFyIGFzeW5jID0gcmVxdWlyZSgnYXN5bmMnKVxudmFyIHdlYnBhY2tEZXZNaWRkbGV3YXJlID0gcmVxdWlyZSgnd2VicGFjay1kZXYtbWlkZGxld2FyZScpXG52YXIgd2VicGFjayA9IHJlcXVpcmUoJ3dlYnBhY2snKVxudmFyIFNpbmdsZUVudHJ5RGVwZW5kZW5jeSA9IHJlcXVpcmUoJ3dlYnBhY2svbGliL2RlcGVuZGVuY2llcy9TaW5nbGVFbnRyeURlcGVuZGVuY3knKVxuXG52YXIgYmxvY2tlZCA9IFtdXG52YXIgaXNCbG9ja2VkID0gZmFsc2VcblxuZnVuY3Rpb24gUGx1Z2luKFxuXHQvKiBjb25maWcud2VicGFjayAqLyB3ZWJwYWNrT3B0aW9ucyxcblx0LyogY29uZmlnLndlYnBhY2tTZXJ2ZXIgKi8gd2VicGFja1NlcnZlck9wdGlvbnMsXG5cdC8qIGNvbmZpZy53ZWJwYWNrTWlkZGxld2FyZSAqLyB3ZWJwYWNrTWlkZGxld2FyZU9wdGlvbnMsXG5cdC8qIGNvbmZpZy5iYXNlUGF0aCAqLyBiYXNlUGF0aCxcblx0LyogY29uZmlnLmZpbGVzICovIGZpbGVzLFxuXHQvKiBjb25maWcuZnJhbWV3b3JrcyAqLyBmcmFtZXdvcmtzLFxuXHRjdXN0b21GaWxlSGFuZGxlcnMsXG5cdGVtaXR0ZXIpIHtcbiAgd2VicGFja09wdGlvbnMgPSBfLmNsb25lKHdlYnBhY2tPcHRpb25zKSB8fCB7fVxuICB3ZWJwYWNrTWlkZGxld2FyZU9wdGlvbnMgPSBfLmNsb25lKHdlYnBhY2tNaWRkbGV3YXJlT3B0aW9ucyB8fCB3ZWJwYWNrU2VydmVyT3B0aW9ucykgfHwge31cblxuICB2YXIgYXBwbHlPcHRpb25zID0gQXJyYXkuaXNBcnJheSh3ZWJwYWNrT3B0aW9ucykgPyB3ZWJwYWNrT3B0aW9ucyA6IFt3ZWJwYWNrT3B0aW9uc11cbiAgdmFyIGluY2x1ZGVJbmRleCA9IGFwcGx5T3B0aW9ucy5sZW5ndGggPiAxXG5cbiAgYXBwbHlPcHRpb25zLmZvckVhY2goZnVuY3Rpb24od2VicGFja09wdGlvbnMsIGluZGV4KSB7XG4gICAgLy8gVGhlIHdlYnBhY2sgdGllciBvd25zIHRoZSB3YXRjaCBiZWhhdmlvciBzbyB3ZSB3YW50IHRvIGZvcmNlIGl0IGluIHRoZSBjb25maWdcbiAgICB3ZWJwYWNrT3B0aW9ucy53YXRjaCA9IHRydWVcblxuICAgIC8vIFdlYnBhY2sgMi4xLjAtYmV0YS43KyB3aWxsIHRocm93IGluIGVycm9yIGlmIGJvdGggZW50cnkgYW5kIHBsdWdpbnMgYXJlIG5vdCBzcGVjaWZpZWQgaW4gb3B0aW9uc1xuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS93ZWJwYWNrL3dlYnBhY2svY29tbWl0L2IzYmM1NDI3OTY5ZTE1ZmQzNjYzZDlhMWM1N2RiZDFlYjJjOTQ4MDVcbiAgICBpZiAoIXdlYnBhY2tPcHRpb25zLmVudHJ5KSB7XG4gICAgICB3ZWJwYWNrT3B0aW9ucy5lbnRyeSA9IHt9XG4gICAgfTtcblxuICAgIGlmICghd2VicGFja09wdGlvbnMub3V0cHV0KSB7XG4gICAgICB3ZWJwYWNrT3B0aW9ucy5vdXRwdXQgPSB7fVxuICAgIH07XG5cbiAgICAvLyBXaGVuIHVzaW5nIGFuIGFycmF5LCBldmVuIG9mIGxlbmd0aCAxLCB3ZSB3YW50IHRvIGluY2x1ZGUgdGhlIGluZGV4IHZhbHVlIGZvciB0aGUgYnVpbGQuXG4gICAgLy8gVGhpcyBpcyBkdWUgdG8gdGhlIHdheSB0aGF0IHRoZSBkZXYgc2VydmVyIGV4cG9zZXMgY29tbW9uUGF0aCBmb3IgYnVpbGQgb3V0cHV0LlxuICAgIHZhciBpbmRleFBhdGggPSBpbmNsdWRlSW5kZXggPyBpbmRleCArICcvJyA6ICcnXG4gICAgdmFyIHB1YmxpY1BhdGggPSBpbmRleFBhdGggIT09ICcnID8gaW5kZXhQYXRoICsgJy8nIDogJydcblxuICAgIC8vIE11c3QgaGF2ZSB0aGUgY29tbW9uIF9rYXJtYV93ZWJwYWNrXyBwcmVmaXggb24gcGF0aCBoZXJlIHRvIGF2b2lkXG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL3dlYnBhY2svd2VicGFjay9pc3N1ZXMvNjQ1XG4gICAgd2VicGFja09wdGlvbnMub3V0cHV0LnBhdGggPSAnL19rYXJtYV93ZWJwYWNrXy8nICsgaW5kZXhQYXRoXG4gICAgd2VicGFja09wdGlvbnMub3V0cHV0LnB1YmxpY1BhdGggPSAnL19rYXJtYV93ZWJwYWNrXy8nICsgcHVibGljUGF0aFxuICAgIHdlYnBhY2tPcHRpb25zLm91dHB1dC5maWxlbmFtZSA9ICdbbmFtZV0nXG4gICAgaWYgKGluY2x1ZGVJbmRleCkge1xuICAgICAgd2VicGFja09wdGlvbnMub3V0cHV0Lmpzb25wRnVuY3Rpb24gPSAnd2VicGFja0pzb25wJyArIGluZGV4XG4gICAgfVxuICAgIHdlYnBhY2tPcHRpb25zLm91dHB1dC5jaHVua0ZpbGVuYW1lID0gJ1tpZF0uYnVuZGxlLmpzJ1xuICB9KVxuXG4gIHRoaXMuZW1pdHRlciA9IGVtaXR0ZXJcbiAgdGhpcy53cmFwTW9jaGEgPSBmcmFtZXdvcmtzLmluZGV4T2YoJ21vY2hhJykgPj0gMCAmJiBpbmNsdWRlSW5kZXhcbiAgdGhpcy5vcHRpb25zQ291bnQgPSBhcHBseU9wdGlvbnMubGVuZ3RoXG4gIHRoaXMuZmlsZXMgPSBbXVxuICB0aGlzLmJhc2VQYXRoID0gYmFzZVBhdGhcbiAgdGhpcy53YWl0aW5nID0gW11cblxuICB2YXIgY29tcGlsZXIgPSB3ZWJwYWNrKHdlYnBhY2tPcHRpb25zKVxuICB2YXIgYXBwbHlQbHVnaW5zID0gY29tcGlsZXIuY29tcGlsZXJzIHx8IFtjb21waWxlcl1cblxuICBhcHBseVBsdWdpbnMuZm9yRWFjaChmdW5jdGlvbihjb21waWxlcikge1xuICAgIGNvbXBpbGVyLnBsdWdpbigndGhpcy1jb21waWxhdGlvbicsIGZ1bmN0aW9uKGNvbXBpbGF0aW9uLCBwYXJhbXMpIHtcbiAgICAgIGNvbXBpbGF0aW9uLmRlcGVuZGVuY3lGYWN0b3JpZXMuc2V0KFNpbmdsZUVudHJ5RGVwZW5kZW5jeSwgcGFyYW1zLm5vcm1hbE1vZHVsZUZhY3RvcnkpXG4gICAgfSlcbiAgICBjb21waWxlci5wbHVnaW4oJ21ha2UnLCB0aGlzLm1ha2UuYmluZCh0aGlzKSlcbiAgfSwgdGhpcyk7XG5cbiAgWydpbnZhbGlkJywgJ3dhdGNoLXJ1bicsICdydW4nXS5mb3JFYWNoKGZ1bmN0aW9uKG5hbWUpIHtcbiAgICBjb21waWxlci5wbHVnaW4obmFtZSwgZnVuY3Rpb24oXywgY2FsbGJhY2spIHtcbiAgICAgIGlzQmxvY2tlZCA9IHRydWVcblxuICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBjYWxsYmFjaygpXG4gICAgICB9XG4gICAgfSlcbiAgfSlcblxuICBjb21waWxlci5wbHVnaW4oJ2RvbmUnLCBmdW5jdGlvbihzdGF0cykge1xuICAgIHZhciBhcHBseVN0YXRzID0gQXJyYXkuaXNBcnJheShzdGF0cy5zdGF0cykgPyBzdGF0cy5zdGF0cyA6IFtzdGF0c11cbiAgICB2YXIgYXNzZXRzID0gW11cbiAgICB2YXIgbm9Bc3NldHMgPSBmYWxzZVxuXG4gICAgYXBwbHlTdGF0cy5mb3JFYWNoKGZ1bmN0aW9uKHN0YXRzKSB7XG4gICAgICBzdGF0cyA9IHN0YXRzLnRvSnNvbigpXG5cbiAgICAgIGFzc2V0cy5wdXNoLmFwcGx5KGFzc2V0cywgc3RhdHMuYXNzZXRzKVxuICAgICAgaWYgKHN0YXRzLmFzc2V0cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgbm9Bc3NldHMgPSB0cnVlXG4gICAgICB9XG4gICAgfSlcblxuICAgIGlmICghdGhpcy53YWl0aW5nIHx8IHRoaXMud2FpdGluZy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRoaXMubm90aWZ5S2FybWFBYm91dENoYW5nZXMoKVxuICAgIH1cblxuICAgIGlmICh0aGlzLndhaXRpbmcgJiYgIW5vQXNzZXRzKSB7XG4gICAgICB2YXIgdyA9IHRoaXMud2FpdGluZ1xuXG4gICAgICB0aGlzLndhaXRpbmcgPSBudWxsXG4gICAgICB3LmZvckVhY2goZnVuY3Rpb24oY2IpIHtcbiAgICAgICAgY2IoKVxuICAgICAgfSlcbiAgICB9XG5cbiAgICBpc0Jsb2NrZWQgPSBmYWxzZVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tlZC5sZW5ndGg7IGkrKykge1xuICAgICAgYmxvY2tlZFtpXSgpXG4gICAgfVxuICAgIGJsb2NrZWQgPSBbXVxuICB9LmJpbmQodGhpcykpXG4gIGNvbXBpbGVyLnBsdWdpbignaW52YWxpZCcsIGZ1bmN0aW9uKCkge1xuICAgIGlmICghdGhpcy53YWl0aW5nKSB7XG4gICAgICB0aGlzLndhaXRpbmcgPSBbXVxuICAgIH1cbiAgfS5iaW5kKHRoaXMpKVxuXG4gIHdlYnBhY2tNaWRkbGV3YXJlT3B0aW9ucy5wdWJsaWNQYXRoID0gJy9fa2FybWFfd2VicGFja18vJ1xuICB2YXIgbWlkZGxld2FyZSA9IHRoaXMubWlkZGxld2FyZSA9IG5ldyB3ZWJwYWNrRGV2TWlkZGxld2FyZShjb21waWxlciwgd2VicGFja01pZGRsZXdhcmVPcHRpb25zKVxuXG4gIGN1c3RvbUZpbGVIYW5kbGVycy5wdXNoKHtcbiAgICB1cmxSZWdleDogL15cXC9fa2FybWFfd2VicGFja19cXC8uKi8sXG4gICAgaGFuZGxlcjogZnVuY3Rpb24ocmVxLCByZXMpIHtcbiAgICAgIG1pZGRsZXdhcmUocmVxLCByZXMsIGZ1bmN0aW9uKCkge1xuICAgICAgICByZXMuc3RhdHVzQ29kZSA9IDQwNFxuICAgICAgICByZXMuZW5kKCdOb3QgZm91bmQnKVxuICAgICAgfSlcbiAgICB9XG4gIH0pXG5cbiAgZW1pdHRlci5vbignZXhpdCcsIGZ1bmN0aW9uKGRvbmUpIHtcbiAgICBtaWRkbGV3YXJlLmNsb3NlKClcbiAgICBkb25lKClcbiAgfSlcbn1cblxuUGx1Z2luLnByb3RvdHlwZS5ub3RpZnlLYXJtYUFib3V0Q2hhbmdlcyA9IGZ1bmN0aW9uKCkge1xuICAvLyBGb3JjZSBhIHJlYnVpbGRcbiAgdGhpcy5lbWl0dGVyLnJlZnJlc2hGaWxlcygpXG59XG5cblBsdWdpbi5wcm90b3R5cGUuYWRkRmlsZSA9IGZ1bmN0aW9uKGVudHJ5KSB7XG4gIGlmICh0aGlzLmZpbGVzLmluZGV4T2YoZW50cnkpID49IDApIHtcbiAgICByZXR1cm5cbiAgfVxuICB0aGlzLmZpbGVzLnB1c2goZW50cnkpXG5cbiAgcmV0dXJuIHRydWVcbn1cblxuUGx1Z2luLnByb3RvdHlwZS5tYWtlID0gZnVuY3Rpb24oY29tcGlsYXRpb24sIGNhbGxiYWNrKSB7XG4gIGFzeW5jLmZvckVhY2godGhpcy5maWxlcy5zbGljZSgpLCBmdW5jdGlvbihmaWxlLCBjYWxsYmFjaykge1xuICAgIHZhciBlbnRyeSA9IGZpbGVcblxuICAgIGlmICh0aGlzLndyYXBNb2NoYSkge1xuICAgICAgZW50cnkgPSByZXF1aXJlLnJlc29sdmUoJy4vbW9jaGEtZW52LWxvYWRlcicpICsgJyEnICsgZW50cnlcbiAgICB9XG5cbiAgICB2YXIgZGVwID0gbmV3IFNpbmdsZUVudHJ5RGVwZW5kZW5jeShlbnRyeSlcblxuICAgIGNvbXBpbGF0aW9uLmFkZEVudHJ5KCcnLCBkZXAsIHBhdGgucmVsYXRpdmUodGhpcy5iYXNlUGF0aCwgZmlsZSkucmVwbGFjZSgvXFxcXC9nLCAnLycpLCBmdW5jdGlvbigpIHtcbiAgICAgIC8vIElmIHRoZSBtb2R1bGUgZmFpbHMgYmVjYXVzZSBvZiBhbiBGaWxlIG5vdCBmb3VuZCBlcnJvciwgcmVtb3ZlIHRoZSB0ZXN0IGZpbGVcbiAgICAgIGlmIChkZXAubW9kdWxlICYmIGRlcC5tb2R1bGUuZXJyb3IgJiZcbiAgICAgICAgZGVwLm1vZHVsZS5lcnJvci5lcnJvciAmJlxuICAgICAgICBkZXAubW9kdWxlLmVycm9yLmVycm9yLmNvZGUgPT09ICdFTk9FTlQnKSB7XG4gICAgICAgIHRoaXMuZmlsZXMgPSB0aGlzLmZpbGVzLmZpbHRlcihmdW5jdGlvbihmKSB7XG4gICAgICAgICAgcmV0dXJuIGZpbGUgIT09IGZcbiAgICAgICAgfSlcbiAgICAgICAgdGhpcy5taWRkbGV3YXJlLmludmFsaWRhdGUoKVxuICAgICAgfVxuICAgICAgY2FsbGJhY2soKVxuICAgIH0uYmluZCh0aGlzKSlcbiAgfS5iaW5kKHRoaXMpLCBjYWxsYmFjaylcbn1cblxuUGx1Z2luLnByb3RvdHlwZS5yZWFkRmlsZSA9IGZ1bmN0aW9uKGZpbGUsIGNhbGxiYWNrKSB7XG4gIHZhciBtaWRkbGV3YXJlID0gdGhpcy5taWRkbGV3YXJlXG4gIHZhciBvcHRpb25zQ291bnQgPSB0aGlzLm9wdGlvbnNDb3VudFxuXG4gIGZ1bmN0aW9uIGRvUmVhZCgpIHtcbiAgICBpZiAob3B0aW9uc0NvdW50ID4gMSkge1xuICAgICAgYXN5bmMudGltZXMob3B0aW9uc0NvdW50LCBmdW5jdGlvbihpZHgsIGNhbGxiYWNrKSB7XG4gICAgICAgIG1pZGRsZXdhcmUuZmlsZVN5c3RlbS5yZWFkRmlsZSgnL19rYXJtYV93ZWJwYWNrXy8nICsgaWR4ICsgJy8nICsgZmlsZS5yZXBsYWNlKC9cXFxcL2csICcvJyksIGNhbGxiYWNrKVxuICAgICAgfSwgZnVuY3Rpb24oZXJyLCBjb250ZW50cykge1xuICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycilcbiAgICAgICAgfTtcbiAgICAgICAgY29udGVudHMgPSBjb250ZW50cy5yZWR1Y2UoZnVuY3Rpb24oYXJyLCB4KSB7XG4gICAgICAgICAgaWYgKCFhcnIpIHtcbiAgICAgICAgICAgIHJldHVybiBbeF1cbiAgICAgICAgICB9O1xuICAgICAgICAgIGFyci5wdXNoKG5ldyBCdWZmZXIoJ1xcbicpLCB4KVxuXG4gICAgICAgICAgcmV0dXJuIGFyclxuICAgICAgICB9LCBudWxsKVxuICAgICAgICBjYWxsYmFjayhudWxsLCBCdWZmZXIuY29uY2F0KGNvbnRlbnRzKSlcbiAgICAgIH0pXG4gICAgfSBlbHNlIHtcbiAgICAgIG1pZGRsZXdhcmUuZmlsZVN5c3RlbS5yZWFkRmlsZSgnL19rYXJtYV93ZWJwYWNrXy8nICsgZmlsZS5yZXBsYWNlKC9cXFxcL2csICcvJyksIGNhbGxiYWNrKVxuICAgIH1cbiAgfVxuICBpZiAoIXRoaXMud2FpdGluZykge1xuICAgIGRvUmVhZCgpXG4gIH0gZWxzZSB7XG4gICAgLy8gUmV0cnkgdG8gcmVhZCBvbmNlIGEgYnVpbGQgaXMgZmluaXNoZWRcbiAgICAvLyBkbyBpdCBvbiBwcm9jZXNzLm5leHRUaWNrIHRvIGNhdGNoIGNoYW5nZXMgd2hpbGUgYnVpbGRpbmdcbiAgICB0aGlzLndhaXRpbmcucHVzaChwcm9jZXNzLm5leHRUaWNrLmJpbmQocHJvY2VzcywgdGhpcy5yZWFkRmlsZS5iaW5kKHRoaXMsIGZpbGUsIGNhbGxiYWNrKSkpXG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlUHJlcHJvY2Vzb3IoLyogY29uZmlnLmJhc2VQYXRoICovIGJhc2VQYXRoLCB3ZWJwYWNrUGx1Z2luKSB7XG4gIHJldHVybiBmdW5jdGlvbihjb250ZW50LCBmaWxlLCBkb25lKSB7XG4gICAgaWYgKHdlYnBhY2tQbHVnaW4uYWRkRmlsZShmaWxlLnBhdGgpKSB7XG4gICAgICAvLyByZWNvbXBpbGUgYXMgd2UgaGF2ZSBhbiBhc3NldCB0aGF0IHdlIGhhdmUgbm90IHNlZW4gYmVmb3JlXG4gICAgICB3ZWJwYWNrUGx1Z2luLm1pZGRsZXdhcmUuaW52YWxpZGF0ZSgpXG4gICAgfVxuXG4gICAgLy8gcmVhZCBibG9ja3MgdW50aWwgYnVuZGxlIGlzIGRvbmVcbiAgICB3ZWJwYWNrUGx1Z2luLnJlYWRGaWxlKHBhdGgucmVsYXRpdmUoYmFzZVBhdGgsIGZpbGUucGF0aCksIGZ1bmN0aW9uKGVyciwgY29udGVudCkge1xuICAgICAgaWYgKGVycikge1xuICAgICAgICB0aHJvdyBlcnJcbiAgICAgIH1cblxuICAgICAgZG9uZShlcnIsIGNvbnRlbnQgJiYgY29udGVudC50b1N0cmluZygpKVxuICAgIH0pXG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlV2VicGFja0Jsb2NrZXIoKSB7XG4gIHJldHVybiBmdW5jdGlvbihyZXF1ZXN0LCByZXNwb25zZSwgbmV4dCkge1xuICAgIGlmIChpc0Jsb2NrZWQpIHtcbiAgICAgIGJsb2NrZWQucHVzaChuZXh0KVxuICAgIH0gZWxzZSB7XG4gICAgICBuZXh0KClcbiAgICB9XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHdlYnBhY2tQbHVnaW46IFsndHlwZScsIFBsdWdpbl0sXG4gICdwcmVwcm9jZXNzb3I6d2VicGFjayc6IFsnZmFjdG9yeScsIGNyZWF0ZVByZXByb2Nlc29yXSxcbiAgJ21pZGRsZXdhcmU6d2VicGFja0Jsb2NrZXInOiBbJ2ZhY3RvcnknLCBjcmVhdGVXZWJwYWNrQmxvY2tlcl1cbn1cbiJdfQ== + +/***/ } +/******/ ]) +}); +; \ No newline at end of file diff --git a/package.json b/package.json index cd19485..f0efada 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,22 @@ "version": "1.7.0", "author": "Tobias Koppers @sokra", "description": "Use webpack with karma", + "license": "MIT", + "homepage": "http://github.com/webpack/karma-webpack", + "main": "dist/karma-webpack.js", + "scripts": { + "lint": "eslint test src", + "pretest": "npm run lint", + "test": "npm run test.unit", + "test.unit": "mocha --compilers js:babel-register --full-trace --check-leaks test/unit", + "test.integration": "npm run build && karma start --single-run", + "travis": "npm run test.unit && npm run test.integration", + "build": "webpack" + }, + "repository": { + "type": "git", + "url": "https://github.com/webpack/karma-webpack.git" + }, "peerDependencies": { "webpack": "^1.4.0 || ^2 || ^2.1.0-beta" }, @@ -16,7 +32,11 @@ "devDependencies": { "babel-cli": "^6.11.4", "babel-core": "^6.11.4", - "babel-eslint": "^6.1.2", + "babel-loader": "^6.2.4", + "babel-plugin-transform-runtime": "^6.12.0", + "babel-polyfill": "^6.9.1", + "babel-preset-es2015": "^6.9.0", + "babel-preset-stage-2": "^6.11.0", "babel-register": "^6.11.6", "chai": "^3.5.0", "chai-as-promised": "^5.3.0", @@ -24,39 +44,12 @@ "eslint": "^3.1.1", "eslint-plugin-babel": "^3.3.0", "istanbul": "^0.4.4", + "json-loader": "^0.5.4", "karma": "^1.x", "karma-chrome-launcher": "~1.0.1", "karma-mocha": "~1.1.1", "karma-spec-reporter": "~0.0.22", - "mocha": "^2.5.3" - }, - "scripts": { - "lint": "eslint test index.js mocha-env-loader.js", - "pretest": "npm run lint", - "test": "npm run test.unit", - "test.unit": "mocha --harmony --full-trace --check-leaks test/unit", - "test.integration": "karma start --single-run", - "travis": "npm run test.unit && npm run test.integration" - }, - "babel": { - "presets": [ - "es2015" - ], - "plugins": [ - "transform-runtime" - ], - "ignore": "**/*.test.js", - "env": { - "development": { - "sourceMaps": "inline" - } - } - }, - "license": "MIT", - "homepage": "http://github.com/webpack/karma-webpack", - "repository": { - "type": "git", - "url": "https://github.com/webpack/karma-webpack.git" - }, - "main": "index.js" + "mocha": "^2.5.3", + "webpack": "^2.1.0-beta.20" + } } diff --git a/index.js b/src/karma-webpack.js similarity index 100% rename from index.js rename to src/karma-webpack.js diff --git a/mocha-env-loader.js b/src/mocha-env-loader.js similarity index 100% rename from mocha-env-loader.js rename to src/mocha-env-loader.js diff --git a/test/integration/karma.config.js b/test/integration/karma.config.js index f8c2f61..f76292e 100644 --- a/test/integration/karma.config.js +++ b/test/integration/karma.config.js @@ -24,7 +24,7 @@ module.exports = function(config) { // list of files / patterns to load in the browser files: [ - 'test/index.js' + 'test/**/*.test.js' ], @@ -102,7 +102,7 @@ module.exports = function(config) { require('karma-mocha'), require('karma-spec-reporter'), require('karma-chrome-launcher'), - require('../../') + require('../../dist/karma-webpack') ] }) } diff --git a/test/unit/es2015Demo.test.js b/test/unit/es2015Demo.test.js index faeb72d..8c1cbbe 100644 --- a/test/unit/es2015Demo.test.js +++ b/test/unit/es2015Demo.test.js @@ -1,4 +1,4 @@ -var assert = require('chai').assert +import {assert} from 'chai' describe('Array', function() { describe('#indexOf()', function() { diff --git a/webpack.config.babel.js b/webpack.config.babel.js new file mode 100644 index 0000000..f7977d6 --- /dev/null +++ b/webpack.config.babel.js @@ -0,0 +1,35 @@ +import path from 'path' +import {name, dependencies, devDependencies} from './package.json' + +const rootPath = (nPath) => path.resolve(__dirname, nPath) +const BUILD_PATH = './dist' +const NODE_MODULES = rootPath('node_modules') + +const CONFIG = { + entry: './src/karma-webpack.js', + target: 'node', + + output: { + path: BUILD_PATH, + filename: 'karma-webpack.js', + library: name, + libraryTarget: 'umd' + }, + + module: { + loaders: [{ + test: /\.json/, + loader: 'json' + }, { + test: /\.js/, + loader: 'babel', + exclude: [NODE_MODULES], + query: {compact: true} + }] + }, + + externals: Object.keys(dependencies) + .concat(Object.keys(devDependencies)) +} + +export default CONFIG