major matcher refactor

This commit is contained in:
Ryan Dy & Rajan Agaskar 2009-10-29 17:03:24 -07:00
parent 8b23698852
commit b67d2a265d
30 changed files with 3319 additions and 3098 deletions

View File

@ -260,7 +260,7 @@ ul.inheritsList
</div>
<div class="fineprint" style="clear:both">
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blankt">JsDoc Toolkit</a> 2.1.0 on Tue Oct 27 2009 21:17:03 GMT-0800 (PST)
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blankt">JsDoc Toolkit</a> 2.1.0 on Thu Oct 29 2009 16:58:08 GMT-0700 (PDT)
</div>
</body>
</html>

View File

@ -308,7 +308,7 @@ ul.inheritsList
</div>
<div class="fineprint" style="clear:both">
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blankt">JsDoc Toolkit</a> 2.1.0 on Tue Oct 27 2009 21:17:03 GMT-0800 (PST)
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blankt">JsDoc Toolkit</a> 2.1.0 on Thu Oct 29 2009 16:58:08 GMT-0700 (PDT)
</div>
</body>
</html>

View File

@ -910,7 +910,7 @@ A convenience method that allows existing specs to be disabled temporarily durin
<!-- ============================== footer ================================= -->
<div class="fineprint" style="clear:both">
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blank">JsDoc Toolkit</a> 2.1.0 on Tue Oct 27 2009 21:17:02 GMT-0800 (PST)
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blank">JsDoc Toolkit</a> 2.1.0 on Thu Oct 29 2009 16:58:08 GMT-0700 (PDT)
</div>
</body>
</html>

View File

@ -341,7 +341,7 @@ ul.inheritsList
<!-- ============================== footer ================================= -->
<div class="fineprint" style="clear:both">
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blank">JsDoc Toolkit</a> 2.1.0 on Tue Oct 27 2009 21:17:02 GMT-0800 (PST)
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blank">JsDoc Toolkit</a> 2.1.0 on Thu Oct 29 2009 16:58:08 GMT-0700 (PDT)
</div>
</body>
</html>

View File

@ -509,7 +509,7 @@ ul.inheritsList
<!-- ============================== footer ================================= -->
<div class="fineprint" style="clear:both">
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blank">JsDoc Toolkit</a> 2.1.0 on Tue Oct 27 2009 21:17:03 GMT-0800 (PST)
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blank">JsDoc Toolkit</a> 2.1.0 on Thu Oct 29 2009 16:58:08 GMT-0700 (PDT)
</div>
</body>
</html>

View File

@ -318,7 +318,7 @@ ul.inheritsList
<!-- ============================== footer ================================= -->
<div class="fineprint" style="clear:both">
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blank">JsDoc Toolkit</a> 2.1.0 on Tue Oct 27 2009 21:17:03 GMT-0800 (PST)
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blank">JsDoc Toolkit</a> 2.1.0 on Thu Oct 29 2009 16:58:08 GMT-0700 (PDT)
</div>
</body>
</html>

View File

@ -282,149 +282,14 @@ ul.inheritsList
<tbody>
<tr>
<td class="attributes">&nbsp;</td>
<td class="attributes">&lt;static&gt; &nbsp;</td>
<td class="nameDescription">
<div class="fixedFont"><b><a href="../symbols/jasmine.Matchers.html#toBe">toBe</a></b>(expected)
<div class="fixedFont">jasmine.Matchers.<b><a href="../symbols/jasmine.Matchers.html#.addMatcher">addMatcher</a></b>(expected, options)
</div>
<div class="description">Matcher that compares the actual to the expected using ===.</div>
</td>
</tr>
<tr>
<td class="attributes">&nbsp;</td>
<td class="nameDescription">
<div class="fixedFont"><b><a href="../symbols/jasmine.Matchers.html#toBeDefined">toBeDefined</a></b>()
</div>
<div class="description">Matcher that compares the acutal to undefined.</div>
</td>
</tr>
<tr>
<td class="attributes">&nbsp;</td>
<td class="nameDescription">
<div class="fixedFont"><b><a href="../symbols/jasmine.Matchers.html#toBeFalsy">toBeFalsy</a></b>()
</div>
<div class="description">Matcher that boolean nots the actual.</div>
</td>
</tr>
<tr>
<td class="attributes">&nbsp;</td>
<td class="nameDescription">
<div class="fixedFont"><b><a href="../symbols/jasmine.Matchers.html#toBeNull">toBeNull</a></b>()
</div>
<div class="description">Matcher that compares the actual to null.</div>
</td>
</tr>
<tr>
<td class="attributes">&nbsp;</td>
<td class="nameDescription">
<div class="fixedFont"><b><a href="../symbols/jasmine.Matchers.html#toBeTruthy">toBeTruthy</a></b>()
</div>
<div class="description">Matcher that boolean not-nots the actual.</div>
</td>
</tr>
<tr>
<td class="attributes">&nbsp;</td>
<td class="nameDescription">
<div class="fixedFont"><b><a href="../symbols/jasmine.Matchers.html#toContain">toContain</a></b>(item)
</div>
<div class="description">Matcher that checks that the expected item is an element in the actual Array.</div>
</td>
</tr>
<tr>
<td class="attributes">&nbsp;</td>
<td class="nameDescription">
<div class="fixedFont"><b><a href="../symbols/jasmine.Matchers.html#toEqual">toEqual</a></b>(expected)
</div>
<div class="description">Matcher that compares the actual to the expected using common sense equality.</div>
</td>
</tr>
<tr>
<td class="attributes">&nbsp;</td>
<td class="nameDescription">
<div class="fixedFont"><b><a href="../symbols/jasmine.Matchers.html#toMatch">toMatch</a></b>(reg_exp)
</div>
<div class="description">Matcher that compares the actual to the expected using a regular expression.</div>
</td>
</tr>
<tr>
<td class="attributes">&nbsp;</td>
<td class="nameDescription">
<div class="fixedFont"><b><a href="../symbols/jasmine.Matchers.html#toNotBe">toNotBe</a></b>(expected)
</div>
<div class="description">Matcher that compares the actual to the expected using !==</div>
</td>
</tr>
<tr>
<td class="attributes">&nbsp;</td>
<td class="nameDescription">
<div class="fixedFont"><b><a href="../symbols/jasmine.Matchers.html#toNotContain">toNotContain</a></b>(item)
</div>
<div class="description">Matcher that checks that the expected item is NOT an element in the actual Array.</div>
</td>
</tr>
<tr>
<td class="attributes">&nbsp;</td>
<td class="nameDescription">
<div class="fixedFont"><b><a href="../symbols/jasmine.Matchers.html#toNotEqual">toNotEqual</a></b>(expected)
</div>
<div class="description">Matcher that compares the actual to the expected using the ! of jasmine.Matchers.toEqual</div>
</td>
</tr>
<tr>
<td class="attributes">&nbsp;</td>
<td class="nameDescription">
<div class="fixedFont"><b><a href="../symbols/jasmine.Matchers.html#toNotMatch">toNotMatch</a></b>(reg_exp)
</div>
<div class="description">Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch</div>
</td>
</tr>
<tr>
<td class="attributes">&nbsp;</td>
<td class="nameDescription">
<div class="fixedFont"><b><a href="../symbols/jasmine.Matchers.html#toThrow">toThrow</a></b>(expectedException)
</div>
<div class="description">Matcher that checks that the expected exception was thrown by the actual.</div>
</td>
</tr>
<tr>
<td class="attributes">&nbsp;</td>
<td class="nameDescription">
<div class="fixedFont"><b><a href="../symbols/jasmine.Matchers.html#wasCalled">wasCalled</a></b>()
</div>
<div class="description">Matcher that checks to see if the acutal, a Jasmine spy, was called.</div>
</td>
</tr>
<tr>
<td class="attributes">&nbsp;</td>
<td class="nameDescription">
<div class="fixedFont"><b><a href="../symbols/jasmine.Matchers.html#wasCalledWith">wasCalledWith</a></b>()
</div>
<div class="description">Matcher that checks to see if the acutal, a Jasmine spy, was called with a set of parameters.</div>
</td>
</tr>
<tr>
<td class="attributes">&nbsp;</td>
<td class="nameDescription">
<div class="fixedFont"><b><a href="../symbols/jasmine.Matchers.html#wasNotCalled">wasNotCalled</a></b>()
</div>
<div class="description">Matcher that checks to see if the acutal, a Jasmine spy, was not called.</div>
</td>
</tr>
</tbody>
</table>
@ -496,11 +361,11 @@ ul.inheritsList
Method Detail
</div>
<a name="toBe"> </a>
<div class="fixedFont">
<a name=".addMatcher"> </a>
<div class="fixedFont">&lt;static&gt;
<b>toBe</b>(expected)
<span class="light">jasmine.Matchers.</span><b>addMatcher</b>(expected, options)
</div>
<div class="description">
@ -521,138 +386,8 @@ ul.inheritsList
</dt>
<dd></dd>
</dl>
<hr />
<a name="toBeDefined"> </a>
<div class="fixedFont">
<b>toBeDefined</b>()
</div>
<div class="description">
Matcher that compares the acutal to undefined.
</div>
<hr />
<a name="toBeFalsy"> </a>
<div class="fixedFont">
<b>toBeFalsy</b>()
</div>
<div class="description">
Matcher that boolean nots the actual.
</div>
<hr />
<a name="toBeNull"> </a>
<div class="fixedFont">
<b>toBeNull</b>()
</div>
<div class="description">
Matcher that compares the actual to null.
</div>
<hr />
<a name="toBeTruthy"> </a>
<div class="fixedFont">
<b>toBeTruthy</b>()
</div>
<div class="description">
Matcher that boolean not-nots the actual.
</div>
<hr />
<a name="toContain"> </a>
<div class="fixedFont">
<b>toContain</b>(item)
</div>
<div class="description">
Matcher that checks that the expected item is an element in the actual Array.
</div>
<dl class="detailList">
<dt class="heading">Parameters:</dt>
<dt>
<span class="light fixedFont">{Object}</span> <b>item</b>
<b>options</b>
</dt>
<dd></dd>
@ -666,338 +401,6 @@ ul.inheritsList
<hr />
<a name="toEqual"> </a>
<div class="fixedFont">
<b>toEqual</b>(expected)
</div>
<div class="description">
Matcher that compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc.
</div>
<dl class="detailList">
<dt class="heading">Parameters:</dt>
<dt>
<b>expected</b>
</dt>
<dd></dd>
</dl>
<hr />
<a name="toMatch"> </a>
<div class="fixedFont">
<b>toMatch</b>(reg_exp)
</div>
<div class="description">
Matcher that compares the actual to the expected using a regular expression. Constructs a RegExp, so takes
a pattern or a String.
</div>
<dl class="detailList">
<dt class="heading">Parameters:</dt>
<dt>
<b>reg_exp</b>
</dt>
<dd></dd>
</dl>
<hr />
<a name="toNotBe"> </a>
<div class="fixedFont">
<b>toNotBe</b>(expected)
</div>
<div class="description">
Matcher that compares the actual to the expected using !==
</div>
<dl class="detailList">
<dt class="heading">Parameters:</dt>
<dt>
<b>expected</b>
</dt>
<dd></dd>
</dl>
<hr />
<a name="toNotContain"> </a>
<div class="fixedFont">
<b>toNotContain</b>(item)
</div>
<div class="description">
Matcher that checks that the expected item is NOT an element in the actual Array.
</div>
<dl class="detailList">
<dt class="heading">Parameters:</dt>
<dt>
<span class="light fixedFont">{Object}</span> <b>item</b>
</dt>
<dd></dd>
</dl>
<hr />
<a name="toNotEqual"> </a>
<div class="fixedFont">
<b>toNotEqual</b>(expected)
</div>
<div class="description">
Matcher that compares the actual to the expected using the ! of jasmine.Matchers.toEqual
</div>
<dl class="detailList">
<dt class="heading">Parameters:</dt>
<dt>
<b>expected</b>
</dt>
<dd></dd>
</dl>
<hr />
<a name="toNotMatch"> </a>
<div class="fixedFont">
<b>toNotMatch</b>(reg_exp)
</div>
<div class="description">
Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch
</div>
<dl class="detailList">
<dt class="heading">Parameters:</dt>
<dt>
<b>reg_exp</b>
</dt>
<dd></dd>
</dl>
<hr />
<a name="toThrow"> </a>
<div class="fixedFont">
<b>toThrow</b>(expectedException)
</div>
<div class="description">
Matcher that checks that the expected exception was thrown by the actual.
</div>
<dl class="detailList">
<dt class="heading">Parameters:</dt>
<dt>
<span class="light fixedFont">{String}</span> <b>expectedException</b>
</dt>
<dd></dd>
</dl>
<hr />
<a name="wasCalled"> </a>
<div class="fixedFont">
<b>wasCalled</b>()
</div>
<div class="description">
Matcher that checks to see if the acutal, a Jasmine spy, was called.
</div>
<hr />
<a name="wasCalledWith"> </a>
<div class="fixedFont">
<b>wasCalledWith</b>()
</div>
<div class="description">
Matcher that checks to see if the acutal, a Jasmine spy, was called with a set of parameters.
</div>
<pre class="code"></pre>
<hr />
<a name="wasNotCalled"> </a>
<div class="fixedFont">
<b>wasNotCalled</b>()
</div>
<div class="description">
Matcher that checks to see if the acutal, a Jasmine spy, was not called.
</div>
@ -1012,7 +415,7 @@ a pattern or a String.
<!-- ============================== footer ================================= -->
<div class="fineprint" style="clear:both">
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blank">JsDoc Toolkit</a> 2.1.0 on Tue Oct 27 2009 21:17:03 GMT-0800 (PST)
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blank">JsDoc Toolkit</a> 2.1.0 on Thu Oct 29 2009 16:58:08 GMT-0700 (PDT)
</div>
</body>
</html>

