mermaid
Version:
Markdownish syntax for generating flowcharts, sequence diagrams and gantt charts.
180 lines (147 loc) • 5.5 kB
JavaScript
function Assert( testContext ) {
this.test = testContext;
}
// Assert helpers
QUnit.assert = Assert.prototype = {
// Specify the number of expected assertions to guarantee that failed test
// (no assertions are run at all) don't slip through.
expect: function( asserts ) {
if ( arguments.length === 1 ) {
this.test.expected = asserts;
} else {
return this.test.expected;
}
},
// Increment this Test's semaphore counter, then return a single-use function that
// decrements that counter a maximum of once.
async: function() {
var test = this.test,
popped = false;
test.semaphore += 1;
test.usedAsync = true;
pauseProcessing();
return function done() {
if ( !popped ) {
test.semaphore -= 1;
popped = true;
resumeProcessing();
} else {
test.pushFailure( "Called the callback returned from `assert.async` more than once",
sourceFromStacktrace( 2 ) );
}
};
},
// Exports test.push() to the user API
push: function( /* result, actual, expected, message */ ) {
var assert = this,
currentTest = ( assert instanceof Assert && assert.test ) || QUnit.config.current;
// Backwards compatibility fix.
// Allows the direct use of global exported assertions and QUnit.assert.*
// Although, it's use is not recommended as it can leak assertions
// to other tests from async tests, because we only get a reference to the current test,
// not exactly the test where assertion were intended to be called.
if ( !currentTest ) {
throw new Error( "assertion outside test context, in " + sourceFromStacktrace( 2 ) );
}
if ( currentTest.usedAsync === true && currentTest.semaphore === 0 ) {
currentTest.pushFailure( "Assertion after the final `assert.async` was resolved",
sourceFromStacktrace( 2 ) );
// Allow this assertion to continue running anyway...
}
if ( !( assert instanceof Assert ) ) {
assert = currentTest.assert;
}
return assert.test.push.apply( assert.test, arguments );
},
ok: function( result, message ) {
message = message || ( result ? "okay" : "failed, expected argument to be truthy, was: " +
QUnit.dump.parse( result ) );
this.push( !!result, result, true, message );
},
notOk: function( result, message ) {
message = message || ( !result ? "okay" : "failed, expected argument to be falsy, was: " +
QUnit.dump.parse( result ) );
this.push( !result, result, false, message );
},
equal: function( actual, expected, message ) {
/*jshint eqeqeq:false */
this.push( expected == actual, actual, expected, message );
},
notEqual: function( actual, expected, message ) {
/*jshint eqeqeq:false */
this.push( expected != actual, actual, expected, message );
},
propEqual: function( actual, expected, message ) {
actual = objectValues( actual );
expected = objectValues( expected );
this.push( QUnit.equiv( actual, expected ), actual, expected, message );
},
notPropEqual: function( actual, expected, message ) {
actual = objectValues( actual );
expected = objectValues( expected );
this.push( !QUnit.equiv( actual, expected ), actual, expected, message );
},
deepEqual: function( actual, expected, message ) {
this.push( QUnit.equiv( actual, expected ), actual, expected, message );
},
notDeepEqual: function( actual, expected, message ) {
this.push( !QUnit.equiv( actual, expected ), actual, expected, message );
},
strictEqual: function( actual, expected, message ) {
this.push( expected === actual, actual, expected, message );
},
notStrictEqual: function( actual, expected, message ) {
this.push( expected !== actual, actual, expected, message );
},
"throws": function( block, expected, message ) {
var actual, expectedType,
expectedOutput = expected,
ok = false,
currentTest = ( this instanceof Assert && this.test ) || QUnit.config.current;
// 'expected' is optional unless doing string comparison
if ( message == null && typeof expected === "string" ) {
message = expected;
expected = null;
}
currentTest.ignoreGlobalErrors = true;
try {
block.call( currentTest.testEnvironment );
} catch (e) {
actual = e;
}
currentTest.ignoreGlobalErrors = false;
if ( actual ) {
expectedType = QUnit.objectType( expected );
// we don't want to validate thrown error
if ( !expected ) {
ok = true;
expectedOutput = null;
// expected is a regexp
} else if ( expectedType === "regexp" ) {
ok = expected.test( errorString( actual ) );
// expected is a string
} else if ( expectedType === "string" ) {
ok = expected === errorString( actual );
// expected is a constructor, maybe an Error constructor
} else if ( expectedType === "function" && actual instanceof expected ) {
ok = true;
// expected is an Error object
} else if ( expectedType === "object" ) {
ok = actual instanceof expected.constructor &&
actual.name === expected.name &&
actual.message === expected.message;
// expected is a validation function which returns true if validation passed
} else if ( expectedType === "function" && expected.call( {}, actual ) === true ) {
expectedOutput = null;
ok = true;
}
}
currentTest.assert.push( ok, actual, expectedOutput, message );
}
};
// Provide an alternative to assert.throws(), for enviroments that consider throws a reserved word
// Known to us are: Closure Compiler, Narwhal
(function() {
/*jshint sub:true */
Assert.prototype.raises = Assert.prototype[ "throws" ];
}());