Skip to content

Commit

Permalink
Core: Implements QUnit.skip
Browse files Browse the repository at this point in the history
Also logs skipped tests on testDone callback that are handled on
the html reporter

Fixes qunitjs#637
Fixes qunitjs#434
Closes qunitjs#652
  • Loading branch information
leobalter committed Sep 11, 2014
1 parent be3dce3 commit 3f08a1a
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 61 deletions.
27 changes: 17 additions & 10 deletions reporter/html.js
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,7 @@ QUnit.log(function( details ) {

QUnit.testDone(function( details ) {
var testTitle, time, testItem, assertList,
good, bad, testCounts,
good, bad, testCounts, skipped,
tests = id( "qunit-tests" );

// QUnit.reset() is deprecated and will be replaced for a new
Expand Down Expand Up @@ -661,17 +661,24 @@ QUnit.testDone(function( details ) {
testTitle.innerHTML += " <b class='counts'>(" + testCounts +
details.assertions.length + ")</b>";

addEvent( testTitle, "click", function() {
toggleClass( assertList, "qunit-collapsed" );
});

time = document.createElement( "span" );
time.className = "runtime";
time.innerHTML = details.runtime + " ms";
if ( details.skipped ) {
addClass( testItem, "skipped" );
skipped = document.createElement( "em" );
skipped.className = "qunit-skipped-label";
skipped.innerHTML = "skipped";
testItem.insertBefore( skipped, testTitle );
} else {
addEvent( testTitle, "click", function() {
toggleClass( assertList, "qunit-collapsed" );
});

testItem.className = bad ? "fail" : "pass";
testItem.className = bad ? "fail" : "pass";

testItem.insertBefore( time, assertList );
time = document.createElement( "span" );
time.className = "runtime";
time.innerHTML = details.runtime + " ms";
testItem.insertBefore( time, assertList );
}
});

if ( !defined.document || document.readyState === "complete" ) {
Expand Down
59 changes: 10 additions & 49 deletions src/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,15 +120,17 @@ QUnit = {
testName: testName,
expected: expected,
async: async,
callback: callback,
module: config.currentModule,
moduleTestEnvironment: config.currentModuleTestEnvironment,
stack: sourceFromStacktrace( 2 )
callback: callback
});

if ( !validTest( test ) ) {
return;
}
test.queue();
},

skip: function( testName ) {
var test = new Test({
testName: testName,
skip: true
});

test.queue();
},
Expand Down Expand Up @@ -436,7 +438,7 @@ window.onerror = function( error, filePath, linerNr ) {
} else {
QUnit.test( "global failure", extend(function() {
QUnit.pushFailure( error, filePath + ":" + linerNr );
}, { validTest: validTest } ) );
}, { validTest: true } ) );
}
return false;
}
Expand Down Expand Up @@ -470,47 +472,6 @@ function done() {
});
}

/** @return Boolean: true if this test should be ran */
function validTest( test ) {
var include,
filter = config.filter && config.filter.toLowerCase(),
module = config.module && config.module.toLowerCase(),
fullName = ( test.module + ": " + test.testName ).toLowerCase();

// Internally-generated tests are always valid
if ( test.callback && test.callback.validTest === validTest ) {
delete test.callback.validTest;
return true;
}

if ( config.testNumber.length > 0 ) {
if ( inArray( test.testNumber, config.testNumber ) < 0 ) {
return false;
}
}

if ( module && ( !test.module || test.module.toLowerCase() !== module ) ) {
return false;
}

if ( !filter ) {
return true;
}

include = filter.charAt( 0 ) !== "!";
if ( !include ) {
filter = filter.slice( 1 );
}

// If the filter matches, we need to honour include
if ( fullName.indexOf( filter ) !== -1 ) {
return include;
}

// Otherwise, do the opposite
return !include;
}

// Doesn't support IE6 to IE9
// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack
function extractStacktrace( e, offset ) {
Expand Down
19 changes: 19 additions & 0 deletions src/qunit.css
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@
cursor: pointer;
}

#qunit-tests li.skipped strong {
cursor: default;
}

#qunit-tests li a {
padding: 0.5em;
color: #C2CCD1;
Expand Down Expand Up @@ -211,6 +215,21 @@

#qunit-banner.qunit-fail { background-color: #EE5757; }

/*** Skipped tests */

#qunit-tests .skipped {
background-color: #EBECE9;
}