View File

@ -318,7 +318,7 @@ ul.inheritsList
<!-- ============================== footer ================================= -->
<div class="fineprint" style="clear:both">
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blank">JsDoc Toolkit</a> 2.1.0 on Tue Oct 27 2009 21:17:03 GMT-0800 (PST)
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blank">JsDoc Toolkit</a> 2.1.0 on Thu Oct 29 2009 16:58:08 GMT-0700 (PDT)
</div>
</body>
</html>

View File

@ -702,7 +702,7 @@ ul.inheritsList
<!-- ============================== footer ================================= -->
<div class="fineprint" style="clear:both">
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blank">JsDoc Toolkit</a> 2.1.0 on Tue Oct 27 2009 21:17:03 GMT-0800 (PST)
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blank">JsDoc Toolkit</a> 2.1.0 on Thu Oct 29 2009 16:58:08 GMT-0700 (PDT)
</div>
</body>
</html>

View File

@ -318,7 +318,7 @@ ul.inheritsList
<!-- ============================== footer ================================= -->
<div class="fineprint" style="clear:both">
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blank">JsDoc Toolkit</a> 2.1.0 on Tue Oct 27 2009 21:17:03 GMT-0800 (PST)
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blank">JsDoc Toolkit</a> 2.1.0 on Thu Oct 29 2009 16:58:08 GMT-0700 (PDT)
</div>
</body>
</html>

View File

@ -329,7 +329,7 @@ ul.inheritsList
<!-- ============================== footer ================================= -->
<div class="fineprint" style="clear:both">
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blank">JsDoc Toolkit</a> 2.1.0 on Tue Oct 27 2009 21:17:03 GMT-0800 (PST)
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blank">JsDoc Toolkit</a> 2.1.0 on Thu Oct 29 2009 16:58:08 GMT-0700 (PDT)
</div>
</body>
</html>

View File

@ -341,7 +341,7 @@ ul.inheritsList
<!-- ============================== footer ================================= -->
<div class="fineprint" style="clear:both">
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blank">JsDoc Toolkit</a> 2.1.0 on Tue Oct 27 2009 21:17:03 GMT-0800 (PST)
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blank">JsDoc Toolkit</a> 2.1.0 on Thu Oct 29 2009 16:58:08 GMT-0700 (PDT)
</div>
</body>
</html>

View File

@ -847,7 +847,7 @@ expect(foo.bar.callCount).toEqual(0);</pre>
<!-- ============================== footer ================================= -->
<div class="fineprint" style="clear:both">
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blank">JsDoc Toolkit</a> 2.1.0 on Tue Oct 27 2009 21:17:03 GMT-0800 (PST)
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blank">JsDoc Toolkit</a> 2.1.0 on Thu Oct 29 2009 16:58:08 GMT-0700 (PDT)
</div>
</body>
</html>

View File

@ -347,7 +347,7 @@ ul.inheritsList
<!-- ============================== footer ================================= -->
<div class="fineprint" style="clear:both">
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blank">JsDoc Toolkit</a> 2.1.0 on Tue Oct 27 2009 21:17:03 GMT-0800 (PST)
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blank">JsDoc Toolkit</a> 2.1.0 on Thu Oct 29 2009 16:58:08 GMT-0700 (PDT)
</div>
</body>
</html>

View File

@ -278,6 +278,16 @@ ul.inheritsList
</thead>
<tbody>
<tr>
<td class="attributes">&lt;static&gt; &nbsp;</td>
<td class="nameDescription">
<div class="fixedFont">
jasmine.<b><a href="../symbols/jasmine.html#.details">details</a></b>
</div>
<div class="description"></div>
</td>
</tr>
<tr>
<td class="attributes">&lt;static&gt; &nbsp;</td>
<td class="nameDescription">
@ -418,6 +428,28 @@ Jasmine environment.</div>
Field Detail
</div>
<a name=".details"> </a>
<div class="fixedFont">&lt;static&gt;
<span class="light">jasmine.</span><b>details</b>
</div>
<div class="description">
</div>
<hr />
<a name=".UPDATE_INTERVAL"> </a>
<div class="fixedFont">&lt;static&gt;
@ -730,7 +762,7 @@ Jasmine environment.
<!-- ============================== footer ================================= -->
<div class="fineprint" style="clear:both">
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blank">JsDoc Toolkit</a> 2.1.0 on Tue Oct 27 2009 21:17:02 GMT-0800 (PST)
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blank">JsDoc Toolkit</a> 2.1.0 on Thu Oct 29 2009 16:58:08 GMT-0700 (PDT)
</div>
</body>
</html>

View File

