Squashed matchers refactor - matchers now unit-testable apart from Expectation and Spec.

This commit is contained in:
Davis W. Frank
2013-05-28 16:54:01 -07:00
parent aca43bd3a3
commit 5700ace2c9
16 changed files with 1949 additions and 1719 deletions

39
spec/core/AnySpec.js Normal file
View File

@@ -0,0 +1,39 @@
describe("Any", function() {
it("matches a string", function() {
var any = new j$.Any(String);
expect(any.jasmineMatches("foo")).toBe(true);
});
it("matches a number", function() {
var any = new j$.Any(Number);
expect(any.jasmineMatches(1)).toBe(true);
});
it("matches a function", function() {
var any = new j$.Any(Function);
expect(any.jasmineMatches(function(){})).toBe(true);
});
it("matches an Object", function() {
var any = new j$.Any(Object);
expect(any.jasmineMatches({})).toBe(true);
});
it("matches another constructed object", function() {
var Thing = function() {},
any = new j$.Any(Thing);
expect(any.jasmineMatches(new Thing())).toBe(true);
});
it("jasmineToString's itself", function() {
var any = new j$.Any(Number);
expect(any.jasmineToString()).toMatch('<jasmine.any');
});
});

View File

@@ -28,85 +28,6 @@ describe("Env", function() {
});
});
describe("equality testing", function() {
describe("with custom equality testers", function() {
var aObj, bObj, isEqual;
beforeEach(function() {
env.addEqualityTester(function(a, b) {
aObj = a;
bObj = b;
return isEqual;
});
});
it("should call the custom equality tester with two objects for comparison", function() {
env.equals_("1", "2");
expect(aObj).toEqual("1");
expect(bObj).toEqual("2");
});
describe("when the custom equality tester returns false", function() {
beforeEach(function() {
isEqual = false;
});
it("should give custom equality testers precedence", function() {
expect(env.equals_('abc', 'abc')).toBeFalsy();
var o = {};
expect(env.equals_(o, o)).toBeFalsy();
});
});
describe("when the custom equality tester returns true", function() {
beforeEach(function() {
isEqual = true;
});
it("should give custom equality testers precedence", function() {
expect(env.equals_('abc', 'def')).toBeTruthy();
expect(env.equals_(true, false)).toBeTruthy();
});
});
describe("when the custom equality tester returns undefined", function() {
beforeEach(function() {
isEqual = jasmine.undefined;
});
it("should use normal equality rules", function() {
expect(env.equals_('abc', 'abc')).toBeTruthy();
expect(env.equals_('abc', 'def')).toBeFalsy();
});
describe("even if there are several", function() {
beforeEach(function() {
env.addEqualityTester(function(a, b) {
return jasmine.undefined;
});
env.addEqualityTester(function(a, b) {
return jasmine.undefined;
});
});
it("should use normal equality rules", function() {
expect(env.equals_('abc', 'abc')).toBeTruthy();
expect(env.equals_('abc', 'def')).toBeFalsy();
});
});
});
it("should evaluate custom equality testers in the order they are declared", function() {
isEqual = false;
env.addEqualityTester(function(a, b) {
return true;
});
expect(env.equals_('abc', 'abc')).toBeFalsy();
});
});
});
describe("#catchException", function() {
it("returns true if the exception is a pending spec exception", function() {
env.catchExceptions(false);
@@ -129,8 +50,10 @@ describe("Env", function() {
}).toThrow(j$.Spec.pendingSpecExceptionMessage);
});
});
});
// TODO: move these into a separate file
describe("Env (integration)", function() {
it("Suites execute as expected (no nesting)", function() {
@@ -301,4 +224,100 @@ describe("Env (integration)", function() {
expect(nestedSpec.getFullName()).toBe("my tests are sometimes singly nested.");
expect(doublyNestedSpec.getFullName()).toBe("my tests are sometimes even doubly nested.");
});
it("Custom equality testers should be per spec", function() {
var env = new j$.Env({global: { setTimeout: setTimeout }}),
reporter = jasmine.createSpyObj('fakeReproter', [
"jasmineStarted",
"jasmineDone",
"suiteStarted",
"suiteDone",
"specStarted",
"specDone"
]);
env.addReporter(reporter);
env.describe("testing custom equality testers", function() {
env.it("with a custom tester", function() {
env.addCustomEqualityTester(function(a, b) { return true; });
env.expect("a").toEqual("b");
});
env.it("without a custom tester", function() {
env.expect("a").toEqual("b");
});
});
env.execute();
var firstSpecResult = reporter.specDone.argsForCall[0][0],
secondSpecResult = reporter.specDone.argsForCall[1][0];
expect(firstSpecResult.status).toEqual("passed");
expect(secondSpecResult.status).toEqual("failed");
});
it("Custom matchers should be per spec", function() {
var env = new j$.Env({global: { setTimeout: setTimeout }}),
matchers = {
toFoo: function() {}
},
reporter = jasmine.createSpyObj('fakeReproter', [
"jasmineStarted",
"jasmineDone",
"suiteStarted",
"suiteDone",
"specStarted",
"specDone"
]);
env.addReporter(reporter);
env.describe("testing custom matchers", function() {
env.it("with a custom matcher", function() {
env.addMatchers(matchers);
expect(env.expect().toFoo).toBeDefined();
});
env.it("without a custom matcher", function() {
expect(env.expect().toFoo).toBeUndefined();
});
});
env.execute();
});
it("Custom equality testers for toContain should be per spec", function() {
var env = new j$.Env({global: { setTimeout: setTimeout }}),
reporter = jasmine.createSpyObj('fakeReproter', [
"jasmineStarted",
"jasmineDone",
"suiteStarted",
"suiteDone",
"specStarted",
"specDone"
]);
env.addReporter(reporter);
env.describe("testing custom equality testers", function() {
env.it("with a custom tester", function() {
env.addCustomEqualityTester(function(a, b) { return true; });
env.expect(["a"]).toContain("b");
});
env.it("without a custom tester", function() {
env.expect("a").toContain("b");
});
});
env.execute();
var firstSpecResult = reporter.specDone.argsForCall[0][0],
secondSpecResult = reporter.specDone.argsForCall[1][0];
expect(firstSpecResult.status).toEqual("passed");
expect(secondSpecResult.status).toEqual("failed");
});
});

View File

@@ -0,0 +1,320 @@
describe("Expectation", function() {
it(".addMatchers makes matchers available to any expectation", function() {
var matchers = {
toFoo: function() {},
toBar: function() {}
},
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({});
expect(expectation.toFoo).toBeDefined();
expect(expectation.toBar).toBeDefined();
});
it(".addCoreMatchers makes matchers available to any expectation", function() {
var coreMatchers = {
toQuux: function() {}
},
expectation;
j$.Expectation.addCoreMatchers(coreMatchers);
expectation = new j$.Expectation({});
expect(expectation.toQuux).toBeDefined();
});
it(".resetMatchers should keep only core matchers", function() {
var matchers = {
toFoo: function() {}
},
coreMatchers = {
toQuux: function() {}
},
expectation;
j$.Expectation.addCoreMatchers(coreMatchers);
j$.Expectation.addMatchers(matchers);
j$.Expectation.resetMatchers();
expectation = new j$.Expectation({});
expect(expectation.toQuux).toBeDefined();
expect(expectation.toFoo).toBeUndefined();
});
it("Factory builds an expectaion/negative expectation", function() {
var builtExpectation = j$.Expectation.Factory();
expect(builtExpectation instanceof j$.Expectation).toBe(true);
expect(builtExpectation.not instanceof j$.Expectation).toBe(true);
expect(builtExpectation.not.isNot).toBe(true);
});
it("wraps matchers's compare functions, passing in matcher dependencies", function() {
var fakeCompare = function() { return { pass: true }; },
matcherFactory = jasmine.createSpy("matcher").andReturn({ compare: fakeCompare }),
matchers = {
toFoo: matcherFactory
},
util = {},
customEqualityTesters = ['a'],
addExpectationResult = jasmine.createSpy("addExpectationResult"),
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({
util: util,
customEqualityTesters: customEqualityTesters,
actual: "an actual",
addExpectationResult: addExpectationResult
});
expectation.toFoo("hello");
expect(matcherFactory).toHaveBeenCalledWith(util, customEqualityTesters)
});
it("wraps matchers's compare functions, passing the actual and expected", function() {
var fakeCompare = jasmine.createSpy('fake-compare').andReturn({pass: true}),
matchers = {
toFoo: function() {
return {
compare: fakeCompare
};
}
},
util = {
buildFailureMessage: jasmine.createSpy('buildFailureMessage')
},
addExpectationResult = jasmine.createSpy("addExpectationResult"),
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({
util: util,
actual: "an actual",
addExpectationResult: addExpectationResult
});
expectation.toFoo("hello");
expect(fakeCompare).toHaveBeenCalledWith("an actual", "hello");
});
it("reports a passing result to the spec when the comparison passes", function() {
var matchers = {
toFoo: function() {
return {
compare: function() { return { pass: true }; }
};
}
},
util = {
buildFailureMessage: jasmine.createSpy('buildFailureMessage')
},
addExpectationResult = jasmine.createSpy("addExpectationResult"),
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({
matchers: matchers,
util: util,
actual: "an actual",
addExpectationResult: addExpectationResult
});
expectation.toFoo("hello");
expect(addExpectationResult).toHaveBeenCalledWith(true, {
matcherName: "toFoo",
passed: true,
message: "",
expected: "hello",
actual: "an actual"
});
});
it("reports a failing result to the spec when the comparison fails", function() {
var matchers = {
toFoo: function() {
return {
compare: function() { return { pass: false }; }
};
}
},
util = {
buildFailureMessage: function() { return ""; }
},
addExpectationResult = jasmine.createSpy("addExpectationResult"),
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({
matchers: matchers,
util: util,
actual: "an actual",
addExpectationResult: addExpectationResult
});
expectation.toFoo("hello");
expect(addExpectationResult).toHaveBeenCalledWith(false, {
matcherName: "toFoo",
passed: false,
expected: "hello",
actual: "an actual",
message: ""
});
});
it("reports a failing result and a custom fail message to the spec when the comparison fails", function() {
var matchers = {
toFoo: function() {
return {
compare: function() {
return {
pass: false,
message: "I am a custom message"
};
}
};
}
},
addExpectationResult = jasmine.createSpy("addExpectationResult"),
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({
matchers: matchers,
actual: "an actual",
addExpectationResult: addExpectationResult
});
expectation.toFoo("hello");
expect(addExpectationResult).toHaveBeenCalledWith(false, {
matcherName: "toFoo",
passed: false,
expected: "hello",
actual: "an actual",
message: "I am a custom message"
});
});
it("reports a passing result to the spec when the comparison fails for a negative expectation", function() {
var matchers = {
toFoo: function() {
return {
compare: function() { return { pass: false }; }
};
}
},
util = {
buildFailureMessage: function() { return ""; }
},
addExpectationResult = jasmine.createSpy("addExpectationResult"),
actual = "an actual",
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({
matchers: matchers,
actual: "an actual",
addExpectationResult: addExpectationResult,
isNot: true
});
expectation.toFoo("hello");
expect(addExpectationResult).toHaveBeenCalledWith(true, {
matcherName: "toFoo",
passed: true,
message: "",
expected: "hello",
actual: actual
});
});
it("reports a failing result to the spec when the comparison passes for a negative expectation", function() {
var matchers = {
toFoo: function() {
return {
compare: function() { return { pass: true }; }
};
}
},
util = {
buildFailureMessage: function() { return "default messge"; }
},
addExpectationResult = jasmine.createSpy("addExpectationResult"),
actual = "an actual",
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({
matchers: matchers,
actual: "an actual",
util: util,
addExpectationResult: addExpectationResult,
isNot: true
});
expectation.toFoo("hello");
expect(addExpectationResult).toHaveBeenCalledWith(false, {
matcherName: "toFoo",
passed: false,
expected: "hello",
actual: actual,
message: "default messge"
});
});
it("reports a failing result and a custom fail message to the spec when the comparison passes for a negative expectation", function() {
var matchers = {
toFoo: function() {
return {
compare: function() {
return {
pass: true,
message: "I am a custom message"
};
}
};
}
},
addExpectationResult = jasmine.createSpy("addExpectationResult"),
actual = "an actual",
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({
matchers: matchers,
actual: "an actual",
addExpectationResult: addExpectationResult,
isNot: true
});
expectation.toFoo("hello");
expect(addExpectationResult).toHaveBeenCalledWith(false, {
matcherName: "toFoo",
passed: false,
expected: "hello",
actual: actual,
message: "I am a custom message"
});
});
});

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,38 @@
describe("ObjectContaining", function() {
it("matches any actual to an empty object", function() {
var containing = new j$.ObjectContaining({});
expect(containing.jasmineMatches("foo")).toBe(true);
});
it("does not match an empty object actual", function() {
var containing = new j$.ObjectContaining("foo");
expect(containing.jasmineMatches({})).toBe(false);
});
it("matches when the key/value pair is present in the actual", function() {
var containing = new jasmine.Matchers.ObjectContaining({foo: "fooVal"});
expect(containing.jasmineMatches({foo: "fooVal", bar: "barVal"})).toBe(true);
});
it("does not match when the key/value pair is not present in the actual", function() {
var containing = new jasmine.Matchers.ObjectContaining({foo: "fooVal"});
expect(containing.jasmineMatches({bar: "barVal", quux: "quuxVal"})).toBe(false);
});
it("does not match when the key is present but the value is different in the actual", function() {
var containing = new jasmine.Matchers.ObjectContaining({foo: "other"});
expect(containing.jasmineMatches({foo: "fooVal", bar: "barVal"})).toBe(false);
});
it("jasmineToString's itself", function() {
var containing = new j$.ObjectContaining({});
expect(containing.jasmineToString()).toMatch("<jasmine.objectContaining");
});
});

600
spec/core/matchersSpec.js Normal file
View File

@@ -0,0 +1,600 @@
describe("Matchers", function() {
describe("toBe", function() {
it("passes when actual === expected", function() {
var matcher = j$.matchers.toBe(),
result;
result = matcher.compare(1, 1);
expect(result.pass).toBe(true);
});
it("fails when actual !== expected", function() {
var matcher = j$.matchers.toBe(),
result;
result = matcher.compare(1, 2);
expect(result.pass).toBe(false);
});
});
describe("toBeCloseTo", function() {
it("passes when within two decimal places by default", function() {
var matcher = j$.matchers.toBeCloseTo(),
result;
result = matcher.compare(0, 0);
expect(result.pass).toBe(true);
result = matcher.compare(0, 0.001);
expect(result.pass).toBe(true);
});
it("fails when not within two decimal places by default", function() {
var matcher = j$.matchers.toBeCloseTo(),
result;
result = matcher.compare(0, 0.01);
expect(result.pass).toBe(false);
});
it("accepts an optional precision argument", function() {
var matcher = j$.matchers.toBeCloseTo(),
result;
result = matcher.compare(0, 0.1, 0);
expect(result.pass).toBe(true);
result = matcher.compare(0, 0.0001, 3);
expect(result.pass).toBe(true);
});
it("rounds expected values", function() {
var matcher = j$.matchers.toBeCloseTo(),
result;
result = matcher.compare(1.23, 1.229);
expect(result.pass).toBe(true);
result = matcher.compare(1.23, 1.226);
expect(result.pass).toBe(true);
result = matcher.compare(1.23, 1.225);
expect(result.pass).toBe(true);
result = matcher.compare(1.23, 1.2249999);
expect(result.pass).toBe(false);
result = matcher.compare(1.23, 1.234);
expect(result.pass).toBe(true);
});
});
describe("toBeDefined", function() {
it("matches for defined values", function() {
var matcher = j$.matchers.toBeDefined(),
result;
result = matcher.compare('foo');
expect(result.pass).toBe(true);
});
it("fails when matching undefined values", function() {
var matcher = j$.matchers.toBeDefined(),
result;
result = matcher.compare(void 0);
expect(result.pass).toBe(false);
})
});
describe("toBeFalsy", function() {
it("passes for 'falsy' values", function() {
var matcher = j$.matchers.toBeFalsy(),
result;
result = matcher.compare(false);
expect(result.pass).toBe(true);
result = matcher.compare(0);
expect(result.pass).toBe(true);
result = matcher.compare('');
expect(result.pass).toBe(true);
result = matcher.compare(null);
expect(result.pass).toBe(true);
result = matcher.compare(void 0);
expect(result.pass).toBe(true);
});
it("fails for 'truthy' values", function() {
var matcher = j$.matchers.toBeFalsy(),
result;
result = matcher.compare(true);
expect(result.pass).toBe(false);
result = matcher.compare(1);
expect(result.pass).toBe(false);
result = matcher.compare("foo");
expect(result.pass).toBe(false);
result = matcher.compare({});
expect(result.pass).toBe(false);
});
});
describe("toBeGreaterThan", function() {
it("passes when actual > expected", function() {
var matcher = j$.matchers.toBeGreaterThan(),
result;
result = matcher.compare(2, 1);
expect(result.pass).toBe(true);
});
it("fails when actual <= expected", function() {
var matcher = j$.matchers.toBeGreaterThan();
result = matcher.compare(1, 1);
expect(result.pass).toBe(false);
result = matcher.compare(1, 2);
expect(result.pass).toBe(false);
});
});
describe("toBeLessThan", function() {
it("passes when actual < expected", function() {
var matcher = j$.matchers.toBeLessThan(),
result;
result = matcher.compare(1, 2);
expect(result.pass).toBe(true);
});
it("fails when actual <= expected", function() {
var matcher = j$.matchers.toBeLessThan(),
result;
result = matcher.compare(1, 1);
expect(result.pass).toBe(false);
result = matcher.compare(2, 1);
expect(result.pass).toBe(false);
});
});
describe("toBeNaN", function() {
it("passes for NaN with a custom .not fail", function() {
var matcher = j$.matchers.toBeNaN(),
result;
result = matcher.compare(Number.NaN);
expect(result.pass).toBe(true);
expect(result.message).toEqual("Expected actual not to be NaN.");
});
it("fails for anything not a NaN", function() {
var matcher = j$.matchers.toBeNaN();
result = matcher.compare(1);
expect(result.pass).toBe(false);
result = matcher.compare(null);
expect(result.pass).toBe(false);
result = matcher.compare(void 0);
expect(result.pass).toBe(false);
result = matcher.compare('');
expect(result.pass).toBe(false);
result = matcher.compare(Number.POSITIVE_INFINITY);
expect(result.pass).toBe(false);
});
it("has a custom message on failure", function() {
var matcher = j$.matchers.toBeNaN(),
result = matcher.compare(0);
expect(result.message).toEqual("Expected 0 to be NaN.");
});
});
describe("toBeNull", function() {
it("passes for null", function() {
var matcher = j$.matchers.toBeNull(),
result;
result = matcher.compare(null);
expect(result.pass).toBe(true);
});
it("fails for non-null", function() {
var matcher = j$.matchers.toBeNull(),
result;
result = matcher.compare('foo');
expect(result.pass).toBe(false);
});
});
describe("toBeTruthy", function() {
it("passes for 'truthy' values", function() {
var matcher = j$.matchers.toBeTruthy(),
result;
result = matcher.compare(true);
expect(result.pass).toBe(true);
result = matcher.compare(1);
expect(result.pass).toBe(true);
result = matcher.compare("foo");
expect(result.pass).toBe(true);
result = matcher.compare({});
expect(result.pass).toBe(true);
});
it("fails for 'falsy' values", function() {
var matcher = j$.matchers.toBeTruthy(),
result;
result = matcher.compare(false);
expect(result.pass).toBe(false);
result = matcher.compare(0);
expect(result.pass).toBe(false);
result = matcher.compare('');
expect(result.pass).toBe(false);
result = matcher.compare(null);
expect(result.pass).toBe(false);
result = matcher.compare(void 0);
expect(result.pass).toBe(false);
});
});
describe("toBeUndefined", function() {
it("passes for undefined values", function() {
var matcher = j$.matchers.toBeUndefined(),
result;
result = matcher.compare(void 0);
expect(result.pass).toBe(true);
});
it("fails when matching defined values", function() {
var matcher = j$.matchers.toBeUndefined();
result = matcher.compare('foo');
expect(result.pass).toBe(false);
})
});
describe("toContain", function() {
it("delegates to j$.matchersUtil.contains", function() {
var util = {
contains: j$.createSpy('delegated-contains').andReturn(true)
},
matcher = j$.matchers.toContain(util);
result = matcher.compare("ABC", "B");
expect(util.contains).toHaveBeenCalledWith("ABC", "B", []);
expect(result.pass).toBe(true);
});
it("delegates to j$.matchersUtil.contains, passing in equality testers if present", function() {
var util = {
contains: j$.createSpy('delegated-contains').andReturn(true)
},
customEqualityTesters = ['a', 'b'],
matcher = j$.matchers.toContain(util, customEqualityTesters);
result = matcher.compare("ABC", "B");
expect(util.contains).toHaveBeenCalledWith("ABC", "B", ['a', 'b']);
expect(result.pass).toBe(true);
});
});
describe("toEqual", function() {
it("delegates to equals function", function() {
var util = {
equals: j$.createSpy('delegated-equals').andReturn(true)
},
matcher = j$.matchers.toEqual(util),
result;
result = matcher.compare(1, 1);
expect(util.equals).toHaveBeenCalledWith(1, 1, []);
expect(result.pass).toBe(true);
});
it("delegates custom equality testers, if present", function() {
var util = {
equals: j$.createSpy('delegated-equals').andReturn(true)
},
customEqualityTesters = ['a', 'b'],
matcher = j$.matchers.toEqual(util, customEqualityTesters),
result;
result = matcher.compare(1, 1);
expect(util.equals).toHaveBeenCalledWith(1, 1, ['a', 'b']);
expect(result.pass).toBe(true);
});
});
describe("toHaveBeenCalled", function() {
it("passes when the actual was called, with a custom .not fail message", function() {
var matcher = j$.matchers.toHaveBeenCalled(),
calledSpy = j$.createSpy('called-spy'),
result;
calledSpy();
result = matcher.compare(calledSpy);
expect(result.pass).toBe(true);
expect(result.message).toEqual("Expected spy called-spy not to have been called.");
});
it("fails when the actual was not called", function() {
var matcher = j$.matchers.toHaveBeenCalled(),
uncalledSpy = j$.createSpy('uncalled spy');
result = matcher.compare(uncalledSpy);
expect(result.pass).toBe(false);
});
it("throws an exception when the actual is not a spy", function() {
var matcher = j$.matchers.toHaveBeenCalled(),
fn = function() {};
expect(function() { matcher.compare(fn) }).toThrow(new Error("Expected a spy, but got Function."));
});
it("throws an exception when invoked with any arguments", function() {
var matcher = j$.matchers.toHaveBeenCalled(),
spy = j$.createSpy('sample spy');
expect(function() { matcher.compare(spy, 'foo') }).toThrow(new Error("toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith"));
});
it("has a custom message on failure", function() {
var matcher = j$.matchers.toHaveBeenCalled(),
spy = j$.createSpy('sample-spy'),
result;
result = matcher.compare(spy);
expect(result.message).toEqual("Expected spy sample-spy to have been called.");
});
});
describe("toHaveBeenCalledWith", function() {
it("passes when the actual was called with matching parameters", function() {
var util = {
contains: j$.createSpy('delegated-contains').andReturn(true)
},
matcher = j$.matchers.toHaveBeenCalledWith(util)
calledSpy = j$.createSpy('called-spy'),
result;
calledSpy('a', 'b');
result = matcher.compare(calledSpy, 'a', 'b');
expect(result.pass).toBe(true);
});
it("fails when the actual was not called", function() {
var util = {
contains: j$.createSpy('delegated-contains').andReturn(false)
},
matcher = j$.matchers.toHaveBeenCalledWith(util),
uncalledSpy = j$.createSpy('uncalled spy'),
result;
result = matcher.compare(uncalledSpy);
expect(result.pass).toBe(false);
});
it("fails when the actual was called with different parameters", function() {
var util = {
contains: j$.createSpy('delegated-contains').andReturn(false)
},
matcher = j$.matchers.toHaveBeenCalledWith(util),
calledSpy = j$.createSpy('called spy'),
result;
calledSpy('a');
result = matcher.compare(calledSpy, 'a', 'b');
expect(result.pass).toBe(false);
});
it("throws an exception when the actual is not a spy", function() {
var matcher = j$.matchers.toHaveBeenCalledWith(),
fn = function() {};
expect(function() { matcher.compare(fn) }).toThrow(new Error("Expected a spy, but got Function."));
});
it("has a custom message on failure", function() {
var matcher = j$.matchers.toHaveBeenCalledWith(),
spy = j$.createSpy('sample-spy'),
messages = matcher.message(spy);
expect(messages.affirmative).toEqual("Expected spy sample-spy to have been called.")
expect(messages.negative).toEqual("Expected spy sample-spy not to have been called.")
});
});
describe("toMatch", function() {
it("passes when RegExps are equivalent", function() {
var matcher = j$.matchers.toMatch(),
result;
result = matcher.compare(/foo/, /foo/);
expect(result.pass).toBe(true);
});
it("fails when RegExps are not equivalent", function() {
var matcher = j$.matchers.toMatch(),
result;
result = matcher.compare(/bar/, /foo/);
expect(result.pass).toBe(false);
});
it("passes when the actual matches the expected string as a pattern", function() {
var matcher = j$.matchers.toMatch(),
result;
result = matcher.compare('foosball', 'foo');
expect(result.pass).toBe(true);
});
it("fails when the actual matches the expected string as a pattern", function() {
var matcher = j$.matchers.toMatch(),
result;
result = matcher.compare('bar', 'foo');
expect(result.pass).toBe(false);
});
});
describe("toThrow", function() {
it("throw an error when the acutal is not a function ", function() {
var matcher = j$.matchers.toThrow();
expect(function() {
matcher.compare({});
}).toThrow(new Error("Actual is not a Function"));
});
it("throws an error when the expected can't be turned into an exception", function() {
var matcher = j$.matchers.toThrow(),
fn = function() {
throw "foo";
},
result;
expect(function() {
matcher.compare(fn, 1);
}).toThrow(new Error("Expected cannot be treated as an exception."));
});
it("passes if the actual throws any exception", function() {
var matcher = j$.matchers.toThrow(),
fn = function() {
throw "foo";
},
result;
result = matcher.compare(fn);
expect(result.pass).toBe(true);
expect(result.message).toEqual("Expected function not to throw an exception.");
});
it("fails if the actual does not throw an exception", function() {
var matcher = j$.matchers.toThrow(),
fn = function() {
return 0;
},
result;
result = matcher.compare(fn);
expect(result.pass).toBe(false);
expect(result.message).toEqual("Expected function to throw an exception.");
});
it("passes if the actual throws an exception with the expected message", function() {
var matcher = j$.matchers.toThrow(),
fn = function() {
throw "foo";
},
result;
result = matcher.compare(fn, "foo");
expect(result.pass).toBe(true);
expect(result.message).toEqual("Expected function not to throw an exception \"foo\".");
});
it("fails if the actual throws an exception with a different message", function() {
var matcher = j$.matchers.toThrow(),
fn = function() {
throw "foo";
},
result;
result = matcher.compare(fn, "bar");
expect(result.pass).toBe(false);
expect(result.message).toEqual("Expected function to throw an exception \"bar\".");
});
it("passes if the actual throws an exception and matches the message of the expected exception", function() {
var matcher = j$.matchers.toThrow(),
fn = function() {
throw "foo";
},
result;
result = matcher.compare(fn, new Error("foo"));
expect(result.pass).toBe(true);
expect(result.message).toEqual("Expected function not to throw an exception \"foo\".");
});
it("fails if the actual throws an exception and it does not match the message of the expected exception with a custom message", function() {
var matcher = j$.matchers.toThrow(),
fn = function() {
throw "foo";
},
result;
result = matcher.compare(fn, new Error("bar"));
expect(result.pass).toBe(false);
expect(result.message).toEqual("Expected function to throw an exception \"bar\".");
});
it("passes if the actual throws an exception and the message matches the expected regular expression", function() {
var matcher = j$.matchers.toThrow(),
fn = function() {
throw "a long message";
},
result;
result = matcher.compare(fn, /long/);
expect(result.pass).toBe(true);
expect(result.message).toEqual("Expected function not to throw an exception matching /long/.");
});
it("fails if the actual throws an exception and the message does not match the expected regular expression", function() {
var matcher = j$.matchers.toThrow(),
fn = function() {
throw "a long message";
},
result;
result = matcher.compare(fn, /short/);
expect(result.pass).toBe(false);
expect(result.message).toEqual("Expected function to throw an exception matching /short/.");
});
});
});

View File

@@ -0,0 +1,199 @@
describe("matchersUtil", function() {
describe("equals", function() {
it("passes for literals that are threequal", function() {
expect(j$.matchersUtil.equals(null, null)).toBe(true);
expect(j$.matchersUtil.equals(void 0, void 0)).toBe(true);
});
it("fails for things that are not equivalent", function() {
expect(j$.matchersUtil.equals({a: "foo"}, 1)).toBe(false);
});
it("passes for Strings that are equivalent", function() {
expect(j$.matchersUtil.equals("foo", "foo")).toBe(true);
});
it("fails for Strings that are not equivalent", function() {
expect(j$.matchersUtil.equals("foo", "bar")).toBe(false);
});
it("passes for Numbers that are equivalent", function() {
expect(j$.matchersUtil.equals(123, 123)).toBe(true);
});
it("fails for Numbers that are not equivalent", function() {
expect(j$.matchersUtil.equals(123, 456)).toBe(false);
});
it("passes for Dates that are equivalent", function() {
expect(j$.matchersUtil.equals(new Date("Jan 1, 1970"), new Date("Jan 1, 1970"))).toBe(true);
});
it("fails for Dates that are not equivalent", function() {
expect(j$.matchersUtil.equals(new Date("Jan 1, 1970"), new Date("Feb 3, 1991"))).toBe(false);
});
it("passes for Booleans that are equivalent", function() {
expect(j$.matchersUtil.equals(true, true)).toBe(true);
});
it("fails for Booleans that are not equivalent", function() {
expect(j$.matchersUtil.equals(true, false)).toBe(false);
});
it("passes for RegExps that are equivalent", function() {
expect(j$.matchersUtil.equals(/foo/, /foo/)).toBe(true);
});
it("fails for RegExps that are not equivalent", function() {
expect(j$.matchersUtil.equals(/foo/, /bar/)).toBe(false);
expect(j$.matchersUtil.equals(new RegExp("foo", "i"), new RegExp("foo"))).toBe(false);
});
it("passes for Arrays that are equivalent", function() {
expect(j$.matchersUtil.equals([1, 2], [1, 2])).toBe(true);
});
it("fails for Arrays that are not equivalent", function() {
expect(j$.matchersUtil.equals([1, 2], [1, 2, 3])).toBe(false);
});
it("passes for Objects that are equivalent (simple case)", function() {
expect(j$.matchersUtil.equals({a: "foo"}, {a: "foo"})).toBe(true);
});
it("fails for Objects that are not equivalent (simple case)", function() {
expect(j$.matchersUtil.equals({a: "foo"}, {a: "bar"})).toBe(false);
});
it("passes for Objects that are equivalent (deep case)", function() {
expect(j$.matchersUtil.equals({a: "foo", b: { c: "bar"}}, {a: "foo", b: { c: "bar"}})).toBe(true);
});
it("fails for Objects that are not equivalent (deep case)", function() {
expect(j$.matchersUtil.equals({a: "foo", b: { c: "baz"}}, {a: "foo", b: { c: "bar"}})).toBe(false);
});
it("passes for Objects that are equivalent (with cycles)", function() {
var actual = { a: "foo" },
expected = { a: "foo" };
actual.b = actual;
expected.b = actual;
expect(j$.matchersUtil.equals(actual, expected)).toBe(true);
});
it("fails for Objects that are not equivalent (with cycles)", function() {
var actual = { a: "foo" },
expected = { a: "bar" };
actual.b = actual;
expected.b = actual;
expect(j$.matchersUtil.equals(actual, expected)).toBe(false);
});
it("fails when comparing an empty object to an empty array (issue #114)", function() {
var emptyObject = {},
emptyArray = [];
expect(j$.matchersUtil.equals(emptyObject, emptyArray)).toBe(false);
expect(j$.matchersUtil.equals(emptyArray, emptyObject)).toBe(false);
});
it("passes when Any is used", function() {
var number = 3,
anyNumber = new j$.Any(Number);
expect(j$.matchersUtil.equals(number, anyNumber)).toBe(true);
expect(j$.matchersUtil.equals(anyNumber, number)).toBe(true);
});
it("fails when Any is compared to something unexepcted", function() {
var number = 3,
anyString = new j$.Any(String);
expect(j$.matchersUtil.equals(number, anyString)).toBe(false);
expect(j$.matchersUtil.equals(anyString, number)).toBe(false);
});
it("passes when ObjectContaining is used", function() {
var obj = {
foo: 3,
bar: 7
};
expect(j$.matchersUtil.equals(obj, new j$.ObjectContaining({foo: 3}))).toBe(true);
});
it("passes when a custom equality matcher returns true", function() {
var tester = function(a, b) { return true; };
expect(j$.matchersUtil.equals(1, 2, [tester])).toBe(true);
});
it("fails for equivalents when a custom equality matcher returns false", function() {
var tester = function(a, b) { return false; };
expect(j$.matchersUtil.equals(1, 2, [tester])).toBe(false);
});
});
describe("contains", function() {
it("passes when expected is a substring of actual", function() {
expect(j$.matchersUtil.contains("ABC", "B")).toBe(true);
});
it("fails when expected is a not substring of actual", function() {
expect(j$.matchersUtil.contains("ABC", "X")).toBe(false);
});
it("passes when expected is an element in an actual array", function() {
expect(j$.matchersUtil.contains(['foo', 'bar'], 'foo')).toBe(true);
});
it("fails when expected is not an element in an actual array", function() {
expect(j$.matchersUtil.contains(['foo', 'bar'], 'baz')).toBe(false);
});
it("passes with mixed-element arrays", function() {
expect(j$.matchersUtil.contains(["foo", {some: "bar"}], "foo")).toBe(true);
expect(j$.matchersUtil.contains(["foo", {some: "bar"}], {some: "bar"})).toBe(true);
});
it("uses custom equality testers if passed in and actual is an Array", function() {
var customTester = function(a,b) {return true;};
expect(j$.matchersUtil.contains([1,2], 2, [customTester])).toBe(true);
});
});
describe("buildMessage", function() {
it("builds an English sentence for a failure case", function() {
var actual = "foo",
name = "toBar",
message = j$.matchersUtil.buildFailureMessage(name, false, actual);
expect(message).toEqual("Expected 'foo' to bar.");
});
it("builds an English sentence for a 'not' failure case", function() {
var actual = "foo",
name = "toBar",
isNot = true,
message = message = j$.matchersUtil.buildFailureMessage(name, isNot, actual);
expect(message).toEqual("Expected 'foo' not to bar.");
});
it("builds an English sentence for an arbitrary array of expected arguments", function(){
var actual = "foo",
name = "toBar",
message = j$.matchersUtil.buildFailureMessage(name, false, actual, "quux", "corge");
expect(message).toEqual("Expected 'foo' to bar 'quux', 'corge'.");
});
});
});