#qunit-tests .qunit-skipped-label {
background-color: #F4FF77;
display: inline-block;
font-style: normal;
color: #366097;
line-height: 1.8em;
padding: 0 0.5em;
margin: -0.4em 0.4em -0.4em 0;
}

/** Result */

Expand Down
61 changes: 60 additions & 1 deletion src/test.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
function Test( settings ) {
extend( this, settings );
this.assert = new Assert( this );
this.assertions = [];
this.testNumber = ++Test.count;
this.semaphore = 0;
this.module = config.currentModule;
this.moduleTestEnvironment = config.currentModuleTestEnvironment;
this.stack = sourceFromStacktrace( 3 );

if ( settings.skip ) {

// Skipped tests will fully ignore any sent callback
this.callback = function() {};
this.async = false;
this.expected = 0;
} else {
this.assert = new Assert( this );
}
}

Test.count = 0;
Expand Down Expand Up @@ -114,6 +126,11 @@ Test.prototype = {
hooks: function( handler ) {
var hooks = [];

// Hooks are also ignored on skipped tests
if ( this.skip ) {
return hooks;
}

if ( QUnit.objectType( config[ handler ] ) === "function" ) {
hooks.push( this.queueHook( config[ handler ], handler ) );
}
Expand Down Expand Up @@ -152,6 +169,7 @@ Test.prototype = {
runLoggingCallbacks( "testDone", {
name: this.testName,
module: this.module,
skipped: !!this.skip,
failed: bad,
passed: this.assertions.length - bad,
total: this.assertions.length,
Expand All @@ -172,6 +190,10 @@ Test.prototype = {
var bad,
test = this;

if ( !this.valid() ) {
return;
}

function run() {

// each of these can by async
Expand Down Expand Up @@ -289,6 +311,43 @@ Test.prototype = {
);
}
}
},

valid: function() {
var include,
filter = config.filter && config.filter.toLowerCase(),
module = config.module && config.module.toLowerCase(),
fullName = ( this.module + ": " + this.testName ).toLowerCase();

// Internally-generated tests are always valid
if ( this.callback && this.callback.validTest ) {
return true;
}

if ( config.testNumber.length > 0 && inArray( this.testNumber, config.testNumber ) < 0 ) {
return false;
}

if ( module && ( !this.module || this.module.toLowerCase() !== module ) ) {
return false;
}

if ( !filter ) {
return true;
}

include = filter.charAt( 0 ) !== "!";
if ( !include ) {
filter = filter.slice( 1 );
}

// If the filter matches, we need to honour include
if ( fullName.indexOf( filter ) !== -1 ) {
return include;
}

// Otherwise, do the opposite
return !include;
}

};
Expand Down
23 changes: 22 additions & 1 deletion test/logs.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@ QUnit.test( "test2", function( assert ) {
failed: 0,
passed: 17,
total: 17,
testNumber: 1
testNumber: 1,
skipped: false
}, "testDone context" );
assert.deepEqual( testContext, {
module: "logs1",
Expand Down Expand Up @@ -219,6 +220,26 @@ QUnit.test( "test2", function( assert ) {
assert.equal( log, 46, "QUnit.log calls" );
});

QUnit.skip( "a skipped test" );

QUnit.test( "test the log for the skipped test", function( assert ) {
assert.expect( 1 );

delete testDoneContext.runtime;
delete testDoneContext.duration;

assert.deepEqual( testDoneContext, {
assertions: [],
module: "logs2",
name: "a skipped test",
failed: 0,
passed: 0,
total: 0,
testNumber: 5,
skipped: true
}, "testDone context" );
});

testAutorun = true;

QUnit.done(function() {
Expand Down
22 changes: 22 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -399,3 +399,25 @@ QUnit.test( "mod2", function( assert ) {
assert.mod2( 2, 0, "2 % 2 == 0" );
assert.mod2( 3, 1, "3 % 2 == 1" );
});

QUnit.module( "QUnit.skip", {
beforeEach: function( assert ) {

// skip test hooks for skipped tests
assert.ok( false, "skipped function" );
throw "Error";
},
afterEach: function( assert ) {
assert.ok( false, "skipped function" );
throw "Error";
}
});

QUnit.skip( "test blocks are skipped", function( assert ) {

// this test callback won't run, even with broken code
assert.expect( 1000 );
throw "Error";
});

QUnit.skip( "no function" );

0 comments on commit 3f08a1a

Please sign in to comment.