karma
Advanced tools
Comparing version 0.9.3 to 0.9.4
@@ -0,1 +1,66 @@ | ||
<a name="v0.9.4"></a> | ||
### v0.9.4 (2013-06-28) | ||
#### Bug Fixes | ||
* **config:** | ||
* make the config changes backwards compatible ([593ad853](https://github.com/karma-runner/karma/commit/593ad853c330a7856f2112db2bfb288f67948fa6)) | ||
* better errors if file invalid or does not exist ([74b533be](https://github.com/karma-runner/karma/commit/74b533beb34c115f5080d412a03573d269d540aa)) | ||
* allow parsing the config multiple times ([78a7094e](https://github.com/karma-runner/karma/commit/78a7094e0f262c431e904f99cf356be53eee3510)) | ||
* **launcher:** better errors when loading launchers ([504e848c](https://github.com/karma-runner/karma/commit/504e848cf66b065380fa72e07f5337ae2d6e35b5)) | ||
* **preprocessor:** | ||
* do not show duplicate warnings ([47c641f7](https://github.com/karma-runner/karma/commit/47c641f7560d28e0d9eac7ae010566d296d5b628)) | ||
* better errors when loading preprocessors ([3390a00b](https://github.com/karma-runner/karma/commit/3390a00b49c513a6da60f48044462118436130f8)) | ||
* **reporter:** better errors when loading reporters ([c645c060](https://github.com/karma-runner/karma/commit/c645c060c4f381902c2005eefe5b3a7bfa63cdcc)) | ||
#### Features | ||
* **config:** pass the config object rather than a wrapper ([d2a3c854](https://github.com/karma-runner/karma/commit/d2a3c8546dc4b10bb9194047a1c11963639f3730)) | ||
#### Breaking Changes | ||
* please update your karma.conf.js as follows: | ||
// before: | ||
module.exports = function(karma) { | ||
karma.configure({port: 123}); | ||
karma.defineLauncher('x', 'Chrome', { | ||
flags: ['--disable-web-security'] | ||
}); | ||
karma.definePreprocessor('y', 'coffee', { | ||
bare: false | ||
}); | ||
karma.defineReporter('z', 'coverage', { | ||
type: 'html' | ||
}); | ||
}; | ||
// after: | ||
module.exports = function(config) { | ||
config.set({ | ||
port: 123, | ||
customLaunchers: { | ||
'x': { | ||
base: 'Chrome', | ||
flags: ['--disable-web-security'] | ||
} | ||
}, | ||
customPreprocessors: { | ||
'y': { | ||
base: 'coffee', | ||
bare: false | ||
} | ||
}, | ||
customReporters: { | ||
'z': { | ||
base: 'coverage', | ||
type: 'html' | ||
} | ||
} | ||
}); | ||
}; | ||
([d2a3c854](https://github.com/karma-runner/karma/commit/d2a3c8546dc4b10bb9194047a1c11963639f3730)) | ||
<a name="v0.9.3"></a> | ||
@@ -2,0 +67,0 @@ ### v0.9.3 (2013-06-16) |
@@ -132,42 +132,80 @@ var path = require('path'); | ||
return config; | ||
}; | ||
var KarmaDsl = function(config) { | ||
this.LOG_DISABLE = constant.LOG_DISABLE; | ||
this.LOG_ERROR = constant.LOG_ERROR; | ||
this.LOG_WARN = constant.LOG_WARN; | ||
this.LOG_INFO = constant.LOG_INFO; | ||
this.LOG_DEBUG = constant.LOG_DEBUG; | ||
// define custom launchers/preprocessors/reporters - create an inlined plugin | ||
var module = Object.create(null); | ||
['launcher', 'preprocessor', 'reporter'].forEach(function(type) { | ||
var definitions = config['custom' + helper.ucFirst(type) + 's'] || {}; | ||
// TODO(vojta): remove | ||
var CONST_ERR = '%s is not supported anymore.\n\tPlease use `frameworks = ["%s"];` instead.'; | ||
['JASMINE', 'MOCHA', 'QUNIT'].forEach(function(framework) { | ||
[framework, framework + '_ADAPTER'].forEach(function(name) { | ||
Object.defineProperty(global, name, {get: function() { | ||
log.warn(CONST_ERR, name, framework.toLowerCase()); | ||
}}); | ||
Object.keys(definitions).forEach(function(name) { | ||
var definition = definitions[name]; | ||
if (!helper.isObject(definition)) { | ||
return log.warn('Can not define %s %s. Definition has to be an object.', type, name); | ||
} | ||
if (!helper.isString(definition.base)) { | ||
return log.warn('Can not define %s %s. Missing base %s.', type, name, type); | ||
} | ||
var token = type + ':' + definition.base; | ||
var locals = { | ||
args: ['value', definition] | ||
}; | ||
module[type + ':' + name] = ['factory', function(injector) { | ||
return injector.createChild([locals], [token]).get(token); | ||
}]; | ||
}); | ||
}); | ||
['REQUIRE', 'REQUIRE_ADAPTER'].forEach(function(name) { | ||
Object.defineProperty(global, name, {get: function() { | ||
log.warn(CONST_ERR, name, 'requirejs'); | ||
}}); | ||
}); | ||
config.plugins.push(module); | ||
['ANGULAR_SCENARIO', 'ANGULAR_SCENARIO_ADAPTER'].forEach(function(name) { | ||
Object.defineProperty(global, name, {get: function() { | ||
log.warn(CONST_ERR, name, 'ng-scenario'); | ||
}}); | ||
}); | ||
return config; | ||
}; | ||
['LOG_DISABLE', 'LOG_INFO', 'LOG_DEBUG', 'LOG_WARN', 'LOG_ERROR'].forEach(function(name) { | ||
Object.defineProperty(global, name, {get: function() { | ||
log.warn('%s is not supported anymore.\n Please use `karma.%s` instead.', name, name); | ||
return constant.LOG_INFO; | ||
// TODO(vojta): remove in 0.11 | ||
var CONST_ERR = '%s is not supported anymore.\n\tPlease use `frameworks = ["%s"];` instead.'; | ||
['JASMINE', 'MOCHA', 'QUNIT'].forEach(function(framework) { | ||
[framework, framework + '_ADAPTER'].forEach(function(name) { | ||
Object.defineProperty(global, name, {configurable: true, get: function() { | ||
log.warn(CONST_ERR, name, framework.toLowerCase()); | ||
return __dirname + '/../../karma-' + framework.toLowerCase() + '/lib/' + | ||
(framework === name ? framework.toLowerCase() : 'adapter') + '.js'; | ||
}}); | ||
}); | ||
}); | ||
this.configure = function(newConfig) { | ||
['REQUIRE', 'REQUIRE_ADAPTER'].forEach(function(name) { | ||
Object.defineProperty(global, name, {configurable: true, get: function() { | ||
log.warn(CONST_ERR, name, 'requirejs'); | ||
return __dirname + '/../../karma-requirejs/lib/' + | ||
(name === 'REQUIRE' ? 'require' : 'adapter') + '.js'; | ||
}}); | ||
}); | ||
['ANGULAR_SCENARIO', 'ANGULAR_SCENARIO_ADAPTER'].forEach(function(name) { | ||
Object.defineProperty(global, name, {configurable: true, get: function() { | ||
log.warn(CONST_ERR, name, 'ng-scenario'); | ||
return __dirname + '/../../karma-ng-scenario/lib/' + | ||
(name === 'ANGULAR_SCENARIO' ? 'angular-scenario' : 'adapter') + '.js'; | ||
}}); | ||
}); | ||
['LOG_DISABLE', 'LOG_INFO', 'LOG_DEBUG', 'LOG_WARN', 'LOG_ERROR'].forEach(function(name) { | ||
Object.defineProperty(global, name, {configurable: true, get: function() { | ||
log.warn('%s is not supported anymore.\n Please use `karma.%s` instead.', name, name); | ||
return constant[name]; | ||
}}); | ||
}); | ||
var Config = function() { | ||
var config = this; | ||
this.LOG_DISABLE = constant.LOG_DISABLE; | ||
this.LOG_ERROR = constant.LOG_ERROR; | ||
this.LOG_WARN = constant.LOG_WARN; | ||
this.LOG_INFO = constant.LOG_INFO; | ||
this.LOG_DEBUG = constant.LOG_DEBUG; | ||
this.set = function(newConfig) { | ||
Object.keys(newConfig).forEach(function(key) { | ||
@@ -178,13 +216,16 @@ config[key] = newConfig[key]; | ||
// this.defineLauncher | ||
// this.defineReporter | ||
// this.definePreprocessor | ||
// TODO(vojta): remove this in 0.10 | ||
this.configure = function(newConfig) { | ||
log.warn('config.configure() is deprecated, please use config.set() instead.'); | ||
this.set(newConfig); | ||
}; | ||
// TODO(vojta): remove this in 0.10 | ||
['launcher', 'reporter', 'preprocessor'].forEach(function(type) { | ||
this['define' + helper.ucFirst(type)] = function(name, base, options) { | ||
var module = Object.create(null); | ||
var token = type + ':' + base; | ||
var locals = { | ||
args: ['value', options] | ||
}; | ||
var methodName = 'define' + helper.ucFirst(type); | ||
var propertyName = 'custom' + helper.ucFirst(type) + 's'; | ||
config[methodName] = function(name, base, options) { | ||
log.warn('config.%s is deprecated, please use "%s" instead.', methodName, propertyName); | ||
if (!helper.isString(name)) { | ||
@@ -202,11 +243,52 @@ return log.warn('Can not define %s. Name has to be a string.', type); | ||
module[type + ':' + name] = ['factory', function(injector) { | ||
return injector.createChild([locals], [token]).get(token); | ||
}]; | ||
config[propertyName] = config[propertyName] || {}; | ||
config[propertyName][name] = options; | ||
options.base = base; | ||
}; | ||
}); | ||
config.plugins.push(module); | ||
}; | ||
}, this); | ||
// DEFAULT CONFIG | ||
this.frameworks = []; | ||
this.port = constant.DEFAULT_PORT; | ||
this.runnerPort = constant.DEFAULT_RUNNER_PORT; | ||
this.hostname = constant.DEFAULT_HOSTNAME; | ||
this.basePath = ''; | ||
this.files = []; | ||
this.exclude = []; | ||
this.logLevel = constant.LOG_INFO; | ||
this.colors = true; | ||
this.autoWatch = false; | ||
this.reporters = ['progress']; | ||
this.singleRun = false; | ||
this.browsers = []; | ||
this.captureTimeout = 60000; | ||
this.proxies = {}; | ||
this.proxyValidateSSL = true; | ||
this.preprocessors = {'**/*.coffee': 'coffee'}; | ||
this.urlRoot = '/'; | ||
this.reportSlowerThan = 0; | ||
this.loggers = [constant.CONSOLE_APPENDER]; | ||
this.transports = ['websocket', 'flashsocket', 'xhr-polling', 'jsonp-polling']; | ||
this.plugins = ['karma-*']; | ||
// TODO(vojta): remove in 0.10 | ||
this.junitReporter = { | ||
outputFile: 'test-results.xml', | ||
suite: '' | ||
}; | ||
// TODO(vojta): remove in 0.10 | ||
this.coverageReporter = { | ||
type: 'html', | ||
dir: 'coverage' | ||
}; | ||
}; | ||
var CONFIG_SYNTAX_HELP = ' module.exports = function(config) {\n' + | ||
' config.set({\n' + | ||
' // your config\n' + | ||
' });\n' + | ||
' };\n'; | ||
var parseConfig = function(configFilePath, cliOptions) { | ||
@@ -218,6 +300,6 @@ var configModule; | ||
} catch(e) { | ||
if (e.code === 'MODULE_NOT_FOUND') { | ||
log.error('Config file does not exist!'); | ||
if (e.code === 'MODULE_NOT_FOUND' && e.message.indexOf(configFilePath) !== -1) { | ||
log.error('File %s does not exist!', configFilePath); | ||
} else { | ||
log.error('Invalid config file!\n', e); | ||
log.error('Invalid config file!\n ' + e.stack); | ||
} | ||
@@ -227,3 +309,3 @@ return process.exit(1); | ||
if (!helper.isFunction(configModule)) { | ||
log.error('Config file must export a function!'); | ||
log.error('Config file must export a function!\n' + CONFIG_SYNTAX_HELP); | ||
return process.exit(1); | ||
@@ -236,39 +318,6 @@ } | ||
var config = { | ||
frameworks: [], | ||
port: constant.DEFAULT_PORT, | ||
runnerPort: constant.DEFAULT_RUNNER_PORT, | ||
hostname: constant.DEFAULT_HOSTNAME, | ||
basePath: '', | ||
files: [], | ||
exclude: [], | ||
logLevel: constant.LOG_INFO, | ||
colors: true, | ||
autoWatch: false, | ||
reporters: ['progress'], | ||
singleRun: false, | ||
browsers: [], | ||
captureTimeout: 60000, | ||
proxies: {}, | ||
proxyValidateSSL: true, | ||
preprocessors: {'**/*.coffee': 'coffee'}, | ||
urlRoot: '/', | ||
reportSlowerThan: 0, | ||
// TODO(vojta): remove | ||
junitReporter: { | ||
outputFile: 'test-results.xml', | ||
suite: '' | ||
}, | ||
// TODO(vojta): remove | ||
coverageReporter: { | ||
type: 'html', | ||
dir: 'coverage/' | ||
}, | ||
loggers: [ constant.CONSOLE_APPENDER ], | ||
transports: [ 'websocket', 'flashsocket', 'xhr-polling', 'jsonp-polling' ], | ||
plugins: [ 'karma-*' ] | ||
}; | ||
var dsl = new KarmaDsl(config); | ||
var config = new Config(); | ||
try { | ||
configModule(dsl); | ||
configModule(config); | ||
} catch(e) { | ||
@@ -280,3 +329,3 @@ log.error('Error in config file!\n', e); | ||
// merge the config from config file and cliOptions (precendense) | ||
dsl.configure(cliOptions); | ||
config.set(cliOptions); | ||
@@ -283,0 +332,0 @@ // configure the logger as soon as we can |
@@ -27,4 +27,9 @@ var log = require('./logger').create('launcher'); | ||
} catch (e) { | ||
// TODO(vojta): throw other exceptions (dep not provided, etc.) | ||
log.warn('Launcher "%s" is not registered!', name); | ||
if (e.message.indexOf('No provider for "launcher:' + name + '"') !== -1) { | ||
log.warn('Can not load "%s", it is not registered!\n ' + | ||
'Perhaps you are missing some plugin?', name); | ||
} else { | ||
log.warn('Can not load "%s"!\n ' + e.stack, name); | ||
} | ||
return; | ||
@@ -31,0 +36,0 @@ } |
@@ -14,5 +14,6 @@ var fs = require('graceful-fs'); | ||
// TODO(vojta): instantiate preprocessors at the start to show warnings immediately | ||
var createPreprocessor = function(config, basePath, injector) { | ||
var patterns = Object.keys(config); | ||
var alreadyDisplayedWarnings = Object.create(null); | ||
@@ -30,8 +31,18 @@ return function(file, done) { | ||
}; | ||
var instantiatePreprocessor = function(preprocessorName) { | ||
var instantiatePreprocessor = function(name) { | ||
if (alreadyDisplayedWarnings[name]) { | ||
return; | ||
} | ||
try { | ||
preprocessors.push(injector.get('preprocessor:' + preprocessorName)); | ||
preprocessors.push(injector.get('preprocessor:' + name)); | ||
} catch (e) { | ||
// TODO(vojta): log warning only once per each preprocessor | ||
log.warn('Pre-processor "%s" is not registered!', preprocessorName); | ||
if (e.message.indexOf('No provider for "preprocessor:' + name + '"') !== -1) { | ||
log.warn('Can not load "%s", it is not registered!\n ' + | ||
'Perhaps you are missing some plugin?', name); | ||
} else { | ||
log.warn('Can not load "%s"!\n ' + e.stack, name); | ||
} | ||
alreadyDisplayedWarnings[name] = true; | ||
} | ||
@@ -38,0 +49,0 @@ }; |
@@ -52,3 +52,8 @@ var helper = require('./helper'); | ||
} catch(e) { | ||
log.warn('Reporter "%s" is not registered!', name); | ||
if (e.message.indexOf('No provider for "reporter:' + name + '"') !== -1) { | ||
log.warn('Can not load "%s", it is not registered!\n ' + | ||
'Perhaps you are missing some plugin?', name); | ||
} else { | ||
log.warn('Can not load "%s"!\n ' + e.stack, name); | ||
} | ||
} | ||
@@ -55,0 +60,0 @@ }); |
@@ -26,24 +26,18 @@ { | ||
"Shyam Seshadri <shyamseshadri@gmail.com>", | ||
"Kim Joar Bekkelund <kjbekkelund@gmail.com>", | ||
"Ilya Volodin <ivolodin@vistaprint.com>", | ||
"Iristyle <Iristyle@github>", | ||
"pavelgj <pavelgj@gmail.com>", | ||
"Andrew Martin <sublimino@gmail.com>", | ||
"Daniel Aleksandersen <code@daniel.priv.no>", | ||
"Iristyle <Iristyle@github>", | ||
"Kim Joar Bekkelund <kjbekkelund@gmail.com>", | ||
"Marcello Nuccio <marcello.nuccio@gmail.com>", | ||
"pavelgj <pavelgj@gmail.com>", | ||
"Igor Minar <iiminar@gmail.com>", | ||
"ngiebel <ngiebel@starkinvestments.com>", | ||
"Roarke Gaskill <roarke.gaskill@gmail.com>", | ||
"Bulat Shakirzyanov <mallluhuct@gmail.com>", | ||
"Tim Cuthbertson <tim@gfxmonk.net>", | ||
"rdodev <rubenoz@gmail.com>", | ||
"Ethan J. Brown <ethan_j_brown@hotmail.com>", | ||
"Hugues Malphettes <hmalphettes@gmail.com>", | ||
"Igor Minar <iiminar@gmail.com>", | ||
"Tim Cuthbertson <tim@gfxmonk.net>", | ||
"ngiebel <ngiebel@starkinvestments.com>", | ||
"rdodev <rubenoz@gmail.com>", | ||
"Eldar Jafarov <djkojb@gmail.com>", | ||
"James Ford <jford@psyked.co.uk>", | ||
"James Shore <jshore@jamesshore.com>", | ||
"Kevin Ortman <kevin_ortman@msn.com>", | ||
"Dillon <mdillon@reachmail.com>", | ||
"David Souther <davidsouther@gmail.com>", | ||
"David Jensen <david@frode.(none)>", | ||
"Andy Joslin <andytjoslin@gmail.com>", | ||
"Marko Anastasov <marko@renderedtext.com>", | ||
@@ -59,6 +53,5 @@ "Merrick Christensen <merrick.christensen@gmail.com>", | ||
"Pete Swan <pete@indabamusic.com>", | ||
"Alexander Shtuchkin <ashtuchkin@gmail.com>", | ||
"Chad Smith <chad@configit.com>", | ||
"Brian Ford <btford@umich.edu>", | ||
"Veronica Lynn <veronica.lynn@redjack.com>", | ||
"AvnerCohen <israbirding@gmail.com>", | ||
"Brian Ford <btford@umich.edu>", | ||
"Yi Wang <e@yi-wang.me>", | ||
@@ -68,7 +61,15 @@ "ahaurw01 <ahaurwitz@gmail.com>", | ||
"hrgdavor <hrgdavor@gmail.com>", | ||
"lanshunfang <lanshunfang@gmail.com>", | ||
"David Jensen <david@frode.(none)>", | ||
"David Souther <davidsouther@gmail.com>", | ||
"Dillon <mdillon@reachmail.com>", | ||
"Eldar Jafarov <djkojb@gmail.com>", | ||
"Ed Rooth <ed.rooth@rackspace.com>", | ||
"Fred Sauer <fredsa@google.com>", | ||
"lanshunfang <lanshunfang@gmail.com>", | ||
"Chad Smith <chad@configit.com>", | ||
"Igor Minar <igor@angularjs.org>", | ||
"Andy Joslin <andytjoslin@gmail.com>", | ||
"Ed Rooth <ed.rooth@rackspace.com>" | ||
"Alexander Shtuchkin <ashtuchkin@gmail.com>", | ||
"James Ford <jford@psyked.co.uk>", | ||
"James Shore <jshore@jamesshore.com>", | ||
"Kevin Ortman <kevin_ortman@msn.com>" | ||
], | ||
@@ -145,3 +146,3 @@ "dependencies": { | ||
}, | ||
"version": "0.9.3" | ||
"version": "0.9.4" | ||
} |
137842
2727