@ -318,7 +318,7 @@ ul.inheritsList
<!-- ============================== footer ================================= -->
<div class="fineprint" style="clear:both">
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blank">JsDoc Toolkit</a> 2.1.0 on Tue Oct 27 2009 21:17:03 GMT-0800 (PST)
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blank">JsDoc Toolkit</a> 2.1.0 on Thu Oct 29 2009 16:58:08 GMT-0700 (PDT)
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@ -51,12 +51,18 @@ jasmine.MessageResult = function(text) {
this.trace = new Error(); // todo: test better
};
jasmine.ExpectationResult = function(passed, message, details) {
jasmine.ExpectationResult = function(params) {
this.type = 'ExpectationResult';
this.passed_ = passed;
this.message = message;
this.details = details;
this.trace = new Error(message); // todo: test better
this.matcherName = params.matcherName;
this.passed_ = params.passed;
this.expected = params.expected;
this.actual = params.actual;
/** @deprecated */
this.details = params.details;
this.message = this.passed_ ? 'Passed.' : params.message;
this.trace = this.passed_ ? '' : new Error(this.message);
};
jasmine.ExpectationResult.prototype.passed = function () {
@ -530,7 +536,7 @@ jasmine.version_= {
"major": 0,
"minor": 10,
"build": 0,
"revision": 1256707024
"revision": 1256860688
};
/**
* @namespace
@ -591,6 +597,11 @@ jasmine.util.argsToArray = function(args) {
return arrayOfArgs;
};
jasmine.util.extend = function(destination, source) {
for (var property in source) destination[property] = source[property];
return destination;
};
/**
* Environment for Jasmine
*
@ -738,18 +749,18 @@ jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchVal
for (var property in b) {
if (!hasKey(a, property) && hasKey(b, property)) {
mismatchKeys.push("expected has key '" + property + "', but missing from <b>actual</b>.");
mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
}
}
for (property in a) {
if (!hasKey(b, property) && hasKey(a, property)) {
mismatchKeys.push("<b>expected</b> missing key '" + property + "', but present in actual.");
mismatchKeys.push("expected missing key '" + property + "', but present in actual.");
}
}
for (property in b) {
if (property == '__Jasmine_been_here_before__') continue;
if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) {
mismatchValues.push("'" + property + "' was<br /><br />'" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "'<br /><br />in expected, but was<br /><br />'" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "'<br /><br />in actual.<br />");
mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual.");
}
}
@ -972,23 +983,23 @@ jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){
* @param actual
* @param {jasmine.NestedResults} results
*/
jasmine.Matchers = function(env, actual, results) {
jasmine.Matchers = function(env, actual, spec) {
this.env = env;
this.actual = actual;
this.passing_message = 'Passed.';
this.results_ = results || new jasmine.NestedResults();
this.spec = spec;
};
jasmine.Matchers.pp = function(str) {
return jasmine.util.htmlEscape(jasmine.pp(str));
};
jasmine.Matchers.prototype.results = function() {
return this.results_;
};
jasmine.Matchers.prototype.report = function(result, failing_message, details) {
this.results_.addResult(new jasmine.ExpectationResult(result, result ? this.passing_message : failing_message, details));
var expectationResult = new jasmine.ExpectationResult({
passed: result,
message: failing_message,
details: details
});
this.spec.addMatcherResult(expectationResult);
return result;
};
@ -997,57 +1008,85 @@ jasmine.Matchers.prototype.report = function(result, failing_message, details) {
*
* @param expected
*/
jasmine.Matchers.prototype.toBe = function(expected) {
return this.report(this.actual === expected, 'Expected<br /><br />' + jasmine.Matchers.pp(expected)
+ '<br /><br />to be the same object as<br /><br />' + jasmine.Matchers.pp(this.actual)
+ '<br />');
jasmine.Matchers.addMatcher = function(matcherName, options) {
jasmine.Matchers.prototype[matcherName] = function () {
jasmine.util.extend(this, options);
var expected = jasmine.util.argsToArray(arguments);
var args = [this.actual].concat(expected);
var result = options.test.apply(this, args);
var message;
if (!result) {
message = options.message.apply(this, args);
}
var expectationResult = new jasmine.ExpectationResult({
matcherName: matcherName,
passed: result,
expected: expected,
actual: this.actual,
message: message
});
this.spec.addMatcherResult(expectationResult);
return result;
};
};
/**
* Matcher that compares the actual to the expected using !==
* toBe: compares the actual to the expected using ===
* @param expected
*/
jasmine.Matchers.prototype.toNotBe = function(expected) {
return this.report(this.actual !== expected, 'Expected<br /><br />' + jasmine.Matchers.pp(expected)
+ '<br /><br />to be a different object from actual, but they were the same.');
};
jasmine.Matchers.addMatcher('toBe', {
test: function (actual, expected) {
return actual === expected;
},
message: function(actual, expected) {
return "Expected " + jasmine.pp(actual) + " to be " + jasmine.pp(expected);
}
});
/**
* Matcher that compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc.
* toNotBe: compares the actual to the expected using !==
* @param expected
*/
jasmine.Matchers.addMatcher('toNotBe', {
test: function (actual, expected) {
return actual !== expected;
},
message: function(actual, expected) {
return "Expected " + jasmine.pp(actual) + " to not be " + jasmine.pp(expected);
}
});
/**
* toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc.
*
* @param expected
*/
jasmine.Matchers.prototype.toEqual = function(expected) {
var mismatchKeys = [];
var mismatchValues = [];
var formatMismatches = function(name, array) {
if (array.length == 0) return '';
var errorOutput = '<br /><br />Different ' + name + ':<br />';
for (var i = 0; i < array.length; i++) {
errorOutput += array[i] + '<br />';
}
return errorOutput;
};
return this.report(this.env.equals_(this.actual, expected, mismatchKeys, mismatchValues),
'Expected<br /><br />' + jasmine.Matchers.pp(expected)
+ '<br /><br />but got<br /><br />' + jasmine.Matchers.pp(this.actual)
+ '<br />'
+ formatMismatches('Keys', mismatchKeys)
+ formatMismatches('Values', mismatchValues), {
matcherName: 'toEqual', expected: expected, actual: this.actual
});
};
jasmine.Matchers.addMatcher('toEqual', {
test: function (actual, expected) {
return this.env.equals_(actual, expected);
},
message: function(actual, expected) {
return "Expected " + jasmine.pp(actual) + " to equal " + jasmine.pp(expected);
}
});
/**
* Matcher that compares the actual to the expected using the ! of jasmine.Matchers.toEqual
* toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual
* @param expected
*/
jasmine.Matchers.prototype.toNotEqual = function(expected) {
return this.report(!this.env.equals_(this.actual, expected),
'Expected ' + jasmine.Matchers.pp(expected) + ' to not equal ' + jasmine.Matchers.pp(this.actual) + ', but it does.');
};
jasmine.Matchers.addMatcher('toNotEqual', {
test: function (actual, expected) {
return !this.env.equals_(actual, expected);
},
message: function(actual, expected) {
return "Expected " + jasmine.pp(actual) + " to not equal " + jasmine.pp(expected);
}
});
/**
* Matcher that compares the actual to the expected using a regular expression. Constructs a RegExp, so takes
@ -1055,77 +1094,166 @@ jasmine.Matchers.prototype.toNotEqual = function(expected) {
*
* @param reg_exp
*/
jasmine.Matchers.prototype.toMatch = function(reg_exp) {
return this.report((new RegExp(reg_exp).test(this.actual)),
'Expected ' + jasmine.Matchers.pp(this.actual) + ' to match ' + reg_exp + '.');
};
jasmine.Matchers.addMatcher('toMatch', {
test: function(actual, expected) {
return new RegExp(expected).test(actual);
},
message: function(actual, expected) {
return actual + " does not match the regular expression " + new RegExp(expected).toString();
}
});
/**
* Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch
* @param reg_exp
*/
jasmine.Matchers.prototype.toNotMatch = function(reg_exp) {
return this.report((!new RegExp(reg_exp).test(this.actual)),
'Expected ' + jasmine.Matchers.pp(this.actual) + ' to not match ' + reg_exp + '.');
};
jasmine.Matchers.addMatcher('toNotMatch', {
test: function(actual, expected) {
return !(new RegExp(expected).test(actual));
},
message: function(actual, expected) {
return actual + " should not match " + new RegExp(expected).toString();
}
});
/**
* Matcher that compares the acutal to undefined.
*/
jasmine.Matchers.prototype.toBeDefined = function() {
return this.report((this.actual !== undefined),
'Expected a value to be defined but it was undefined.');
};
jasmine.Matchers.addMatcher('toBeDefined', {
test: function(actual) {
return (actual !== undefined);
},
message: function() {
return 'Expected actual to not be undefined.';
}
});
/**
* Matcher that compares the acutal to undefined.
*/
jasmine.Matchers.addMatcher('toBeUndefined', {
test: function(actual) {
return (actual === undefined);
},
message: function(actual) {
return 'Expected ' + jasmine.pp(actual) + ' to be undefined.';
}
});
/**
* Matcher that compares the actual to null.
*
*/
jasmine.Matchers.prototype.toBeNull = function() {
return this.report((this.actual === null),
'Expected a value to be null but it was ' + jasmine.Matchers.pp(this.actual) + '.');
};
jasmine.Matchers.addMatcher('toBeNull', {
test: function(actual) {
return (actual === null);
},
message: function(actual) {
return 'Expected ' + jasmine.pp(actual) + ' to be null.';
}
});
/**
* Matcher that boolean not-nots the actual.
*/
jasmine.Matchers.prototype.toBeTruthy = function() {
return this.report(!!this.actual,
'Expected a value to be truthy but it was ' + jasmine.Matchers.pp(this.actual) + '.');
};
jasmine.Matchers.addMatcher('toBeTruthy', {
test: function(actual) {
return !!actual;
},
message: function() {
return 'Expected actual to be truthy';
}
});
/**
* Matcher that boolean nots the actual.
*/
jasmine.Matchers.prototype.toBeFalsy = function() {
return this.report(!this.actual,
'Expected a value to be falsy but it was ' + jasmine.Matchers.pp(this.actual) + '.');
};
jasmine.Matchers.addMatcher('toBeFalsy', {
test: function(actual) {
return !actual;
},
message: function(actual) {
return 'Expected ' + jasmine.pp(actual) + ' to be falsy';
}
});
/**
* Matcher that checks to see if the acutal, a Jasmine spy, was called.
*/
jasmine.Matchers.prototype.wasCalled = function() {
if (!this.actual || !this.actual.isSpy) {
return this.report(false, 'Expected a spy, but got ' + jasmine.Matchers.pp(this.actual) + '.');
jasmine.Matchers.addMatcher('wasCalled', {
getActual_: function() {
var args = jasmine.util.argsToArray(arguments);
if (args.length > 1) {
throw(new Error('wasCalled does not take arguments, use wasCalledWith'));
}
return args.splice(0, 1)[0];
},
test: function() {
var actual = this.getActual_.apply(this, arguments);
if (!actual || !actual.isSpy) {
return false;
}
return actual.wasCalled;
},
message: function() {
var actual = this.getActual_.apply(this, arguments);
if (!actual || !actual.isSpy) {
return 'Actual is not a spy.';
}
return "Expected spy " + actual.identity + " to have been called.";
}
if (arguments.length > 0) {
return this.report(false, 'wasCalled matcher does not take arguments');
}
return this.report((this.actual.wasCalled),
'Expected spy "' + this.actual.identity + '" to have been called, but it was not.');
};
});
/**
* Matcher that checks to see if the acutal, a Jasmine spy, was not called.
*/
jasmine.Matchers.prototype.wasNotCalled = function() {
if (!this.actual || !this.actual.isSpy) {
return this.report(false, 'Expected a spy, but got ' + jasmine.Matchers.pp(this.actual) + '.');
jasmine.Matchers.addMatcher('wasNotCalled', {
getActual_: function() {
var args = jasmine.util.argsToArray(arguments);
return args.splice(0, 1)[0];
},
test: function() {
var actual = this.getActual_.apply(this, arguments);
if (!actual || !actual.isSpy) {
return false;
}
return !actual.wasCalled;
},
message: function() {
var actual = this.getActual_.apply(this, arguments);
if (!actual || !actual.isSpy) {
return 'Actual is not a spy.';
}
return "Expected spy " + actual.identity + " to not have been called.";
}
return this.report((!this.actual.wasCalled),
'Expected spy "' + this.actual.identity + '" to not have been called, but it was.');
};
});
jasmine.Matchers.addMatcher('wasCalledWith', {
test: function() {
var args = jasmine.util.argsToArray(arguments);
var actual = args.splice(0, 1)[0];
if (!actual || !actual.isSpy) {
return false;
}
return this.env.contains_(actual.argsForCall, args);
},
message: function() {
var args = jasmine.util.argsToArray(arguments);
var actual = args.splice(0, 1)[0];
var message;
if (!actual || !actual.isSpy) {
message = 'Actual is not a spy';
} else {
message = "Expected spy to have been called with " + jasmine.pp(args) + " but was called with " + actual.argsForCall;
}
return message;
}
});
/**
* Matcher that checks to see if the acutal, a Jasmine spy, was called with a set of parameters.
@ -1133,78 +1261,89 @@ jasmine.Matchers.prototype.wasNotCalled = function() {
* @example
*
*/
jasmine.Matchers.prototype.wasCalledWith = function() {
if (!this.actual || !this.actual.isSpy) {
return this.report(false, 'Expected a spy, but got ' + jasmine.Matchers.pp(this.actual) + '.', {
matcherName: 'wasCalledWith'
});
}
var args = jasmine.util.argsToArray(arguments);
return this.report(this.env.contains_(this.actual.argsForCall, args),
'Expected ' + jasmine.Matchers.pp(this.actual.argsForCall) + ' to contain ' + jasmine.Matchers.pp(args) + ', but it does not.', {
matcherName: 'wasCalledWith', expected: args, actual: this.actual.argsForCall
});
};
/**
* Matcher that checks that the expected item is an element in the actual Array.
*
* @param {Object} item
*/
jasmine.Matchers.prototype.toContain = function(item) {
return this.report(this.env.contains_(this.actual, item),
'Expected ' + jasmine.Matchers.pp(this.actual) + ' to contain ' + jasmine.Matchers.pp(item) + ', but it does not.', {
matcherName: 'toContain', expected: item, actual: this.actual
});
};
jasmine.Matchers.addMatcher('toContain', {
test: function(actual, expected) {
return this.env.contains_(actual, expected);
},
message: function(actual, expected) {
return 'Expected ' + jasmine.pp(actual) + ' to contain ' + jasmine.pp(expected);
}
});
/**
* Matcher that checks that the expected item is NOT an element in the actual Array.
*
* @param {Object} item
*/
jasmine.Matchers.prototype.toNotContain = function(item) {
return this.report(!this.env.contains_(this.actual, item),
'Expected ' + jasmine.Matchers.pp(this.actual) + ' not to contain ' + jasmine.Matchers.pp(item) + ', but it does.');
};
jasmine.Matchers.addMatcher('toNotContain', {
test: function(actual, expected) {
return !this.env.contains_(actual, expected);
},
message: function(actual, expected) {
return 'Expected ' + jasmine.pp(actual) + ' to not contain ' + jasmine.pp(expected);
}
});
jasmine.Matchers.prototype.toBeLessThan = function(expected) {
return this.report(this.actual < expected,
'Expected ' + jasmine.Matchers.pp(this.actual) + ' to be less than ' + jasmine.Matchers.pp(expected) + ', but it was not.');
};
jasmine.Matchers.addMatcher('toBeLessThan', {
test: function(actual, expected) {
return actual < expected;
},
message: function(actual, expected) {
return 'Expected ' + jasmine.pp(actual) + ' to be less than ' + jasmine.pp(expected);
}
});
jasmine.Matchers.prototype.toBeGreaterThan = function(expected) {
return this.report(this.actual > expected,
'Expected ' + jasmine.Matchers.pp(this.actual) + ' to be greater than ' + jasmine.Matchers.pp(expected) + ', but it was not.');
};
jasmine.Matchers.addMatcher('toBeGreaterThan', {
test: function(actual, expected) {
return actual > expected;
},
message: function(actual, expected) {
return 'Expected ' + jasmine.pp(actual) + ' to be greater than ' + jasmine.pp(expected);
}
});
/**
* Matcher that checks that the expected exception was thrown by the actual.
*
* @param {String} expectedException
*/
jasmine.Matchers.prototype.toThrow = function(expectedException) {
var exception = null;
try {
this.actual();
} catch (e) {
exception = e;
}
if (expectedException !== undefined) {
if (exception == null) {
return this.report(false, "Expected function to throw " + jasmine.Matchers.pp(expectedException) + ", but it did not.");
jasmine.Matchers.addMatcher('toThrow', {
getException_: function(actual, expected) {
var exception;
if (typeof actual != 'function') {
throw new Error('Actual is not a function');
}
try {
actual();
} catch (e) {
exception = e;
}
return exception;
},
test: function(actual, expected) {
var result = false;
var exception = this.getException_(actual, expected);
if (exception) {
result = (expected === undefined || this.env.equals_(exception.message || exception, expected.message || expected));
}
return result;
},
message: function(actual, expected) {
var exception = this.getException_(actual, expected);
if (exception && (expected === undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) {
return ["Expected function to throw", expected.message || expected, ", but it threw", exception.message || exception ].join(' ');
} else {
return "Expected function to throw an exception.";
}
return this.report(
this.env.equals_(
exception.message || exception,
expectedException.message || expectedException),
"Expected function to throw " + jasmine.Matchers.pp(expectedException) + ", but it threw " + jasmine.Matchers.pp(exception) + ".");
} else {
return this.report(exception != null, "Expected function to throw an exception, but it did not.");
}
};
});
jasmine.Matchers.Any = function(expectedClass) {
this.expectedClass = expectedClass;
@ -1716,8 +1855,12 @@ jasmine.Spec.prototype.addToQueue = function (block) {
}
};
jasmine.Spec.prototype.addMatcherResult = function(result) {
this.results_.addResult(result);
};
jasmine.Spec.prototype.expect = function(actual) {
return new (this.getMatchersClass_())(this.env, actual, this.results_);
return new (this.getMatchersClass_())(this.env, actual, this);
};
jasmine.Spec.prototype.waits = function(timeout) {
@ -1733,7 +1876,11 @@ jasmine.Spec.prototype.waitsFor = function(timeout, latchFunction, timeoutMessag
};
jasmine.Spec.prototype.fail = function (e) {
this.results_.addResult(new jasmine.ExpectationResult(false, e ? jasmine.util.formatException(e) : null, null));
var expectationResult = new jasmine.ExpectationResult({
passed: false,
message: e ? jasmine.util.formatException(e) : 'Exception'
});
this.results_.addResult(expectationResult);
};
jasmine.Spec.prototype.getMatchersClass_ = function() {

View File

@ -58,6 +58,16 @@ body .run_spec {
/*white-space: pre;*/
/*}*/
.resultMessage span.result {
display: block;
line-height: 2em;
color: black;
}
.resultMessage .mismatch {
color: black;
}
.stackTrace {
white-space: pre;
font-size: .8em;
@ -73,4 +83,4 @@ body .run_spec {
#jasmine_content {
position:fixed;
left: 100%;
}
}

View File

@ -6,7 +6,7 @@ describe('Exceptions:', function() {
env.updateInterval = 0;
});
it('jasmine.formatException formats Firefox exception maessages as expected', function() {
it('jasmine.formatException formats Firefox exception messages as expected', function() {
var sampleFirefoxException = {
fileName: 'foo.js',
line: '1978',
@ -19,7 +19,7 @@ describe('Exceptions:', function() {
expect(jasmine.util.formatException(sampleFirefoxException)).toEqual(expected);
});
it('jasmine.formatException formats Webkit exception maessages as expected', function() {
it('jasmine.formatException formats Webkit exception messages as expected', function() {
var sampleWebkitException = {
sourceURL: 'foo.js',
lineNumber: '1978',
@ -81,7 +81,7 @@ describe('Exceptions:', function() {
var specResults = suiteResults.getItems();
expect(suiteResults.passed()).toEqual(false);
//
expect(specResults.length).toEqual(5);
expect(specResults[0].passed()).toMatch(false);
var blockResults = specResults[0].getItems();

View File

@ -1,20 +1,14 @@
describe("jasmine.Matchers", function() {
var env;
var env, mockSpec;
beforeEach(function() {
env = new jasmine.Env();
env.updateInterval = 0;
mockSpec = jasmine.createSpyObj('spec', ['addMatcherResult']);
});
function match(value) {
return new jasmine.Matchers(env, value);
}
function detailsFor(actual, matcherName, matcherArgs) {
var matcher = match(actual);
matcher[matcherName].apply(matcher, matcherArgs);
expect(matcher.results().getItems().length).toEqual(1);
return matcher.results().getItems()[0].details;
function match(value) {
return new jasmine.Matchers(env, value, mockSpec);
}
it("toEqual with primitives, objects, dates, html nodes, etc.", function() {
@ -22,8 +16,12 @@ describe("jasmine.Matchers", function() {
expect(match({foo:'bar'}).toEqual(null)).toEqual(false);
var functionA = function() { return 'hi'; };
var functionB = function() { return 'hi'; };
var functionA = function() {
return 'hi';
};
var functionB = function() {
return 'hi';
};
expect(match({foo:functionA}).toEqual({foo:functionB})).toEqual(false);
expect(match({foo:functionA}).toEqual({foo:functionA})).toEqual(true);
@ -49,6 +47,34 @@ describe("jasmine.Matchers", function() {
expect((match(['a', 'b']).toEqual(['a', 'b', undefined]))).toEqual(false);
});
it("toEqual to build an Expectation Result", function() {
var matcher = match('a');
matcher.toEqual('b');
var result = mockSpec.addMatcherResult.mostRecentCall.args[0];
expect(result.matcherName).toEqual("toEqual");
expect(result.passed()).toEqual(false);
expect(result.message).toMatch("a");
expect(result.message).toMatch("b");
expect(result.expected).toEqual(["b"]);
expect(result.actual).toEqual("a");
});
it("toNotEqual to build an Expectation Result", function() {
var matcher = match('a');
matcher.toNotEqual('a');
var result = mockSpec.addMatcherResult.mostRecentCall.args[0];
expect(result.matcherName).toEqual("toNotEqual");
expect(result.passed()).toEqual(false);
expect(result.message).toMatch(/a/);
expect(result.message).toMatch(/not/);
expect(result.expected).toEqual(["a"]);
expect(result.actual).toEqual("a");
});
it('toBe should return true only if the expected and actual items === each other', function() {
var a = {};
var b = {};
@ -62,6 +88,35 @@ describe("jasmine.Matchers", function() {
expect((match(a).toNotBe(c))).toEqual(false);
});
it("toBe to build an ExpectationResult", function() {
var expected = 'b';
var actual = 'a';
var matcher = match(actual);
matcher.toBe(expected);
var result = mockSpec.addMatcherResult.mostRecentCall.args[0];
expect(result.matcherName).toEqual("toBe");
expect(result.passed()).toEqual(false);
expect(result.message).toMatch(jasmine.pp(actual));
expect(result.message).toMatch(jasmine.pp(expected));
expect(result.expected).toEqual([expected]);
expect(result.actual).toEqual(actual);
});
it("toNotBe to build an ExpectationResult", function() {
var str = 'a';
var matcher = match(str);
matcher.toNotBe(str);
var result = mockSpec.addMatcherResult.mostRecentCall.args[0];
expect(result.matcherName).toEqual("toNotBe");
expect(result.passed()).toEqual(false);
expect(result.message).toMatch(str);
expect(result.expected).toEqual([str]);
expect(result.actual).toEqual(str);
});
it("toMatch and #toNotMatch should perform regular expression matching on strings", function() {
expect((match('foobarbel').toMatch(/bar/))).toEqual(true);
@ -77,17 +132,116 @@ describe("jasmine.Matchers", function() {
expect((match('foobazbel').toNotMatch("bar"))).toEqual(true);
});
it("toMatch w/ RegExp to build an ExpectationResult", function() {
var matcher = match('a');
matcher.toMatch(/b/);
var result = mockSpec.addMatcherResult.mostRecentCall.args[0];
expect(result.matcherName).toEqual("toMatch");
expect(result.passed()).toEqual(false);
expect(result.message).toEqual("a does not match the regular expression /b/");
expect(result.expected.toString()).toEqual("/b/");
expect(result.actual).toEqual("a");
});
it("toMatch w/ String to build an ExpectationResult", function() {
var matcher = match('a');
matcher.toMatch("b");
var result = mockSpec.addMatcherResult.mostRecentCall.args[0];
expect(result.matcherName).toEqual("toMatch");
expect(result.passed()).toEqual(false);
expect(result.message).toEqual("a does not match the regular expression /b/");
expect(result.expected.toString()).toEqual("b");
expect(result.actual).toEqual("a");
});
it("toNotMatch w/ RegExp to build an ExpectationResult", function() {
var matcher = match('a');
matcher.toNotMatch(/a/);
var result = mockSpec.addMatcherResult.mostRecentCall.args[0];
expect(result.matcherName).toEqual("toNotMatch");
expect(result.passed()).toEqual(false);
expect(result.message).toMatch("/a/");
expect(result.message).toMatch("not");
expect(result.expected.toString()).toEqual("/a/");
expect(result.actual).toEqual("a");
});
it("toNotMatch w/ String to build an ExpectationResult", function() {
var matcher = match('a');
matcher.toNotMatch('a');
var result = mockSpec.addMatcherResult.mostRecentCall.args[0];
expect(result.matcherName).toEqual("toNotMatch");
expect(result.passed()).toEqual(false);
expect(result.message).toMatch("/a/");
expect(result.message).toMatch("not");
expect(result.expected.toString()).toEqual('a');
expect(result.actual).toEqual("a");
});
it("toBeDefined", function() {
expect(match('foo').toBeDefined()).toEqual(true);
expect(match(undefined).toBeDefined()).toEqual(false);
});
it("toBeDefined to build an ExpectationResult", function() {
var matcher = match(undefined);
matcher.toBeDefined();
var result = mockSpec.addMatcherResult.mostRecentCall.args[0];
expect(result.matcherName).toEqual("toBeDefined");
expect(result.passed()).toEqual(false);
expect(result.message).toEqual('Expected actual to not be undefined.');
expect(result.actual).toEqual(undefined);
});
it("toBeUndefined", function() {
expect(match('foo').toBeUndefined()).toEqual(false);
expect(match(undefined).toBeUndefined()).toEqual(true);
});
it("toBeNull", function() {
expect(match(null).toBeNull()).toEqual(true);
expect(match(undefined).toBeNull()).toEqual(false);
expect(match("foo").toBeNull()).toEqual(false);
});
it("toBeNull w/ String to build an ExpectationResult", function() {
var actual = 'a';
var matcher = match(actual);
matcher.toBeNull();
var result = mockSpec.addMatcherResult.mostRecentCall.args[0];
expect(result.matcherName).toEqual("toBeNull");
expect(result.passed()).toEqual(false);
expect(result.message).toMatch(jasmine.pp(actual));
expect(result.message).toMatch('null');
expect(result.actual).toEqual(actual);
});
it("toBeNull w/ Object to build an ExpectationResult", function() {
var actual = {a: 'b'};
var matcher = match(actual);
matcher.toBeNull();
var result = mockSpec.addMatcherResult.mostRecentCall.args[0];
expect(result.matcherName).toEqual("toBeNull");
expect(result.passed()).toEqual(false);
expect(result.message).toMatch(jasmine.pp(actual));
expect(result.message).toMatch('null');
expect(result.actual).toEqual(actual);
});
it("toBeFalsy", function() {
expect(match(false).toBeFalsy()).toEqual(true);
expect(match(true).toBeFalsy()).toEqual(false);
@ -96,6 +250,20 @@ describe("jasmine.Matchers", function() {
expect(match("").toBeFalsy()).toEqual(true);
});
it("toBeFalsy to build an ExpectationResult", function() {
var actual = 'a';
var matcher = match(actual);
matcher.toBeFalsy();
var result = mockSpec.addMatcherResult.mostRecentCall.args[0];
expect(result.matcherName).toEqual("toBeFalsy");
expect(result.passed()).toEqual(false);
expect(result.message).toMatch(jasmine.pp(actual));
expect(result.message).toMatch('falsy');
expect(result.actual).toEqual(actual);
});
it("toBeTruthy", function() {
expect(match(false).toBeTruthy()).toEqual(false);
expect(match(true).toBeTruthy()).toEqual(true);
@ -107,6 +275,18 @@ describe("jasmine.Matchers", function() {
expect(match({foo: 1}).toBeTruthy()).toEqual(true);
});
it("toBeTruthy to build an ExpectationResult", function() {
var matcher = match(false);
matcher.toBeTruthy();
var result = mockSpec.addMatcherResult.mostRecentCall.args[0];
expect(result.matcherName).toEqual("toBeTruthy");
expect(result.passed()).toEqual(false);
expect(result.message).toEqual("Expected actual to be truthy");
expect(result.actual).toEqual(false);
});
it("toEqual", function() {
expect(match(undefined).toEqual(undefined)).toEqual(true);
expect(match({foo:'bar'}).toEqual({foo:'bar'})).toEqual(true);
@ -122,10 +302,13 @@ describe("jasmine.Matchers", function() {
expect(match("foo").toEqual(jasmine.any(Object))).toEqual(false);
expect(match({someObj:'foo'}).toEqual(jasmine.any(Object))).toEqual(true);
expect(match({someObj:'foo'}).toEqual(jasmine.any(Function))).toEqual(false);
expect(match(function() {}).toEqual(jasmine.any(Object))).toEqual(false);
expect(match(function() {
}).toEqual(jasmine.any(Object))).toEqual(false);
expect(match(["foo", "goo"]).toEqual(["foo", jasmine.any(String)])).toEqual(true);
expect(match(function() {}).toEqual(jasmine.any(Function))).toEqual(true);
expect(match(["a", function() {}]).toEqual(["a", jasmine.any(Function)])).toEqual(true);
expect(match(function() {
}).toEqual(jasmine.any(Function))).toEqual(true);
expect(match(["a", function() {
}]).toEqual(["a", jasmine.any(Function)])).toEqual(true);
});
it("toEqual handles circular objects ok", function() {
@ -154,7 +337,7 @@ describe("jasmine.Matchers", function() {
it("toContain and toNotContain", function() {
expect(match('ABC').toContain('A')).toEqual(true);
expect(match('ABC').toContain('X')).toEqual(false);
expect(match(['A', 'B', 'C']).toContain('A')).toEqual(true);
expect(match(['A', 'B', 'C']).toContain('F')).toEqual(false);
expect(match(['A', 'B', 'C']).toNotContain('F')).toEqual(true);
@ -162,10 +345,40 @@ describe("jasmine.Matchers", function() {
expect(match(['A', {some:'object'}, 'C']).toContain({some:'object'})).toEqual(true);
expect(match(['A', {some:'object'}, 'C']).toContain({some:'other object'})).toEqual(false);
});
expect(detailsFor('abc', 'toContain', ['x'])).toEqual({
matcherName: 'toContain', expected: 'x', actual: 'abc'
});
it("toContain to build an ExpectationResult", function() {
var actual = ['a','b','c'];
var matcher = match(actual);
var expected = 'x';
matcher.toContain(expected);
var result = mockSpec.addMatcherResult.mostRecentCall.args[0];
expect(result.matcherName).toEqual("toContain");
expect(result.passed()).toEqual(false);
expect(result.message).toMatch(jasmine.pp(actual));
expect(result.message).toMatch('contain');
expect(result.message).toMatch(jasmine.pp(expected));
expect(result.actual).toEqual(actual);
expect(result.expected).toEqual([expected]);
});
it("toNotContain to build an ExpectationResult", function() {
var actual = ['a','b','c'];
var matcher = match(actual);
var expected = 'b';
matcher.toNotContain(expected);
var result = mockSpec.addMatcherResult.mostRecentCall.args[0];
expect(result.matcherName).toEqual("toNotContain");
expect(result.passed()).toEqual(false);
expect(result.message).toMatch(jasmine.pp(actual));
expect(result.message).toMatch('not contain');
expect(result.message).toMatch(jasmine.pp(expected));
expect(result.actual).toEqual(actual);
expect(result.expected).toEqual([expected]);
});
it("toBeLessThan should pass if actual is less than expected", function() {
@ -174,141 +387,178 @@ describe("jasmine.Matchers", function() {
expect(match(37).toBeLessThan(37)).toEqual(false);
});
it("toBeLessThan to build an ExpectationResult", function() {
var actual = 3;
var matcher = match(actual);
var expected = 1;
matcher.toBeLessThan(expected);
var result = mockSpec.addMatcherResult.mostRecentCall.args[0];
expect(result.matcherName).toEqual("toBeLessThan");
expect(result.passed()).toEqual(false);
expect(result.message).toMatch(jasmine.pp(actual) + ' to be less than');
expect(result.message).toMatch(jasmine.pp(expected));
expect(result.actual).toEqual(actual);
expect(result.expected).toEqual([expected]);
});
it("toBeGreaterThan should pass if actual is greater than expected", function() {
expect(match(37).toBeGreaterThan(42)).toEqual(false);
expect(match(37).toBeGreaterThan(-42)).toEqual(true);
expect(match(37).toBeGreaterThan(37)).toEqual(false);
});
it("toBeGreaterThan to build an ExpectationResult", function() {
var actual = 1;
var matcher = match(actual);
var expected = 3;
matcher.toBeGreaterThan(expected);
var result = mockSpec.addMatcherResult.mostRecentCall.args[0];
expect(result.matcherName).toEqual("toBeGreaterThan");
expect(result.passed()).toEqual(false);
expect(result.message).toMatch(jasmine.pp(actual) + ' to be greater than');
expect(result.message).toMatch(jasmine.pp(expected));
expect(result.actual).toEqual(actual);
expect(result.expected).toEqual([expected]);
});
it("toThrow", function() {
var expected = new jasmine.Matchers(env, function() {
throw new Error("Fake Error");
});
}, mockSpec);
expect(expected.toThrow()).toEqual(true);
expect(expected.toThrow("Fake Error")).toEqual(true);
expect(expected.toThrow(new Error("Fake Error"))).toEqual(true);
expect(expected.toThrow("Other Error")).toEqual(false);
var result = mockSpec.addMatcherResult.mostRecentCall.args[0];
expect(result.message).toMatch("Other Error");
expect(expected.toThrow(new Error("Other Error"))).toEqual(false);
result = mockSpec.addMatcherResult.mostRecentCall.args[0];
expect(result.message).toMatch("Other Error");
var exception;
try {
(function (){
new jasmine.Matchers(env, 'not-a-function', mockSpec).toThrow();
})();
} catch (e) {
exception = e;
};
expect(exception).toBeDefined();
expect(exception.message).toEqual('Actual is not a function');
expect(match(function() {
}).toThrow()).toEqual(false);
result = mockSpec.addMatcherResult.mostRecentCall.args[0];
expect(result.message).toEqual('Expected function to throw an exception.');
expect(match(function() {}).toThrow()).toEqual(false);
});
it("wasCalled, wasNotCalled, wasCalledWith", function() {
var currentSuite;
var spec;
currentSuite = env.describe('default current suite', function() {
spec = env.it();
var spyMatch = function(value, spec) {
return new jasmine.Matchers(env, value, spec);
}
describe("wasCalled, wasNotCalled, wasCalledWith", function() {
var TestClass;
beforeEach(function() {
TestClass = { someFunction: function() {
} };
});
it('should always show an error if the actual is not a spy', function () {
expect(match(TestClass.someFunction).wasCalled()).toEqual(false);
var result = mockSpec.addMatcherResult.mostRecentCall.args[0];
expect(result.message).toEqual("Actual is not a spy.");
expect(match(TestClass.someFunction).wasNotCalled()).toEqual(false);
result = mockSpec.addMatcherResult.mostRecentCall.args[0];
expect(result.message).toEqual("Actual is not a spy.");
});
var TestClass = { someFunction: function() {
} };
it("should work for spys", function() {
TestClass.someFunction = jasmine.createSpy("My spy");
var expected;
expect(match(TestClass.someFunction).wasCalled()).toEqual(false);
expect(match(TestClass.someFunction).wasNotCalled()).toEqual(false);
expect(match(TestClass.someFunction).wasCalled()).toEqual(false);
expect(match(TestClass.someFunction).wasNotCalled()).toEqual(true);
spec.spyOn(TestClass, 'someFunction');
TestClass.someFunction();
expect(match(TestClass.someFunction).wasCalled()).toEqual(true);
expect(function () { match(TestClass.someFunction).wasCalled('some arg');}).toThrow('wasCalled does not take arguments, use wasCalledWith');
expect(match(TestClass.someFunction).wasNotCalled()).toEqual(false);
expect(match(TestClass.someFunction).wasCalled()).toEqual(false);
expect(match(TestClass.someFunction).wasNotCalled()).toEqual(true);
TestClass.someFunction('a', 'b', 'c');
expect(match(TestClass.someFunction).wasCalledWith('a', 'b', 'c')).toEqual(true);
var expected = match(TestClass.someFunction);
expect(expected.wasCalledWith('c', 'b', 'a')).toEqual(false);
result = mockSpec.addMatcherResult.mostRecentCall.args[0];
expect(result.passed()).toEqual(false);
TestClass.someFunction();
expect(match(TestClass.someFunction).wasCalled()).toEqual(true);
expect(match(TestClass.someFunction).wasCalled('some arg')).toEqual(false);
expect(match(TestClass.someFunction).wasNotCalled()).toEqual(false);
TestClass.someFunction.reset();
TestClass.someFunction('a', 'b', 'c');
TestClass.someFunction('d', 'e', 'f');
expect(expected.wasCalledWith('a', 'b', 'c')).toEqual(true);
expect(expected.wasCalledWith('d', 'e', 'f')).toEqual(true);
expect(expected.wasCalledWith('x', 'y', 'z')).toEqual(false);
});
});
TestClass.someFunction('a', 'b', 'c');
expect(match(TestClass.someFunction).wasCalledWith('a', 'b', 'c')).toEqual(true);
expected = match(TestClass.someFunction);
expect(expected.wasCalledWith('c', 'b', 'a')).toEqual(false);
expect(expected.results().getItems()[0].passed()).toEqual(false);
TestClass.someFunction.reset();
TestClass.someFunction('a', 'b', 'c');
TestClass.someFunction('d', 'e', 'f');
expect(expected.wasCalledWith('a', 'b', 'c')).toEqual(true);
expect(expected.wasCalledWith('d', 'e', 'f')).toEqual(true);
expect(expected.wasCalledWith('x', 'y', 'z')).toEqual(false);
expect(detailsFor(TestClass.someFunction, 'wasCalledWith', ['x', 'y', 'z'])).toEqual({
matcherName: 'wasCalledWith', expected: ['x', 'y', 'z'], actual: TestClass.someFunction.argsForCall
describe("wasCalledWith to build an ExpectationResult", function () {
var TestClass;
beforeEach(function() {
var currentSuite;
var spec;
currentSuite = env.describe('default current suite', function() {
spec = env.it();
}, spec);
TestClass = { someFunction: function(a, b) {
} };
spec.spyOn(TestClass, 'someFunction');
});
it("should handle case of actual not being a spy", function() {
var matcher = match();
matcher.wasCalledWith('a', 'b');
var result = mockSpec.addMatcherResult.mostRecentCall.args[0];
expect(result.matcherName).toEqual("wasCalledWith");
expect(result.passed()).toEqual(false);
expect(result.message).toEqual("Actual is not a spy");
expect(result.actual).toEqual(undefined);
expect(result.expected).toEqual(['a','b']);
matcher = match('foo');
matcher.wasCalledWith('a', 'b');
result = mockSpec.addMatcherResult.mostRecentCall.args[0];
expect(result.matcherName).toEqual("wasCalledWith");
expect(result.passed()).toEqual(false);
expect(result.message).toEqual("Actual is not a spy");
expect(result.actual).toEqual('foo');
expect(result.expected).toEqual(['a','b']);
});
it("should should handle the case of a spy", function() {
TestClass.someFunction('a', 'c');
var matcher = match(TestClass.someFunction);
matcher.wasCalledWith('a', 'b');
var result = mockSpec.addMatcherResult.mostRecentCall.args[0];
expect(result.matcherName).toEqual("wasCalledWith");
expect(result.passed()).toEqual(false);
expect(result.message).toMatch("['a', 'b']");
expect(result.message).toMatch("['a', 'c']");
expect(result.actual).toEqual(TestClass.someFunction);
expect(result.expected).toEqual(['a','b']);
});
});
it("should report mismatches in some nice way", function() {
var results = new jasmine.NestedResults();
var expected = new jasmine.Matchers(env, true, results);
expected.toEqual(true);
expected.toEqual(false);
expect(results.getItems().length).toEqual(2);
expect(results.getItems()[0].passed()).toEqual(true);
expect(results.getItems()[1].passed()).toEqual(false);
results = new jasmine.NestedResults();
expected = new jasmine.Matchers(env, false, results);
expected.toEqual(true);
var expectedMessage = 'Expected<br /><br />true<br /><br />but got<br /><br />false<br />';
expect(results.getItems()[0].message).toEqual(expectedMessage);
results = new jasmine.NestedResults();
expected = new jasmine.Matchers(env, null, results);
expected.toEqual('not null');
expectedMessage = 'Expected<br /><br />\'not null\'<br /><br />but got<br /><br />null<br />';
expect(results.getItems()[0].message).toEqual(expectedMessage);
results = new jasmine.NestedResults();
expected = new jasmine.Matchers(env, undefined, results);
expected.toEqual('not undefined');
expectedMessage = 'Expected<br /><br />\'not undefined\'<br /><br />but got<br /><br />undefined<br />';
expect(results.getItems()[0].message).toEqual(expectedMessage);
results = new jasmine.NestedResults();
expected = new jasmine.Matchers(env, {foo:'one',baz:'two', more: 'blah'}, results);
expected.toEqual({foo:'one', bar: '<b>three</b> &', baz: '2'});
expectedMessage =
"Expected<br /><br />{ foo : 'one', bar : '&lt;b&gt;three&lt;/b&gt; &amp;', baz : '2' }<br /><br />but got<br /><br />{ foo : 'one', baz : 'two', more : 'blah' }<br />" +
"<br /><br />Different Keys:<br />" +
"expected has key 'bar', but missing from <b>actual</b>.<br />" +
"<b>expected</b> missing key 'more', but present in actual.<br />" +
"<br /><br />Different Values:<br />" +
"'bar' was<br /><br />'&lt;b&gt;three&lt;/b&gt; &amp;'<br /><br />in expected, but was<br /><br />'undefined'<br /><br />in actual.<br /><br />" +
"'baz' was<br /><br />'2'<br /><br />in expected, but was<br /><br />'two'<br /><br />in actual.<br /><br />";
var actualMessage = results.getItems()[0].message;
expect(actualMessage).toEqual(expectedMessage);
results = new jasmine.NestedResults();
expected = new jasmine.Matchers(env, true, results);
expected.toEqual(true);
expect(results.getItems()[0].message).toEqual('Passed.');
expected = new jasmine.Matchers(env, [1, 2, 3], results);
results.getItems().length = 0;
expected.toEqual([1, 2, 3]);
expect(results.getItems()[0].passed()).toEqual(true);
expected = new jasmine.Matchers(env, [1, 2, 3], results);
results.getItems().length = 0;
expected.toEqual([{}, {}, {}]);
expect(results.getItems()[0].passed()).toEqual(false);
expected = new jasmine.Matchers(env, [{}, {}, {}], results);
results.getItems().length = 0;
expected.toEqual([1, 2, 3]);
expect(results.getItems()[0].passed()).toEqual(false);
});
});

View File

@ -3,14 +3,18 @@ describe('jasmine.NestedResults', function() {
// Leaf case
var results = new jasmine.NestedResults();
results.addResult(new jasmine.ExpectationResult(true,'Passed.'));
results.addResult(new jasmine.ExpectationResult({
matcherName: "foo", passed: true, message: 'Passed.', actual: 'bar', expected: 'bar'}
));
expect(results.getItems().length).toEqual(1);
expect(results.totalCount).toEqual(1);
expect(results.passedCount).toEqual(1);
expect(results.failedCount).toEqual(0);
results.addResult(new jasmine.ExpectationResult(false, 'FAIL.'));
results.addResult(new jasmine.ExpectationResult({
matcherName: "baz", passed: false, message: 'FAIL.', actual: "corge", expected: "quux"
}));
expect(results.getItems().length).toEqual(2);
expect(results.totalCount).toEqual(2);
@ -21,12 +25,21 @@ describe('jasmine.NestedResults', function() {
it('should roll up counts for nested results', function() {
// Branch case
var leafResultsOne = new jasmine.NestedResults();
leafResultsOne.addResult(new jasmine.ExpectationResult( true, ''));
leafResultsOne.addResult(new jasmine.ExpectationResult( false, ''));
leafResultsOne.addResult(new jasmine.ExpectationResult({
matcherName: "toSomething", passed: true, message: 'message', actual: '', expected:''
}));
leafResultsOne.addResult(new jasmine.ExpectationResult({
matcherName: "toSomethingElse", passed: false, message: 'message', actual: 'a', expected: 'b'
}));
var leafResultsTwo = new jasmine.NestedResults();
leafResultsTwo.addResult(new jasmine.ExpectationResult( true, ''));
leafResultsTwo.addResult(new jasmine.ExpectationResult( false, ''));
leafResultsTwo.addResult(new jasmine.ExpectationResult({
matcherName: "toSomething", passed: true, message: 'message', actual: '', expected: ''
}));
leafResultsTwo.addResult(new jasmine.ExpectationResult({
matcherName: "toSomethineElse", passed: false, message: 'message', actual: 'c', expected: 'd'
}));
var branchResults = new jasmine.NestedResults();
branchResults.addResult(leafResultsOne);
@ -38,4 +51,4 @@ describe('jasmine.NestedResults', function() {
expect(branchResults.failedCount).toEqual(2);
});
});
});

View File

@ -37,7 +37,6 @@ describe("jasmine spec running", function () {
expect(it4.id).toEqual(4);
});
it("should build up some objects with results we can inspect", function() {
var specWithNoBody, specWithExpectation, specWithFailingExpectations, specWithMultipleExpectations;

View File

@ -76,4 +76,52 @@ describe("TrivialReporter", function() {
});
});
});
describe("failure messages (integration)", function () {
var spec, results, expectationResult;
beforeEach(function() {
results = {
passed: function() {
return false;
},
getItems: function() {
}};
spec = {
suite: {
getFullName: function() {
return "suite 1";
}
},
getFullName: function() {
return "foo";
},
results: function() {
return results;
}
};
trivialReporter = new jasmine.TrivialReporter({ body: body });
trivialReporter.reportRunnerStarting({
suites: function() {
return [ new jasmine.Suite({}, "suite 1", null, null) ];
}
});
});
it("should add the failure message to the DOM (non-toEquals matchers)", function() {
expectationResult = new jasmine.ExpectationResult({
matcherName: "toBeNull", passed: false, message: "Expected 'a' to be null, but it was not"
});
spyOn(results, 'getItems').andReturn([expectationResult]);
trivialReporter.reportSpecResults(spec);
var divs = body.getElementsByTagName("div");
expect(divs[3].innerHTML).toEqual("Expected 'a' to be null, but it was not");
});
});
});

23
spec/suites/UtilSpec.js Normal file
View File

@ -0,0 +1,23 @@
describe("jasmine.util", function() {
describe("extend", function () {
it("should add properies to a destination object ", function() {
var destination = {baz: 'baz'};
jasmine.util.extend(destination, {
foo: 'foo', bar: 'bar'
});
expect(destination).toEqual({foo: 'foo', bar: 'bar', baz: 'baz'});
});
it("should replace properies that already exist on a destination object", function() {
var destination = {foo: 'foo'};
jasmine.util.extend(destination, {
foo: 'bar'
});
expect(destination).toEqual({foo: 'bar'});
jasmine.util.extend(destination, {
foo: null
});
expect(destination).toEqual({foo: null});
});
});
});

View File

@ -145,18 +145,18 @@ jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchVal
for (var property in b) {
if (!hasKey(a, property) && hasKey(b, property)) {
mismatchKeys.push("expected has key '" + property + "', but missing from <b>actual</b>.");
mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
}
}
for (property in a) {
if (!hasKey(b, property) && hasKey(a, property)) {
mismatchKeys.push("<b>expected</b> missing key '" + property + "', but present in actual.");
mismatchKeys.push("expected missing key '" + property + "', but present in actual.");
}
}
for (property in b) {
if (property == '__Jasmine_been_here_before__') continue;
if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) {
mismatchValues.push("'" + property + "' was<br /><br />'" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "'<br /><br />in expected, but was<br /><br />'" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "'<br /><br />in actual.<br />");
mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual.");
}
}

View File

@ -4,23 +4,23 @@
* @param actual
* @param {jasmine.NestedResults} results
*/
jasmine.Matchers = function(env, actual, results) {
jasmine.Matchers = function(env, actual, spec) {
this.env = env;
this.actual = actual;
this.passing_message = 'Passed.';
this.results_ = results || new jasmine.NestedResults();
this.spec = spec;
};
jasmine.Matchers.pp = function(str) {
return jasmine.util.htmlEscape(jasmine.pp(str));
};
jasmine.Matchers.prototype.results = function() {
return this.results_;
};
jasmine.Matchers.prototype.report = function(result, failing_message, details) {
this.results_.addResult(new jasmine.ExpectationResult(result, result ? this.passing_message : failing_message, details));
var expectationResult = new jasmine.ExpectationResult({
passed: result,
message: failing_message,
details: details
});
this.spec.addMatcherResult(expectationResult);
return result;
};
@ -29,57 +29,85 @@ jasmine.Matchers.prototype.report = function(result, failing_message, details) {
*
* @param expected
*/
jasmine.Matchers.prototype.toBe = function(expected) {
return this.report(this.actual === expected, 'Expected<br /><br />' + jasmine.Matchers.pp(expected)
+ '<br /><br />to be the same object as<br /><br />' + jasmine.Matchers.pp(this.actual)
+ '<br />');
jasmine.Matchers.addMatcher = function(matcherName, options) {
jasmine.Matchers.prototype[matcherName] = function () {
jasmine.util.extend(this, options);
var expected = jasmine.util.argsToArray(arguments);
var args = [this.actual].concat(expected);
var result = options.test.apply(this, args);
var message;
if (!result) {
message = options.message.apply(this, args);
}
var expectationResult = new jasmine.ExpectationResult({
matcherName: matcherName,
passed: result,
expected: expected,
actual: this.actual,
message: message
});
this.spec.addMatcherResult(expectationResult);
return result;
};
};
/**
* Matcher that compares the actual to the expected using !==
* toBe: compares the actual to the expected using ===
* @param expected
*/
jasmine.Matchers.prototype.toNotBe = function(expected) {
return this.report(this.actual !== expected, 'Expected<br /><br />' + jasmine.Matchers.pp(expected)
+ '<br /><br />to be a different object from actual, but they were the same.');
};
jasmine.Matchers.addMatcher('toBe', {
test: function (actual, expected) {
return actual === expected;
},
message: function(actual, expected) {
return "Expected " + jasmine.pp(actual) + " to be " + jasmine.pp(expected);
}
});
/**
* Matcher that compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc.
* toNotBe: compares the actual to the expected using !==
* @param expected
*/
jasmine.Matchers.addMatcher('toNotBe', {
test: function (actual, expected) {
return actual !== expected;
},
message: function(actual, expected) {
return "Expected " + jasmine.pp(actual) + " to not be " + jasmine.pp(expected);
}
});
/**
* toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc.
*
* @param expected
*/
jasmine.Matchers.prototype.toEqual = function(expected) {
var mismatchKeys = [];
var mismatchValues = [];
var formatMismatches = function(name, array) {
if (array.length == 0) return '';
var errorOutput = '<br /><br />Different ' + name + ':<br />';
for (var i = 0; i < array.length; i++) {
errorOutput += array[i] + '<br />';
}
return errorOutput;
};
return this.report(this.env.equals_(this.actual, expected, mismatchKeys, mismatchValues),
'Expected<br /><br />' + jasmine.Matchers.pp(expected)
+ '<br /><br />but got<br /><br />' + jasmine.Matchers.pp(this.actual)
+ '<br />'
+ formatMismatches('Keys', mismatchKeys)
+ formatMismatches('Values', mismatchValues), {
matcherName: 'toEqual', expected: expected, actual: this.actual
});
};
jasmine.Matchers.addMatcher('toEqual', {
test: function (actual, expected) {
return this.env.equals_(actual, expected);
},
message: function(actual, expected) {
return "Expected " + jasmine.pp(actual) + " to equal " + jasmine.pp(expected);
}
});
/**
* Matcher that compares the actual to the expected using the ! of jasmine.Matchers.toEqual
* toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual
* @param expected
*/
jasmine.Matchers.prototype.toNotEqual = function(expected) {
return this.report(!this.env.equals_(this.actual, expected),
'Expected ' + jasmine.Matchers.pp(expected) + ' to not equal ' + jasmine.Matchers.pp(this.actual) + ', but it does.');
};
jasmine.Matchers.addMatcher('toNotEqual', {
test: function (actual, expected) {
return !this.env.equals_(actual, expected);
},
message: function(actual, expected) {
return "Expected " + jasmine.pp(actual) + " to not equal " + jasmine.pp(expected);
}
});
/**
* Matcher that compares the actual to the expected using a regular expression. Constructs a RegExp, so takes
@ -87,77 +115,166 @@ jasmine.Matchers.prototype.toNotEqual = function(expected) {
*
* @param reg_exp
*/
jasmine.Matchers.prototype.toMatch = function(reg_exp) {
return this.report((new RegExp(reg_exp).test(this.actual)),
'Expected ' + jasmine.Matchers.pp(this.actual) + ' to match ' + reg_exp + '.');
};
jasmine.Matchers.addMatcher('toMatch', {
test: function(actual, expected) {
return new RegExp(expected).test(actual);
},
message: function(actual, expected) {
return actual + " does not match the regular expression " + new RegExp(expected).toString();
}
});
/**
* Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch
* @param reg_exp
*/
jasmine.Matchers.prototype.toNotMatch = function(reg_exp) {
return this.report((!new RegExp(reg_exp).test(this.actual)),
'Expected ' + jasmine.Matchers.pp(this.actual) + ' to not match ' + reg_exp + '.');
};
jasmine.Matchers.addMatcher('toNotMatch', {
test: function(actual, expected) {
return !(new RegExp(expected).test(actual));
},
message: function(actual, expected) {
return actual + " should not match " + new RegExp(expected).toString();
}
});
/**
* Matcher that compares the acutal to undefined.
*/
jasmine.Matchers.prototype.toBeDefined = function() {
return this.report((this.actual !== undefined),
'Expected a value to be defined but it was undefined.');
};
jasmine.Matchers.addMatcher('toBeDefined', {
test: function(actual) {
return (actual !== undefined);
},
message: function() {
return 'Expected actual to not be undefined.';
}
});
/**
* Matcher that compares the acutal to undefined.
*/
jasmine.Matchers.addMatcher('toBeUndefined', {
test: function(actual) {
return (actual === undefined);
},
message: function(actual) {
return 'Expected ' + jasmine.pp(actual) + ' to be undefined.';
}
});
/**
* Matcher that compares the actual to null.
*
*/
jasmine.Matchers.prototype.toBeNull = function() {
return this.report((this.actual === null),
'Expected a value to be null but it was ' + jasmine.Matchers.pp(this.actual) + '.');
};
jasmine.Matchers.addMatcher('toBeNull', {
test: function(actual) {
return (actual === null);
},
message: function(actual) {
return 'Expected ' + jasmine.pp(actual) + ' to be null.';
}
});
/**
* Matcher that boolean not-nots the actual.
*/
jasmine.Matchers.prototype.toBeTruthy = function() {
return this.report(!!this.actual,
'Expected a value to be truthy but it was ' + jasmine.Matchers.pp(this.actual) + '.');
};
jasmine.Matchers.addMatcher('toBeTruthy', {
test: function(actual) {
return !!actual;
},
message: function() {
return 'Expected actual to be truthy';
}
});
/**
* Matcher that boolean nots the actual.
*/
jasmine.Matchers.prototype.toBeFalsy = function() {
return this.report(!this.actual,
'Expected a value to be falsy but it was ' + jasmine.Matchers.pp(this.actual) + '.');
};
jasmine.Matchers.addMatcher('toBeFalsy', {
test: function(actual) {
return !actual;
},
message: function(actual) {
return 'Expected ' + jasmine.pp(actual) + ' to be falsy';
}
});
/**
* Matcher that checks to see if the acutal, a Jasmine spy, was called.
*/
jasmine.Matchers.prototype.wasCalled = function() {
if (!this.actual || !this.actual.isSpy) {
return this.report(false, 'Expected a spy, but got ' + jasmine.Matchers.pp(this.actual) + '.');
jasmine.Matchers.addMatcher('wasCalled', {
getActual_: function() {
var args = jasmine.util.argsToArray(arguments);
if (args.length > 1) {
throw(new Error('wasCalled does not take arguments, use wasCalledWith'));
}
return args.splice(0, 1)[0];
},
test: function() {
var actual = this.getActual_.apply(this, arguments);
if (!actual || !actual.isSpy) {
return false;
}
return actual.wasCalled;
},
message: function() {
var actual = this.getActual_.apply(this, arguments);
if (!actual || !actual.isSpy) {
return 'Actual is not a spy.';
}
return "Expected spy " + actual.identity + " to have been called.";
}
if (arguments.length > 0) {
return this.report(false, 'wasCalled matcher does not take arguments');
}
return this.report((this.actual.wasCalled),
'Expected spy "' + this.actual.identity + '" to have been called, but it was not.');
};
});
/**
* Matcher that checks to see if the acutal, a Jasmine spy, was not called.
*/
jasmine.Matchers.prototype.wasNotCalled = function() {
if (!this.actual || !this.actual.isSpy) {
return this.report(false, 'Expected a spy, but got ' + jasmine.Matchers.pp(this.actual) + '.');
jasmine.Matchers.addMatcher('wasNotCalled', {
getActual_: function() {
var args = jasmine.util.argsToArray(arguments);
return args.splice(0, 1)[0];
},
test: function() {
var actual = this.getActual_.apply(this, arguments);
if (!actual || !actual.isSpy) {
return false;
}
return !actual.wasCalled;
},
message: function() {
var actual = this.getActual_.apply(this, arguments);
if (!actual || !actual.isSpy) {
return 'Actual is not a spy.';
}
return "Expected spy " + actual.identity + " to not have been called.";
}
return this.report((!this.actual.wasCalled),
'Expected spy "' + this.actual.identity + '" to not have been called, but it was.');
};
});
jasmine.Matchers.addMatcher('wasCalledWith', {
test: function() {
var args = jasmine.util.argsToArray(arguments);
var actual = args.splice(0, 1)[0];
if (!actual || !actual.isSpy) {
return false;
}
return this.env.contains_(actual.argsForCall, args);
},
message: function() {
var args = jasmine.util.argsToArray(arguments);
var actual = args.splice(0, 1)[0];
var message;
if (!actual || !actual.isSpy) {
message = 'Actual is not a spy';
} else {
message = "Expected spy to have been called with " + jasmine.pp(args) + " but was called with " + actual.argsForCall;
}
return message;
}
});
/**
* Matcher that checks to see if the acutal, a Jasmine spy, was called with a set of parameters.
@ -165,78 +282,89 @@ jasmine.Matchers.prototype.wasNotCalled = function() {
* @example
*
*/
jasmine.Matchers.prototype.wasCalledWith = function() {
if (!this.actual || !this.actual.isSpy) {
return this.report(false, 'Expected a spy, but got ' + jasmine.Matchers.pp(this.actual) + '.', {
matcherName: 'wasCalledWith'
});
}
var args = jasmine.util.argsToArray(arguments);
return this.report(this.env.contains_(this.actual.argsForCall, args),
'Expected ' + jasmine.Matchers.pp(this.actual.argsForCall) + ' to contain ' + jasmine.Matchers.pp(args) + ', but it does not.', {
matcherName: 'wasCalledWith', expected: args, actual: this.actual.argsForCall
});
};
/**
* Matcher that checks that the expected item is an element in the actual Array.
*
* @param {Object} item
*/
jasmine.Matchers.prototype.toContain = function(item) {
return this.report(this.env.contains_(this.actual, item),
'Expected ' + jasmine.Matchers.pp(this.actual) + ' to contain ' + jasmine.Matchers.pp(item) + ', but it does not.', {
matcherName: 'toContain', expected: item, actual: this.actual
});
};
jasmine.Matchers.addMatcher('toContain', {
test: function(actual, expected) {
return this.env.contains_(actual, expected);
},
message: function(actual, expected) {
return 'Expected ' + jasmine.pp(actual) + ' to contain ' + jasmine.pp(expected);
}
});
/**
* Matcher that checks that the expected item is NOT an element in the actual Array.
*
* @param {Object} item
*/
jasmine.Matchers.prototype.toNotContain = function(item) {
return this.report(!this.env.contains_(this.actual, item),
'Expected ' + jasmine.Matchers.pp(this.actual) + ' not to contain ' + jasmine.Matchers.pp(item) + ', but it does.');
};
jasmine.Matchers.addMatcher('toNotContain', {
test: function(actual, expected) {
return !this.env.contains_(actual, expected);
},
message: function(actual, expected) {
return 'Expected ' + jasmine.pp(actual) + ' to not contain ' + jasmine.pp(expected);
}
});
jasmine.Matchers.prototype.toBeLessThan = function(expected) {
return this.report(this.actual < expected,
'Expected ' + jasmine.Matchers.pp(this.actual) + ' to be less than ' + jasmine.Matchers.pp(expected) + ', but it was not.');
};
jasmine.Matchers.addMatcher('toBeLessThan', {
test: function(actual, expected) {
return actual < expected;
},
message: function(actual, expected) {
return 'Expected ' + jasmine.pp(actual) + ' to be less than ' + jasmine.pp(expected);
}
});
jasmine.Matchers.prototype.toBeGreaterThan = function(expected) {
return this.report(this.actual > expected,
'Expected ' + jasmine.Matchers.pp(this.actual) + ' to be greater than ' + jasmine.Matchers.pp(expected) + ', but it was not.');
};
jasmine.Matchers.addMatcher('toBeGreaterThan', {
test: function(actual, expected) {
return actual > expected;
},
message: function(actual, expected) {
return 'Expected ' + jasmine.pp(actual) + ' to be greater than ' + jasmine.pp(expected);
}
});
/**
* Matcher that checks that the expected exception was thrown by the actual.
*
* @param {String} expectedException
*/
jasmine.Matchers.prototype.toThrow = function(expectedException) {
var exception = null;
try {
this.actual();
} catch (e) {
exception = e;
}
if (expectedException !== undefined) {
if (exception == null) {
return this.report(false, "Expected function to throw " + jasmine.Matchers.pp(expectedException) + ", but it did not.");
jasmine.Matchers.addMatcher('toThrow', {
getException_: function(actual, expected) {
var exception;
if (typeof actual != 'function') {
throw new Error('Actual is not a function');
}
try {
actual();
} catch (e) {
exception = e;
}
return exception;
},
test: function(actual, expected) {
var result = false;
var exception = this.getException_(actual, expected);
if (exception) {
result = (expected === undefined || this.env.equals_(exception.message || exception, expected.message || expected));
}
return result;
},
message: function(actual, expected) {
var exception = this.getException_(actual, expected);
if (exception && (expected === undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) {
return ["Expected function to throw", expected.message || expected, ", but it threw", exception.message || exception ].join(' ');
} else {
return "Expected function to throw an exception.";
}
return this.report(
this.env.equals_(
exception.message || exception,
expectedException.message || expectedException),
"Expected function to throw " + jasmine.Matchers.pp(expectedException) + ", but it threw " + jasmine.Matchers.pp(exception) + ".");
} else {
return this.report(exception != null, "Expected function to throw an exception, but it did not.");
}
};
});
jasmine.Matchers.Any = function(expectedClass) {
this.expectedClass = expectedClass;

View File

@ -57,8 +57,12 @@ jasmine.Spec.prototype.addToQueue = function (block) {
}
};
jasmine.Spec.prototype.addMatcherResult = function(result) {
this.results_.addResult(result);
};
jasmine.Spec.prototype.expect = function(actual) {
return new (this.getMatchersClass_())(this.env, actual, this.results_);
return new (this.getMatchersClass_())(this.env, actual, this);
};
jasmine.Spec.prototype.waits = function(timeout) {
@ -74,7 +78,11 @@ jasmine.Spec.prototype.waitsFor = function(timeout, latchFunction, timeoutMessag
};
jasmine.Spec.prototype.fail = function (e) {
this.results_.addResult(new jasmine.ExpectationResult(false, e ? jasmine.util.formatException(e) : null, null));
var expectationResult = new jasmine.ExpectationResult({
passed: false,
message: e ? jasmine.util.formatException(e) : 'Exception'
});
this.results_.addResult(expectationResult);
};
jasmine.Spec.prototype.getMatchersClass_ = function() {

View File

@ -51,12 +51,18 @@ jasmine.MessageResult = function(text) {
this.trace = new Error(); // todo: test better
};
jasmine.ExpectationResult = function(passed, message, details) {
jasmine.ExpectationResult = function(params) {
this.type = 'ExpectationResult';
this.passed_ = passed;
this.message = message;
this.details = details;
this.trace = new Error(message); // todo: test better
this.matcherName = params.matcherName;
this.passed_ = params.passed;
this.expected = params.expected;
this.actual = params.actual;
/** @deprecated */
this.details = params.details;
this.message = this.passed_ ? 'Passed.' : params.message;
this.trace = this.passed_ ? '' : new Error(this.message);
};
jasmine.ExpectationResult.prototype.passed = function () {
@ -524,4 +530,4 @@ jasmine.include = function(url, opt_global) {
return eval(xhr.responseText);
}
};
};

View File

@ -57,3 +57,8 @@ jasmine.util.argsToArray = function(args) {
return arrayOfArgs;
};
jasmine.util.extend = function(destination, source) {
for (var property in source) destination[property] = source[property];
return destination;
};