grunt-contrib-qunit
Advanced tools
Comparing version 1.2.0 to 1.3.0
{ | ||
"name": "grunt-contrib-qunit", | ||
"description": "Run QUnit unit tests in a headless PhantomJS instance", | ||
"version": "1.2.0", | ||
"version": "1.3.0", | ||
"author": { | ||
@@ -16,3 +16,3 @@ "name": "Grunt Team", | ||
"scripts": { | ||
"test": "grunt test --stack && grunt connect qunit:modules --modules=\"module1\"" | ||
"test": "grunt test --stack" | ||
}, | ||
@@ -28,2 +28,3 @@ "dependencies": { | ||
"grunt-contrib-jshint": "^1.0.0", | ||
"grunt-shell": "^1.3.0", | ||
"qunitjs": "^1.20.0" | ||
@@ -30,0 +31,0 @@ }, |
@@ -49,3 +49,3 @@ /* | ||
// Send it. | ||
sendMessage('qunit.log', obj.result, actual, expected, obj.message, obj.source); | ||
sendMessage('qunit.log', obj.result, actual, expected, obj.message, obj.source, obj.todo); | ||
}); | ||
@@ -58,3 +58,3 @@ | ||
QUnit.testDone(function(obj) { | ||
sendMessage('qunit.testDone', obj.name, obj.failed, obj.passed, obj.total, obj.duration); | ||
sendMessage('qunit.testDone', obj.name, obj.failed, obj.passed, obj.total, obj.runtime, obj.skipped, obj.todo); | ||
}); | ||
@@ -61,0 +61,0 @@ |
@@ -1,2 +0,2 @@ | ||
# grunt-contrib-qunit v1.2.0 [![Build Status: Linux](https://travis-ci.org/gruntjs/grunt-contrib-qunit.svg?branch=master)](https://travis-ci.org/gruntjs/grunt-contrib-qunit) [![Build Status: Windows](https://ci.appveyor.com/api/projects/status/3vd43779joyj6qji/branch/master?svg=true)](https://ci.appveyor.com/project/gruntjs/grunt-contrib-qunit/branch/master) | ||
# grunt-contrib-qunit v1.3.0 [![Build Status: Linux](https://travis-ci.org/gruntjs/grunt-contrib-qunit.svg?branch=master)](https://travis-ci.org/gruntjs/grunt-contrib-qunit) [![Build Status: Windows](https://ci.appveyor.com/api/projects/status/3vd43779joyj6qji/branch/master?svg=true)](https://ci.appveyor.com/project/gruntjs/grunt-contrib-qunit/branch/master) | ||
@@ -103,8 +103,18 @@ > Run QUnit unit tests in a headless PhantomJS instance | ||
### Filtering specs | ||
### Command line options | ||
**Filtering by module name**: | ||
#### Filtering by module name: `--modules` | ||
`grunt qunit --modules=foo` will run the module `foo`. You can specify one or multiple, comma-separated modules to run. | ||
`grunt qunit --modules="foo"` | ||
Will run the module `foo`. You can specify one or multiple, comma-separated modules to run. | ||
#### Running tests in seeded-random order: `--seed` | ||
`grunt qunit --seed="a-string"` | ||
Specify the seed to pass to QUnit, to run tests in random, but deterministic order. See [`QUnit.config.seed`](https://api.qunitjs.com/QUnit.config/) docs for more information. | ||
_Note: You must be using `QUnit` version `1.23.0` or greater for these features to work properly._ | ||
### Usage examples | ||
@@ -188,3 +198,3 @@ | ||
[PhantomJS API Reference]: https://github.com/ariya/phantomjs/wiki/API-Reference | ||
[PhantomJS API Reference]: http://phantomjs.org/api | ||
@@ -239,2 +249,3 @@ ```js | ||
* 2017-02-07 v1.3.0 Add ability to run tests in seeded-random order through `--seed` flag Add note about min version of QUnit required to use the CLI flags Implement support for todo tests and revamp reporting logic (#137) | ||
* 2016-04-14 v1.2.0 Add support for filtering running modules using command line (--modules) Removed 'grunt.warn' output from `error.onError` handler, onus now on end user binding to event. Update docs. | ||
@@ -263,2 +274,2 @@ * 2016-03-11 v1.1.0 Adding support for 'summaryOnly'. Fix `options.force`. Fix query string for `noGlobals`. Update docs. | ||
*This file was generated on Thu Apr 14 2016 16:23:00.* | ||
*This file was generated on Tue Feb 07 2017 10:51:07.* |
@@ -20,4 +20,6 @@ /* | ||
// Keep track of the last-started module, test and status. | ||
var options, currentModule, currentTest, status; | ||
// Keep track of the last-started module and test. Additionally, keep track | ||
// of status for individual test files and the entire test suite. | ||
var options, currentModule, currentTest, currentStatus, status; | ||
// Keep track of the last-started test(s). | ||
@@ -66,2 +68,50 @@ var unfinished = {}; | ||
}; | ||
var createStatus = function() { | ||
return { | ||
passed: 0, | ||
failed: 0, | ||
skipped: 0, | ||
todo: 0, | ||
runtime: 0, | ||
assertions: { | ||
passed: 0, | ||
failed: 0 | ||
} | ||
}; | ||
}; | ||
var mergeStatus = function(statusA, statusB) { | ||
statusA.passed += statusB.passed; | ||
statusA.failed += statusB.failed; | ||
statusA.skipped += statusB.skipped; | ||
statusA.todo += statusB.todo; | ||
statusA.runtime += statusB.runtime; | ||
statusA.assertions.passed += statusB.assertions.passed; | ||
statusA.assertions.failed += statusB.assertions.failed; | ||
}; | ||
var generateMessage = function(status) { | ||
var totalTests = status.passed + status.failed + status.skipped + status.todo; | ||
var totalAssertions = status.assertions.passed + status.assertions.failed; | ||
return [ | ||
totalTests, | ||
" tests completed with ", | ||
status.failed, | ||
" failed, " + | ||
status.skipped, | ||
" skipped, and ", | ||
status.todo, | ||
" todo. \n" + | ||
totalAssertions, | ||
" assertions (in ", | ||
status.runtime, | ||
"ms), passed: " + | ||
status.assertions.passed, | ||
", failed: ", | ||
status.assertions.failed | ||
].join( "" ); | ||
}; | ||
// Copied from QUnit source code | ||
@@ -92,2 +142,6 @@ var generateHash = function(module) { | ||
// QUnit hooks. | ||
phantomjs.on('qunit.begin', function() { | ||
currentStatus = createStatus(); | ||
}); | ||
phantomjs.on('qunit.moduleStart', function(name) { | ||
@@ -102,6 +156,9 @@ unfinished[name] = true; | ||
phantomjs.on('qunit.log', function(result, actual, expected, message, source) { | ||
if (!result) { | ||
phantomjs.on('qunit.log', function(result, actual, expected, message, source, todo) { | ||
if (!result && !todo) { | ||
failedAssertions.push({ | ||
actual: actual, expected: expected, message: message, source: source, | ||
actual: actual, | ||
expected: expected, | ||
message: message, | ||
source: source, | ||
testName: currentTest | ||
@@ -117,9 +174,26 @@ }); | ||
phantomjs.on('qunit.testDone', function(name, failed/*, passed, total*/) { | ||
phantomjs.on('qunit.testDone', function(name, failed, passed, total, runtime, skipped, todo) { | ||
var testPassed = failed > 0 ? todo : !todo; | ||
if (skipped) { | ||
currentStatus.skipped++; | ||
} else if (!testPassed) { | ||
currentStatus.failed++; | ||
} else if (todo) { | ||
currentStatus.todo++; | ||
} else { | ||
currentStatus.passed++; | ||
} | ||
// Log errors if necessary, otherwise success. | ||
if (failed > 0) { | ||
// list assertions | ||
if (!testPassed) { | ||
// list assertions or message about todo failure | ||
if (grunt.option('verbose')) { | ||
grunt.log.error(); | ||
logFailedAssertions(); | ||
if (todo) { | ||
grunt.log.error('Expected at least one failing assertion in todo test:' + name); | ||
} else { | ||
logFailedAssertions(); | ||
} | ||
} else { | ||
@@ -133,15 +207,14 @@ grunt.log.write('F'.red); | ||
phantomjs.on('qunit.done', function(failed, passed, total, duration) { | ||
phantomjs.on('qunit.done', function(failed, passed, total, runtime) { | ||
phantomjs.halt(); | ||
status.failed += failed; | ||
status.passed += passed; | ||
status.total += total; | ||
status.duration += duration; | ||
currentStatus.runtime += runtime; | ||
currentStatus.assertions.passed += passed; | ||
currentStatus.assertions.failed += failed; | ||
// Print assertion errors here, if verbose mode is disabled. | ||
if (!grunt.option('verbose')) { | ||
if (failed > 0) { | ||
if (currentStatus.failed > 0) { | ||
grunt.log.writeln(); | ||
logFailedAssertions(); | ||
} else if (total === 0) { | ||
warnUnlessForced('0/0 assertions ran (' + duration + 'ms)'); | ||
} else { | ||
@@ -151,2 +224,4 @@ grunt.log.ok(); | ||
} | ||
mergeStatus(status, currentStatus); | ||
}); | ||
@@ -166,4 +241,4 @@ | ||
grunt.log.error('PhantomJS unable to load "' + url + '" URI.'); | ||
status.failed += 1; | ||
status.total += 1; | ||
}); | ||
@@ -178,4 +253,4 @@ | ||
'- Or, a misconfiguration of this task.'); | ||
status.failed += 1; | ||
status.total += 1; | ||
}); | ||
@@ -218,11 +293,15 @@ | ||
var parsed; | ||
if (options.noGlobals) { | ||
// Append a noglobal query string param to all urls | ||
var appendToUrls = function(queryParam, value) { | ||
// Append the query param to all urls | ||
urls = urls.map(function(testUrl) { | ||
parsed = url.parse(testUrl, true); | ||
parsed.query.noglobals = 'true'; | ||
var parsed = url.parse(testUrl, true); | ||
parsed.query[queryParam] = value; | ||
delete parsed.search; | ||
return url.format(parsed); | ||
}); | ||
}; | ||
if (options.noGlobals) { | ||
// Append a noglobal query string param to all urls | ||
appendToUrls('noglobals', 'true'); | ||
} | ||
@@ -236,10 +315,10 @@ | ||
// Append moduleId to all urls | ||
urls = urls.map(function(testUrl) { | ||
parsed = url.parse(testUrl, true); | ||
parsed.query.moduleId = hashes; | ||
delete parsed.search; | ||
return url.format(parsed); | ||
}); | ||
appendToUrls('moduleId', hashes); | ||
} | ||
if (grunt.option('seed')) { | ||
// Append seed to all urls | ||
appendToUrls('seed', grunt.option('seed')); | ||
} | ||
// This task is asynchronous. | ||
@@ -249,3 +328,3 @@ var done = this.async(); | ||
// Reset status. | ||
status = {failed: 0, passed: 0, total: 0, duration: 0}; | ||
status = createStatus(); | ||
@@ -283,2 +362,3 @@ // Pass-through console.log statements. | ||
function() { | ||
var message = generateMessage(status); | ||
var success; | ||
@@ -288,9 +368,6 @@ | ||
if (status.failed > 0) { | ||
warnUnlessForced(status.failed + '/' + status.total + | ||
' assertions failed (' + status.duration + 'ms)'); | ||
} else if (status.total === 0) { | ||
warnUnlessForced('0/0 assertions ran (' + status.duration + 'ms)'); | ||
warnUnlessForced(message); | ||
} else { | ||
grunt.verbose.writeln(); | ||
grunt.log.ok(status.total + ' assertions passed (' + status.duration + 'ms)'); | ||
grunt.log.ok(message); | ||
} | ||
@@ -297,0 +374,0 @@ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
28254
378
272
0
7