127 lines
No EOL
4.9 KiB
JavaScript
127 lines
No EOL
4.9 KiB
JavaScript
/**
|
|
*
|
|
* Often a project will want to encapsulate custom matching code for use across multiple specs. Here is how to create a Jasmine-compatible custom matcher.
|
|
*
|
|
* A custom matcher at its root is a comparison function that takes an `actual` value and `expected` value. This factory is passed to Jasmine, ideally in a call to `beforeEach` and will be in scope and available for all of the specs inside a given call to `describe`. Custom matchers are torn down between specs. The name of the factory will be the name of the matcher exposed on the return value of the call to `expect`.
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* This object has a custom matcher named "toBeGoofy".
|
|
*/
|
|
var customMatchers = {
|
|
|
|
/**
|
|
* ## Matcher Factories
|
|
*
|
|
* Custom matcher factories are passed a `matchersUtil` parameter, which has a set
|
|
* of utility functions for matchers to use to perform tasks like determining
|
|
* whether two objects are equal
|
|
* (see: [`MatchersUtil`][MatchersUtil] for reference documentation). By using
|
|
* `MatchersUtil` where appropriate, custom matchers can work with
|
|
* [custom equality testers][CustomEqualityTesters] and
|
|
* [custom object formatters][CustomObjectFormatters] without any extra effort.
|
|
*
|
|
* A second `customEqualityTesters` parameter is passed for compatibility with
|
|
* Jasmine 3.5 and earlier. Matchers written for Jasmine 3.6 and later should
|
|
* ignore it. It will no longer be provided in Jasmine 4.
|
|
*
|
|
* [MatchersUtil]: /api/edge/MatchersUtil.html
|
|
* [CustomEqualityTesters]: /tutorials/custom_equality
|
|
* [CustomObjectFormatters]: /tutorials/custom_object_formatters
|
|
*/
|
|
toBeGoofy: function(matchersUtil) {
|
|
/**
|
|
* The factory method should return an object with a `compare` function that will be called to check the expectation.
|
|
*/
|
|
return {
|
|
/**
|
|
* ## A Function to `compare`
|
|
*
|
|
* The compare function receives the value passed to `expect()` as the first argument - the actual - and the value (if any) passed to the matcher itself as second argument.
|
|
*/
|
|
compare: function(actual, expected) {
|
|
|
|
/**
|
|
* `toBeGoofy` takes an optional `expected` argument, so define it here if not passed in.
|
|
*/
|
|
if (expected === undefined) {
|
|
expected = '';
|
|
}
|
|
|
|
/**
|
|
* ### Result
|
|
*
|
|
* The `compare` function must return a result object with a `pass` property that is a boolean result of the matcher. The `pass` property tells the expectation whether the matcher was successful (`true`) or unsuccessful (`false`). If the expectation is called/chained with `.not`, the expectation will negate this to determine whether the expectation is met.
|
|
*/
|
|
var result = {};
|
|
|
|
/**
|
|
* `toBeGoofy` tests for equality of the actual's `hyuk` property to see if it matches the expectation.
|
|
*/
|
|
result.pass = matchersUtil.equals(actual.hyuk, "gawrsh" + expected);
|
|
|
|
/**
|
|
* ### Failure Messages
|
|
*
|
|
* If left `undefined`, the expectation will attempt to craft a failure message for the matcher. However, if the return value has a `message` property it will be used for a failed expectation.
|
|
*/
|
|
if (result.pass) {
|
|
/**
|
|
* The matcher succeeded, so the custom failure message should be present in the case of a negative expectation - when the expectation is used with `.not`.
|
|
*/
|
|
result.message = "Expected " + actual + " not to be quite so goofy";
|
|
} else {
|
|
/**
|
|
* The matcher failed, so the custom failure message should be present in the case of a positive expectation
|
|
*/
|
|
result.message = "Expected " + actual + " to be goofy, but it was not very goofy";
|
|
}
|
|
|
|
/**
|
|
* Return the result of the comparison.
|
|
*/
|
|
return result;
|
|
}
|
|
};
|
|
}
|
|
};
|
|
|
|
/**
|
|
* ### Custom negative comparators
|
|
*
|
|
* If you need more control over the negative comparison (the `not` case) than the simple boolean inversion above, you can also have your matcher factory include another key, `negativeCompare` alongside `compare`, for which the value is a function to invoke when `.not` is used. This function/key is optional.
|
|
*/
|
|
|
|
/**
|
|
* ## Registration and Usage
|
|
*/
|
|
describe("Custom matcher: 'toBeGoofy'", function() {
|
|
/**
|
|
* Register the custom matchers with Jasmine. All properties on the object passed in will be available as custom matchers (e.g., in this case `toBeGoofy`).
|
|
*/
|
|
beforeEach(function() {
|
|
jasmine.addMatchers(customMatchers);
|
|
});
|
|
|
|
/**
|
|
* Once a custom matcher is registered with Jasmine, it is available on any expectation.
|
|
*/
|
|
it("is available on an expectation", function() {
|
|
expect({
|
|
hyuk: 'gawrsh'
|
|
}).toBeGoofy();
|
|
});
|
|
|
|
it("can take an 'expected' parameter", function() {
|
|
expect({
|
|
hyuk: 'gawrsh is fun'
|
|
}).toBeGoofy(' is fun');
|
|
});
|
|
|
|
it("can be negated", function() {
|
|
expect({
|
|
hyuk: 'this is fun'
|
|
}).not.toBeGoofy();
|
|
});
|
|
}); |