Skip to content

Instantly share code, notes, and snippets.

@scottrippey
Last active August 29, 2015 14:16
Show Gist options
  • Save scottrippey/ea962b6783809e54c1b0 to your computer and use it in GitHub Desktop.
Save scottrippey/ea962b6783809e54c1b0 to your computer and use it in GitHub Desktop.
Jasmine test cases - "these" - version 2 (supporting message templates)
describe("typeof", function() {
// You can pass in an object of test cases:
these("should output {1} when the input is ", {
"any number": [ 0, "number" ],
"NaN": [ NaN, "number" ],
"undefined": [ undefined, "undefined" ],
"null": [ null, "object" ],
"a Date": [ new Date(), "object" ],
"anon object": [ {}, "object" ],
"anon function": [ function(){}, "object" ],
}, function(input, expectedOutput) {
var actualOutput = typeof input;
expect(actualOutput).toBe(expectedOutput);
});
// Generates the following `it` statements:
// it("should output \"number\" when the input is any number", ...)
// it("should output \"number\" when the input is NaN", ...)
// ...
// it("should output \"object\" when the input is anon function", ...)
// You can pass in an array of test cases:
these("expects {0} to output {1}", [
[ 0, "number" ],
[ NaN, "number" ],
[ undefined, "undefined" ],
[ null, "object" ],
[ new Date(), "object" ],
[ {}, "object" ],
[ function(){}, "object" ],
], function(input, expectedOutput) {
var actualOutput = typeof input;
expect(actualOutput).toBe(expectedOutput);
});
// Generates the following `it` statements:
// it("expects 0 to output \"number\"", ...)
// it("expects NaN to output \"number\"", ...)
// ...
// it("expects function(){} to output \"object\", ...)
});
/**
* Creates a bunch of "it" blocks, one for each test case.
*
* @param {String} desc - Describes each test case
* @param {Object.<string, Array>|Array.<Array>} testCases
* @param {String} testCases.<key> - Describes the test case
* @param {Array} testCases.<value> - An array of args that will be passed to the test
* @param {Function} test - This test will be called once for each test case.
*/
function these(desc, testCases, test) {
_these(desc, testCases, test, it);
}
function xthese(desc, testCases, test) {
_these(desc, testCases, test, xit);
}
function _these(desc, testCases, test, it) {
if (Array.isArray(testCases)) {
testCases.forEach(function(testCaseArgs) {
var description = _getDescription(desc, testCaseArgs);
it(description, _getTestCallback(test, testCaseArgs));
});
} else {
Object.keys(testCases).forEach(function (testCaseName) {
var testCaseArgs = testCases[testCaseName];
var description = _getDescription(desc + testCaseName, testCaseArgs);
it(description, _getTestCallback(test, testCaseArgs));
});
}
}
function _getTestCallback(test, testCaseArgs) {
// The callback passed to `it` can contain a "done" parameter for async calls.
// Let's ensure we include that parameter here:
if (test.length === 0 ) {
return function() {
return test.apply(null, testCaseArgs);
};
} else {
return function(done) {
return test.apply(null, testCaseArgs.concat([ done ]) );
};
}
}
function _getDescription(desc, testCaseArgs) {
// Treat the description as a template, and replace {0} or {1} with arg[0] or arg[1]:
return desc.replace(/\{(\d+)\}/g, function($0, $1) {
var index = parseInt($1, 10);
if (index >= testCaseArgs.length) return $0; // Invalid index
var value = testCaseArgs[index];
var prettyResult =
// Values that don't look good with JSON.stringify:
(value === undefined) ? "undefined"
: (typeof value === 'function') ? (value.name || value.toString() ) // Print the function's name or body
: (typeof value === 'number') ? value.toString() // Works better for NaN or Infinity
: JSON.stringify(value);
return prettyResult;
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment