Merge branch 'custom-object-formatters' into cof-merge-candidate

This commit is contained in:
Steve Gravrock
2020-02-11 11:44:38 -08:00
84 changed files with 3047 additions and 1017 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -24,8 +24,9 @@ describe('AsyncExpectation', function() {
var addExpectationResult = jasmine.createSpy('addExpectationResult'), var addExpectationResult = jasmine.createSpy('addExpectationResult'),
actual = Promise.resolve(), actual = Promise.resolve(),
pp = jasmineUnderTest.makePrettyPrinter(),
expectation = jasmineUnderTest.Expectation.asyncFactory({ expectation = jasmineUnderTest.Expectation.asyncFactory({
util: jasmineUnderTest.matchersUtil, matchersUtil: new jasmineUnderTest.MatchersUtil({ pp: pp }),
actual: actual, actual: actual,
addExpectationResult: addExpectationResult addExpectationResult: addExpectationResult
}); });
@@ -47,7 +48,9 @@ describe('AsyncExpectation', function() {
var addExpectationResult = jasmine.createSpy('addExpectationResult'), var addExpectationResult = jasmine.createSpy('addExpectationResult'),
actual = Promise.reject(), actual = Promise.reject(),
expectation = jasmineUnderTest.Expectation.asyncFactory({ expectation = jasmineUnderTest.Expectation.asyncFactory({
util: jasmineUnderTest.matchersUtil, matchersUtil: new jasmineUnderTest.MatchersUtil({
pp: function() {}
}),
actual: actual, actual: actual,
addExpectationResult: addExpectationResult addExpectationResult: addExpectationResult
}); });
@@ -91,7 +94,7 @@ describe('AsyncExpectation', function() {
it('prepends the context to the generated failure message', function() { it('prepends the context to the generated failure message', function() {
jasmine.getEnv().requirePromises(); jasmine.getEnv().requirePromises();
var util = { var matchersUtil = {
buildFailureMessage: function() { buildFailureMessage: function() {
return 'failure message'; return 'failure message';
} }
@@ -100,7 +103,7 @@ describe('AsyncExpectation', function() {
expectation = jasmineUnderTest.Expectation.asyncFactory({ expectation = jasmineUnderTest.Expectation.asyncFactory({
actual: Promise.reject('rejected'), actual: Promise.reject('rejected'),
addExpectationResult: addExpectationResult, addExpectationResult: addExpectationResult,
util: util matchersUtil: matchersUtil
}); });
return expectation return expectation
@@ -119,16 +122,17 @@ describe('AsyncExpectation', function() {
it('prepends the context to a custom failure message', function() { it('prepends the context to a custom failure message', function() {
jasmine.getEnv().requirePromises(); jasmine.getEnv().requirePromises();
var util = { var matchersUtil = {
buildFailureMessage: function() { buildFailureMessage: function() {
return 'failure message'; return 'failure message';
} },
pp: jasmineUnderTest.makePrettyPrinter()
}, },
addExpectationResult = jasmine.createSpy('addExpectationResult'), addExpectationResult = jasmine.createSpy('addExpectationResult'),
expectation = jasmineUnderTest.Expectation.asyncFactory({ expectation = jasmineUnderTest.Expectation.asyncFactory({
actual: Promise.reject('b'), actual: Promise.reject('b'),
addExpectationResult: addExpectationResult, addExpectationResult: addExpectationResult,
util: util matchersUtil: matchersUtil
}); });
return expectation return expectation
@@ -149,7 +153,7 @@ describe('AsyncExpectation', function() {
pending('should actually work, but no custom matchers for async yet'); pending('should actually work, but no custom matchers for async yet');
jasmine.getEnv().requirePromises(); jasmine.getEnv().requirePromises();
var util = { var matchersUtil = {
buildFailureMessage: function() { buildFailureMessage: function() {
return 'failure message'; return 'failure message';
} }
@@ -159,7 +163,7 @@ describe('AsyncExpectation', function() {
expectation = jasmineUnderTest.Expectation.asyncFactory({ expectation = jasmineUnderTest.Expectation.asyncFactory({
actual: actual, actual: actual,
addExpectationResult: addExpectationResult, addExpectationResult: addExpectationResult,
util: util matchersUtil: matchersUtil
}); });
return expectation return expectation
@@ -180,10 +184,11 @@ describe('AsyncExpectation', function() {
var addExpectationResult = jasmine.createSpy('addExpectationResult'), var addExpectationResult = jasmine.createSpy('addExpectationResult'),
actual = Promise.resolve(), actual = Promise.resolve(),
pp = jasmineUnderTest.makePrettyPrinter(),
expectation = jasmineUnderTest.Expectation.asyncFactory({ expectation = jasmineUnderTest.Expectation.asyncFactory({
actual: actual, actual: actual,
addExpectationResult: addExpectationResult, addExpectationResult: addExpectationResult,
util: jasmineUnderTest.matchersUtil matchersUtil: new jasmineUnderTest.MatchersUtil({ pp: pp })
}); });
return expectation return expectation
@@ -208,7 +213,9 @@ describe('AsyncExpectation', function() {
expectation = jasmineUnderTest.Expectation.asyncFactory({ expectation = jasmineUnderTest.Expectation.asyncFactory({
actual: actual, actual: actual,
addExpectationResult: addExpectationResult, addExpectationResult: addExpectationResult,
util: jasmineUnderTest.matchersUtil matchersUtil: new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
})
}); });
return expectation return expectation
@@ -256,7 +263,7 @@ describe('AsyncExpectation', function() {
matchers = { matchers = {
toFoo: matcherFactory toFoo: matcherFactory
}, },
util = { matchersUtil = {
buildFailureMessage: jasmine.createSpy('buildFailureMessage') buildFailureMessage: jasmine.createSpy('buildFailureMessage')
}, },
customEqualityTesters = ['a'], customEqualityTesters = ['a'],
@@ -264,7 +271,7 @@ describe('AsyncExpectation', function() {
expectation; expectation;
expectation = jasmineUnderTest.Expectation.asyncFactory({ expectation = jasmineUnderTest.Expectation.asyncFactory({
util: util, matchersUtil: matchersUtil,
customAsyncMatchers: matchers, customAsyncMatchers: matchers,
customEqualityTesters: customEqualityTesters, customEqualityTesters: customEqualityTesters,
actual: 'an actual', actual: 'an actual',
@@ -273,7 +280,7 @@ describe('AsyncExpectation', function() {
return expectation.toFoo('hello').then(function() { return expectation.toFoo('hello').then(function() {
expect(matcherFactory).toHaveBeenCalledWith( expect(matcherFactory).toHaveBeenCalledWith(
util, matchersUtil,
customEqualityTesters customEqualityTesters
); );
}); });
@@ -292,14 +299,14 @@ describe('AsyncExpectation', function() {
}; };
} }
}, },
util = { matchersUtil = {
buildFailureMessage: jasmine.createSpy('buildFailureMessage') buildFailureMessage: jasmine.createSpy('buildFailureMessage')
}, },
addExpectationResult = jasmine.createSpy('addExpectationResult'), addExpectationResult = jasmine.createSpy('addExpectationResult'),
expectation; expectation;
expectation = jasmineUnderTest.Expectation.asyncFactory({ expectation = jasmineUnderTest.Expectation.asyncFactory({
util: util, matchersUtil: matchersUtil,
customAsyncMatchers: matchers, customAsyncMatchers: matchers,
actual: 'an actual', actual: 'an actual',
addExpectationResult: addExpectationResult addExpectationResult: addExpectationResult
@@ -322,7 +329,7 @@ describe('AsyncExpectation', function() {
}; };
} }
}, },
util = { matchersUtil = {
buildFailureMessage: jasmine.createSpy('buildFailureMessage') buildFailureMessage: jasmine.createSpy('buildFailureMessage')
}, },
addExpectationResult = jasmine.createSpy('addExpectationResult'), addExpectationResult = jasmine.createSpy('addExpectationResult'),
@@ -335,7 +342,7 @@ describe('AsyncExpectation', function() {
expectation = jasmineUnderTest.Expectation.asyncFactory({ expectation = jasmineUnderTest.Expectation.asyncFactory({
customAsyncMatchers: matchers, customAsyncMatchers: matchers,
util: util, matchersUtil: matchersUtil,
actual: 'an actual', actual: 'an actual',
addExpectationResult: addExpectationResult addExpectationResult: addExpectationResult
}); });
@@ -365,7 +372,7 @@ describe('AsyncExpectation', function() {
}; };
} }
}, },
util = { matchersUtil = {
buildFailureMessage: function() { buildFailureMessage: function() {
return ''; return '';
} }
@@ -380,7 +387,7 @@ describe('AsyncExpectation', function() {
expectation = jasmineUnderTest.Expectation.asyncFactory({ expectation = jasmineUnderTest.Expectation.asyncFactory({
customAsyncMatchers: matchers, customAsyncMatchers: matchers,
util: util, matchersUtil: matchersUtil,
actual: 'an actual', actual: 'an actual',
addExpectationResult: addExpectationResult addExpectationResult: addExpectationResult
}); });
@@ -536,7 +543,7 @@ describe('AsyncExpectation', function() {
}; };
} }
}, },
util = { matchersUtil = {
buildFailureMessage: function() { buildFailureMessage: function() {
return 'default message'; return 'default message';
} }
@@ -553,7 +560,7 @@ describe('AsyncExpectation', function() {
expectation = jasmineUnderTest.Expectation.asyncFactory({ expectation = jasmineUnderTest.Expectation.asyncFactory({
customAsyncMatchers: matchers, customAsyncMatchers: matchers,
actual: 'an actual', actual: 'an actual',
util: util, matchersUtil: matchersUtil,
addExpectationResult: addExpectationResult addExpectationResult: addExpectationResult
}).not; }).not;

View File

@@ -312,4 +312,78 @@ describe('Env', function() {
expect(globalErrors.install).toHaveBeenCalled(); expect(globalErrors.install).toHaveBeenCalled();
}); });
}); });
it('creates an expectationFactory that uses the current custom equality testers and object formatters', function(done) {
function customEqualityTester() {}
function customObjectFormatter() {}
function prettyPrinter() {}
var RealSpec = jasmineUnderTest.Spec,
specInstance,
expectationFactory;
spyOn(jasmineUnderTest, 'MatchersUtil');
spyOn(jasmineUnderTest, 'makePrettyPrinter').and.returnValue(prettyPrinter);
spyOn(jasmineUnderTest, 'Spec').and.callFake(function(options) {
expectationFactory = options.expectationFactory;
specInstance = new RealSpec(options);
return specInstance;
});
env.it('spec', function() {
env.addCustomEqualityTester(customEqualityTester);
env.addCustomObjectFormatter(customObjectFormatter);
expectationFactory('actual', specInstance);
});
env.addReporter({
jasmineDone: function() {
expect(jasmineUnderTest.makePrettyPrinter).toHaveBeenCalledWith([
customObjectFormatter
]);
expect(jasmineUnderTest.MatchersUtil).toHaveBeenCalledWith({
customTesters: [customEqualityTester],
pp: prettyPrinter
});
done();
}
});
env.execute();
});
it('creates an asyncExpectationFactory that uses the current custom equality testers and object formatters', function(done) {
function customEqualityTester() {}
function customObjectFormatter() {}
function prettyPrinter() {}
var RealSpec = jasmineUnderTest.Spec,
specInstance,
asyncExpectationFactory;
spyOn(jasmineUnderTest, 'MatchersUtil');
spyOn(jasmineUnderTest, 'makePrettyPrinter').and.returnValue(prettyPrinter);
spyOn(jasmineUnderTest, 'Spec').and.callFake(function(options) {
asyncExpectationFactory = options.asyncExpectationFactory;
specInstance = new RealSpec(options);
return specInstance;
});
env.it('spec', function() {
env.addCustomEqualityTester(customEqualityTester);
env.addCustomObjectFormatter(customObjectFormatter);
asyncExpectationFactory('actual', specInstance);
});
env.addReporter({
jasmineDone: function() {
expect(jasmineUnderTest.makePrettyPrinter).toHaveBeenCalledWith([
customObjectFormatter
]);
expect(jasmineUnderTest.MatchersUtil).toHaveBeenCalledWith({
customTesters: [customEqualityTester],
pp: prettyPrinter
});
done();
}
});
env.execute();
});
}); });

View File

@@ -72,21 +72,21 @@ describe('ExpectationFilterChain', function() {
matcherResult = { pass: false }, matcherResult = { pass: false },
matcherName = 'foo', matcherName = 'foo',
args = [], args = [],
util = {}, matchersUtil = {},
result; result;
result = chain.buildFailureMessage( result = chain.buildFailureMessage(
matcherResult, matcherResult,
matcherName, matcherName,
args, args,
util matchersUtil
); );
expect(first).toHaveBeenCalledWith( expect(first).toHaveBeenCalledWith(
matcherResult, matcherResult,
matcherName, matcherName,
args, args,
util matchersUtil
); );
expect(second).not.toHaveBeenCalled(); expect(second).not.toHaveBeenCalled();
expect(result).toEqual('first'); expect(result).toEqual('first');

View File

@@ -37,7 +37,7 @@ describe('Expectation', function() {
matchers = { matchers = {
toFoo: matcherFactory toFoo: matcherFactory
}, },
util = { matchersUtil = {
buildFailureMessage: jasmine.createSpy('buildFailureMessage') buildFailureMessage: jasmine.createSpy('buildFailureMessage')
}, },
customEqualityTesters = ['a'], customEqualityTesters = ['a'],
@@ -45,7 +45,7 @@ describe('Expectation', function() {
expectation; expectation;
expectation = jasmineUnderTest.Expectation.factory({ expectation = jasmineUnderTest.Expectation.factory({
util: util, matchersUtil: matchersUtil,
customMatchers: matchers, customMatchers: matchers,
customEqualityTesters: customEqualityTesters, customEqualityTesters: customEqualityTesters,
actual: 'an actual', actual: 'an actual',
@@ -54,7 +54,10 @@ describe('Expectation', function() {
expectation.toFoo('hello'); expectation.toFoo('hello');
expect(matcherFactory).toHaveBeenCalledWith(util, customEqualityTesters); expect(matcherFactory).toHaveBeenCalledWith(
matchersUtil,
customEqualityTesters
);
}); });
it("wraps matchers's compare functions, passing the actual and expected", function() { it("wraps matchers's compare functions, passing the actual and expected", function() {
@@ -68,14 +71,14 @@ describe('Expectation', function() {
}; };
} }
}, },
util = { matchersUtil = {
buildFailureMessage: jasmine.createSpy('buildFailureMessage') buildFailureMessage: jasmine.createSpy('buildFailureMessage')
}, },
addExpectationResult = jasmine.createSpy('addExpectationResult'), addExpectationResult = jasmine.createSpy('addExpectationResult'),
expectation; expectation;
expectation = jasmineUnderTest.Expectation.factory({ expectation = jasmineUnderTest.Expectation.factory({
util: util, matchersUtil: matchersUtil,
customMatchers: matchers, customMatchers: matchers,
actual: 'an actual', actual: 'an actual',
addExpectationResult: addExpectationResult addExpectationResult: addExpectationResult
@@ -96,7 +99,7 @@ describe('Expectation', function() {
}; };
} }
}, },
util = { matchersUtil = {
buildFailureMessage: jasmine.createSpy('buildFailureMessage') buildFailureMessage: jasmine.createSpy('buildFailureMessage')
}, },
addExpectationResult = jasmine.createSpy('addExpectationResult'), addExpectationResult = jasmine.createSpy('addExpectationResult'),
@@ -104,7 +107,7 @@ describe('Expectation', function() {
expectation = jasmineUnderTest.Expectation.factory({ expectation = jasmineUnderTest.Expectation.factory({
customMatchers: matchers, customMatchers: matchers,
util: util, matchersUtil: matchersUtil,
actual: 'an actual', actual: 'an actual',
addExpectationResult: addExpectationResult addExpectationResult: addExpectationResult
}); });
@@ -132,7 +135,7 @@ describe('Expectation', function() {
}; };
} }
}, },
util = { matchersUtil = {
buildFailureMessage: function() { buildFailureMessage: function() {
return ''; return '';
} }
@@ -142,7 +145,7 @@ describe('Expectation', function() {
expectation = jasmineUnderTest.Expectation.factory({ expectation = jasmineUnderTest.Expectation.factory({
customMatchers: matchers, customMatchers: matchers,
util: util, matchersUtil: matchersUtil,
actual: 'an actual', actual: 'an actual',
addExpectationResult: addExpectationResult addExpectationResult: addExpectationResult
}); });
@@ -275,7 +278,7 @@ describe('Expectation', function() {
}; };
} }
}, },
util = { matchersUtil = {
buildFailureMessage: function() { buildFailureMessage: function() {
return 'default message'; return 'default message';
} }
@@ -287,7 +290,7 @@ describe('Expectation', function() {
expectation = jasmineUnderTest.Expectation.factory({ expectation = jasmineUnderTest.Expectation.factory({
customMatchers: matchers, customMatchers: matchers,
actual: 'an actual', actual: 'an actual',
util: util, matchersUtil: matchersUtil,
addExpectationResult: addExpectationResult addExpectationResult: addExpectationResult
}).not; }).not;
@@ -539,7 +542,7 @@ describe('Expectation', function() {
}; };
} }
}, },
util = { matchersUtil = {
buildFailureMessage: function() { buildFailureMessage: function() {
return 'failure message'; return 'failure message';
} }
@@ -547,7 +550,7 @@ describe('Expectation', function() {
addExpectationResult = jasmine.createSpy('addExpectationResult'), addExpectationResult = jasmine.createSpy('addExpectationResult'),
expectation = jasmineUnderTest.Expectation.factory({ expectation = jasmineUnderTest.Expectation.factory({
customMatchers: matchers, customMatchers: matchers,
util: util, matchersUtil: matchersUtil,
actual: 'an actual', actual: 'an actual',
addExpectationResult: addExpectationResult addExpectationResult: addExpectationResult
}); });
@@ -658,9 +661,10 @@ describe('Expectation', function() {
} }
}, },
addExpectationResult = jasmine.createSpy('addExpectationResult'), addExpectationResult = jasmine.createSpy('addExpectationResult'),
pp = jasmineUnderTest.makePrettyPrinter(),
expectation = jasmineUnderTest.Expectation.factory({ expectation = jasmineUnderTest.Expectation.factory({
customMatchers: matchers, customMatchers: matchers,
util: jasmineUnderTest.matchersUtil, matchersUtil: new jasmineUnderTest.MatchersUtil({ pp: pp }),
actual: 'an actual', actual: 'an actual',
addExpectationResult: addExpectationResult addExpectationResult: addExpectationResult
}); });

View File

@@ -1,17 +1,19 @@
describe('jasmineUnderTest.pp', function() { describe('PrettyPrinter', function() {
it('should wrap strings in single quotes', function() { it('should wrap strings in single quotes', function() {
expect(jasmineUnderTest.pp('some string')).toEqual("'some string'"); var pp = jasmineUnderTest.makePrettyPrinter();
expect(jasmineUnderTest.pp("som' string")).toEqual("'som' string'"); expect(pp('some string')).toEqual("'some string'");
expect(pp("som' string")).toEqual("'som' string'");
}); });
it('should stringify primitives properly', function() { it('should stringify primitives properly', function() {
expect(jasmineUnderTest.pp(true)).toEqual('true'); var pp = jasmineUnderTest.makePrettyPrinter();
expect(jasmineUnderTest.pp(false)).toEqual('false'); expect(pp(true)).toEqual('true');
expect(jasmineUnderTest.pp(null)).toEqual('null'); expect(pp(false)).toEqual('false');
expect(jasmineUnderTest.pp(jasmine.undefined)).toEqual('undefined'); expect(pp(null)).toEqual('null');
expect(jasmineUnderTest.pp(3)).toEqual('3'); expect(pp(jasmine.undefined)).toEqual('undefined');
expect(jasmineUnderTest.pp(-3.14)).toEqual('-3.14'); expect(pp(3)).toEqual('3');
expect(jasmineUnderTest.pp(-0)).toEqual('-0'); expect(pp(-3.14)).toEqual('-3.14');
expect(pp(-0)).toEqual('-0');
}); });
describe('stringify sets', function() { describe('stringify sets', function() {
@@ -20,7 +22,8 @@ describe('jasmineUnderTest.pp', function() {
var set = new Set(); var set = new Set();
set.add(1); set.add(1);
set.add(2); set.add(2);
expect(jasmineUnderTest.pp(set)).toEqual('Set( 1, 2 )'); var pp = jasmineUnderTest.makePrettyPrinter();
expect(pp(set)).toEqual('Set( 1, 2 )');
}); });
it('should truncate sets with more elements than jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH', function() { it('should truncate sets with more elements than jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH', function() {
@@ -33,7 +36,8 @@ describe('jasmineUnderTest.pp', function() {
set.add('a'); set.add('a');
set.add('b'); set.add('b');
set.add('c'); set.add('c');
expect(jasmineUnderTest.pp(set)).toEqual("Set( 'a', 'b', ... )"); var pp = jasmineUnderTest.makePrettyPrinter();
expect(pp(set)).toEqual("Set( 'a', 'b', ... )");
} finally { } finally {
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxSize; jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxSize;
} }
@@ -45,7 +49,8 @@ describe('jasmineUnderTest.pp', function() {
jasmine.getEnv().requireFunctioningMaps(); jasmine.getEnv().requireFunctioningMaps();
var map = new Map(); var map = new Map();
map.set(1, 2); map.set(1, 2);
expect(jasmineUnderTest.pp(map)).toEqual('Map( [ 1, 2 ] )'); var pp = jasmineUnderTest.makePrettyPrinter();
expect(pp(map)).toEqual('Map( [ 1, 2 ] )');
}); });
it('should truncate maps with more elements than jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH', function() { it('should truncate maps with more elements than jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH', function() {
@@ -58,9 +63,8 @@ describe('jasmineUnderTest.pp', function() {
map.set('a', 1); map.set('a', 1);
map.set('b', 2); map.set('b', 2);
map.set('c', 3); map.set('c', 3);
expect(jasmineUnderTest.pp(map)).toEqual( var pp = jasmineUnderTest.makePrettyPrinter();
"Map( [ 'a', 1 ], [ 'b', 2 ], ... )" expect(pp(map)).toEqual("Map( [ 'a', 1 ], [ 'b', 2 ], ... )");
);
} finally { } finally {
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxSize; jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxSize;
} }
@@ -69,43 +73,44 @@ describe('jasmineUnderTest.pp', function() {
describe('stringify arrays', function() { describe('stringify arrays', function() {
it('should stringify arrays properly', function() { it('should stringify arrays properly', function() {
expect(jasmineUnderTest.pp([1, 2])).toEqual('[ 1, 2 ]'); var pp = jasmineUnderTest.makePrettyPrinter();
expect( expect(pp([1, 2])).toEqual('[ 1, 2 ]');
jasmineUnderTest.pp([1, 'foo', {}, jasmine.undefined, null]) expect(pp([1, 'foo', {}, jasmine.undefined, null])).toEqual(
).toEqual("[ 1, 'foo', Object({ }), undefined, null ]"); "[ 1, 'foo', Object({ }), undefined, null ]"
);
}); });
it('should truncate arrays that are longer than jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH', function() { it('should truncate arrays that are longer than jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH', function() {
var originalMaxLength = jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH; var originalMaxLength = jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH;
var array = [1, 2, 3]; var array = [1, 2, 3];
var pp = jasmineUnderTest.makePrettyPrinter();
try { try {
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2; jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
expect(jasmineUnderTest.pp(array)).toEqual('[ 1, 2, ... ]'); expect(pp(array)).toEqual('[ 1, 2, ... ]');
} finally { } finally {
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxLength; jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxLength;
} }
}); });
it('should stringify arrays with properties properly', function() { it('should stringify arrays with properties properly', function() {
var pp = jasmineUnderTest.makePrettyPrinter();
var arr = [1, 2]; var arr = [1, 2];
arr.foo = 'bar'; arr.foo = 'bar';
arr.baz = {}; arr.baz = {};
expect(jasmineUnderTest.pp(arr)).toEqual( expect(pp(arr)).toEqual("[ 1, 2, foo: 'bar', baz: Object({ }) ]");
"[ 1, 2, foo: 'bar', baz: Object({ }) ]"
);
}); });
it('should stringify empty arrays with properties properly', function() { it('should stringify empty arrays with properties properly', function() {
var pp = jasmineUnderTest.makePrettyPrinter();
var empty = []; var empty = [];
empty.foo = 'bar'; empty.foo = 'bar';
empty.baz = {}; empty.baz = {};
expect(jasmineUnderTest.pp(empty)).toEqual( expect(pp(empty)).toEqual("[ foo: 'bar', baz: Object({ }) ]");
"[ foo: 'bar', baz: Object({ }) ]"
);
}); });
it('should stringify long arrays with properties properly', function() { it('should stringify long arrays with properties properly', function() {
var pp = jasmineUnderTest.makePrettyPrinter();
var originalMaxLength = jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH; var originalMaxLength = jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH;
var long = [1, 2, 3]; var long = [1, 2, 3];
long.foo = 'bar'; long.foo = 'bar';
@@ -113,7 +118,7 @@ describe('jasmineUnderTest.pp', function() {
try { try {
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2; jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
expect(jasmineUnderTest.pp(long)).toEqual( expect(pp(long)).toEqual(
"[ 1, 2, ..., foo: 'bar', baz: Object({ }) ]" "[ 1, 2, ..., foo: 'bar', baz: Object({ }) ]"
); );
} finally { } finally {
@@ -122,26 +127,25 @@ describe('jasmineUnderTest.pp', function() {
}); });
it('should indicate circular array references', function() { it('should indicate circular array references', function() {
var pp = jasmineUnderTest.makePrettyPrinter();
var array1 = [1, 2]; var array1 = [1, 2];
var array2 = [array1]; var array2 = [array1];
array1.push(array2); array1.push(array2);
expect(jasmineUnderTest.pp(array1)).toEqual( expect(pp(array1)).toEqual('[ 1, 2, [ <circular reference: Array> ] ]');
'[ 1, 2, [ <circular reference: Array> ] ]'
);
}); });
it('should not indicate circular references incorrectly', function() { it('should not indicate circular references incorrectly', function() {
var pp = jasmineUnderTest.makePrettyPrinter();
var array = [[1]]; var array = [[1]];
expect(jasmineUnderTest.pp(array)).toEqual('[ [ 1 ] ]'); expect(pp(array)).toEqual('[ [ 1 ] ]');
}); });
}); });
it('should stringify objects properly', function() { it('should stringify objects properly', function() {
expect(jasmineUnderTest.pp({ foo: 'bar' })).toEqual( var pp = jasmineUnderTest.makePrettyPrinter();
"Object({ foo: 'bar' })" expect(pp({ foo: 'bar' })).toEqual("Object({ foo: 'bar' })");
);
expect( expect(
jasmineUnderTest.pp({ pp({
foo: 'bar', foo: 'bar',
baz: 3, baz: 3,
nullValue: null, nullValue: null,
@@ -150,24 +154,24 @@ describe('jasmineUnderTest.pp', function() {
).toEqual( ).toEqual(
"Object({ foo: 'bar', baz: 3, nullValue: null, undefinedValue: undefined })" "Object({ foo: 'bar', baz: 3, nullValue: null, undefinedValue: undefined })"
); );
expect(jasmineUnderTest.pp({ foo: function() {}, bar: [1, 2, 3] })).toEqual( expect(pp({ foo: function() {}, bar: [1, 2, 3] })).toEqual(
'Object({ foo: Function, bar: [ 1, 2, 3 ] })' 'Object({ foo: Function, bar: [ 1, 2, 3 ] })'
); );
}); });
it('should stringify objects that almost look like DOM nodes', function() { it('should stringify objects that almost look like DOM nodes', function() {
expect(jasmineUnderTest.pp({ nodeType: 1 })).toEqual( var pp = jasmineUnderTest.makePrettyPrinter();
'Object({ nodeType: 1 })' expect(pp({ nodeType: 1 })).toEqual('Object({ nodeType: 1 })');
);
}); });
it('should truncate objects with too many keys', function() { it('should truncate objects with too many keys', function() {
var pp = jasmineUnderTest.makePrettyPrinter();
var originalMaxLength = jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH; var originalMaxLength = jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH;
var long = { a: 1, b: 2, c: 3 }; var long = { a: 1, b: 2, c: 3 };
try { try {
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2; jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
expect(jasmineUnderTest.pp(long)).toEqual('Object({ a: 1, b: 2, ... })'); expect(pp(long)).toEqual('Object({ a: 1, b: 2, ... })');
} finally { } finally {
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxLength; jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxLength;
} }
@@ -185,12 +189,11 @@ describe('jasmineUnderTest.pp', function() {
} }
it('should truncate outputs that are too long', function() { it('should truncate outputs that are too long', function() {
var pp = jasmineUnderTest.makePrettyPrinter();
var big = [{ a: 1, b: 'a long string' }, {}]; var big = [{ a: 1, b: 'a long string' }, {}];
withMaxChars(34, function() { withMaxChars(34, function() {
expect(jasmineUnderTest.pp(big)).toEqual( expect(pp(big)).toEqual("[ Object({ a: 1, b: 'a long st ...");
"[ Object({ a: 1, b: 'a long st ..."
);
}); });
}); });
@@ -214,59 +217,55 @@ describe('jasmineUnderTest.pp', function() {
jasmineToString: jasmine jasmineToString: jasmine
.createSpy('d jasmineToString') .createSpy('d jasmineToString')
.and.returnValue('') .and.returnValue('')
}; },
pp = jasmineUnderTest.makePrettyPrinter();
withMaxChars(30, function() { withMaxChars(30, function() {
jasmineUnderTest.pp([{ a: a, b: b, c: c }, d]); pp([{ a: a, b: b, c: c }, d]);
expect(c.jasmineToString).not.toHaveBeenCalled(); expect(c.jasmineToString).not.toHaveBeenCalled();
expect(d.jasmineToString).not.toHaveBeenCalled(); expect(d.jasmineToString).not.toHaveBeenCalled();
}); });
}); });
it("should print 'null' as the constructor of an object with its own constructor property", function() { it("should print 'null' as the constructor of an object with its own constructor property", function() {
expect(jasmineUnderTest.pp({ constructor: function() {} })).toContain( var pp = jasmineUnderTest.makePrettyPrinter();
'null({' expect(pp({ constructor: function() {} })).toContain('null({');
); expect(pp({ constructor: 'foo' })).toContain('null({');
expect(jasmineUnderTest.pp({ constructor: 'foo' })).toContain('null({');
}); });
it('should not include inherited properties when stringifying an object', function() { it('should not include inherited properties when stringifying an object', function() {
var pp = jasmineUnderTest.makePrettyPrinter();
var SomeClass = function SomeClass() {}; var SomeClass = function SomeClass() {};
SomeClass.prototype.foo = 'inherited foo'; SomeClass.prototype.foo = 'inherited foo';
var instance = new SomeClass(); var instance = new SomeClass();
instance.bar = 'my own bar'; instance.bar = 'my own bar';
expect(jasmineUnderTest.pp(instance)).toEqual( expect(pp(instance)).toEqual("SomeClass({ bar: 'my own bar' })");
"SomeClass({ bar: 'my own bar' })"
);
}); });
it('should not recurse objects and arrays more deeply than jasmineUnderTest.MAX_PRETTY_PRINT_DEPTH', function() { it('should not recurse objects and arrays more deeply than jasmineUnderTest.MAX_PRETTY_PRINT_DEPTH', function() {
var pp = jasmineUnderTest.makePrettyPrinter();
var originalMaxDepth = jasmineUnderTest.MAX_PRETTY_PRINT_DEPTH; var originalMaxDepth = jasmineUnderTest.MAX_PRETTY_PRINT_DEPTH;
var nestedObject = { level1: { level2: { level3: { level4: 'leaf' } } } }; var nestedObject = { level1: { level2: { level3: { level4: 'leaf' } } } };
var nestedArray = [1, [2, [3, [4, 'leaf']]]]; var nestedArray = [1, [2, [3, [4, 'leaf']]]];
try { try {
jasmineUnderTest.MAX_PRETTY_PRINT_DEPTH = 2; jasmineUnderTest.MAX_PRETTY_PRINT_DEPTH = 2;
expect(jasmineUnderTest.pp(nestedObject)).toEqual( expect(pp(nestedObject)).toEqual(
'Object({ level1: Object({ level2: Object }) })' 'Object({ level1: Object({ level2: Object }) })'
); );
expect(jasmineUnderTest.pp(nestedArray)).toEqual('[ 1, [ 2, Array ] ]'); expect(pp(nestedArray)).toEqual('[ 1, [ 2, Array ] ]');
jasmineUnderTest.MAX_PRETTY_PRINT_DEPTH = 3; jasmineUnderTest.MAX_PRETTY_PRINT_DEPTH = 3;
expect(jasmineUnderTest.pp(nestedObject)).toEqual( expect(pp(nestedObject)).toEqual(
'Object({ level1: Object({ level2: Object({ level3: Object }) }) })' 'Object({ level1: Object({ level2: Object({ level3: Object }) }) })'
); );
expect(jasmineUnderTest.pp(nestedArray)).toEqual( expect(pp(nestedArray)).toEqual('[ 1, [ 2, [ 3, Array ] ] ]');
'[ 1, [ 2, [ 3, Array ] ] ]'
);
jasmineUnderTest.MAX_PRETTY_PRINT_DEPTH = 4; jasmineUnderTest.MAX_PRETTY_PRINT_DEPTH = 4;
expect(jasmineUnderTest.pp(nestedObject)).toEqual( expect(pp(nestedObject)).toEqual(
"Object({ level1: Object({ level2: Object({ level3: Object({ level4: 'leaf' }) }) }) })" "Object({ level1: Object({ level2: Object({ level3: Object({ level4: 'leaf' }) }) }) })"
); );
expect(jasmineUnderTest.pp(nestedArray)).toEqual( expect(pp(nestedArray)).toEqual("[ 1, [ 2, [ 3, [ 4, 'leaf' ] ] ] ]");
"[ 1, [ 2, [ 3, [ 4, 'leaf' ] ] ] ]"
);
} finally { } finally {
jasmineUnderTest.MAX_PRETTY_PRINT_DEPTH = originalMaxDepth; jasmineUnderTest.MAX_PRETTY_PRINT_DEPTH = originalMaxDepth;
} }
@@ -274,28 +273,32 @@ describe('jasmineUnderTest.pp', function() {
it('should stringify immutable circular objects', function() { it('should stringify immutable circular objects', function() {
if (Object.freeze) { if (Object.freeze) {
var pp = jasmineUnderTest.makePrettyPrinter();
var frozenObject = { foo: { bar: 'baz' } }; var frozenObject = { foo: { bar: 'baz' } };
frozenObject.circular = frozenObject; frozenObject.circular = frozenObject;
frozenObject = Object.freeze(frozenObject); frozenObject = Object.freeze(frozenObject);
expect(jasmineUnderTest.pp(frozenObject)).toEqual( expect(pp(frozenObject)).toEqual(
"Object({ foo: Object({ bar: 'baz' }), circular: <circular reference: Object> })" "Object({ foo: Object({ bar: 'baz' }), circular: <circular reference: Object> })"
); );
} }
}); });
it('should stringify RegExp objects properly', function() { it('should stringify RegExp objects properly', function() {
expect(jasmineUnderTest.pp(/x|y|z/)).toEqual('/x|y|z/'); var pp = jasmineUnderTest.makePrettyPrinter();
expect(pp(/x|y|z/)).toEqual('/x|y|z/');
}); });
it('should indicate circular object references', function() { it('should indicate circular object references', function() {
var pp = jasmineUnderTest.makePrettyPrinter();
var sampleValue = { foo: 'hello' }; var sampleValue = { foo: 'hello' };
sampleValue.nested = sampleValue; sampleValue.nested = sampleValue;
expect(jasmineUnderTest.pp(sampleValue)).toEqual( expect(pp(sampleValue)).toEqual(
"Object({ foo: 'hello', nested: <circular reference: Object> })" "Object({ foo: 'hello', nested: <circular reference: Object> })"
); );
}); });
it('should indicate getters on objects as such', function() { it('should indicate getters on objects as such', function() {
var pp = jasmineUnderTest.makePrettyPrinter();
var sampleValue = { id: 1 }; var sampleValue = { id: 1 };
if (sampleValue.__defineGetter__) { if (sampleValue.__defineGetter__) {
//not supported in IE! //not supported in IE!
@@ -304,34 +307,38 @@ describe('jasmineUnderTest.pp', function() {
}); });
} }
if (sampleValue.__defineGetter__) { if (sampleValue.__defineGetter__) {
expect(jasmineUnderTest.pp(sampleValue)).toEqual( expect(pp(sampleValue)).toEqual(
'Object({ id: 1, calculatedValue: <getter> })' 'Object({ id: 1, calculatedValue: <getter> })'
); );
} else { } else {
expect(jasmineUnderTest.pp(sampleValue)).toEqual('Object({ id: 1 })'); expect(pp(sampleValue)).toEqual('Object({ id: 1 })');
} }
}); });
it('should not do HTML escaping of strings', function() { it('should not do HTML escaping of strings', function() {
expect(jasmineUnderTest.pp('some <b>html string</b> &', false)).toEqual( var pp = jasmineUnderTest.makePrettyPrinter();
expect(pp('some <b>html string</b> &', false)).toEqual(
"'some <b>html string</b> &'" "'some <b>html string</b> &'"
); );
}); });
it('should abbreviate the global (usually window) object', function() { it('should abbreviate the global (usually window) object', function() {
expect(jasmineUnderTest.pp(jasmine.getGlobal())).toEqual('<global>'); var pp = jasmineUnderTest.makePrettyPrinter();
expect(pp(jasmine.getGlobal())).toEqual('<global>');
}); });
it('should stringify Date objects properly', function() { it('should stringify Date objects properly', function() {
var pp = jasmineUnderTest.makePrettyPrinter();
var now = new Date(); var now = new Date();
expect(jasmineUnderTest.pp(now)).toEqual('Date(' + now.toString() + ')'); expect(pp(now)).toEqual('Date(' + now.toString() + ')');
}); });
describe('with a spy object', function() { describe('with a spy object', function() {
var env; var env, pp;
beforeEach(function() { beforeEach(function() {
env = new jasmineUnderTest.Env(); env = new jasmineUnderTest.Env();
pp = jasmineUnderTest.makePrettyPrinter();
}); });
afterEach(function() { afterEach(function() {
@@ -353,19 +360,17 @@ describe('jasmineUnderTest.pp', function() {
}); });
spyRegistry.spyOn(TestObject, 'someFunction'); spyRegistry.spyOn(TestObject, 'someFunction');
expect(jasmineUnderTest.pp(TestObject.someFunction)).toEqual( expect(pp(TestObject.someFunction)).toEqual('spy on someFunction');
'spy on someFunction'
);
expect(jasmineUnderTest.pp(env.createSpy('something'))).toEqual( expect(pp(env.createSpy('something'))).toEqual('spy on something');
'spy on something'
);
}); });
it('should stringify spyOn toString properly', function() { it('should stringify spyOn toString properly', function() {
var TestObject = { var TestObject = {
someFunction: function() {} someFunction: function() {}
}; },
env = new jasmineUnderTest.Env(),
pp = jasmineUnderTest.makePrettyPrinter();
var spyRegistry = new jasmineUnderTest.SpyRegistry({ var spyRegistry = new jasmineUnderTest.SpyRegistry({
currentSpies: function() { currentSpies: function() {
@@ -379,30 +384,40 @@ describe('jasmineUnderTest.pp', function() {
spyRegistry.spyOn(TestObject, 'toString'); spyRegistry.spyOn(TestObject, 'toString');
var testSpyObj = env.createSpyObj('TheClassName', ['toString']); var testSpyObj = env.createSpyObj('TheClassName', ['toString']);
expect(jasmineUnderTest.pp(testSpyObj)).toEqual( expect(pp(testSpyObj)).toEqual('spy on TheClassName.toString');
'spy on TheClassName.toString'
);
}); });
}); });
it('should stringify objects that implement jasmineToString', function() { it('should stringify objects that implement jasmineToString', function() {
var pp = jasmineUnderTest.makePrettyPrinter();
var obj = { var obj = {
jasmineToString: function() { jasmineToString: function() {
return 'strung'; return 'strung';
} }
}; };
expect(jasmineUnderTest.pp(obj)).toEqual('strung'); expect(pp(obj)).toEqual('strung');
});
it('should pass itself to jasmineToString', function() {
var pp = jasmineUnderTest.makePrettyPrinter([]);
var obj = {
jasmineToString: jasmine.createSpy('jasmineToString').and.returnValue('')
};
pp(obj);
expect(obj.jasmineToString).toHaveBeenCalledWith(pp);
}); });
it('should stringify objects that implement custom toString', function() { it('should stringify objects that implement custom toString', function() {
var pp = jasmineUnderTest.makePrettyPrinter();
var obj = { var obj = {
toString: function() { toString: function() {
return 'my toString'; return 'my toString';
} }
}; };
expect(jasmineUnderTest.pp(obj)).toEqual('my toString'); expect(pp(obj)).toEqual('my toString');
// Simulate object from another global context (e.g. an iframe or Web Worker) that does not actually have a custom // Simulate object from another global context (e.g. an iframe or Web Worker) that does not actually have a custom
// toString despite obj.toString !== Object.prototype.toString // toString despite obj.toString !== Object.prototype.toString
@@ -413,20 +428,22 @@ describe('jasmineUnderTest.pp', function() {
} }
}; };
expect(jasmineUnderTest.pp(objFromOtherContext)).toEqual( expect(pp(objFromOtherContext)).toEqual(
"Object({ foo: 'bar', toString: Function })" "Object({ foo: 'bar', toString: Function })"
); );
}); });
it("should stringify objects have have a toString that isn't a function", function() { it("should stringify objects have have a toString that isn't a function", function() {
var pp = jasmineUnderTest.makePrettyPrinter();
var obj = { var obj = {
toString: 'foo' toString: 'foo'
}; };
expect(jasmineUnderTest.pp(obj)).toEqual("Object({ toString: 'foo' })"); expect(pp(obj)).toEqual("Object({ toString: 'foo' })");
}); });
it('should stringify objects from anonymous constructors with custom toString', function() { it('should stringify objects from anonymous constructors with custom toString', function() {
var pp = jasmineUnderTest.makePrettyPrinter();
var MyAnonymousConstructor = (function() { var MyAnonymousConstructor = (function() {
return function() {}; return function() {};
})(); })();
@@ -436,17 +453,19 @@ describe('jasmineUnderTest.pp', function() {
var a = new MyAnonymousConstructor(); var a = new MyAnonymousConstructor();
expect(jasmineUnderTest.pp(a)).toEqual('<anonymous>({ })'); expect(pp(a)).toEqual('<anonymous>({ })');
}); });
it('should handle objects with null prototype', function() { it('should handle objects with null prototype', function() {
var pp = jasmineUnderTest.makePrettyPrinter();
var obj = Object.create(null); var obj = Object.create(null);
obj.foo = 'bar'; obj.foo = 'bar';
expect(jasmineUnderTest.pp(obj)).toEqual("null({ foo: 'bar' })"); expect(pp(obj)).toEqual("null({ foo: 'bar' })");
}); });
it('should gracefully handle objects with invalid toString implementations', function() { it('should gracefully handle objects with invalid toString implementations', function() {
var pp = jasmineUnderTest.makePrettyPrinter();
var obj = { var obj = {
foo: { foo: {
toString: function() { toString: function() {
@@ -476,8 +495,72 @@ describe('jasmineUnderTest.pp', function() {
} }
}; };
expect(jasmineUnderTest.pp(obj)).toEqual( expect(pp(obj)).toEqual(
'Object({ foo: [object Number], bar: [object Object], baz: 3, qux: Error: bar, baddy: has-invalid-toString-method })' 'Object({ foo: [object Number], bar: [object Object], baz: 3, qux: Error: bar, baddy: has-invalid-toString-method })'
); );
}); });
describe('Custom object formatters', function() {
it('should use the first custom object formatter that does not return undefined', function() {
var customObjectFormatters = [
function(obj) {
return undefined;
},
function(obj) {
return '2nd: ' + obj.foo;
},
function(obj) {
return '3rd: ' + obj.foo;
}
],
pp = jasmineUnderTest.makePrettyPrinter(customObjectFormatters),
obj = { foo: 'bar' };
expect(pp(obj)).toEqual('2nd: bar');
});
it('should fall back to built in logic if all custom object formatters return undefined', function() {
var customObjectFormatters = [
function(obj) {
return undefined;
}
],
pp = jasmineUnderTest.makePrettyPrinter(customObjectFormatters),
obj = { foo: 'bar' };
expect(pp(obj)).toEqual("Object({ foo: 'bar' })");
});
});
describe('#customFormat_', function() {
it('should use the first custom object formatter that does not return undefined', function() {
var customObjectFormatters = [
function(obj) {
return undefined;
},
function(obj) {
return '2nd: ' + obj.foo;
},
function(obj) {
return '3rd: ' + obj.foo;
}
],
pp = jasmineUnderTest.makePrettyPrinter(customObjectFormatters),
obj = { foo: 'bar' };
expect(pp.customFormat_(obj)).toEqual('2nd: bar');
});
it('should return undefined if all custom object formatters return undefined', function() {
var customObjectFormatters = [
function(obj) {
return undefined;
}
],
pp = jasmineUnderTest.makePrettyPrinter(customObjectFormatters),
obj = { foo: 'bar' };
expect(pp.customFormat_(obj)).toBeUndefined();
});
});
}); });

View File

@@ -0,0 +1,101 @@
describe('asymmetricEqualityTesterArgCompatShim', function() {
it('provides all the properties of the MatchersUtil', function() {
var matchersUtil = {
foo: function() {},
bar: function() {}
},
shim = jasmineUnderTest.asymmetricEqualityTesterArgCompatShim(
matchersUtil,
[]
);
expect(shim.foo).toBe(matchersUtil.foo);
expect(shim.bar).toBe(matchersUtil.bar);
});
it('provides all the properties of the customEqualityTesters', function() {
var customEqualityTesters = [function() {}, function() {}],
shim = jasmineUnderTest.asymmetricEqualityTesterArgCompatShim(
{},
customEqualityTesters
);
expect(shim.length).toBe(2);
expect(shim[0]).toBe(customEqualityTesters[0]);
expect(shim[1]).toBe(customEqualityTesters[1]);
});
it('provides all the properties of Array.prototype', function() {
var shim = jasmineUnderTest.asymmetricEqualityTesterArgCompatShim({}, []);
expect(shim.filter).toBe(Array.prototype.filter);
expect(shim.forEach).toBe(Array.prototype.forEach);
expect(shim.map).toBe(Array.prototype.map);
});
it('provides properties of Array.prototype', function() {
var keys = [
'concat',
'constructor',
'every',
'filter',
'forEach',
'indexOf',
'join',
'lastIndexOf',
'length',
'map',
'pop',
'push',
'reduce',
'reduceRight',
'reverse',
'shift',
'slice',
'some',
'sort',
'splice',
'toLocaleString',
'toString',
'unshift'
],
optionalKeys = [
'copyWithin',
'entries',
'fill',
'find',
'findIndex',
'flat',
'flatMap',
'includes',
'keys',
'toSource',
'values'
],
shim = jasmineUnderTest.asymmetricEqualityTesterArgCompatShim({}, []),
i,
k;
// Properties that are present on all supported runtimes
for (i = 0; i < keys.length; i++) {
k = keys[i];
expect(shim[k])
.withContext(k)
.not.toBeUndefined();
expect(shim[k])
.withContext(k)
.toBe(Array.prototype[k]);
}
// Properties that are present on only some supported runtimes
for (i = 0; i < optionalKeys.length; i++) {
k = optionalKeys[i];
if (shim[k] !== undefined) {
expect(shim[k])
.withContext(k)
.toBe(Array.prototype[k]);
}
}
});
});

View File

@@ -15,32 +15,41 @@ describe("ArrayContaining", function() {
it("matches when the item is in the actual", function() { it("matches when the item is in the actual", function() {
var containing = new jasmineUnderTest.ArrayContaining(["foo"]); var containing = new jasmineUnderTest.ArrayContaining(["foo"]);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch(["foo"])).toBe(true); expect(containing.asymmetricMatch(["foo"], matchersUtil)).toBe(true);
}); });
it("matches when additional items are in the actual", function() { it("matches when additional items are in the actual", function() {
var containing = new jasmineUnderTest.ArrayContaining(["foo"]); var containing = new jasmineUnderTest.ArrayContaining(["foo"]);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch(["foo", "bar"])).toBe(true); expect(containing.asymmetricMatch(["foo", "bar"], matchersUtil)).toBe(true);
}); });
it("does not match when the item is not in the actual", function() { it("does not match when the item is not in the actual", function() {
var containing = new jasmineUnderTest.ArrayContaining(["foo"]); var containing = new jasmineUnderTest.ArrayContaining(["foo"]);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch(["bar"])).toBe(false); expect(containing.asymmetricMatch(["bar"], matchersUtil)).toBe(false);
}); });
it("does not match when the actual is not an array", function() { it("does not match when the actual is not an array", function() {
var containing = new jasmineUnderTest.ArrayContaining(["foo"]); var containing = new jasmineUnderTest.ArrayContaining(["foo"]);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch("foo")).toBe(false); expect(containing.asymmetricMatch("foo", matchersUtil)).toBe(false);
}); });
it("jasmineToStrings itself", function() { it("jasmineToStrings itself", function() {
var containing = new jasmineUnderTest.ArrayContaining([]); var sample = [],
matcher = new jasmineUnderTest.ArrayContaining(sample),
pp = jasmine.createSpy('pp').and.returnValue('sample');
expect(containing.jasmineToString()).toMatch("<jasmine.arrayContaining"); expect(matcher.jasmineToString(pp)).toEqual(
'<jasmine.arrayContaining(sample)>'
);
expect(pp).toHaveBeenCalledWith(sample);
}); });
it("uses custom equality testers", function() { it("uses custom equality testers", function() {
@@ -52,7 +61,8 @@ describe("ArrayContaining", function() {
} }
}; };
var containing = new jasmineUnderTest.ArrayContaining(["fooVal"]); var containing = new jasmineUnderTest.ArrayContaining(["fooVal"]);
var matchersUtil = new jasmineUnderTest.MatchersUtil({customTesters: [tester]});
expect(containing.asymmetricMatch(["fooBar"], [tester])).toBe(true); expect(containing.asymmetricMatch(["fooBar"], matchersUtil)).toBe(true);
}); });
}); });

View File

@@ -1,8 +1,9 @@
describe("ArrayWithExactContents", function() { describe("ArrayWithExactContents", function() {
it("matches an array with the same items in a different order", function() { it("matches an array with the same items in a different order", function() {
var matcher = new jasmineUnderTest.ArrayWithExactContents(['a', 2, /a/]); var matcher = new jasmineUnderTest.ArrayWithExactContents(['a', 2, /a/]);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matcher.asymmetricMatch([2, 'a', /a/])).toBe(true); expect(matcher.asymmetricMatch([2, 'a', /a/], matchersUtil)).toBe(true);
}); });
it("does not work when not passed an array", function() { it("does not work when not passed an array", function() {
@@ -15,21 +16,28 @@ describe("ArrayWithExactContents", function() {
it("does not match when an item is missing", function() { it("does not match when an item is missing", function() {
var matcher = new jasmineUnderTest.ArrayWithExactContents(['a', 2, /a/]); var matcher = new jasmineUnderTest.ArrayWithExactContents(['a', 2, /a/]);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matcher.asymmetricMatch(['a', 2])).toBe(false); expect(matcher.asymmetricMatch(['a', 2], matchersUtil)).toBe(false);
expect(matcher.asymmetricMatch(['a', 2, undefined])).toBe(false); expect(matcher.asymmetricMatch(['a', 2, undefined], matchersUtil)).toBe(false);
}); });
it("does not match when there is an extra item", function() { it("does not match when there is an extra item", function() {
var matcher = new jasmineUnderTest.ArrayWithExactContents(['a']); var matcher = new jasmineUnderTest.ArrayWithExactContents(['a']);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matcher.asymmetricMatch(['a', 2])).toBe(false); expect(matcher.asymmetricMatch(['a', 2], matchersUtil)).toBe(false);
}); });
it("jasmineToStrings itself", function() { it("jasmineToStrings itself", function() {
var matcher = new jasmineUnderTest.ArrayWithExactContents([]); var sample = [],
matcher = new jasmineUnderTest.ArrayWithExactContents(sample),
pp = jasmine.createSpy('pp').and.returnValue('sample');
expect(matcher.jasmineToString()).toMatch("<jasmine.arrayWithExactContents"); expect(matcher.jasmineToString(pp)).toEqual(
'<jasmine.arrayWithExactContents(sample)>'
);
expect(pp).toHaveBeenCalledWith(sample);
}); });
it("uses custom equality testers", function() { it("uses custom equality testers", function() {
@@ -41,7 +49,8 @@ describe("ArrayWithExactContents", function() {
} }
}; };
var matcher = new jasmineUnderTest.ArrayWithExactContents(["fooVal"]); var matcher = new jasmineUnderTest.ArrayWithExactContents(["fooVal"]);
var matchersUtil = new jasmineUnderTest.MatchersUtil({customTesters: [tester]});
expect(matcher.asymmetricMatch(["fooBar"], [tester])).toBe(true); expect(matcher.asymmetricMatch(["fooBar"], matchersUtil)).toBe(true);
}); });
}); });

View File

@@ -31,8 +31,9 @@ describe('MapContaining', function() {
['foo', [1, 2, 3]], ['foo', [1, 2, 3]],
]); ]);
var containing = new jasmineUnderTest.MapContaining(containingMap); var containing = new jasmineUnderTest.MapContaining(containingMap);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch(actualMap)).toBe(true); expect(containing.asymmetricMatch(actualMap, matchersUtil)).toBe(true);
}); });
it('does not match when a key is not in actual', function() { it('does not match when a key is not in actual', function() {
@@ -46,8 +47,9 @@ describe('MapContaining', function() {
['foo', [1, 2, 3]], ['foo', [1, 2, 3]],
]); ]);
var containing = new jasmineUnderTest.MapContaining(containingMap); var containing = new jasmineUnderTest.MapContaining(containingMap);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch(actualMap)).toBe(false); expect(containing.asymmetricMatch(actualMap, matchersUtil)).toBe(false);
}); });
it('does not match when a value is not in actual', function() { it('does not match when a value is not in actual', function() {
@@ -61,8 +63,9 @@ describe('MapContaining', function() {
['foo', [1, 2]], ['foo', [1, 2]],
]); ]);
var containing = new jasmineUnderTest.MapContaining(containingMap); var containing = new jasmineUnderTest.MapContaining(containingMap);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch(actualMap)).toBe(false); expect(containing.asymmetricMatch(actualMap, matchersUtil)).toBe(false);
}); });
it('matches when all the key/value pairs in sample have asymmetric matches in actual', function() { it('matches when all the key/value pairs in sample have asymmetric matches in actual', function() {
@@ -74,17 +77,18 @@ describe('MapContaining', function() {
var containingMap = new MapI([ var containingMap = new MapI([
[ [
jasmine.stringMatching(/^foo\d/), jasmineUnderTest.stringMatching(/^foo\d/),
'bar' 'bar'
], ],
[ [
'baz', 'baz',
jasmine.arrayContaining([2, 3]) jasmineUnderTest.arrayContaining([2, 3])
], ],
]); ]);
var containing = new jasmineUnderTest.MapContaining(containingMap); var containing = new jasmineUnderTest.MapContaining(containingMap);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch(actualMap)).toBe(true); expect(containing.asymmetricMatch(actualMap, matchersUtil)).toBe(true);
}); });
it('does not match when a key in sample has no asymmetric matches in actual', function() { it('does not match when a key in sample has no asymmetric matches in actual', function() {
@@ -95,17 +99,18 @@ describe('MapContaining', function() {
var containingMap = new MapI([ var containingMap = new MapI([
[ [
jasmine.stringMatching(/^foo\d/), jasmineUnderTest.stringMatching(/^foo\d/),
'bar' 'bar'
], ],
[ [
'baz', 'baz',
jasmine.arrayContaining([2, 3]) jasmineUnderTest.arrayContaining([2, 3])
], ],
]); ]);
var containing = new jasmineUnderTest.MapContaining(containingMap); var containing = new jasmineUnderTest.MapContaining(containingMap);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch(actualMap)).toBe(false); expect(containing.asymmetricMatch(actualMap, matchersUtil)).toBe(false);
}); });
it('does not match when a value in sample has no asymmetric matches in actual', function() { it('does not match when a value in sample has no asymmetric matches in actual', function() {
@@ -116,17 +121,18 @@ describe('MapContaining', function() {
var containingMap = new MapI([ var containingMap = new MapI([
[ [
jasmine.stringMatching(/^foo\d/), jasmineUnderTest.stringMatching(/^foo\d/),
'bar' 'bar'
], ],
[ [
'baz', 'baz',
jasmine.arrayContaining([4, 5]) jasmineUnderTest.arrayContaining([4, 5])
], ],
]); ]);
var containing = new jasmineUnderTest.MapContaining(containingMap); var containing = new jasmineUnderTest.MapContaining(containingMap);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch(actualMap)).toBe(false); expect(containing.asymmetricMatch(actualMap, matchersUtil)).toBe(false);
}); });
it('matches recursively', function() { it('matches recursively', function() {
@@ -147,8 +153,9 @@ describe('MapContaining', function() {
], ],
]); ]);
var containing = new jasmineUnderTest.MapContaining(containingMap); var containing = new jasmineUnderTest.MapContaining(containingMap);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch(actualMap)).toBe(true); expect(containing.asymmetricMatch(actualMap, matchersUtil)).toBe(true);
}); });
it('uses custom equality testers', function() { it('uses custom equality testers', function() {
@@ -158,8 +165,9 @@ describe('MapContaining', function() {
} }
var actualMap = new MapI([['foo', -1]]); var actualMap = new MapI([['foo', -1]]);
var containing = new jasmineUnderTest.MapContaining(new MapI([['foo', -2]])); var containing = new jasmineUnderTest.MapContaining(new MapI([['foo', -2]]));
var matchersUtil = new jasmineUnderTest.MatchersUtil({customTesters: [tester]});
expect(containing.asymmetricMatch(actualMap, [tester])).toBe(true); expect(containing.asymmetricMatch(actualMap, matchersUtil)).toBe(true);
}); });
it('does not match when actual is not a map', function() { it('does not match when actual is not a map', function() {
@@ -176,8 +184,13 @@ describe('MapContaining', function() {
}); });
it('defines a `jasmineToString` method', function() { it('defines a `jasmineToString` method', function() {
var containing = new jasmineUnderTest.MapContaining(new Map()); var sample = new Map(),
containing = new jasmineUnderTest.MapContaining(sample),
pp = jasmine.createSpy('pp').and.returnValue('sample');
expect(containing.jasmineToString()).toMatch(/^<jasmine\.mapContaining/); expect(containing.jasmineToString(pp)).toEqual(
'<jasmine.mapContaining(sample)>'
);
expect(pp).toHaveBeenCalledWith(sample);
}); });
}); });

View File

@@ -2,8 +2,9 @@ describe("ObjectContaining", function() {
it("matches any object actual to an empty object", function() { it("matches any object actual to an empty object", function() {
var containing = new jasmineUnderTest.ObjectContaining({}); var containing = new jasmineUnderTest.ObjectContaining({});
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch({foo: 1})).toBe(true); expect(containing.asymmetricMatch({foo: 1}, matchersUtil)).toBe(true);
}); });
it("does not match when the actual is not an object", function() { it("does not match when the actual is not an object", function() {
@@ -24,58 +25,72 @@ describe("ObjectContaining", function() {
it("matches when the key/value pair is present in the actual", function() { it("matches when the key/value pair is present in the actual", function() {
var containing = new jasmineUnderTest.ObjectContaining({foo: "fooVal"}); var containing = new jasmineUnderTest.ObjectContaining({foo: "fooVal"});
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch({foo: "fooVal", bar: "barVal"})).toBe(true); expect(containing.asymmetricMatch({foo: "fooVal", bar: "barVal"}, matchersUtil)).toBe(true);
}); });
it("does not match when the key/value pair is not present in the actual", function() { it("does not match when the key/value pair is not present in the actual", function() {
var containing = new jasmineUnderTest.ObjectContaining({foo: "fooVal"}); var containing = new jasmineUnderTest.ObjectContaining({foo: "fooVal"});
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch({bar: "barVal", quux: "quuxVal"})).toBe(false); expect(containing.asymmetricMatch({bar: "barVal", quux: "quuxVal"}, matchersUtil)).toBe(false);
}); });
it("does not match when the key is present but the value is different in the actual", function() { it("does not match when the key is present but the value is different in the actual", function() {
var containing = new jasmineUnderTest.ObjectContaining({foo: "other"}); var containing = new jasmineUnderTest.ObjectContaining({foo: "other"});
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch({foo: "fooVal", bar: "barVal"})).toBe(false); expect(containing.asymmetricMatch({foo: "fooVal", bar: "barVal"}, matchersUtil)).toBe(false);
}); });
it("jasmineToString's itself", function() { it("jasmineToString's itself", function() {
var containing = new jasmineUnderTest.ObjectContaining({}); var sample = {},
matcher = new jasmineUnderTest.ObjectContaining(sample),
pp = jasmine.createSpy('pp').and.returnValue('sample');
expect(matcher.jasmineToString(pp)).toEqual(
'<jasmine.objectContaining(sample)>'
);
expect(pp).toHaveBeenCalledWith(sample);
expect(containing.jasmineToString()).toMatch("<jasmine.objectContaining");
}); });
it("matches recursively", function() { it("matches recursively", function() {
var containing = new jasmineUnderTest.ObjectContaining({one: new jasmineUnderTest.ObjectContaining({two: {}})}); var containing = new jasmineUnderTest.ObjectContaining({one: new jasmineUnderTest.ObjectContaining({two: {}})});
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch({one: {two: {}}})).toBe(true); expect(containing.asymmetricMatch({one: {two: {}}}, matchersUtil)).toBe(true);
}); });
it("matches when key is present with undefined value", function() { it("matches when key is present with undefined value", function() {
var containing = new jasmineUnderTest.ObjectContaining({ one: undefined }); var containing = new jasmineUnderTest.ObjectContaining({ one: undefined });
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch({ one: undefined })).toBe(true); expect(containing.asymmetricMatch({ one: undefined }, matchersUtil)).toBe(true);
}); });
it("does not match when key with undefined value is not present", function() { it("does not match when key with undefined value is not present", function() {
var containing = new jasmineUnderTest.ObjectContaining({ one: undefined }); var containing = new jasmineUnderTest.ObjectContaining({ one: undefined });
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch({})).toBe(false); expect(containing.asymmetricMatch({}, matchersUtil)).toBe(false);
}); });
it("matches defined properties", function(){ it("matches defined properties", function(){
var containing = new jasmineUnderTest.ObjectContaining({ foo: "fooVal" }); var containing = new jasmineUnderTest.ObjectContaining({ foo: "fooVal" });
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var definedPropertyObject = {}; var definedPropertyObject = {};
Object.defineProperty(definedPropertyObject, "foo", { Object.defineProperty(definedPropertyObject, "foo", {
get: function() { return "fooVal" } get: function() { return "fooVal" }
}); });
expect(containing.asymmetricMatch(definedPropertyObject)).toBe(true); expect(containing.asymmetricMatch(definedPropertyObject, matchersUtil)).toBe(true);
}); });
it("matches prototype properties", function(){ it("matches prototype properties", function(){
var containing = new jasmineUnderTest.ObjectContaining({ foo: "fooVal" }); var containing = new jasmineUnderTest.ObjectContaining({ foo: "fooVal" });
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var prototypeObject = {foo: "fooVal"}; var prototypeObject = {foo: "fooVal"};
var obj; var obj;
@@ -89,7 +104,7 @@ describe("ObjectContaining", function() {
obj = new Foo(); obj = new Foo();
} }
expect(containing.asymmetricMatch(obj)).toBe(true); expect(containing.asymmetricMatch(obj, matchersUtil)).toBe(true);
}); });
it("uses custom equality testers", function() { it("uses custom equality testers", function() {
@@ -101,8 +116,9 @@ describe("ObjectContaining", function() {
} }
}; };
var containing = new jasmineUnderTest.ObjectContaining({foo: "fooVal"}); var containing = new jasmineUnderTest.ObjectContaining({foo: "fooVal"});
var matchersUtil = new jasmineUnderTest.MatchersUtil({customTesters: [tester]});
expect(containing.asymmetricMatch({foo: "fooBar"}, [tester])).toBe(true); expect(containing.asymmetricMatch({foo: "fooBar"}, matchersUtil)).toBe(true);
}); });
describe("valuesForDiff_", function() { describe("valuesForDiff_", function() {

View File

@@ -28,8 +28,9 @@ describe('SetContaining', function() {
[1, 2, 3], {'foo': 'bar'} [1, 2, 3], {'foo': 'bar'}
]); ]);
var containing = new jasmineUnderTest.SetContaining(containingSet); var containing = new jasmineUnderTest.SetContaining(containingSet);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch(actualSet)).toBe(true); expect(containing.asymmetricMatch(actualSet, matchersUtil)).toBe(true);
}); });
it('does not match when a value is not in actual', function() { it('does not match when a value is not in actual', function() {
@@ -41,8 +42,9 @@ describe('SetContaining', function() {
[1, 2], {'foo': 'bar'} [1, 2], {'foo': 'bar'}
]); ]);
var containing = new jasmineUnderTest.SetContaining(containingSet); var containing = new jasmineUnderTest.SetContaining(containingSet);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch(actualSet)).toBe(false); expect(containing.asymmetricMatch(actualSet, matchersUtil)).toBe(false);
}); });
it('matches when all the values in sample have asymmetric matches in actual', function() { it('matches when all the values in sample have asymmetric matches in actual', function() {
@@ -51,12 +53,13 @@ describe('SetContaining', function() {
]); ]);
var containingSet = new SetI([ var containingSet = new SetI([
jasmine.stringMatching(/^foo\d/), jasmineUnderTest.stringMatching(/^foo\d/),
jasmine.arrayContaining([2, 3]), jasmineUnderTest.arrayContaining([2, 3]),
]); ]);
var containing = new jasmineUnderTest.SetContaining(containingSet); var containing = new jasmineUnderTest.SetContaining(containingSet);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch(actualSet)).toBe(true); expect(containing.asymmetricMatch(actualSet, matchersUtil)).toBe(true);
}); });
it('does not match when a value in sample has no asymmetric matches in actual', function() { it('does not match when a value in sample has no asymmetric matches in actual', function() {
@@ -69,8 +72,9 @@ describe('SetContaining', function() {
jasmine.arrayContaining([2, 3]), jasmine.arrayContaining([2, 3]),
]); ]);
var containing = new jasmineUnderTest.SetContaining(containingSet); var containing = new jasmineUnderTest.SetContaining(containingSet);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch(actualSet)).toBe(false); expect(containing.asymmetricMatch(actualSet, matchersUtil)).toBe(false);
}); });
it('matches recursively', function() { it('matches recursively', function() {
@@ -82,8 +86,9 @@ describe('SetContaining', function() {
new jasmineUnderTest.SetContaining(new SetI(['bar'])), 'foo' new jasmineUnderTest.SetContaining(new SetI(['bar'])), 'foo'
]); ]);
var containing = new jasmineUnderTest.SetContaining(containingSet); var containing = new jasmineUnderTest.SetContaining(containingSet);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch(actualSet)).toBe(true); expect(containing.asymmetricMatch(actualSet, matchersUtil)).toBe(true);
}); });
it('uses custom equality testers', function() { it('uses custom equality testers', function() {
@@ -93,8 +98,9 @@ describe('SetContaining', function() {
} }
var actualSet = new SetI(['foo', -1]); var actualSet = new SetI(['foo', -1]);
var containing = new jasmineUnderTest.SetContaining(new SetI([-2, 'foo'])); var containing = new jasmineUnderTest.SetContaining(new SetI([-2, 'foo']));
var matchersUtil = new jasmineUnderTest.MatchersUtil({customTesters: [tester]});
expect(containing.asymmetricMatch(actualSet, [tester])).toBe(true); expect(containing.asymmetricMatch(actualSet, matchersUtil)).toBe(true);
}); });
it('does not match when actual is not a set', function() { it('does not match when actual is not a set', function() {
@@ -111,8 +117,13 @@ describe('SetContaining', function() {
}); });
it('defines a `jasmineToString` method', function() { it('defines a `jasmineToString` method', function() {
var containing = new jasmineUnderTest.SetContaining(new Set()); var sample = new Set(),
containing = new jasmineUnderTest.SetContaining(sample),
pp = jasmine.createSpy('pp').and.returnValue('sample');
expect(containing.jasmineToString()).toMatch(/^<jasmine\.setContaining/); expect(containing.jasmineToString(pp)).toEqual(
'<jasmine.setContaining(sample)>'
);
expect(pp).toHaveBeenCalledWith(sample);
}); });
}); });

View File

@@ -115,4 +115,36 @@ describe('Custom Async Matchers (Integration)', function() {
env.addReporter({ specDone: specExpectations, jasmineDone: done }); env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute(); env.execute();
}); });
it("provides custom equality testers to the matcher factory via matchersUtil", function(done) {
jasmine.getEnv().requirePromises();
var matcherFactory = function (matchersUtil) {
return {
compare: function (actual, expected) {
return Promise.resolve({pass: matchersUtil.equals(actual[0], expected)});
}
};
},
customEqualityFn = jasmine.createSpy("customEqualityFn").and.callFake(function (a, b) {
return a.toString() === b;
});
env.it("spec with expectation", function() {
env.addCustomEqualityTester(customEqualityFn);
env.addAsyncMatchers({
toBeArrayWithFirstElement: matcherFactory
});
return env.expectAsync([1, 2]).toBeArrayWithFirstElement("1");
});
var specExpectations = function(result) {
expect(customEqualityFn).toHaveBeenCalledWith(1, "1");
expect(result.failedExpectations).toEqual([]);
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
});
}); });

View File

@@ -1,8 +1,8 @@
describe("Custom Matchers (Integration)", function() { describe("Custom Matchers (Integration)", function () {
var env; var env;
var fakeTimer; var fakeTimer;
beforeEach(function() { beforeEach(function () {
env = new jasmineUnderTest.Env(); env = new jasmineUnderTest.Env();
env.configure({random: false}); env.configure({random: false});
}); });
@@ -11,13 +11,13 @@ describe("Custom Matchers (Integration)", function() {
env.cleanup_(); env.cleanup_();
}); });
it("allows adding more matchers local to a spec", function(done) { it("allows adding more matchers local to a spec", function (done) {
env.it('spec defining a custom matcher', function() { env.it('spec defining a custom matcher', function () {
env.addMatchers({ env.addMatchers({
matcherForSpec: function() { matcherForSpec: function () {
return { return {
compare: function(actual, expected) { compare: function (actual, expected) {
return { pass: false, message: "matcherForSpec: actual: " + actual + "; expected: " + expected }; return {pass: false, message: "matcherForSpec: actual: " + actual + "; expected: " + expected};
} }
} }
} }
@@ -87,6 +87,8 @@ describe("Custom Matchers (Integration)", function() {
it("supports asymmetric equality testers that take a list of custom equality testers", function(done) { it("supports asymmetric equality testers that take a list of custom equality testers", function(done) {
// TODO: remove this in the next major release. // TODO: remove this in the next major release.
spyOn(jasmineUnderTest, 'getEnv').and.returnValue(env);
env.it("spec using custom asymmetric equality tester", function() { env.it("spec using custom asymmetric equality tester", function() {
var customEqualityFn = function(a, b) { var customEqualityFn = function(a, b) {
if (a === 2 && b === "two") { if (a === 2 && b === "two") {
@@ -233,4 +235,34 @@ describe("Custom Matchers (Integration)", function() {
env.addReporter({ specDone: specExpectations, jasmineDone: done }); env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute(); env.execute();
}); });
it("provides custom equality testers to the matcher factory via matchersUtil", function (done) {
var matcherFactory = function (matchersUtil) {
return {
compare: function (actual, expected) {
return {pass: matchersUtil.equals(actual[0], expected)};
}
};
},
customEqualityFn = jasmine.createSpy("customEqualityFn").and.callFake(function (a, b) {
return a.toString() === b;
});
env.it("spec with expectation", function () {
env.addCustomEqualityTester(customEqualityFn);
env.addMatchers({
toBeArrayWithFirstElement: matcherFactory
});
env.expect([1, 2]).toBeArrayWithFirstElement("1");
});
var specExpectations = function (result) {
expect(customEqualityFn).toHaveBeenCalledWith(1, "1");
expect(result.failedExpectations).toEqual([]);
};
env.addReporter({specDone: specExpectations, jasmineDone: done});
env.execute();
});
}); });

View File

@@ -0,0 +1,67 @@
describe("Custom object formatters", function() {
var env;
beforeEach(function() {
env = new jasmineUnderTest.Env();
env.configure({random: false});
});
it("scopes custom object formatters to a spec", function(done) {
env.it('a spec with custom pretty-printer', function() {
env.addCustomObjectFormatter(function(obj) { return 'custom(' + obj + ')'; });
env.expect(42).toBeUndefined();
});
env.it('a spec without custom pretty-printer', function() {
env.expect(42).toBeUndefined();
});
var specResults = [];
var specDone = function(result) {
specResults.push(result);
};
var expectations = function() {
expect(specResults[0].failedExpectations[0].message).toEqual("Expected custom(42) to be undefined.");
expect(specResults[1].failedExpectations[0].message).toEqual("Expected 42 to be undefined.");
done();
};
env.addReporter({ specDone:specDone, jasmineDone: expectations});
env.execute();
});
it("scopes custom object formatters to a suite", function(done) {
env.it('a spec without custom pretty-printer', function() {
env.expect(42).toBeUndefined();
});
env.describe('with custom pretty-printer', function() {
env.beforeEach(function() {
env.addCustomObjectFormatter(function(obj) { return 'custom(' + obj + ')'; });
});
env.it('a spec', function() {
env.expect(42).toBeUndefined();
});
});
var specResults = [];
var specDone = function(result) {
specResults.push(result);
};
var expectations = function() {
expect(specResults[0].failedExpectations[0].message).toEqual("Expected 42 to be undefined.");
expect(specResults[1].failedExpectations[0].message).toEqual("Expected custom(42) to be undefined.");
done();
};
env.addReporter({ specDone:specDone, jasmineDone: expectations});
env.execute();
});
it("throws an exception if you try to add a custom object formatter outside a runable", function() {
expect(function() {
env.addCustomObjectFormatter(function() {});
}).toThrowError('Custom object formatters must be added in a before function or a spec')
});
});

View File

@@ -2584,4 +2584,33 @@ describe("Env integration", function() {
env.execute(); env.execute();
}); });
it("supports asymmetric equality testers that take a matchersUtil", function(done) {
var env = new jasmineUnderTest.Env();
env.it("spec using custom asymmetric equality tester", function() {
var customEqualityFn = function(a, b) {
if (a === 2 && b === "two") {
return true;
}
};
var arrayWithFirstElement = function(sample) {
return {
asymmetricMatch: function (actual, matchersUtil) {
return matchersUtil.equals(sample, actual[0]);
}
};
};
env.addCustomEqualityTester(customEqualityFn);
env.expect(["two"]).toEqual(arrayWithFirstElement(2));
});
var specExpectations = function(result) {
expect(result.status).toEqual('passed');
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
});
}); });

View File

@@ -56,6 +56,27 @@ describe('Matchers (Integration)', function() {
}); });
} }
function verifyFailsWithCustomObjectFormatters(config) {
it('uses custom object formatters', function(done) {
env.it('a spec', function () {
env.addCustomObjectFormatter(config.formatter);
config.expectations(env);
});
var specExpectations = function (result) {
expect(result.status).toEqual('failed');
expect(result.failedExpectations.length)
.withContext('Number of failed expectations')
.toEqual(1);
expect(result.failedExpectations[0].message)
.toEqual(config.expectedMessage);
};
env.addReporter({specDone: specExpectations, jasmineDone: done});
env.execute();
});
}
function verifyPassesAsync(expectations) { function verifyPassesAsync(expectations) {
it('passes', function(done) { it('passes', function(done) {
jasmine.getEnv().requirePromises(); jasmine.getEnv().requirePromises();
@@ -107,6 +128,30 @@ describe('Matchers (Integration)', function() {
}); });
} }
function verifyFailsWithCustomObjectFormattersAsync(config) {
it('uses custom object formatters', function(done) {
var env = new jasmineUnderTest.Env();
jasmine.getEnv().requirePromises();
env.it('a spec', function () {
env.addCustomObjectFormatter(config.formatter);
return config.expectations(env);
});
var specExpectations = function (result) {
expect(result.status).toEqual('failed');
expect(result.failedExpectations.length)
.withContext('Number of failed expectations')
.toEqual(1);
expect(result.failedExpectations[0].message)
.toEqual(config.expectedMessage);
};
env.addReporter({specDone: specExpectations, jasmineDone: done});
env.execute();
});
}
describe('nothing', function() { describe('nothing', function() {
verifyPasses(function(env) { verifyPasses(function(env) {
env.expect().nothing(); env.expect().nothing();
@@ -223,6 +268,16 @@ describe('Matchers (Integration)', function() {
verifyFails(function(env) { verifyFails(function(env) {
env.expect(2).toBeNaN(); env.expect(2).toBeNaN();
}); });
verifyFailsWithCustomObjectFormatters({
formatter: function(val) {
return '|' + val + '|';
},
expectations: function(env) {
env.expect(1).toBeNaN();
},
expectedMessage: 'Expected |1| to be NaN.'
});
}); });
describe('toBeNegativeInfinity', function() { describe('toBeNegativeInfinity', function() {
@@ -233,6 +288,16 @@ describe('Matchers (Integration)', function() {
verifyFails(function(env) { verifyFails(function(env) {
env.expect(2).toBeNegativeInfinity(); env.expect(2).toBeNegativeInfinity();
}); });
verifyFailsWithCustomObjectFormatters({
formatter: function(val) {
return '|' + val + '|';
},
expectations: function(env) {
env.expect(1).toBeNegativeInfinity();
},
expectedMessage: 'Expected |1| to be -Infinity.'
});
}); });
describe('toBeNull', function() { describe('toBeNull', function() {
@@ -253,6 +318,16 @@ describe('Matchers (Integration)', function() {
verifyFails(function(env) { verifyFails(function(env) {
env.expect(2).toBePositiveInfinity(); env.expect(2).toBePositiveInfinity();
}); });
verifyFailsWithCustomObjectFormatters({
formatter: function(val) {
return '|' + val + '|';
},
expectations: function(env) {
env.expect(1).toBePositiveInfinity();
},
expectedMessage: 'Expected |1| to be Infinity.'
})
}); });
describe('toBeResolved', function() { describe('toBeResolved', function() {
@@ -276,6 +351,17 @@ describe('Matchers (Integration)', function() {
verifyFailsAsync(function(env) { verifyFailsAsync(function(env) {
return env.expectAsync(Promise.resolve('foo')).toBeResolvedTo('bar'); return env.expectAsync(Promise.resolve('foo')).toBeResolvedTo('bar');
}); });
verifyFailsWithCustomObjectFormattersAsync({
formatter: function(val) {
return '|' + val + '|';
},
expectations: function(env) {
return env.expectAsync(Promise.resolve('x')).toBeResolvedTo('y');
},
expectedMessage: 'Expected a promise to be resolved to |y| ' +
'but it was resolved to |x|.'
});
}); });
describe('toBeRejected', function() { describe('toBeRejected', function() {
@@ -299,6 +385,17 @@ describe('Matchers (Integration)', function() {
verifyFailsAsync(function(env) { verifyFailsAsync(function(env) {
return env.expectAsync(Promise.resolve()).toBeRejectedWith('nope'); return env.expectAsync(Promise.resolve()).toBeRejectedWith('nope');
}); });
verifyFailsWithCustomObjectFormattersAsync({
formatter: function(val) {
return '|' + val + '|';
},
expectations: function(env) {
return env.expectAsync(Promise.reject('x')).toBeRejectedWith('y');
},
expectedMessage: 'Expected a promise to be rejected with |y| ' +
'but it was rejected with |x|.'
});
}); });
describe('toBeRejectedWithError', function() { describe('toBeRejectedWithError', function() {
@@ -309,6 +406,17 @@ describe('Matchers (Integration)', function() {
verifyFailsAsync(function(env) { verifyFailsAsync(function(env) {
return env.expectAsync(Promise.resolve()).toBeRejectedWithError(Error); return env.expectAsync(Promise.resolve()).toBeRejectedWithError(Error);
}); });
verifyFailsWithCustomObjectFormattersAsync({
formatter: function(val) {
return '|' + val + '|';
},
expectations: function(env) {
return env.expectAsync(Promise.reject('foo')).toBeRejectedWithError('foo');
},
expectedMessage: 'Expected a promise to be rejected with Error: |foo| ' +
'but it was rejected with |foo|.'
});
}); });
describe('toBeTrue', function() { describe('toBeTrue', function() {
@@ -365,6 +473,20 @@ describe('Matchers (Integration)', function() {
verifyFails(function(env) { verifyFails(function(env) {
env.expect('a').toEqual('b'); env.expect('a').toEqual('b');
}); });
verifyFailsWithCustomObjectFormatters({
formatter: function(val) {
if (val === 5) {
return "five"
} else if (val === 4) {
return "four"
}
},
expectations: function(env) {
env.expect([{foo: 4}]).toEqual([{foo: 5}]);
},
expectedMessage: 'Expected $[0].foo = four to equal five.'
});
}); });
describe('toHaveBeenCalled', function() { describe('toHaveBeenCalled', function() {
@@ -423,6 +545,19 @@ describe('Matchers (Integration)', function() {
var spy = env.createSpy(); var spy = env.createSpy();
env.expect(spy).toHaveBeenCalledWith('foo'); env.expect(spy).toHaveBeenCalledWith('foo');
}); });
verifyFailsWithCustomObjectFormatters({
formatter: function(val) {
return '|' + val + '|';
},
expectations: function(env) {
var spy = env.createSpy('foo');
env.expect(spy).toHaveBeenCalledWith('x');
},
expectedMessage: 'Expected spy foo to have been called with:\n' +
' |x|\n' +
'but it was never called.'
});
}); });
describe('toHaveClass', function() { describe('toHaveClass', function() {
@@ -455,12 +590,28 @@ describe('Matchers (Integration)', function() {
describe('toThrow', function() { describe('toThrow', function() {
verifyPasses(function(env) { verifyPasses(function(env) {
env.expect(function() { throw new Error(); }).toThrow(); env.addCustomEqualityTester(function(a, b) {
return a.toString() === b.toString();
});
env.expect(function() { throw '5'; }).toThrow(5);
}); });
verifyFails(function(env) { verifyFails(function(env) {
env.expect(function() {}).toThrow(); env.expect(function() {}).toThrow();
}); });
verifyFailsWithCustomObjectFormatters({
formatter: function(val) {
return '|' + val + '|';
},
expectations: function(env) {
var spy = env.createSpy('foo');
env.expect(function() {
throw 'x'
}).not.toThrow();
},
expectedMessage: 'Expected function not to throw, but it threw |x|.'
});
}); });
describe('toThrowError', function() { describe('toThrowError', function() {
@@ -471,6 +622,19 @@ describe('Matchers (Integration)', function() {
verifyFails(function(env) { verifyFails(function(env) {
env.expect(function() { }).toThrowError(); env.expect(function() { }).toThrowError();
}); });
verifyFailsWithCustomObjectFormatters({
formatter: function(val) {
return '|' + val + '|';
},
expectations: function(env) {
var spy = env.createSpy('foo');
env.expect(function() {
throw 'x'
}).toThrowError();
},
expectedMessage: 'Expected function to throw an Error, but it threw |x|.'
});
}); });
describe('toThrowMatching', function() { describe('toThrowMatching', function() {
@@ -485,5 +649,21 @@ describe('Matchers (Integration)', function() {
verifyFails(function(env) { verifyFails(function(env) {
env.expect(throws).toThrowMatching(function() { return false; }); env.expect(throws).toThrowMatching(function() { return false; });
}); });
verifyFailsWithCustomObjectFormatters({
formatter: function(val) {
return '|' + val + '|';
},
expectations: function(env) {
var spy = env.createSpy('foo');
env.expect(function() {
throw new Error('nope')
}).toThrowMatching(function() {
return false;
});
},
expectedMessage: 'Expected function to throw an exception matching ' +
'a predicate, but it threw Error with message |nope|.'
});
}); });
}); });

View File

@@ -1,47 +1,136 @@
describe("DiffBuilder", function() { describe("DiffBuilder", function () {
it("records the actual and expected objects", function() { it("records the actual and expected objects", function () {
var diffBuilder = jasmineUnderTest.DiffBuilder(); var diffBuilder = jasmineUnderTest.DiffBuilder();
diffBuilder.record({x: 'actual'}, {x: 'expected'}); diffBuilder.setRoots({x: 'actual'}, {x: 'expected'});
diffBuilder.recordMismatch();
expect(diffBuilder.getMessage()).toEqual("Expected Object({ x: 'actual' }) to equal Object({ x: 'expected' })."); expect(diffBuilder.getMessage()).toEqual("Expected Object({ x: 'actual' }) to equal Object({ x: 'expected' }).");
}); });
it("prints the path at which the difference was found", function() { it("prints the path at which the difference was found", function () {
var diffBuilder = jasmineUnderTest.DiffBuilder(); var diffBuilder = jasmineUnderTest.DiffBuilder();
diffBuilder.setRoots({foo: {x: 'actual'}}, {foo: {x: 'expected'}});
diffBuilder.withPath('foo', function() { diffBuilder.withPath('foo', function () {
diffBuilder.record({x: 'actual'}, {x: 'expected'}); diffBuilder.recordMismatch();
}); });
expect(diffBuilder.getMessage()).toEqual("Expected $.foo = Object({ x: 'actual' }) to equal Object({ x: 'expected' })."); expect(diffBuilder.getMessage()).toEqual("Expected $.foo = Object({ x: 'actual' }) to equal Object({ x: 'expected' }).");
}); });
it("prints multiple messages, separated by newlines", function() { it("prints multiple messages, separated by newlines", function () {
var diffBuilder = jasmineUnderTest.DiffBuilder(); var diffBuilder = jasmineUnderTest.DiffBuilder();
diffBuilder.setRoots({foo: 1, bar: 3}, {foo: 2, bar: 4});
diffBuilder.withPath('foo', function() { diffBuilder.withPath('foo', function () {
diffBuilder.record(1, 2); diffBuilder.recordMismatch();
});
diffBuilder.withPath('bar', function () {
diffBuilder.recordMismatch();
}); });
var message = var message =
"Expected $.foo = 1 to equal 2.\n" + "Expected $.foo = 1 to equal 2.\n" +
"Expected 3 to equal 4."; "Expected $.bar = 3 to equal 4.";
diffBuilder.record(3, 4);
expect(diffBuilder.getMessage()).toEqual(message); expect(diffBuilder.getMessage()).toEqual(message);
}); });
it("allows customization of the message", function() { it("allows customization of the message", function () {
var diffBuilder = jasmineUnderTest.DiffBuilder(); var diffBuilder = jasmineUnderTest.DiffBuilder();
diffBuilder.setRoots({x: 'bar'}, {x: 'foo'});
function darthVaderFormatter(actual, expected, path) { function darthVaderFormatter(actual, expected, path) {
return "I find your lack of " + expected + " disturbing. (was " + actual + ", at " + path + ")" return "I find your lack of " + expected + " disturbing. (was " + actual + ", at " + path + ")"
} }
diffBuilder.withPath('x', function() { diffBuilder.withPath('x', function () {
diffBuilder.record('bar', 'foo', darthVaderFormatter); diffBuilder.recordMismatch(darthVaderFormatter);
}); });
expect(diffBuilder.getMessage()).toEqual("I find your lack of foo disturbing. (was bar, at $.x)"); expect(diffBuilder.getMessage()).toEqual("I find your lack of foo disturbing. (was bar, at $.x)");
}); });
it("uses the injected pretty-printer", function () {
var prettyPrinter = function (val) {
return '|' + val + '|';
},
diffBuilder = jasmineUnderTest.DiffBuilder({prettyPrinter: prettyPrinter});
prettyPrinter.customFormat_ = function () {
};
diffBuilder.setRoots({foo: 'actual'}, {foo: 'expected'});
diffBuilder.withPath('foo', function () {
diffBuilder.recordMismatch();
});
expect(diffBuilder.getMessage()).toEqual("Expected $.foo = |actual| to equal |expected|.");
});
it("passes the injected pretty-printer to the diff formatter", function () {
var diffFormatter = jasmine.createSpy('diffFormatter'),
prettyPrinter = function () {
},
diffBuilder = jasmineUnderTest.DiffBuilder({prettyPrinter: prettyPrinter});
prettyPrinter.customFormat_ = function () {
};
diffBuilder.setRoots({x: 'bar'}, {x: 'foo'});
diffBuilder.withPath('x', function () {
diffBuilder.recordMismatch(diffFormatter);
});
diffBuilder.getMessage();
expect(diffFormatter).toHaveBeenCalledWith('bar', 'foo', jasmine.anything(), prettyPrinter);
});
it("uses custom object formatters on leaf nodes", function() {
var formatter = function(x) {
if (typeof x === 'number') {
return '[number:' + x + ']';
}
};
prettyPrinter = jasmineUnderTest.makePrettyPrinter([formatter]);
var diffBuilder = new jasmineUnderTest.DiffBuilder({prettyPrinter: prettyPrinter});
diffBuilder.setRoots(5, 4);
diffBuilder.recordMismatch();
expect(diffBuilder.getMessage()).toEqual('Expected [number:5] to equal [number:4].');
});
it("uses custom object formatters on non leaf nodes", function () {
var formatter = function (x) {
if (x.hasOwnProperty('a')) {
return '[thing with a=' + x.a + ', b=' + JSON.stringify(x.b) + ']';
}
};
prettyPrinter = jasmineUnderTest.makePrettyPrinter([formatter]);
var diffBuilder = new jasmineUnderTest.DiffBuilder({prettyPrinter: prettyPrinter});
var expectedMsg = 'Expected $[0].foo = [thing with a=1, b={"x":42}] to equal [thing with a=1, b={"x":43}].\n' +
"Expected $[0].bar = 'yes' to equal 'no'.";
diffBuilder.setRoots(
[{foo: {a: 1, b: {x: 42}}, bar: 'yes'}],
[{foo: {a: 1, b: {x: 43}}, bar: 'no'}]
);
diffBuilder.withPath(0, function () {
diffBuilder.withPath('foo', function () {
diffBuilder.withPath('b', function () {
diffBuilder.withPath('x', function () {
diffBuilder.recordMismatch();
});
});
});
diffBuilder.withPath('bar', function () {
diffBuilder.recordMismatch();
});
});
expect(diffBuilder.getMessage()).toEqual(expectedMsg);
});
}); });

View File

@@ -0,0 +1,136 @@
describe('MismatchTree', function () {
describe('#add', function () {
describe('When the path is empty', function () {
it('flags the root node as mismatched', function () {
var tree = new jasmineUnderTest.MismatchTree();
tree.add(new jasmineUnderTest.ObjectPath([]));
expect(tree.isMismatch).toBe(true);
});
});
describe('When the path is not empty', function () {
it('flags the node as mismatched', function () {
var tree = new jasmineUnderTest.MismatchTree();
tree.add(new jasmineUnderTest.ObjectPath(['a', 'b']));
expect(tree.child('a').child('b').isMismatch).toBe(true);
});
it('does not flag ancestors as mismatched', function () {
var tree = new jasmineUnderTest.MismatchTree();
tree.add(new jasmineUnderTest.ObjectPath(['a', 'b']));
expect(tree.isMismatch).toBe(false);
expect(tree.child('a').isMismatch).toBe(false);
});
});
it('stores the formatter on only the target node', function () {
var tree = new jasmineUnderTest.MismatchTree();
tree.add(new jasmineUnderTest.ObjectPath(['a', 'b']), formatter);
expect(tree.formatter).toBeFalsy();
expect(tree.child('a').formatter).toBeFalsy();
expect(tree.child('a').child('b').formatter).toBe(formatter);
});
it('stores the path to the node', function () {
var tree = new jasmineUnderTest.MismatchTree();
tree.add(new jasmineUnderTest.ObjectPath(['a', 'b']), formatter);
expect(tree.child('a').child('b').path.components).toEqual(['a', 'b']);
});
});
describe('#traverse', function () {
it('calls the callback for all nodes that are or contain mismatches', function () {
var tree = new jasmineUnderTest.MismatchTree();
tree.add(new jasmineUnderTest.ObjectPath(['a', 'b']), formatter);
tree.add(new jasmineUnderTest.ObjectPath(['c']));
var visit = jasmine.createSpy('visit').and.returnValue(true);
tree.traverse(visit);
expect(visit).toHaveBeenCalledWith(
new jasmineUnderTest.ObjectPath([]), false, undefined
);
expect(visit).toHaveBeenCalledWith(
new jasmineUnderTest.ObjectPath(['a']), false, undefined
);
expect(visit).toHaveBeenCalledWith(
new jasmineUnderTest.ObjectPath(['a', 'b']), true, formatter
);
expect(visit).toHaveBeenCalledWith(
new jasmineUnderTest.ObjectPath(['c']), true, undefined
);
});
it('does not call the callback if there are no mismatches', function () {
var tree = new jasmineUnderTest.MismatchTree();
var visit = jasmine.createSpy('visit');
tree.traverse(visit);
expect(visit).not.toHaveBeenCalled();
});
it('visits parents before children', function () {
var tree = new jasmineUnderTest.MismatchTree();
tree.add(new jasmineUnderTest.ObjectPath(['a', 'b']));
var visited = [];
tree.traverse(function (path) {
visited.push(path);
return true;
});
expect(visited).toEqual([
new jasmineUnderTest.ObjectPath([]),
new jasmineUnderTest.ObjectPath(['a']),
new jasmineUnderTest.ObjectPath(['a', 'b'])
]);
});
it('visits children in the order they were recorded', function() {
var tree = new jasmineUnderTest.MismatchTree();
tree.add(new jasmineUnderTest.ObjectPath(['length']));
tree.add(new jasmineUnderTest.ObjectPath([1]));
var visited = [];
tree.traverse(function (path) {
visited.push(path);
return true;
});
expect(visited).toEqual([
new jasmineUnderTest.ObjectPath([]),
new jasmineUnderTest.ObjectPath(['length']),
new jasmineUnderTest.ObjectPath([1])
]);
});
it('does not visit children if the callback returns falsy', function() {
var tree = new jasmineUnderTest.MismatchTree();
tree.add(new jasmineUnderTest.ObjectPath(['a', 'b']));
var visited = [];
tree.traverse(function (path) {
visited.push(path);
return path.depth() === 0;
});
expect(visited).toEqual([
new jasmineUnderTest.ObjectPath([]),
new jasmineUnderTest.ObjectPath(['a'])
]);
});
});
function formatter() {
}
});

View File

@@ -1,13 +1,8 @@
describe('NullDiffBuilder', function() { describe('NullDiffBuilder', function () {
it('responds to withPath() by calling the passed function', function() { it('responds to withPath() by calling the passed function', function () {
var spy = jasmine.createSpy('callback'); var spy = jasmine.createSpy('callback');
jasmineUnderTest.NullDiffBuilder().withPath('does not matter', spy); jasmineUnderTest.NullDiffBuilder().withPath('does not matter', spy);
expect(spy).toHaveBeenCalled(); expect(spy).toHaveBeenCalled();
}); });
it('responds to record()', function() {
expect(function() {
jasmineUnderTest.NullDiffBuilder().record('does not matter');
}).not.toThrow();
})
}); });

View File

@@ -39,5 +39,13 @@ describe('ObjectPath', function() {
expect(path.toString()).toEqual('$.foo'); expect(path.toString()).toEqual('$.foo');
expect(root.toString()).toEqual(''); expect(root.toString()).toEqual('');
}) });
describe('#dereference', function() {
it('returns the value corresponding to the path', function () {
var path = new ObjectPath().add('foo').add(1).add('bar');
var obj = {foo: ['', {bar: 42}]};
expect(path.dereference(obj)).toEqual(42);
});
});
}); });

View File

@@ -2,7 +2,8 @@ describe('toBeRejected', function() {
it('passes if the actual is rejected', function() { it('passes if the actual is rejected', function() {
jasmine.getEnv().requirePromises(); jasmine.getEnv().requirePromises();
var matcher = jasmineUnderTest.asyncMatchers.toBeRejected(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil(),
matcher = jasmineUnderTest.asyncMatchers.toBeRejected(matchersUtil),
actual = Promise.reject('AsyncExpectationSpec rejection'); actual = Promise.reject('AsyncExpectationSpec rejection');
return matcher.compare(actual).then(function(result) { return matcher.compare(actual).then(function(result) {
@@ -13,7 +14,8 @@ describe('toBeRejected', function() {
it('fails if the actual is resolved', function() { it('fails if the actual is resolved', function() {
jasmine.getEnv().requirePromises(); jasmine.getEnv().requirePromises();
var matcher = jasmineUnderTest.asyncMatchers.toBeRejected(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil(),
matcher = jasmineUnderTest.asyncMatchers.toBeRejected(matchersUtil),
actual = Promise.resolve(); actual = Promise.resolve();
return matcher.compare(actual).then(function(result) { return matcher.compare(actual).then(function(result) {
@@ -22,7 +24,8 @@ describe('toBeRejected', function() {
}); });
it('fails if actual is not a promise', function() { it('fails if actual is not a promise', function() {
var matcher = jasmineUnderTest.asyncMatchers.toBeRejected(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil(),
matcher = jasmineUnderTest.asyncMatchers.toBeRejected(matchersUtil),
actual = 'not a promise'; actual = 'not a promise';
function f() { function f() {

View File

@@ -2,7 +2,8 @@ describe('#toBeRejectedWithError', function () {
it('passes when Error type matches', function () { it('passes when Error type matches', function () {
jasmine.getEnv().requirePromises(); jasmine.getEnv().requirePromises();
var matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: new jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
actual = Promise.reject(new TypeError('foo')); actual = Promise.reject(new TypeError('foo'));
return matcher.compare(actual, TypeError).then(function (result) { return matcher.compare(actual, TypeError).then(function (result) {
@@ -16,7 +17,8 @@ describe('#toBeRejectedWithError', function () {
it('passes when Error type and message matches', function () { it('passes when Error type and message matches', function () {
jasmine.getEnv().requirePromises(); jasmine.getEnv().requirePromises();
var matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: new jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
actual = Promise.reject(new TypeError('foo')); actual = Promise.reject(new TypeError('foo'));
return matcher.compare(actual, TypeError, 'foo').then(function (result) { return matcher.compare(actual, TypeError, 'foo').then(function (result) {
@@ -30,7 +32,8 @@ describe('#toBeRejectedWithError', function () {
it('passes when Error matches and is exactly Error', function() { it('passes when Error matches and is exactly Error', function() {
jasmine.getEnv().requirePromises(); jasmine.getEnv().requirePromises();
var matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: new jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
actual = Promise.reject(new Error()); actual = Promise.reject(new Error());
return matcher.compare(actual, Error).then(function (result) { return matcher.compare(actual, Error).then(function (result) {
@@ -45,7 +48,8 @@ describe('#toBeRejectedWithError', function () {
it('passes when Error message matches a string', function () { it('passes when Error message matches a string', function () {
jasmine.getEnv().requirePromises(); jasmine.getEnv().requirePromises();
var matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: new jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
actual = Promise.reject(new Error('foo')); actual = Promise.reject(new Error('foo'));
return matcher.compare(actual, 'foo').then(function (result) { return matcher.compare(actual, 'foo').then(function (result) {
@@ -59,7 +63,8 @@ describe('#toBeRejectedWithError', function () {
it('passes when Error message matches a RegExp', function () { it('passes when Error message matches a RegExp', function () {
jasmine.getEnv().requirePromises(); jasmine.getEnv().requirePromises();
var matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: new jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
actual = Promise.reject(new Error('foo')); actual = Promise.reject(new Error('foo'));
return matcher.compare(actual, /foo/).then(function (result) { return matcher.compare(actual, /foo/).then(function (result) {
@@ -73,7 +78,8 @@ describe('#toBeRejectedWithError', function () {
it('passes when Error message is empty', function () { it('passes when Error message is empty', function () {
jasmine.getEnv().requirePromises(); jasmine.getEnv().requirePromises();
var matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: new jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
actual = Promise.reject(new Error()); actual = Promise.reject(new Error());
return matcher.compare(actual, '').then(function (result) { return matcher.compare(actual, '').then(function (result) {
@@ -87,7 +93,8 @@ describe('#toBeRejectedWithError', function () {
it('passes when no arguments', function () { it('passes when no arguments', function () {
jasmine.getEnv().requirePromises(); jasmine.getEnv().requirePromises();
var matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: new jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
actual = Promise.reject(new Error()); actual = Promise.reject(new Error());
return matcher.compare(actual, void 0).then(function (result) { return matcher.compare(actual, void 0).then(function (result) {
@@ -101,7 +108,8 @@ describe('#toBeRejectedWithError', function () {
it('fails when resolved', function () { it('fails when resolved', function () {
jasmine.getEnv().requirePromises(); jasmine.getEnv().requirePromises();
var matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: new jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
actual = Promise.resolve(new Error('foo')); actual = Promise.resolve(new Error('foo'));
return matcher.compare(actual, 'foo').then(function (result) { return matcher.compare(actual, 'foo').then(function (result) {
@@ -115,7 +123,8 @@ describe('#toBeRejectedWithError', function () {
it('fails when rejected with non Error type', function () { it('fails when rejected with non Error type', function () {
jasmine.getEnv().requirePromises(); jasmine.getEnv().requirePromises();
var matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: new jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
actual = Promise.reject('foo'); actual = Promise.reject('foo');
return matcher.compare(actual, 'foo').then(function (result) { return matcher.compare(actual, 'foo').then(function (result) {
@@ -129,7 +138,8 @@ describe('#toBeRejectedWithError', function () {
it('fails when Error type mismatches', function () { it('fails when Error type mismatches', function () {
jasmine.getEnv().requirePromises(); jasmine.getEnv().requirePromises();
var matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: new jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
actual = Promise.reject(new Error('foo')); actual = Promise.reject(new Error('foo'));
return matcher.compare(actual, TypeError, 'foo').then(function (result) { return matcher.compare(actual, TypeError, 'foo').then(function (result) {
@@ -143,7 +153,8 @@ describe('#toBeRejectedWithError', function () {
it('fails when Error message mismatches', function () { it('fails when Error message mismatches', function () {
jasmine.getEnv().requirePromises(); jasmine.getEnv().requirePromises();
var matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: new jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
actual = Promise.reject(new Error('foo')); actual = Promise.reject(new Error('foo'));
return matcher.compare(actual, 'bar').then(function (result) { return matcher.compare(actual, 'bar').then(function (result) {
@@ -155,7 +166,8 @@ describe('#toBeRejectedWithError', function () {
}); });
it('fails if actual is not a promise', function() { it('fails if actual is not a promise', function() {
var matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: new jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
actual = 'not a promise'; actual = 'not a promise';
function f() { function f() {

View File

@@ -2,7 +2,8 @@ describe('#toBeRejectedWith', function () {
it('should return true if the promise is rejected with the expected value', function () { it('should return true if the promise is rejected with the expected value', function () {
jasmine.getEnv().requirePromises(); jasmine.getEnv().requirePromises();
var matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWith(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil(),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWith(matchersUtil),
actual = Promise.reject({error: 'PEBCAK'}); actual = Promise.reject({error: 'PEBCAK'});
return matcher.compare(actual, {error: 'PEBCAK'}).then(function (result) { return matcher.compare(actual, {error: 'PEBCAK'}).then(function (result) {
@@ -13,7 +14,8 @@ describe('#toBeRejectedWith', function () {
it('should fail if the promise resolves', function () { it('should fail if the promise resolves', function () {
jasmine.getEnv().requirePromises(); jasmine.getEnv().requirePromises();
var matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWith(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil(),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWith(matchersUtil),
actual = Promise.resolve(); actual = Promise.resolve();
return matcher.compare(actual, '').then(function (result) { return matcher.compare(actual, '').then(function (result) {
@@ -24,7 +26,8 @@ describe('#toBeRejectedWith', function () {
it('should fail if the promise is rejected with a different value', function () { it('should fail if the promise is rejected with a different value', function () {
jasmine.getEnv().requirePromises(); jasmine.getEnv().requirePromises();
var matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWith(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWith(matchersUtil),
actual = Promise.reject('A Bad Apple'); actual = Promise.reject('A Bad Apple');
return matcher.compare(actual, 'Some Cool Thing').then(function (result) { return matcher.compare(actual, 'Some Cool Thing').then(function (result) {
@@ -38,7 +41,8 @@ describe('#toBeRejectedWith', function () {
it('should build its error correctly when negated', function () { it('should build its error correctly when negated', function () {
jasmine.getEnv().requirePromises(); jasmine.getEnv().requirePromises();
var matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWith(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWith(matchersUtil),
actual = Promise.reject(true); actual = Promise.reject(true);
return matcher.compare(actual, true).then(function (result) { return matcher.compare(actual, true).then(function (result) {
@@ -53,7 +57,8 @@ describe('#toBeRejectedWith', function () {
jasmine.getEnv().requirePromises(); jasmine.getEnv().requirePromises();
var customEqualityTesters = [function() { return true; }], var customEqualityTesters = [function() { return true; }],
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWith(jasmineUnderTest.matchersUtil, customEqualityTesters), matchersUtil = new jasmineUnderTest.MatchersUtil({customTesters: customEqualityTesters}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWith(matchersUtil),
actual = Promise.reject('actual'); actual = Promise.reject('actual');
return matcher.compare(actual, 'expected').then(function(result) { return matcher.compare(actual, 'expected').then(function(result) {
@@ -62,7 +67,8 @@ describe('#toBeRejectedWith', function () {
}); });
it('fails if actual is not a promise', function() { it('fails if actual is not a promise', function() {
var matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWith(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWith(matchersUtil),
actual = 'not a promise'; actual = 'not a promise';
function f() { function f() {

View File

@@ -2,7 +2,8 @@ describe('toBeResolved', function() {
it('passes if the actual is resolved', function() { it('passes if the actual is resolved', function() {
jasmine.getEnv().requirePromises(); jasmine.getEnv().requirePromises();
var matcher = jasmineUnderTest.asyncMatchers.toBeResolved(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil(),
matcher = jasmineUnderTest.asyncMatchers.toBeResolved(matchersUtil),
actual = Promise.resolve(); actual = Promise.resolve();
return matcher.compare(actual).then(function(result) { return matcher.compare(actual).then(function(result) {
@@ -13,7 +14,8 @@ describe('toBeResolved', function() {
it('fails if the actual is rejected', function() { it('fails if the actual is rejected', function() {
jasmine.getEnv().requirePromises(); jasmine.getEnv().requirePromises();
var matcher = jasmineUnderTest.asyncMatchers.toBeResolved(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil(),
matcher = jasmineUnderTest.asyncMatchers.toBeResolved(matchersUtil),
actual = Promise.reject('AsyncExpectationSpec rejection'); actual = Promise.reject('AsyncExpectationSpec rejection');
return matcher.compare(actual).then(function(result) { return matcher.compare(actual).then(function(result) {
@@ -22,7 +24,8 @@ describe('toBeResolved', function() {
}); });
it('fails if actual is not a promise', function() { it('fails if actual is not a promise', function() {
var matcher = jasmineUnderTest.asyncMatchers.toBeResolved(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil(),
matcher = jasmineUnderTest.asyncMatchers.toBeResolved(matchersUtil),
actual = 'not a promise'; actual = 'not a promise';
function f() { function f() {

View File

@@ -2,7 +2,8 @@ describe('#toBeResolvedTo', function() {
it('passes if the promise is resolved to the expected value', function() { it('passes if the promise is resolved to the expected value', function() {
jasmine.getEnv().requirePromises(); jasmine.getEnv().requirePromises();
var matcher = jasmineUnderTest.asyncMatchers.toBeResolvedTo(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil(),
matcher = jasmineUnderTest.asyncMatchers.toBeResolvedTo(matchersUtil),
actual = Promise.resolve({foo: 42}); actual = Promise.resolve({foo: 42});
return matcher.compare(actual, {foo: 42}).then(function(result) { return matcher.compare(actual, {foo: 42}).then(function(result) {
@@ -13,7 +14,8 @@ describe('#toBeResolvedTo', function() {
it('fails if the promise is rejected', function() { it('fails if the promise is rejected', function() {
jasmine.getEnv().requirePromises(); jasmine.getEnv().requirePromises();
var matcher = jasmineUnderTest.asyncMatchers.toBeResolvedTo(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: new jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeResolvedTo(matchersUtil),
actual = Promise.reject('AsyncExpectationSpec error'); actual = Promise.reject('AsyncExpectationSpec error');
return matcher.compare(actual, '').then(function(result) { return matcher.compare(actual, '').then(function(result) {
@@ -27,7 +29,8 @@ describe('#toBeResolvedTo', function() {
it('fails if the promise is resolved to a different value', function() { it('fails if the promise is resolved to a different value', function() {
jasmine.getEnv().requirePromises(); jasmine.getEnv().requirePromises();
var matcher = jasmineUnderTest.asyncMatchers.toBeResolvedTo(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: new jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeResolvedTo(matchersUtil),
actual = Promise.resolve({foo: 17}); actual = Promise.resolve({foo: 17});
return matcher.compare(actual, {foo: 42}).then(function(result) { return matcher.compare(actual, {foo: 42}).then(function(result) {
@@ -41,7 +44,8 @@ describe('#toBeResolvedTo', function() {
it('builds its message correctly when negated', function() { it('builds its message correctly when negated', function() {
jasmine.getEnv().requirePromises(); jasmine.getEnv().requirePromises();
var matcher = jasmineUnderTest.asyncMatchers.toBeResolvedTo(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: new jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeResolvedTo(matchersUtil),
actual = Promise.resolve(true); actual = Promise.resolve(true);
return matcher.compare(actual, true).then(function(result) { return matcher.compare(actual, true).then(function(result) {
@@ -56,7 +60,11 @@ describe('#toBeResolvedTo', function() {
jasmine.getEnv().requirePromises(); jasmine.getEnv().requirePromises();
var customEqualityTesters = [function() { return true; }], var customEqualityTesters = [function() { return true; }],
matcher = jasmineUnderTest.asyncMatchers.toBeResolvedTo(jasmineUnderTest.matchersUtil, customEqualityTesters), matchersUtil = new jasmineUnderTest.MatchersUtil({
customTesters: customEqualityTesters,
pp: jasmineUnderTest.makePrettyPrinter()
}),
matcher = jasmineUnderTest.asyncMatchers.toBeResolvedTo(matchersUtil),
actual = Promise.resolve('actual'); actual = Promise.resolve('actual');
return matcher.compare(actual, 'expected').then(function(result) { return matcher.compare(actual, 'expected').then(function(result) {
@@ -65,7 +73,8 @@ describe('#toBeResolvedTo', function() {
}); });
it('fails if actual is not a promise', function() { it('fails if actual is not a promise', function() {
var matcher = jasmineUnderTest.asyncMatchers.toBeResolvedTo(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeResolvedTo(matchersUtil),
actual = 'not a promise'; actual = 'not a promise';
function f() { function f() {

View File

@@ -1,4 +1,11 @@
describe("matchersUtil", function() { describe("matchersUtil", function() {
it("exposes the injected pretty-printer as .pp", function() {
var pp = function() {},
matchersUtil = new jasmineUnderTest.MatchersUtil({pp: pp});
expect(matchersUtil.pp).toBe(pp);
});
describe("equals", function() { describe("equals", function() {
describe('Properties', function() { describe('Properties', function() {
var fc; var fc;
@@ -72,178 +79,210 @@ describe("matchersUtil", function() {
}); });
it("passes for literals that are triple-equal", function() { it("passes for literals that are triple-equal", function() {
expect(jasmineUnderTest.matchersUtil.equals(null, null)).toBe(true); var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(jasmineUnderTest.matchersUtil.equals(void 0, void 0)).toBe(true); expect(matchersUtil.equals(null, null)).toBe(true);
expect(matchersUtil.equals(void 0, void 0)).toBe(true);
}); });
it("fails for things that are not equivalent", function() { it("fails for things that are not equivalent", function() {
expect(jasmineUnderTest.matchersUtil.equals({a: "foo"}, 1)).toBe(false); var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals({a: "foo"}, 1)).toBe(false);
}); });
it("passes for Strings that are equivalent", function() { it("passes for Strings that are equivalent", function() {
expect(jasmineUnderTest.matchersUtil.equals("foo", "foo")).toBe(true); var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals("foo", "foo")).toBe(true);
}); });
it("fails for Strings that are not equivalent", function() { it("fails for Strings that are not equivalent", function() {
expect(jasmineUnderTest.matchersUtil.equals("foo", "bar")).toBe(false); var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals("foo", "bar")).toBe(false);
}); });
it("passes for Numbers that are equivalent", function() { it("passes for Numbers that are equivalent", function() {
expect(jasmineUnderTest.matchersUtil.equals(123, 123)).toBe(true); var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals(123, 123)).toBe(true);
}); });
it("fails for Numbers that are not equivalent", function() { it("fails for Numbers that are not equivalent", function() {
expect(jasmineUnderTest.matchersUtil.equals(123, 456)).toBe(false); var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals(123, 456)).toBe(false);
}); });
it("passes for Dates that are equivalent", function() { it("passes for Dates that are equivalent", function() {
expect(jasmineUnderTest.matchersUtil.equals(new Date("Jan 1, 1970"), new Date("Jan 1, 1970"))).toBe(true); var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals(new Date("Jan 1, 1970"), new Date("Jan 1, 1970"))).toBe(true);
}); });
it("fails for Dates that are not equivalent", function() { it("fails for Dates that are not equivalent", function() {
expect(jasmineUnderTest.matchersUtil.equals(new Date("Jan 1, 1970"), new Date("Feb 3, 1991"))).toBe(false); var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals(new Date("Jan 1, 1970"), new Date("Feb 3, 1991"))).toBe(false);
}); });
it("passes for Booleans that are equivalent", function() { it("passes for Booleans that are equivalent", function() {
expect(jasmineUnderTest.matchersUtil.equals(true, true)).toBe(true); var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals(true, true)).toBe(true);
}); });
it("fails for Booleans that are not equivalent", function() { it("fails for Booleans that are not equivalent", function() {
expect(jasmineUnderTest.matchersUtil.equals(true, false)).toBe(false); var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals(true, false)).toBe(false);
}); });
it("passes for RegExps that are equivalent", function() { it("passes for RegExps that are equivalent", function() {
expect(jasmineUnderTest.matchersUtil.equals(/foo/, /foo/)).toBe(true); var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals(/foo/, /foo/)).toBe(true);
}); });
it("fails for RegExps that are not equivalent", function() { it("fails for RegExps that are not equivalent", function() {
expect(jasmineUnderTest.matchersUtil.equals(/foo/, /bar/)).toBe(false); var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(jasmineUnderTest.matchersUtil.equals(new RegExp("foo", "i"), new RegExp("foo"))).toBe(false); expect(matchersUtil.equals(/foo/, /bar/)).toBe(false);
expect(matchersUtil.equals(new RegExp("foo", "i"), new RegExp("foo"))).toBe(false);
}); });
it("passes for Arrays that are equivalent", function() { it("passes for Arrays that are equivalent", function() {
expect(jasmineUnderTest.matchersUtil.equals([1, 2], [1, 2])).toBe(true); var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals([1, 2], [1, 2])).toBe(true);
}); });
it("passes for Arrays that are equivalent, with elements added by changing length", function() { it("passes for Arrays that are equivalent, with elements added by changing length", function() {
var foo = []; var foo = [],
matchersUtil = new jasmineUnderTest.MatchersUtil();
foo.length = 1; foo.length = 1;
expect(jasmineUnderTest.matchersUtil.equals(foo, [undefined])).toBe(true); expect(matchersUtil.equals(foo, [undefined])).toBe(true);
}); });
it("fails for Arrays that have different lengths", function() { it("fails for Arrays that have different lengths", function() {
expect(jasmineUnderTest.matchersUtil.equals([1, 2], [1, 2, 3])).toBe(false); matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals([1, 2], [1, 2, 3])).toBe(false);
}); });
it("fails for Arrays that have different elements", function() { it("fails for Arrays that have different elements", function() {
expect(jasmineUnderTest.matchersUtil.equals([1, 2, 3], [1, 5, 3])).toBe(false); var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals([1, 2, 3], [1, 5, 3])).toBe(false);
}); });
it("fails for Arrays whose contents are equivalent, but have differing properties", function() { it("fails for Arrays whose contents are equivalent, but have differing properties", function() {
var one = [1,2,3], var one = [1,2,3],
two = [1,2,3]; two = [1,2,3],
matchersUtil = new jasmineUnderTest.MatchersUtil();
one.foo = 'bar'; one.foo = 'bar';
two.foo = 'baz'; two.foo = 'baz';
expect(jasmineUnderTest.matchersUtil.equals(one, two)).toBe(false); expect(matchersUtil.equals(one, two)).toBe(false);
}); });
it("passes for Arrays with equivalent contents and properties", function() { it("passes for Arrays with equivalent contents and properties", function() {
var one = [1,2,3], var one = [1,2,3],
two = [1,2,3]; two = [1,2,3],
matchersUtil = new jasmineUnderTest.MatchersUtil();
one.foo = 'bar'; one.foo = 'bar';
two.foo = 'bar'; two.foo = 'bar';
expect(jasmineUnderTest.matchersUtil.equals(one, two)).toBe(true); expect(matchersUtil.equals(one, two)).toBe(true);
}); });
it("passes for Errors that are the same type and have the same message", function() { it("passes for Errors that are the same type and have the same message", function() {
expect(jasmineUnderTest.matchersUtil.equals(new Error("foo"), new Error("foo"))).toBe(true); var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals(new Error("foo"), new Error("foo"))).toBe(true);
}); });
it("fails for Errors that are the same type and have different messages", function() { it("fails for Errors that are the same type and have different messages", function() {
expect(jasmineUnderTest.matchersUtil.equals(new Error("foo"), new Error("bar"))).toBe(false); var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals(new Error("foo"), new Error("bar"))).toBe(false);
}); });
it("fails for objects with different constructors", function() { it("fails for objects with different constructors", function() {
var matchersUtil = new jasmineUnderTest.MatchersUtil();
function One() {} function One() {}
function Two() {} function Two() {}
expect(jasmineUnderTest.matchersUtil.equals(new One(), new Two())).toBe(false); expect(matchersUtil.equals(new One(), new Two())).toBe(false);
}); });
it("passes for Objects that are equivalent (simple case)", function() { it("passes for Objects that are equivalent (simple case)", function() {
expect(jasmineUnderTest.matchersUtil.equals({a: "foo"}, {a: "foo"})).toBe(true); var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals({a: "foo"}, {a: "foo"})).toBe(true);
}); });
it("fails for Objects that are not equivalent (simple case)", function() { it("fails for Objects that are not equivalent (simple case)", function() {
expect(jasmineUnderTest.matchersUtil.equals({a: "foo"}, {a: "bar"})).toBe(false); var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals({a: "foo"}, {a: "bar"})).toBe(false);
}); });
it("passes for Objects that are equivalent (deep case)", function() { it("passes for Objects that are equivalent (deep case)", function() {
expect(jasmineUnderTest.matchersUtil.equals({a: "foo", b: { c: "bar"}}, {a: "foo", b: { c: "bar"}})).toBe(true); var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(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() { it("fails for Objects that are not equivalent (deep case)", function() {
expect(jasmineUnderTest.matchersUtil.equals({a: "foo", b: { c: "baz"}}, {a: "foo", b: { c: "bar"}})).toBe(false); var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals({a: "foo", b: { c: "baz"}}, {a: "foo", b: { c: "bar"}})).toBe(false);
}); });
it("passes for Objects that are equivalent (with cycles)", function() { it("passes for Objects that are equivalent (with cycles)", function() {
var actual = { a: "foo" }, var actual = { a: "foo" },
expected = { a: "foo" }; expected = { a: "foo" },
matchersUtil = new jasmineUnderTest.MatchersUtil();
actual.b = actual; actual.b = actual;
expected.b = actual; expected.b = actual;
expect(jasmineUnderTest.matchersUtil.equals(actual, expected)).toBe(true); expect(matchersUtil.equals(actual, expected)).toBe(true);
}); });
it("fails for Objects that are not equivalent (with cycles)", function() { it("fails for Objects that are not equivalent (with cycles)", function() {
var actual = { a: "foo" }, var actual = { a: "foo" },
expected = { a: "bar" }; expected = { a: "bar" },
matchersUtil = new jasmineUnderTest.MatchersUtil();
actual.b = actual; actual.b = actual;
expected.b = actual; expected.b = actual;
expect(jasmineUnderTest.matchersUtil.equals(actual, expected)).toBe(false); expect(matchersUtil.equals(actual, expected)).toBe(false);
}); });
it("fails for Objects that have the same number of keys, but different keys/values", function () { it("fails for Objects that have the same number of keys, but different keys/values", function () {
var expected = { a: undefined }, var expected = { a: undefined },
actual = { b: 1 }; actual = { b: 1 },
matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(jasmineUnderTest.matchersUtil.equals(actual, expected)).toBe(false); expect(matchersUtil.equals(actual, expected)).toBe(false);
}); });
it("fails when comparing an empty object to an empty array (issue #114)", function() { it("fails when comparing an empty object to an empty array (issue #114)", function() {
var emptyObject = {}, var emptyObject = {},
emptyArray = []; emptyArray = [],
matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(jasmineUnderTest.matchersUtil.equals(emptyObject, emptyArray)).toBe(false);
expect(jasmineUnderTest.matchersUtil.equals(emptyArray, emptyObject)).toBe(false); expect(matchersUtil.equals(emptyObject, emptyArray)).toBe(false);
expect(matchersUtil.equals(emptyArray, emptyObject)).toBe(false);
}); });
it("passes for equivalent frozen objects (GitHub issue #266)", function() { it("passes for equivalent frozen objects (GitHub issue #266)", function() {
var a = { foo: 1 }, var a = { foo: 1 },
b = {foo: 1 }; b = {foo: 1 },
matchersUtil = new jasmineUnderTest.MatchersUtil();
Object.freeze(a); Object.freeze(a);
Object.freeze(b); Object.freeze(b);
expect(jasmineUnderTest.matchersUtil.equals(a,b)).toBe(true); expect(matchersUtil.equals(a,b)).toBe(true);
}); });
it("passes for equivalent Promises (GitHub issue #1314)", function() { it("passes for equivalent Promises (GitHub issue #1314)", function() {
if (typeof Promise === 'undefined') { return; } if (typeof Promise === 'undefined') { return; }
var p1 = new Promise(function () {}), var p1 = new Promise(function () {}),
p2 = new Promise(function () {}); p2 = new Promise(function () {}),
matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(jasmineUnderTest.matchersUtil.equals(p1, p1)).toBe(true); expect(matchersUtil.equals(p1, p1)).toBe(true);
expect(jasmineUnderTest.matchersUtil.equals(p1, p2)).toBe(false); expect(matchersUtil.equals(p1, p2)).toBe(false);
}); });
describe("when running in a browser", function() { describe("when running in a browser", function() {
@@ -256,6 +295,8 @@ describe("matchersUtil", function() {
return; return;
} }
var a = document.createElement("div"); var a = document.createElement("div");
var matchersUtil = new jasmineUnderTest.MatchersUtil();
a.setAttribute("test-attr", "attr-value"); a.setAttribute("test-attr", "attr-value");
a.appendChild(document.createTextNode('test')); a.appendChild(document.createTextNode('test'));
@@ -263,17 +304,18 @@ describe("matchersUtil", function() {
b.setAttribute("test-attr", "attr-value"); b.setAttribute("test-attr", "attr-value");
b.appendChild(document.createTextNode('test')); b.appendChild(document.createTextNode('test'));
expect(jasmineUnderTest.matchersUtil.equals(a,b)).toBe(true); expect(matchersUtil.equals(a,b)).toBe(true);
}); });
it("passes for equivalent objects from different frames", function() { it("passes for equivalent objects from different frames", function() {
if (isNotRunningInBrowser()) { if (isNotRunningInBrowser()) {
return; return;
} }
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var iframe = document.createElement('iframe'); var iframe = document.createElement('iframe');
document.body.appendChild(iframe); document.body.appendChild(iframe);
iframe.contentWindow.eval('window.testObject = {}'); iframe.contentWindow.eval('window.testObject = {}');
expect(jasmineUnderTest.matchersUtil.equals({}, iframe.contentWindow.testObject)).toBe(true); expect(matchersUtil.equals({}, iframe.contentWindow.testObject)).toBe(true);
document.body.removeChild(iframe); document.body.removeChild(iframe);
}); });
@@ -281,6 +323,7 @@ describe("matchersUtil", function() {
if (isNotRunningInBrowser()) { if (isNotRunningInBrowser()) {
return; return;
} }
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var a = document.createElement("div"); var a = document.createElement("div");
a.setAttribute("test-attr", "attr-value"); a.setAttribute("test-attr", "attr-value");
a.appendChild(document.createTextNode('test')); a.appendChild(document.createTextNode('test'));
@@ -289,16 +332,16 @@ describe("matchersUtil", function() {
b.setAttribute("test-attr", "attr-value2"); b.setAttribute("test-attr", "attr-value2");
b.appendChild(document.createTextNode('test')); b.appendChild(document.createTextNode('test'));
expect(jasmineUnderTest.matchersUtil.equals(a,b)).toBe(false); expect(matchersUtil.equals(a,b)).toBe(false);
b.setAttribute("test-attr", "attr-value"); b.setAttribute("test-attr", "attr-value");
expect(jasmineUnderTest.matchersUtil.equals(a,b)).toBe(true); expect(matchersUtil.equals(a,b)).toBe(true);
b.appendChild(document.createTextNode('2')); b.appendChild(document.createTextNode('2'));
expect(jasmineUnderTest.matchersUtil.equals(a,b)).toBe(false); expect(matchersUtil.equals(a,b)).toBe(false);
a.appendChild(document.createTextNode('2')); a.appendChild(document.createTextNode('2'));
expect(jasmineUnderTest.matchersUtil.equals(a,b)).toBe(true); expect(matchersUtil.equals(a,b)).toBe(true);
}); });
}); });
@@ -311,43 +354,47 @@ describe("matchersUtil", function() {
if (isNotRunningInNode()) { if (isNotRunningInNode()) {
return; return;
} }
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var vm = require('vm'); var vm = require('vm');
var sandbox = { var sandbox = {
obj: null obj: null
}; };
vm.runInNewContext('obj = {a: 1, b: 2}', sandbox); vm.runInNewContext('obj = {a: 1, b: 2}', sandbox);
expect(jasmineUnderTest.matchersUtil.equals(sandbox.obj, {a: 1, b: 2})).toBe(true); expect(matchersUtil.equals(sandbox.obj, {a: 1, b: 2})).toBe(true);
}); });
it("passes for equivalent arrays from different vm contexts", function() { it("passes for equivalent arrays from different vm contexts", function() {
if (isNotRunningInNode()) { if (isNotRunningInNode()) {
return; return;
} }
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var vm = require('vm'); var vm = require('vm');
var sandbox = { var sandbox = {
arr: null arr: null
}; };
vm.runInNewContext('arr = [1, 2]', sandbox); vm.runInNewContext('arr = [1, 2]', sandbox);
expect(jasmineUnderTest.matchersUtil.equals(sandbox.arr, [1, 2])).toBe(true); expect(matchersUtil.equals(sandbox.arr, [1, 2])).toBe(true);
}); });
}); });
it("passes when Any is used", function() { it("passes when Any is used", function() {
var number = 3, var number = 3,
anyNumber = new jasmineUnderTest.Any(Number); anyNumber = new jasmineUnderTest.Any(Number),
matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(jasmineUnderTest.matchersUtil.equals(number, anyNumber)).toBe(true); expect(matchersUtil.equals(number, anyNumber)).toBe(true);
expect(jasmineUnderTest.matchersUtil.equals(anyNumber, number)).toBe(true); expect(matchersUtil.equals(anyNumber, number)).toBe(true);
}); });
it("fails when Any is compared to something unexpected", function() { it("fails when Any is compared to something unexpected", function() {
var number = 3, var number = 3,
anyString = new jasmineUnderTest.Any(String); anyString = new jasmineUnderTest.Any(String),
matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(jasmineUnderTest.matchersUtil.equals(number, anyString)).toBe(false); expect(matchersUtil.equals(number, anyString)).toBe(false);
expect(jasmineUnderTest.matchersUtil.equals(anyString, number)).toBe(false); expect(matchersUtil.equals(anyString, number)).toBe(false);
}); });
it("passes when ObjectContaining is used", function() { it("passes when ObjectContaining is used", function() {
@@ -355,135 +402,209 @@ describe("matchersUtil", function() {
foo: 3, foo: 3,
bar: 7 bar: 7
}, },
containing = new jasmineUnderTest.ObjectContaining({foo: 3}); containing = new jasmineUnderTest.ObjectContaining({foo: 3}),
matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(jasmineUnderTest.matchersUtil.equals(obj, containing)).toBe(true); expect(matchersUtil.equals(obj, containing)).toBe(true);
expect(jasmineUnderTest.matchersUtil.equals(containing, obj)).toBe(true); expect(matchersUtil.equals(containing, obj)).toBe(true);
}); });
it("passes when MapContaining is used", function() { it("passes when MapContaining is used", function() {
jasmine.getEnv().requireFunctioningMaps(); jasmine.getEnv().requireFunctioningMaps();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var obj = new Map(); var obj = new Map();
obj.set(1, 2); obj.set(1, 2);
obj.set('foo', 'bar'); obj.set('foo', 'bar');
var containing = new jasmineUnderTest.MapContaining(new Map()); var containing = new jasmineUnderTest.MapContaining(new Map());
containing.sample.set('foo', 'bar'); containing.sample.set('foo', 'bar');
expect(jasmineUnderTest.matchersUtil.equals(obj, containing)).toBe(true); expect(matchersUtil.equals(obj, containing)).toBe(true);
expect(jasmineUnderTest.matchersUtil.equals(containing, obj)).toBe(true); expect(matchersUtil.equals(containing, obj)).toBe(true);
}); });
it("passes when SetContaining is used", function() { it("passes when SetContaining is used", function() {
jasmine.getEnv().requireFunctioningSets(); jasmine.getEnv().requireFunctioningSets();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var obj = new Set(); var obj = new Set();
obj.add(1); obj.add(1);
obj.add('foo'); obj.add('foo');
var containing = new jasmineUnderTest.SetContaining(new Set()); var containing = new jasmineUnderTest.SetContaining(new Set());
containing.sample.add(1); containing.sample.add(1);
expect(jasmineUnderTest.matchersUtil.equals(obj, containing)).toBe(true); expect(matchersUtil.equals(obj, containing)).toBe(true);
expect(jasmineUnderTest.matchersUtil.equals(containing, obj)).toBe(true); expect(matchersUtil.equals(containing, obj)).toBe(true);
}); });
it("passes when an asymmetric equality tester returns true", function() { it("passes when an asymmetric equality tester returns true", function() {
var tester = { asymmetricMatch: function(other) { return true; } }; var tester = { asymmetricMatch: function(other) { return true; } },
matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(jasmineUnderTest.matchersUtil.equals(false, tester)).toBe(true); expect(matchersUtil.equals(false, tester)).toBe(true);
expect(jasmineUnderTest.matchersUtil.equals(tester, false)).toBe(true); expect(matchersUtil.equals(tester, false)).toBe(true);
}); });
it("fails when an asymmetric equality tester returns false", function() { it("fails when an asymmetric equality tester returns false", function() {
var tester = { asymmetricMatch: function(other) { return false; } }; var tester = { asymmetricMatch: function(other) { return false; } },
matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(jasmineUnderTest.matchersUtil.equals(true, tester)).toBe(false); expect(matchersUtil.equals(true, tester)).toBe(false);
expect(jasmineUnderTest.matchersUtil.equals(tester, true)).toBe(false); expect(matchersUtil.equals(tester, true)).toBe(false);
}); });
it("passes when ArrayContaining is used", function() { it("passes when ArrayContaining is used", function() {
var arr = ["foo", "bar"]; var arr = ["foo", "bar"],
matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(jasmineUnderTest.matchersUtil.equals(arr, new jasmineUnderTest.ArrayContaining(["bar"]))).toBe(true); expect(matchersUtil.equals(arr, new jasmineUnderTest.ArrayContaining(["bar"]))).toBe(true);
}); });
it("passes when a custom equality matcher returns true", function() { it("passes when a custom equality matcher passed to equals returns true", function() {
var tester = function(a, b) { return true; }; // TODO: remove this in the next major release.
var tester = function(a, b) { return true; },
matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(jasmineUnderTest.matchersUtil.equals(1, 2, [tester])).toBe(true); expect(matchersUtil.equals(1, 2, [tester])).toBe(true);
});
it("passes when a custom equality matcher passed to the constructor returns true", function() {
var tester = function(a, b) { return true; },
matchersUtil = new jasmineUnderTest.MatchersUtil({customTesters: [tester], pp: function() {}});
expect(matchersUtil.equals(1, 2)).toBe(true);
}); });
it("passes for two empty Objects", function () { it("passes for two empty Objects", function () {
expect(jasmineUnderTest.matchersUtil.equals({}, {})).toBe(true); var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals({}, {})).toBe(true);
}); });
describe("when a custom equality matcher is installed that returns 'undefined'", function () { describe("when a custom equality matcher is passed to equals that returns 'undefined'", function () {
// TODO: remove this in the next major release.
var tester = function(a, b) { return jasmine.undefined; }; var tester = function(a, b) { return jasmine.undefined; };
it("passes for two empty Objects", function () { it("passes for two empty Objects", function () {
expect(jasmineUnderTest.matchersUtil.equals({}, {}, [tester])).toBe(true); var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals({}, {}, [tester])).toBe(true);
}); });
}); });
it("fails for equivalents when a custom equality matcher returns false", function() { describe("when a custom equality matcher is passed to the constructor that returns 'undefined'", function () {
var tester = function(a, b) { return false; }; var tester = function(a, b) { return jasmine.undefined; };
expect(jasmineUnderTest.matchersUtil.equals(1, 1, [tester])).toBe(false); it("passes for two empty Objects", function () {
var matchersUtil = new jasmineUnderTest.MatchersUtil({customTesters: [tester], pp: function() {}});
expect(matchersUtil.equals({}, {})).toBe(true);
});
}); });
it("passes for an asymmetric equality tester that returns true when a custom equality tester return false", function() { it("fails for equivalents when a custom equality matcher passed to equals returns false", function() {
// TODO: remove this in the next major release.
var tester = function(a, b) { return false; },
matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals(1, 1, [tester])).toBe(false);
});
it("fails for equivalents when a custom equality matcher passed to the constructor returns false", function() {
var tester = function(a, b) { return false; },
matchersUtil = new jasmineUnderTest.MatchersUtil({customTesters: [tester], pp: function() {}});
expect(matchersUtil.equals(1, 1)).toBe(false);
});
it("passes for an asymmetric equality tester that returns true when a custom equality tester passed to equals return false", function() {
// TODO: remove this in the next major release.
var asymmetricTester = { asymmetricMatch: function(other) { return true; } }, var asymmetricTester = { asymmetricMatch: function(other) { return true; } },
symmetricTester = function(a, b) { return false; }; symmetricTester = function(a, b) { return false; },
matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(jasmineUnderTest.matchersUtil.equals(asymmetricTester, true, [symmetricTester])).toBe(true); expect(matchersUtil.equals(asymmetricTester, true, [symmetricTester])).toBe(true);
expect(jasmineUnderTest.matchersUtil.equals(true, asymmetricTester, [symmetricTester])).toBe(true); expect(matchersUtil.equals(true, asymmetricTester, [symmetricTester])).toBe(true);
}); });
it("passes custom equality matchers to asymmetric equality testers", function() { it("passes for an asymmetric equality tester that returns true when a custom equality tester passed to the constructor return false", function() {
var tester = function(a, b) {}; var asymmetricTester = { asymmetricMatch: function(other) { return true; } },
var asymmetricTester = { asymmetricMatch: jasmine.createSpy('asymmetricMatch') }; symmetricTester = function(a, b) { return false; },
asymmetricTester.asymmetricMatch.and.returnValue(true); matchersUtil = new jasmineUnderTest.MatchersUtil({customTesters: [symmetricTester()], pp: function() {}});
var other = {};
expect(jasmineUnderTest.matchersUtil.equals(asymmetricTester, other, [tester])).toBe(true); expect(matchersUtil.equals(asymmetricTester, true)).toBe(true);
expect(asymmetricTester.asymmetricMatch).toHaveBeenCalledWith(other, [tester]); expect(matchersUtil.equals(true, asymmetricTester)).toBe(true);
});
describe("The compatibility shim passed to asymmetric equality testers", function() {
describe("When equals is called with custom equality testers", function() {
it("is both a matchersUtil and the custom equality testers passed to equals", function() {
var asymmetricTester = jasmine.createSpyObj('tester', ['asymmetricMatch']),
symmetricTester = function() { } ,
matchersUtil = new jasmineUnderTest.MatchersUtil(),
shim;
matchersUtil.equals(true, asymmetricTester, [symmetricTester]);
shim = asymmetricTester.asymmetricMatch.calls.argsFor(0)[1];
expect(shim).toEqual(jasmine.any(jasmineUnderTest.MatchersUtil));
expect(shim.length).toEqual(1);
expect(shim[0]).toEqual(symmetricTester);
});
});
describe("When equals is called with custom equality testers", function() {
it("is both a matchersUtil and the custom equality testers passed to the constructor", function() {
var asymmetricTester = jasmine.createSpyObj('tester', ['asymmetricMatch']),
symmetricTester = function() { } ,
matchersUtil = new jasmineUnderTest.MatchersUtil({customTesters: [symmetricTester], pp: function() {}}),
shim;
matchersUtil.equals(true, asymmetricTester);
shim = asymmetricTester.asymmetricMatch.calls.argsFor(0)[1];
expect(shim).toEqual(jasmine.any(jasmineUnderTest.MatchersUtil));
expect(shim.length).toEqual(1);
expect(shim[0]).toEqual(symmetricTester);
});
});
}); });
it("passes when an Any is compared to an Any that checks for the same type", function() { it("passes when an Any is compared to an Any that checks for the same type", function() {
var any1 = new jasmineUnderTest.Any(Function), var any1 = new jasmineUnderTest.Any(Function),
any2 = new jasmineUnderTest.Any(Function); any2 = new jasmineUnderTest.Any(Function),
matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(jasmineUnderTest.matchersUtil.equals(any1, any2)).toBe(true); expect(matchersUtil.equals(any1, any2)).toBe(true);
}); });
it("passes for null prototype objects with same properties", function () { it("passes for null prototype objects with same properties", function () {
var objA = Object.create(null), var objA = Object.create(null),
objB = Object.create(null); objB = Object.create(null),
matchersUtil = new jasmineUnderTest.MatchersUtil();
objA.name = 'test'; objA.name = 'test';
objB.name = 'test'; objB.name = 'test';
expect(jasmineUnderTest.matchersUtil.equals(objA, objB)).toBe(true); expect(matchersUtil.equals(objA, objB)).toBe(true);
}); });
it("fails for null prototype objects with different properties", function () { it("fails for null prototype objects with different properties", function () {
var objA = Object.create(null), var objA = Object.create(null),
objB = Object.create(null); objB = Object.create(null),
matchersUtil = new jasmineUnderTest.MatchersUtil();
objA.name = 'test'; objA.name = 'test';
objB.test = 'name'; objB.test = 'name';
expect(jasmineUnderTest.matchersUtil.equals(objA, objB)).toBe(false); expect(matchersUtil.equals(objA, objB)).toBe(false);
}); });
it("passes when comparing two empty sets", function() { it("passes when comparing two empty sets", function() {
jasmine.getEnv().requireFunctioningSets(); jasmine.getEnv().requireFunctioningSets();
expect(jasmineUnderTest.matchersUtil.equals(new Set(), new Set())).toBe(true); var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals(new Set(), new Set())).toBe(true);
}); });
it("passes when comparing identical sets", function() { it("passes when comparing identical sets", function() {
jasmine.getEnv().requireFunctioningSets(); jasmine.getEnv().requireFunctioningSets();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var setA = new Set(); var setA = new Set();
setA.add(6); setA.add(6);
setA.add(5); setA.add(5);
@@ -491,12 +612,13 @@ describe("matchersUtil", function() {
setB.add(6); setB.add(6);
setB.add(5); setB.add(5);
expect(jasmineUnderTest.matchersUtil.equals(setA, setB)).toBe(true); expect(matchersUtil.equals(setA, setB)).toBe(true);
}); });
it("passes when comparing identical sets with different insertion order and simple elements", function() { it("passes when comparing identical sets with different insertion order and simple elements", function() {
jasmine.getEnv().requireFunctioningSets(); jasmine.getEnv().requireFunctioningSets();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var setA = new Set(); var setA = new Set();
setA.add(3); setA.add(3);
setA.add(6); setA.add(6);
@@ -504,12 +626,13 @@ describe("matchersUtil", function() {
setB.add(6); setB.add(6);
setB.add(3); setB.add(3);
expect(jasmineUnderTest.matchersUtil.equals(setA, setB)).toBe(true); expect(matchersUtil.equals(setA, setB)).toBe(true);
}); });
it("passes when comparing identical sets with different insertion order and complex elements 1", function() { it("passes when comparing identical sets with different insertion order and complex elements 1", function() {
jasmine.getEnv().requireFunctioningSets(); jasmine.getEnv().requireFunctioningSets();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var setA1 = new Set(); var setA1 = new Set();
setA1.add(['a',3]); setA1.add(['a',3]);
setA1.add([6,1]); setA1.add([6,1]);
@@ -531,12 +654,13 @@ describe("matchersUtil", function() {
setB.add(setB1); setB.add(setB1);
setB.add(setB2); setB.add(setB2);
expect(jasmineUnderTest.matchersUtil.equals(setA, setB)).toBe(true); expect(matchersUtil.equals(setA, setB)).toBe(true);
}); });
it("passes when comparing identical sets with different insertion order and complex elements 2", function() { it("passes when comparing identical sets with different insertion order and complex elements 2", function() {
jasmine.getEnv().requireFunctioningSets(); jasmine.getEnv().requireFunctioningSets();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var setA = new Set(); var setA = new Set();
setA.add([[1,2], [3,4]]); setA.add([[1,2], [3,4]]);
setA.add([[5,6], [7,8]]); setA.add([[5,6], [7,8]]);
@@ -544,11 +668,12 @@ describe("matchersUtil", function() {
setB.add([[5,6], [7,8]]); setB.add([[5,6], [7,8]]);
setB.add([[1,2], [3,4]]); setB.add([[1,2], [3,4]]);
expect(jasmineUnderTest.matchersUtil.equals(setA, setB)).toBe(true); expect(matchersUtil.equals(setA, setB)).toBe(true);
}); });
it("fails for sets with different elements", function() { it("fails for sets with different elements", function() {
jasmine.getEnv().requireFunctioningSets(); jasmine.getEnv().requireFunctioningSets();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var setA = new Set(); var setA = new Set();
setA.add(6); setA.add(6);
setA.add(3); setA.add(3);
@@ -558,11 +683,12 @@ describe("matchersUtil", function() {
setB.add(4); setB.add(4);
setB.add(5); setB.add(5);
expect(jasmineUnderTest.matchersUtil.equals(setA, setB)).toBe(false); expect(matchersUtil.equals(setA, setB)).toBe(false);
}); });
it("fails for sets of different size", function() { it("fails for sets of different size", function() {
jasmine.getEnv().requireFunctioningSets(); jasmine.getEnv().requireFunctioningSets();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var setA = new Set(); var setA = new Set();
setA.add(6); setA.add(6);
setA.add(3); setA.add(3);
@@ -571,36 +697,40 @@ describe("matchersUtil", function() {
setB.add(4); setB.add(4);
setB.add(5); setB.add(5);
expect(jasmineUnderTest.matchersUtil.equals(setA, setB)).toBe(false); expect(matchersUtil.equals(setA, setB)).toBe(false);
}); });
it("passes when comparing two empty maps", function() { it("passes when comparing two empty maps", function() {
jasmine.getEnv().requireFunctioningMaps(); jasmine.getEnv().requireFunctioningMaps();
expect(jasmineUnderTest.matchersUtil.equals(new Map(), new Map())).toBe(true); var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals(new Map(), new Map())).toBe(true);
}); });
it("passes when comparing identical maps", function() { it("passes when comparing identical maps", function() {
jasmine.getEnv().requireFunctioningMaps(); jasmine.getEnv().requireFunctioningMaps();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var mapA = new Map(); var mapA = new Map();
mapA.set(6, 5); mapA.set(6, 5);
var mapB = new Map(); var mapB = new Map();
mapB.set(6, 5); mapB.set(6, 5);
expect(jasmineUnderTest.matchersUtil.equals(mapA, mapB)).toBe(true); expect(matchersUtil.equals(mapA, mapB)).toBe(true);
}); });
it("passes when comparing identical maps with different insertion order", function() { it("passes when comparing identical maps with different insertion order", function() {
jasmine.getEnv().requireFunctioningMaps(); jasmine.getEnv().requireFunctioningMaps();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var mapA = new Map(); var mapA = new Map();
mapA.set("a", 3); mapA.set("a", 3);
mapA.set(6, 1); mapA.set(6, 1);
var mapB = new Map(); var mapB = new Map();
mapB.set(6, 1); mapB.set(6, 1);
mapB.set("a", 3); mapB.set("a", 3);
expect(jasmineUnderTest.matchersUtil.equals(mapA, mapB)).toBe(true); expect(matchersUtil.equals(mapA, mapB)).toBe(true);
}); });
it("fails for maps with different elements", function() { it("fails for maps with different elements", function() {
jasmine.getEnv().requireFunctioningMaps(); jasmine.getEnv().requireFunctioningMaps();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var mapA = new Map(); var mapA = new Map();
mapA.set(6, 3); mapA.set(6, 3);
mapA.set(5, 1); mapA.set(5, 1);
@@ -608,17 +738,18 @@ describe("matchersUtil", function() {
mapB.set(6, 4); mapB.set(6, 4);
mapB.set(5, 1); mapB.set(5, 1);
expect(jasmineUnderTest.matchersUtil.equals(mapA, mapB)).toBe(false); expect(matchersUtil.equals(mapA, mapB)).toBe(false);
}); });
it("fails for maps of different size", function() { it("fails for maps of different size", function() {
jasmine.getEnv().requireFunctioningMaps(); jasmine.getEnv().requireFunctioningMaps();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var mapA = new Map(); var mapA = new Map();
mapA.set(6, 3); mapA.set(6, 3);
var mapB = new Map(); var mapB = new Map();
mapB.set(6, 4); mapB.set(6, 4);
mapB.set(5, 1); mapB.set(5, 1);
expect(jasmineUnderTest.matchersUtil.equals(mapA, mapB)).toBe(false); expect(matchersUtil.equals(mapA, mapB)).toBe(false);
}); });
describe("when running in an environment with array polyfills", function() { describe("when running in an environment with array polyfills", function() {
@@ -673,105 +804,160 @@ describe("matchersUtil", function() {
return { return {
self: 'asymmetric tester value', self: 'asymmetric tester value',
other: 'other value' other: 'other value'
} };
} }
}, },
diffBuilder = jasmine.createSpyObj('diffBuilder', ['record', 'withPath']); actual = {x: 42},
diffBuilder.withPath.and.callFake(function(p, block) { block() }); expected = {x: tester},
jasmineUnderTest.matchersUtil.equals({x: 42}, {x: tester}, [], diffBuilder); diffBuilder = jasmine.createSpyObj('diffBuilder', ['recordMismatch', 'withPath', 'setRoots']);
diffBuilder.withPath.and.callFake(function(p, block) { block(); });
jasmineUnderTest.matchersUtil.equals(actual, expected, [], diffBuilder);
expect(diffBuilder.setRoots).toHaveBeenCalledWith(actual, expected);
expect(diffBuilder.withPath).toHaveBeenCalledWith('x', jasmine.any(Function)); expect(diffBuilder.withPath).toHaveBeenCalledWith('x', jasmine.any(Function));
expect(diffBuilder.record). toHaveBeenCalledWith( expect(diffBuilder.recordMismatch). toHaveBeenCalledWith();
'other value', 'asymmetric tester value'
);
}); });
it("records both objects when the tester does not implement valuesForDiff", function() { it("records both objects when the tester does not implement valuesForDiff", function() {
var tester = { var tester = {
asymmetricMatch: function() { return false; }, asymmetricMatch: function() { return false; },
}, },
diffBuilder = jasmine.createSpyObj('diffBuilder', ['record', 'withPath']); actual = {x: 42},
diffBuilder.withPath.and.callFake(function(p, block) { block() }); expected = {x: tester},
jasmineUnderTest.matchersUtil.equals({x: 42}, {x: tester}, [], diffBuilder); diffBuilder = jasmine.createSpyObj('diffBuilder', ['recordMismatch', 'withPath', 'setRoots']);
diffBuilder.withPath.and.callFake(function(p, block) { block(); });
jasmineUnderTest.matchersUtil.equals(actual, expected, [], diffBuilder);
expect(diffBuilder.setRoots).toHaveBeenCalledWith(actual, expected);
expect(diffBuilder.withPath).toHaveBeenCalledWith('x', jasmine.any(Function)); expect(diffBuilder.withPath).toHaveBeenCalledWith('x', jasmine.any(Function));
expect(diffBuilder.record). toHaveBeenCalledWith(42, tester); expect(diffBuilder.recordMismatch). toHaveBeenCalledWith();
}); });
}); });
it('uses a diffBuilder if one is provided as the fourth argument', function() {
// TODO: remove this in the next major release.
var diffBuilder = new jasmineUnderTest.DiffBuilder(),
matchersUtil = new jasmineUnderTest.MatchersUtil();
spyOn(diffBuilder, 'recordMismatch');
spyOn(diffBuilder, 'withPath').and.callThrough();
matchersUtil.equals([1], [2], [], diffBuilder);
expect(diffBuilder.withPath).toHaveBeenCalledWith('length', jasmine.any(Function));
expect(diffBuilder.withPath).toHaveBeenCalledWith(0, jasmine.any(Function));
expect(diffBuilder.recordMismatch).toHaveBeenCalledWith();
});
it('uses a diffBuilder if one is provided as the third argument', function() {
var diffBuilder = new jasmineUnderTest.DiffBuilder(),
matchersUtil = new jasmineUnderTest.MatchersUtil();
spyOn(diffBuilder, 'recordMismatch');
spyOn(diffBuilder, 'withPath').and.callThrough();
matchersUtil.equals([1], [2], diffBuilder);
expect(diffBuilder.withPath).toHaveBeenCalledWith('length', jasmine.any(Function));
expect(diffBuilder.withPath).toHaveBeenCalledWith(0, jasmine.any(Function));
expect(diffBuilder.recordMismatch).toHaveBeenCalled();
});
}); });
describe("contains", function() { describe("contains", function() {
it("passes when expected is a substring of actual", function() { it("passes when expected is a substring of actual", function() {
expect(jasmineUnderTest.matchersUtil.contains("ABC", "BC")).toBe(true); var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.contains("ABC", "BC")).toBe(true);
}); });
it("fails when expected is a not substring of actual", function() { it("fails when expected is a not substring of actual", function() {
expect(jasmineUnderTest.matchersUtil.contains("ABC", "X")).toBe(false); var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.contains("ABC", "X")).toBe(false);
}); });
it("passes when expected is an element in an actual array", function() { it("passes when expected is an element in an actual array", function() {
expect(jasmineUnderTest.matchersUtil.contains(['foo', 'bar'], 'foo')).toBe(true); var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.contains(['foo', 'bar'], 'foo')).toBe(true);
}); });
it("fails when expected is not an element in an actual array", function() { it("fails when expected is not an element in an actual array", function() {
expect(jasmineUnderTest.matchersUtil.contains(['foo', 'bar'], 'baz')).toBe(false); var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.contains(['foo', 'bar'], 'baz')).toBe(false);
}); });
it("passes with mixed-element arrays", function() { it("passes with mixed-element arrays", function() {
expect(jasmineUnderTest.matchersUtil.contains(["foo", {some: "bar"}], "foo")).toBe(true); var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(jasmineUnderTest.matchersUtil.contains(["foo", {some: "bar"}], {some: "bar"})).toBe(true); expect(matchersUtil.contains(["foo", {some: "bar"}], "foo")).toBe(true);
expect(matchersUtil.contains(["foo", {some: "bar"}], {some: "bar"})).toBe(true);
}); });
it("uses custom equality testers if passed in and actual is an Array", function() { it("uses custom equality testers if passed to contains and actual is an Array", function() {
var customTester = function(a, b) {return true;}; // TODO: remove this in the next major release.
var customTester = function(a, b) {return true;},
matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(jasmineUnderTest.matchersUtil.contains([1, 2], 3, [customTester])).toBe(true); expect(matchersUtil.contains([1, 2], 3, [customTester])).toBe(true);
});
it("uses custom equality testers if passed to the constructor and actual is an Array", function() {
var customTester = function(a, b) {return true;},
matchersUtil = new jasmineUnderTest.MatchersUtil({customTesters: [customTester], pp: function() {}});
expect(matchersUtil.contains([1, 2], 3)).toBe(true);
}); });
it("fails when actual is undefined", function() { it("fails when actual is undefined", function() {
expect(jasmineUnderTest.matchersUtil.contains(undefined, 'A')).toBe(false); var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.contains(undefined, 'A')).toBe(false);
}); });
it("fails when actual is null", function() { it("fails when actual is null", function() {
expect(jasmineUnderTest.matchersUtil.contains(null, 'A')).toBe(false); var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.contains(null, 'A')).toBe(false);
}); });
it("passes with array-like objects", function() { it("passes with array-like objects", function() {
var capturedArgs = null; var capturedArgs = null,
matchersUtil = new jasmineUnderTest.MatchersUtil();
function testFunction(){ function testFunction(){
capturedArgs = arguments; capturedArgs = arguments;
} }
testFunction('foo', 'bar'); testFunction('foo', 'bar');
expect(jasmineUnderTest.matchersUtil.contains(capturedArgs, 'bar')).toBe(true); expect(matchersUtil.contains(capturedArgs, 'bar')).toBe(true);
}); });
it("passes for set members", function() { it("passes for set members", function() {
jasmine.getEnv().requireFunctioningSets(); jasmine.getEnv().requireFunctioningSets();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var setItem = {'foo': 'bar'}; var setItem = {'foo': 'bar'};
var set = new Set(); var set = new Set();
set.add(setItem); set.add(setItem);
expect(jasmineUnderTest.matchersUtil.contains(set, setItem)).toBe(true); expect(matchersUtil.contains(set, setItem)).toBe(true);
}); });
// documenting current behavior // documenting current behavior
it("fails (!) for objects that equal to a set member", function() { it("fails (!) for objects that equal to a set member", function() {
jasmine.getEnv().requireFunctioningSets(); jasmine.getEnv().requireFunctioningSets();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var set = new Set(); var set = new Set();
set.add({'foo': 'bar'}); set.add({'foo': 'bar'});
expect(jasmineUnderTest.matchersUtil.contains(set, {'foo': 'bar'})).toBe(false); expect(matchersUtil.contains(set, {'foo': 'bar'})).toBe(false);
}); });
}); });
describe("buildMessage", function() { describe("buildFailureMessage", function() {
it("builds an English sentence for a failure case", function() { it("builds an English sentence for a failure case", function() {
var actual = "foo", var actual = "foo",
name = "toBar", name = "toBar",
message = jasmineUnderTest.matchersUtil.buildFailureMessage(name, false, actual); pp = jasmineUnderTest.makePrettyPrinter(),
matchersUtil = new jasmineUnderTest.MatchersUtil({pp: pp}),
message = matchersUtil.buildFailureMessage(name, false, actual);
expect(message).toEqual("Expected 'foo' to bar."); expect(message).toEqual("Expected 'foo' to bar.");
}); });
@@ -780,7 +966,9 @@ describe("matchersUtil", function() {
var actual = "foo", var actual = "foo",
name = "toBar", name = "toBar",
isNot = true, isNot = true,
message = message = jasmineUnderTest.matchersUtil.buildFailureMessage(name, isNot, actual); pp = jasmineUnderTest.makePrettyPrinter(),
matchersUtil = new jasmineUnderTest.MatchersUtil({pp: pp}),
message = message = matchersUtil.buildFailureMessage(name, isNot, actual);
expect(message).toEqual("Expected 'foo' not to bar."); expect(message).toEqual("Expected 'foo' not to bar.");
}); });
@@ -788,9 +976,24 @@ describe("matchersUtil", function() {
it("builds an English sentence for an arbitrary array of expected arguments", function() { it("builds an English sentence for an arbitrary array of expected arguments", function() {
var actual = "foo", var actual = "foo",
name = "toBar", name = "toBar",
message = jasmineUnderTest.matchersUtil.buildFailureMessage(name, false, actual, "quux", "corge"); pp = jasmineUnderTest.makePrettyPrinter(),
matchersUtil = new jasmineUnderTest.MatchersUtil({pp: pp}),
message = matchersUtil.buildFailureMessage(name, false, actual, "quux", "corge");
expect(message).toEqual("Expected 'foo' to bar 'quux', 'corge'."); expect(message).toEqual("Expected 'foo' to bar 'quux', 'corge'.");
}); });
it("uses the injected pretty-printer to format the expecteds and actual", function() {
var actual = "foo",
expected1 = "qux",
expected2 = "grault",
name = "toBar",
isNot = false,
pp = function(value) { return '<' + value + '>'; },
matchersUtil = new jasmineUnderTest.MatchersUtil({pp: pp}),
message = message = matchersUtil.buildFailureMessage(name, isNot, actual, expected1, expected2);
expect(message).toEqual("Expected <foo> to bar <qux>, <grault>.");
});
}); });
}); });

View File

@@ -10,7 +10,9 @@ describe('toBeInstanceOf', function() {
}); });
it('passes for NaN', function() { it('passes for NaN', function() {
var matcher = jasmineUnderTest.matchers.toBeInstanceOf(); var matcher = jasmineUnderTest.matchers.toBeInstanceOf({
pp: jasmineUnderTest.makePrettyPrinter()
});
var result = matcher.compare(NaN, Number); var result = matcher.compare(NaN, Number);
expect(result).toEqual({ expect(result).toEqual({
pass: true, pass: true,
@@ -156,7 +158,9 @@ describe('toBeInstanceOf', function() {
it('passes for objects with no constructor', function() { it('passes for objects with no constructor', function() {
var object = Object.create(null); var object = Object.create(null);
var matcher = jasmineUnderTest.matchers.toBeInstanceOf(); var matcher = jasmineUnderTest.matchers.toBeInstanceOf({
pp: jasmineUnderTest.makePrettyPrinter()
});
var result = matcher.compare(object, Object); var result = matcher.compare(object, Object);
expect(result).toEqual({ expect(result).toEqual({
pass: true, pass: true,
@@ -219,7 +223,9 @@ describe('toBeInstanceOf', function() {
}); });
it('raises an error if missing an expected value', function() { it('raises an error if missing an expected value', function() {
var matcher = jasmineUnderTest.matchers.toBeInstanceOf(); var matcher = jasmineUnderTest.matchers.toBeInstanceOf({
pp: jasmineUnderTest.makePrettyPrinter()
});
expect(function() { expect(function() {
matcher.compare({}, undefined); matcher.compare({}, undefined);
}).toThrowError('<toBeInstanceOf> : Expected value is not a constructor function\n' + }).toThrowError('<toBeInstanceOf> : Expected value is not a constructor function\n' +

View File

@@ -29,7 +29,9 @@ describe("toBeNaN", function() {
}); });
it("has a custom message on failure", function() { it("has a custom message on failure", function() {
var matcher = jasmineUnderTest.matchers.toBeNaN(), var matcher = jasmineUnderTest.matchers.toBeNaN({
pp: jasmineUnderTest.makePrettyPrinter()
}),
result = matcher.compare(0); result = matcher.compare(0);
expect(result.message()).toEqual("Expected 0 to be NaN."); expect(result.message()).toEqual("Expected 0 to be NaN.");

View File

@@ -14,7 +14,9 @@ describe("toBeNegativeInfinity", function() {
}); });
it("has a custom message on failure", function() { it("has a custom message on failure", function() {
var matcher = jasmineUnderTest.matchers.toBeNegativeInfinity(), var matcher = jasmineUnderTest.matchers.toBeNegativeInfinity({
pp: jasmineUnderTest.makePrettyPrinter()
}),
result = matcher.compare(0); result = matcher.compare(0);
expect(result.message()).toEqual("Expected 0 to be -Infinity.") expect(result.message()).toEqual("Expected 0 to be -Infinity.")

View File

@@ -14,7 +14,9 @@ describe("toBePositiveInfinity", function() {
}); });
it("has a custom message on failure", function() { it("has a custom message on failure", function() {
var matcher = jasmineUnderTest.matchers.toBePositiveInfinity(), var matcher = jasmineUnderTest.matchers.toBePositiveInfinity({
pp: jasmineUnderTest.makePrettyPrinter()
}),
result = matcher.compare(0); result = matcher.compare(0);
expect(result.message()).toEqual("Expected 0 to be Infinity.") expect(result.message()).toEqual("Expected 0 to be Infinity.")

View File

@@ -1,6 +1,7 @@
describe("toBe", function() { describe("toBe", function() {
it("passes with no message when actual === expected", function() { it("passes with no message when actual === expected", function() {
var matcher = jasmineUnderTest.matchers.toBe(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil(),
matcher = jasmineUnderTest.matchers.toBe(matchersUtil),
result; result;
result = matcher.compare(1, 1); result = matcher.compare(1, 1);
@@ -8,7 +9,8 @@ describe("toBe", function() {
}); });
it("passes with a custom message when expected is an array", function() { it("passes with a custom message when expected is an array", function() {
var matcher = jasmineUnderTest.matchers.toBe(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.matchers.toBe(matchersUtil),
result, result,
array = [1]; array = [1];
@@ -18,7 +20,8 @@ describe("toBe", function() {
}); });
it("passes with a custom message when expected is an object", function() { it("passes with a custom message when expected is an object", function() {
var matcher = jasmineUnderTest.matchers.toBe(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.matchers.toBe(matchersUtil),
result, result,
obj = {foo: "bar"}; obj = {foo: "bar"};
@@ -28,7 +31,8 @@ describe("toBe", function() {
}); });
it("fails with no message when actual !== expected", function() { it("fails with no message when actual !== expected", function() {
var matcher = jasmineUnderTest.matchers.toBe(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil(),
matcher = jasmineUnderTest.matchers.toBe(matchersUtil),
result; result;
result = matcher.compare(1, 2); result = matcher.compare(1, 2);
@@ -37,7 +41,8 @@ describe("toBe", function() {
}); });
it("fails with a custom message when expected is an array", function() { it("fails with a custom message when expected is an array", function() {
var matcher = jasmineUnderTest.matchers.toBe(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.matchers.toBe(matchersUtil),
result; result;
result = matcher.compare([1], [1]); result = matcher.compare([1], [1]);
@@ -46,11 +51,24 @@ describe("toBe", function() {
}); });
it("fails with a custom message when expected is an object", function() { it("fails with a custom message when expected is an object", function() {
var matcher = jasmineUnderTest.matchers.toBe(jasmineUnderTest.matchersUtil), var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.matchers.toBe(matchersUtil),
result; result;
result = matcher.compare({foo: "bar"}, {foo: "bar"}); result = matcher.compare({foo: "bar"}, {foo: "bar"});
expect(result.pass).toBe(false); expect(result.pass).toBe(false);
expect(result.message).toBe("Expected Object({ foo: 'bar' }) to be Object({ foo: 'bar' }). Tip: To check for deep equality, use .toEqual() instead of .toBe().") expect(result.message).toBe("Expected Object({ foo: 'bar' }) to be Object({ foo: 'bar' }). Tip: To check for deep equality, use .toEqual() instead of .toBe().")
}); });
it("works with custom object formatters when expected is an object", function() {
var formatter = function(x) { return '<' + x.foo + '>'; },
prettyPrinter = jasmineUnderTest.makePrettyPrinter([formatter]),
matchersUtil = new jasmineUnderTest.MatchersUtil({pp: prettyPrinter}),
matcher = jasmineUnderTest.matchers.toBe(matchersUtil),
result;
result = matcher.compare({foo: "bar"}, {foo: "bar"});
expect(result.pass).toBe(false);
expect(result.message).toBe("Expected <bar> to be <bar>. Tip: To check for deep equality, use .toEqual() instead of .toBe().")
});
}); });

View File

@@ -1,26 +1,25 @@
describe("toContain", function() { describe("toContain", function() {
it("delegates to jasmineUnderTest.matchersUtil.contains", function() { it("delegates to jasmineUnderTest.matchersUtil.contains", function() {
var util = { var matchersUtil = {
contains: jasmine.createSpy('delegated-contains').and.returnValue(true) contains: jasmine.createSpy('delegated-contains').and.returnValue(true)
}, },
matcher = jasmineUnderTest.matchers.toContain(util), matcher = jasmineUnderTest.matchers.toContain(matchersUtil),
result; result;
result = matcher.compare("ABC", "B"); result = matcher.compare("ABC", "B");
expect(util.contains).toHaveBeenCalledWith("ABC", "B", []); expect(matchersUtil.contains).toHaveBeenCalledWith("ABC", "B");
expect(result.pass).toBe(true); expect(result.pass).toBe(true);
}); });
it("delegates to jasmineUnderTest.matchersUtil.contains, passing in equality testers if present", function() { it("works with custom equality testers", function() {
var util = { var tester = function (a, b) {
contains: jasmine.createSpy('delegated-contains').and.returnValue(true) return a.toString() === b.toString();
}, },
customEqualityTesters = ['a', 'b'], matchersUtil = new jasmineUnderTest.MatchersUtil({customTesters: [tester]}),
matcher = jasmineUnderTest.matchers.toContain(util, customEqualityTesters), matcher = jasmineUnderTest.matchers.toContain(matchersUtil),
result; result;
result = matcher.compare("ABC", "B"); result = matcher.compare(['1', '2'], 2);
expect(util.contains).toHaveBeenCalledWith("ABC", "B", ['a', 'b']);
expect(result.pass).toBe(true); expect(result.pass).toBe(true);
}); });
}); });

View File

@@ -2,8 +2,10 @@ describe("toEqual", function() {
"use strict"; "use strict";
function compareEquals(actual, expected) { function compareEquals(actual, expected) {
var util = jasmineUnderTest.matchersUtil, var matchersUtil = new jasmineUnderTest.MatchersUtil({
matcher = jasmineUnderTest.matchers.toEqual(util); pp: jasmineUnderTest.makePrettyPrinter()
}),
matcher = jasmineUnderTest.matchers.toEqual(matchersUtil);
var result = matcher.compare(actual, expected); var result = matcher.compare(actual, expected);
@@ -11,37 +13,32 @@ describe("toEqual", function() {
} }
it("delegates to equals function", function() { it("delegates to equals function", function() {
var util = { var matchersUtil = {
equals: jasmine.createSpy('delegated-equals').and.returnValue(true), equals: jasmine.createSpy('delegated-equals').and.returnValue(true),
buildFailureMessage: function() { buildFailureMessage: function() {
return 'does not matter' return 'does not matter';
}, },
DiffBuilder: jasmineUnderTest.matchersUtil.DiffBuilder DiffBuilder: new jasmineUnderTest.DiffBuilder()
}, },
matcher = jasmineUnderTest.matchers.toEqual(util), matcher = jasmineUnderTest.matchers.toEqual(matchersUtil),
result; result;
result = matcher.compare(1, 1); result = matcher.compare(1, 1);
expect(util.equals).toHaveBeenCalledWith(1, 1, [], jasmine.anything()); expect(matchersUtil.equals).toHaveBeenCalledWith(1, 1, jasmine.anything());
expect(result.pass).toBe(true); expect(result.pass).toBe(true);
}); });
it("delegates custom equality testers, if present", function() { it("works with custom equality testers", function() {
var util = { var tester = function (a, b) {
equals: jasmine.createSpy('delegated-equals').and.returnValue(true), return a.toString() === b.toString();
buildFailureMessage: function() {
return 'does not matter'
},
DiffBuilder: jasmineUnderTest.matchersUtil.DiffBuilder
}, },
customEqualityTesters = ['a', 'b'], matchersUtil = new jasmineUnderTest.MatchersUtil({customTesters: [tester]}),
matcher = jasmineUnderTest.matchers.toEqual(util, customEqualityTesters), matcher = jasmineUnderTest.matchers.toEqual(matchersUtil),
result; result;
result = matcher.compare(1, 1); result = matcher.compare(1, '1');
expect(util.equals).toHaveBeenCalledWith(1, 1, ['a', 'b'], jasmine.anything());
expect(result.pass).toBe(true); expect(result.pass).toBe(true);
}); });
@@ -100,16 +97,66 @@ describe("toEqual", function() {
expect(compareEquals(actual, expected).message).toEqual(message); expect(compareEquals(actual, expected).message).toEqual(message);
}); });
it("reports extra and missing properties together", function() { it("uses custom object formatters to pretty-print simple properties", function() {
function formatter(x) {
if (typeof x === 'number') {
return '|' + x + '|';
}
}
var actual = {x: {y: 1, z: 2, f: 4}}, var actual = {x: {y: 1, z: 2, f: 4}},
expected = {x: {y: 1, z: 2, g: 3}}, expected = {x: {y: 1, z: 2, g: 3}},
pp = jasmineUnderTest.makePrettyPrinter([formatter]),
matchersUtil = new jasmineUnderTest.MatchersUtil({pp: pp}),
matcher = jasmineUnderTest.matchers.toEqual(matchersUtil),
message = message =
"Expected $.x to have properties\n" + "Expected $.x to have properties\n" +
" g: 3\n" + " g: |3|\n" +
"Expected $.x not to have properties\n" + "Expected $.x not to have properties\n" +
" f: 4"; " f: |4|";
expect(compareEquals(actual, expected).message).toEqual(message); expect(matcher.compare(actual, expected).message).toEqual(message);
});
it("uses custom object formatters to show simple values in diffs", function() {
function formatter(x) {
if (typeof x === 'number') {
return '|' + x + '|';
}
}
var actual = [{foo: 4}],
expected = [{foo: 5}],
prettyPrinter = jasmineUnderTest.makePrettyPrinter([formatter]),
matchersUtil = new jasmineUnderTest.MatchersUtil({pp: prettyPrinter}),
matcher = jasmineUnderTest.matchers.toEqual(matchersUtil),
message = "Expected $[0].foo = |4| to equal |5|.";
expect(matcher.compare(actual, expected).message).toEqual(message);
});
it("uses custom object formatters to show more complex objects diffs", function() {
function formatter(x) {
if (x.hasOwnProperty('a')) {
return '[thing with a=' + x.a + ', b=' + x.b + ']';
}
}
var actual = [{
foo: {a: 1, b: 2},
bar: 'should not be pretty printed'
}],
expected = [{
foo: {a: 5, b: 2},
bar: "shouldn't be pretty printed"
}],
prettyPrinter = jasmineUnderTest.makePrettyPrinter([formatter]),
matchersUtil = new jasmineUnderTest.MatchersUtil({pp: prettyPrinter}),
matcher = jasmineUnderTest.matchers.toEqual(matchersUtil),
message = "Expected $[0].foo = [thing with a=1, b=2] to equal [thing with a=5, b=2].\n" +
"Expected $[0].bar = 'should not be pretty printed' to equal 'shouldn't be pretty printed'.";
expect(matcher.compare(actual, expected).message).toEqual(message);
}); });
it("reports extra and missing properties of the root-level object", function() { it("reports extra and missing properties of the root-level object", function() {
@@ -282,12 +329,31 @@ describe("toEqual", function() {
function Bar() {} function Bar() {}
var actual = {x: new Foo()}, var actual = {x: new Foo()},
expected = {x: new Bar()}, expected = {x: new Bar()},
message = "Expected $.x to be a kind of Bar, but was Foo({ })."; message = "Expected $.x to be a kind of Bar, but was Foo({ }).";
expect(compareEquals(actual, expected).message).toEqual(message); expect(compareEquals(actual, expected).message).toEqual(message);
}); });
it("uses custom object formatters for the value but not the type when reporting objects with different constructors", function () {
function Foo() {}
function Bar() {}
function formatter(x) {
if (x instanceof Foo || x instanceof Bar) {
return '|' + x + '|';
}
}
var actual = {x: new Foo()},
expected = {x: new Bar()},
message = "Expected $.x to be a kind of Bar, but was |[object Object]|.",
pp = jasmineUnderTest.makePrettyPrinter([formatter]),
matchersUtil = new jasmineUnderTest.MatchersUtil({pp: pp}),
matcher = jasmineUnderTest.matchers.toEqual(matchersUtil);
expect(matcher.compare(actual, expected).message).toEqual(message);
});
it("reports type mismatches at the root level", function () { it("reports type mismatches at the root level", function () {
function Foo() {} function Foo() {}
function Bar() {} function Bar() {}
@@ -299,6 +365,11 @@ describe("toEqual", function() {
expect(compareEquals(actual, expected).message).toEqual(message); expect(compareEquals(actual, expected).message).toEqual(message);
}); });
it("reports value mismatches at the root level", function() {
expect(compareEquals(1, 2).message).toEqual("Expected 1 to equal 2.");
});
it("reports mismatches between objects with their own constructor property", function () { it("reports mismatches between objects with their own constructor property", function () {
function Foo() {} function Foo() {}
function Bar() {} function Bar() {}
@@ -830,6 +901,24 @@ describe("toEqual", function() {
expect(compareEquals(actual, expected).message).toEqual(message); expect(compareEquals(actual, expected).message).toEqual(message);
}); });
it("uses custom object formatters when the actual array is longer", function() {
function formatter(x) {
if (typeof x === 'number') {
return '|' + x + '|';
}
}
var actual = [1, 1, 2, 3, 5],
expected = [1, 1, 2, 3],
pp = jasmineUnderTest.makePrettyPrinter([formatter]),
matchersUtil = new jasmineUnderTest.MatchersUtil({pp: pp}),
matcher = jasmineUnderTest.matchers.toEqual(matchersUtil),
message = 'Expected $.length = |5| to equal |4|.\n' +
'Unexpected $[4] = |5| in array.';
expect(matcher.compare(actual, expected).message).toEqual(message);
});
it("expected array is longer", function() { it("expected array is longer", function() {
var actual = [1, 1, 2, 3], var actual = [1, 1, 2, 3],
expected = [1, 1, 2, 3, 5], expected = [1, 1, 2, 3, 5],

View File

@@ -1,23 +1,25 @@
describe("toHaveBeenCalledBefore", function () { describe("toHaveBeenCalledBefore", function() {
it("throws an exception when the actual is not a spy", function () { it("throws an exception when the actual is not a spy", function() {
var matcher = jasmineUnderTest.matchers.toHaveBeenCalledBefore(), var matcher = jasmineUnderTest.matchers.toHaveBeenCalledBefore({
fn = function () { pp: jasmineUnderTest.makePrettyPrinter()
}, }),
spy = new jasmineUnderTest.Spy('a spy'); fn = function() {},
spy = new jasmineUnderTest.Env().createSpy('a spy');
expect(function () { expect(function () {
matcher.compare(fn, spy) matcher.compare(fn, spy);
}).toThrowError(Error, /Expected a spy, but got Function./); }).toThrowError(Error, /Expected a spy, but got Function./);
}); });
it("throws an exception when the expected is not a spy", function () { it("throws an exception when the expected is not a spy", function() {
var matcher = jasmineUnderTest.matchers.toHaveBeenCalledBefore(), var matcher = jasmineUnderTest.matchers.toHaveBeenCalledBefore({
spy = new jasmineUnderTest.Spy('a spy'), pp: jasmineUnderTest.makePrettyPrinter()
fn = function () { }),
}; spy = new jasmineUnderTest.Env().createSpy('a spy'),
fn = function() {};
expect(function () { expect(function () {
matcher.compare(spy, fn) matcher.compare(spy, fn);
}).toThrowError(Error, /Expected a spy, but got Function./); }).toThrowError(Error, /Expected a spy, but got Function./);
}); });

View File

@@ -21,7 +21,9 @@ describe("toHaveBeenCalled", function() {
}); });
it("throws an exception when the actual is not a spy", function() { it("throws an exception when the actual is not a spy", function() {
var matcher = jasmineUnderTest.matchers.toHaveBeenCalled(), var matcher = jasmineUnderTest.matchers.toHaveBeenCalled({
pp: jasmineUnderTest.makePrettyPrinter()
}),
fn = function() {}; fn = function() {};
expect(function() { matcher.compare(fn) }).toThrowError(Error, /Expected a spy, but got Function./); expect(function() { matcher.compare(fn) }).toThrowError(Error, /Expected a spy, but got Function./);

View File

@@ -49,7 +49,9 @@ describe("toHaveBeenCalledTimes", function() {
}); });
it("throws an exception when the actual is not a spy", function() { it("throws an exception when the actual is not a spy", function() {
var matcher = jasmineUnderTest.matchers.toHaveBeenCalledTimes(), var matcher = jasmineUnderTest.matchers.toHaveBeenCalledTimes({
pp: jasmineUnderTest.makePrettyPrinter()
}),
fn = function() {}; fn = function() {};
expect(function() { expect(function() {

View File

@@ -1,10 +1,11 @@
describe("toHaveBeenCalledWith", function() { describe("toHaveBeenCalledWith", function() {
it("passes when the actual was called with matching parameters", function() { it("passes when the actual was called with matching parameters", function() {
var util = { var matchersUtil = {
contains: jasmine.createSpy('delegated-contains').and.returnValue(true) contains: jasmine.createSpy('delegated-contains').and.returnValue(true),
pp: jasmineUnderTest.makePrettyPrinter()
}, },
matcher = jasmineUnderTest.matchers.toHaveBeenCalledWith(util), matcher = jasmineUnderTest.matchers.toHaveBeenCalledWith(matchersUtil),
calledSpy = new jasmineUnderTest.Spy('called-spy'), calledSpy = new jasmineUnderTest.Spy('called-spy'),
result; result;
@@ -15,25 +16,24 @@ describe("toHaveBeenCalledWith", function() {
expect(result.message()).toEqual("Expected spy called-spy not to have been called with:\n [ 'a', 'b' ]\nbut it was."); expect(result.message()).toEqual("Expected spy called-spy not to have been called with:\n [ 'a', 'b' ]\nbut it was.");
}); });
it("passes through the custom equality testers", function() { it("supports custom equality testers", function() {
var util = { var customEqualityTesters = [function() { return true; }],
contains: jasmine.createSpy('delegated-contains').and.returnValue(true) matchersUtil = new jasmineUnderTest.MatchersUtil({customTesters: customEqualityTesters}),
}, matcher = jasmineUnderTest.matchers.toHaveBeenCalledWith(matchersUtil),
customEqualityTesters = [function() { return true; }], calledSpy = new jasmineUnderTest.Spy('called-spy'),
matcher = jasmineUnderTest.matchers.toHaveBeenCalledWith(util, customEqualityTesters), result;
calledSpy = new jasmineUnderTest.Spy('called-spy');
calledSpy('a', 'b'); calledSpy('a', 'b');
matcher.compare(calledSpy, 'a', 'b'); result = matcher.compare(calledSpy, 'a', 'b');
expect(result.pass).toBe(true);
expect(util.contains).toHaveBeenCalledWith([['a', 'b']], ['a', 'b'], customEqualityTesters);
}); });
it("fails when the actual was not called", function() { it("fails when the actual was not called", function() {
var util = { var matchersUtil = {
contains: jasmine.createSpy('delegated-contains').and.returnValue(false) contains: jasmine.createSpy('delegated-contains').and.returnValue(false),
pp: jasmineUnderTest.makePrettyPrinter()
}, },
matcher = jasmineUnderTest.matchers.toHaveBeenCalledWith(util), matcher = jasmineUnderTest.matchers.toHaveBeenCalledWith(matchersUtil),
uncalledSpy = new jasmineUnderTest.Spy('uncalled spy'), uncalledSpy = new jasmineUnderTest.Spy('uncalled spy'),
result; result;
@@ -43,8 +43,8 @@ describe("toHaveBeenCalledWith", function() {
}); });
it("fails when the actual was called with different parameters", function() { it("fails when the actual was called with different parameters", function() {
var util = jasmineUnderTest.matchersUtil, var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.matchers.toHaveBeenCalledWith(util), matcher = jasmineUnderTest.matchers.toHaveBeenCalledWith(matchersUtil),
calledSpy = new jasmineUnderTest.Spy('called spy'), calledSpy = new jasmineUnderTest.Spy('called spy'),
result; result;
@@ -73,8 +73,11 @@ describe("toHaveBeenCalledWith", function() {
}); });
it("throws an exception when the actual is not a spy", function() { it("throws an exception when the actual is not a spy", function() {
var matcher = jasmineUnderTest.matchers.toHaveBeenCalledWith(), var matcher = jasmineUnderTest.matchers.toHaveBeenCalledWith({
fn = function() {}; pp: jasmineUnderTest.makePrettyPrinter()
}),
fn = function () {
};
expect(function() { matcher.compare(fn) }).toThrowError(/Expected a spy, but got Function./); expect(function() { matcher.compare(fn) }).toThrowError(/Expected a spy, but got Function./);
}); });

View File

@@ -27,7 +27,9 @@ describe('toHaveClass', function() {
}); });
it('throws an exception when actual is not a DOM element', function() { it('throws an exception when actual is not a DOM element', function() {
var matcher = jasmineUnderTest.matchers.toHaveClass(); var matcher = jasmineUnderTest.matchers.toHaveClass({
pp: jasmineUnderTest.makePrettyPrinter()
});
expect(function() { expect(function() {
matcher.compare('x', 'foo'); matcher.compare('x', 'foo');

View File

@@ -54,7 +54,9 @@ describe("toThrowError", function() {
}); });
it("fails if thrown is not an instanceof Error", function() { it("fails if thrown is not an instanceof Error", function() {
var matcher = jasmineUnderTest.matchers.toThrowError(), var matcher = jasmineUnderTest.matchers.toThrowError({
pp: jasmineUnderTest.makePrettyPrinter()
}),
fn = function() { fn = function() {
throw 4; throw 4;
}, },
@@ -103,7 +105,9 @@ describe("toThrowError", function() {
}); });
it("fails with the correct message if thrown is a falsy value", function() { it("fails with the correct message if thrown is a falsy value", function() {
var matcher = jasmineUnderTest.matchers.toThrowError(), var matcher = jasmineUnderTest.matchers.toThrowError({
pp: jasmineUnderTest.makePrettyPrinter()
}),
fn = function() { fn = function() {
throw undefined; throw undefined;
}, },
@@ -128,7 +132,9 @@ describe("toThrowError", function() {
}); });
it("passes if thrown is an Error and the expected is the same message", function() { it("passes if thrown is an Error and the expected is the same message", function() {
var matcher = jasmineUnderTest.matchers.toThrowError(), var matcher = jasmineUnderTest.matchers.toThrowError({
pp: jasmineUnderTest.makePrettyPrinter()
}),
fn = function() { fn = function() {
throw new Error("foo"); throw new Error("foo");
}, },
@@ -141,7 +147,9 @@ describe("toThrowError", function() {
}); });
it("fails if thrown is an Error and the expected is not the same message", function() { it("fails if thrown is an Error and the expected is not the same message", function() {
var matcher = jasmineUnderTest.matchers.toThrowError(), var matcher = jasmineUnderTest.matchers.toThrowError({
pp: jasmineUnderTest.makePrettyPrinter()
}),
fn = function() { fn = function() {
throw new Error("foo"); throw new Error("foo");
}, },
@@ -154,7 +162,9 @@ describe("toThrowError", function() {
}); });
it("passes if thrown is an Error and the expected is a RegExp that matches the message", function() { it("passes if thrown is an Error and the expected is a RegExp that matches the message", function() {
var matcher = jasmineUnderTest.matchers.toThrowError(), var matcher = jasmineUnderTest.matchers.toThrowError({
pp: jasmineUnderTest.makePrettyPrinter()
}),
fn = function() { fn = function() {
throw new Error("a long message"); throw new Error("a long message");
}, },
@@ -167,7 +177,9 @@ describe("toThrowError", function() {
}); });
it("fails if thrown is an Error and the expected is a RegExp that does not match the message", function() { it("fails if thrown is an Error and the expected is a RegExp that does not match the message", function() {
var matcher = jasmineUnderTest.matchers.toThrowError(), var matcher = jasmineUnderTest.matchers.toThrowError({
pp: jasmineUnderTest.makePrettyPrinter()
}),
fn = function() { fn = function() {
throw new Error("a long message"); throw new Error("a long message");
}, },
@@ -180,10 +192,7 @@ describe("toThrowError", function() {
}); });
it("passes if thrown is an Error and the expected the same Error", function() { it("passes if thrown is an Error and the expected the same Error", function() {
var util = { var matcher = jasmineUnderTest.matchers.toThrowError(),
equals: jasmine.createSpy('delegated-equal').and.returnValue(true)
},
matcher = jasmineUnderTest.matchers.toThrowError(),
fn = function() { fn = function() {
throw new Error(); throw new Error();
}, },
@@ -196,10 +205,7 @@ describe("toThrowError", function() {
}); });
it("passes if thrown is a custom error that takes arguments and the expected is the same error", function() { it("passes if thrown is a custom error that takes arguments and the expected is the same error", function() {
var util = { var matcher = jasmineUnderTest.matchers.toThrowError(),
equals: jasmine.createSpy('delegated-equal').and.returnValue(true)
},
matcher = jasmineUnderTest.matchers.toThrowError(),
CustomError = function CustomError(arg) { arg.x }, CustomError = function CustomError(arg) { arg.x },
fn = function() { fn = function() {
throw new CustomError({ x: 1 }); throw new CustomError({ x: 1 });
@@ -215,10 +221,7 @@ describe("toThrowError", function() {
}); });
it("fails if thrown is an Error and the expected is a different Error", function() { it("fails if thrown is an Error and the expected is a different Error", function() {
var util = { var matcher = jasmineUnderTest.matchers.toThrowError(),
equals: jasmine.createSpy('delegated-equal').and.returnValue(false)
},
matcher = jasmineUnderTest.matchers.toThrowError(),
fn = function() { fn = function() {
throw new Error(); throw new Error();
}, },
@@ -231,10 +234,11 @@ describe("toThrowError", function() {
}); });
it("passes if thrown is a type of Error and it is equal to the expected Error and message", function() { it("passes if thrown is a type of Error and it is equal to the expected Error and message", function() {
var util = { var matchersUtil = {
equals: jasmine.createSpy('delegated-equal').and.returnValue(true) equals: jasmine.createSpy('delegated-equal').and.returnValue(true),
pp: jasmineUnderTest.makePrettyPrinter()
}, },
matcher = jasmineUnderTest.matchers.toThrowError(), matcher = jasmineUnderTest.matchers.toThrowError(matchersUtil),
fn = function() { fn = function() {
throw new TypeError("foo"); throw new TypeError("foo");
}, },
@@ -247,11 +251,12 @@ describe("toThrowError", function() {
}); });
it("passes if thrown is a custom error that takes arguments and it is equal to the expected custom error and message", function() { it("passes if thrown is a custom error that takes arguments and it is equal to the expected custom error and message", function() {
var util = { var matchersUtil = {
equals: jasmine.createSpy('delegated-equal').and.returnValue(true) equals: jasmine.createSpy('delegated-equal').and.returnValue(true),
pp: jasmineUnderTest.makePrettyPrinter()
}, },
matcher = jasmineUnderTest.matchers.toThrowError(), matcher = jasmineUnderTest.matchers.toThrowError(matchersUtil),
CustomError = function CustomError(arg) { this.message = arg.message }, CustomError = function CustomError(arg) { this.message = arg.message; },
fn = function() { fn = function() {
throw new CustomError({message: "foo"}); throw new CustomError({message: "foo"});
}, },
@@ -266,10 +271,11 @@ describe("toThrowError", function() {
}); });
it("fails if thrown is a type of Error and the expected is a different Error", function() { it("fails if thrown is a type of Error and the expected is a different Error", function() {
var util = { var matchersUtil = {
equals: jasmine.createSpy('delegated-equal').and.returnValue(false) equals: jasmine.createSpy('delegated-equal').and.returnValue(false),
pp: jasmineUnderTest.makePrettyPrinter()
}, },
matcher = jasmineUnderTest.matchers.toThrowError(), matcher = jasmineUnderTest.matchers.toThrowError(matchersUtil),
fn = function() { fn = function() {
throw new TypeError("foo"); throw new TypeError("foo");
}, },
@@ -282,10 +288,11 @@ describe("toThrowError", function() {
}); });
it("passes if thrown is a type of Error and has the same type as the expected Error and the message matches the expected message", function() { it("passes if thrown is a type of Error and has the same type as the expected Error and the message matches the expected message", function() {
var util = { var matchersUtil = {
equals: jasmine.createSpy('delegated-equal').and.returnValue(true) equals: jasmine.createSpy('delegated-equal').and.returnValue(true),
pp: jasmineUnderTest.makePrettyPrinter()
}, },
matcher = jasmineUnderTest.matchers.toThrowError(), matcher = jasmineUnderTest.matchers.toThrowError(matchersUtil),
fn = function() { fn = function() {
throw new TypeError("foo"); throw new TypeError("foo");
}, },
@@ -298,10 +305,11 @@ describe("toThrowError", function() {
}); });
it("fails if thrown is a type of Error and the expected is a different Error", function() { it("fails if thrown is a type of Error and the expected is a different Error", function() {
var util = { var matchersUtil = {
equals: jasmine.createSpy('delegated-equal').and.returnValue(false) equals: jasmine.createSpy('delegated-equal').and.returnValue(false),
pp: jasmineUnderTest.makePrettyPrinter()
}, },
matcher = jasmineUnderTest.matchers.toThrowError(), matcher = jasmineUnderTest.matchers.toThrowError(matchersUtil),
fn = function() { fn = function() {
throw new TypeError("foo"); throw new TypeError("foo");
}, },

View File

@@ -32,7 +32,9 @@ describe("toThrowMatching", function() {
}); });
it("fails with the correct message if thrown is a falsy value", function() { it("fails with the correct message if thrown is a falsy value", function() {
var matcher = jasmineUnderTest.matchers.toThrowMatching(), var matcher = jasmineUnderTest.matchers.toThrowMatching({
pp: jasmineUnderTest.makePrettyPrinter()
}),
fn = function() { fn = function() {
throw undefined; throw undefined;
}, },
@@ -58,8 +60,10 @@ describe("toThrowMatching", function() {
}); });
it("fails if the argument is a function that returns false when called with the error", function() { it("fails if the argument is a function that returns false when called with the error", function() {
var matcher = jasmineUnderTest.matchers.toThrowMatching(), var matcher = jasmineUnderTest.matchers.toThrowMatching({
predicate = function(e) { return e.message === "oh no" }, pp: jasmineUnderTest.makePrettyPrinter()
}),
predicate = function(e) { return e.message === "oh no" },
fn = function() { fn = function() {
throw new TypeError("nope"); throw new TypeError("nope");
}, },

View File

@@ -23,10 +23,11 @@ describe("toThrow", function() {
}); });
it("passes if it throws but there is no expected", function() { it("passes if it throws but there is no expected", function() {
var util = { var matchersUtil = {
equals: jasmine.createSpy('delegated-equal').and.returnValue(true) equals: jasmine.createSpy('delegated-equal').and.returnValue(true),
pp: jasmineUnderTest.makePrettyPrinter()
}, },
matcher = jasmineUnderTest.matchers.toThrow(util), matcher = jasmineUnderTest.matchers.toThrow(matchersUtil),
fn = function() { fn = function() {
throw 5; throw 5;
}, },
@@ -39,7 +40,9 @@ describe("toThrow", function() {
}); });
it("passes even if what is thrown is falsy", function() { it("passes even if what is thrown is falsy", function() {
var matcher = jasmineUnderTest.matchers.toThrow(), var matcher = jasmineUnderTest.matchers.toThrow({
pp: jasmineUnderTest.makePrettyPrinter()
}),
fn = function() { fn = function() {
throw undefined; throw undefined;
}, },
@@ -51,10 +54,11 @@ describe("toThrow", function() {
}); });
it("passes if what is thrown is equivalent to what is expected", function() { it("passes if what is thrown is equivalent to what is expected", function() {
var util = { var matchersUtil = {
equals: jasmine.createSpy('delegated-equal').and.returnValue(true) equals: jasmine.createSpy('delegated-equal').and.returnValue(true),
pp: jasmineUnderTest.makePrettyPrinter()
}, },
matcher = jasmineUnderTest.matchers.toThrow(util), matcher = jasmineUnderTest.matchers.toThrow(matchersUtil),
fn = function() { fn = function() {
throw 5; throw 5;
}, },
@@ -67,10 +71,11 @@ describe("toThrow", function() {
}); });
it("fails if what is thrown is not equivalent to what is expected", function() { it("fails if what is thrown is not equivalent to what is expected", function() {
var util = { var matchersUtil = {
equals: jasmine.createSpy('delegated-equal').and.returnValue(false) equals: jasmine.createSpy('delegated-equal').and.returnValue(false),
pp: jasmineUnderTest.makePrettyPrinter()
}, },
matcher = jasmineUnderTest.matchers.toThrow(util), matcher = jasmineUnderTest.matchers.toThrow(matchersUtil),
fn = function() { fn = function() {
throw 5; throw 5;
}, },
@@ -83,10 +88,11 @@ describe("toThrow", function() {
}); });
it("fails if what is thrown is not equivalent to undefined", function() { it("fails if what is thrown is not equivalent to undefined", function() {
var util = { var matchersUtil = {
equals: jasmine.createSpy('delegated-equal').and.returnValue(false) equals: jasmine.createSpy('delegated-equal').and.returnValue(false),
pp: jasmineUnderTest.makePrettyPrinter()
}, },
matcher = jasmineUnderTest.matchers.toThrow(util), matcher = jasmineUnderTest.matchers.toThrow(matchersUtil),
fn = function() { fn = function() {
throw 5; throw 5;
}, },

View File

@@ -1,10 +1,7 @@
(function(env) { (function(env) {
env.registerIntegrationMatchers = function() { env.registerIntegrationMatchers = function() {
jasmine.addMatchers({ jasmine.addMatchers({
toHaveFailedExpectationsForRunnable: function( toHaveFailedExpectationsForRunnable: function() {
util,
customeEqualityTesters
) {
return { return {
compare: function(actual, fullName, expectedFailures) { compare: function(actual, fullName, expectedFailures) {
var foundRunnable = false, var foundRunnable = false,

View File

@@ -1,43 +1,46 @@
describe('jasmineUnderTest.pp (HTML Dependent)', function() { describe('PrettyPrinter (HTML Dependent)', function() {
it('should stringify non-element HTML nodes properly', function() { it('should stringify non-element HTML nodes properly', function() {
var sampleNode = document.createTextNode(''); var sampleNode = document.createTextNode('');
expect(jasmineUnderTest.pp(sampleNode)).toEqual('HTMLNode'); var pp = jasmineUnderTest.makePrettyPrinter();
expect(jasmineUnderTest.pp({ foo: sampleNode })).toEqual( expect(pp(sampleNode)).toEqual('HTMLNode');
'Object({ foo: HTMLNode })' expect(pp({ foo: sampleNode })).toEqual('Object({ foo: HTMLNode })');
);
}); });
it('should stringify empty HTML elements as their opening tags', function() { it('should stringify empty HTML elements as their opening tags', function() {
var simple = document.createElement('div'); var simple = document.createElement('div');
var pp = jasmineUnderTest.makePrettyPrinter();
simple.className = 'foo'; simple.className = 'foo';
expect(jasmineUnderTest.pp(simple)).toEqual('<div class="foo">'); expect(pp(simple)).toEqual('<div class="foo">');
}); });
it('should stringify non-empty HTML elements as tags with placeholders', function() { it('should stringify non-empty HTML elements as tags with placeholders', function() {
var pp = jasmineUnderTest.makePrettyPrinter();
var nonEmpty = document.createElement('div'); var nonEmpty = document.createElement('div');
nonEmpty.className = 'foo'; nonEmpty.className = 'foo';
nonEmpty.innerHTML = '<p>Irrelevant</p>'; nonEmpty.innerHTML = '<p>Irrelevant</p>';
expect(jasmineUnderTest.pp(nonEmpty)).toEqual('<div class="foo">...</div>'); expect(pp(nonEmpty)).toEqual('<div class="foo">...</div>');
}); });
it("should print Firefox's wrapped native objects correctly", function() { it("should print Firefox's wrapped native objects correctly", function() {
if (jasmine.getEnv().firefoxVersion) { if (jasmine.getEnv().firefoxVersion) {
var pp = jasmineUnderTest.makePrettyPrinter();
try { try {
new CustomEvent(); new CustomEvent();
} catch (e) { } catch (e) {
var err = e; var err = e;
} }
// Different versions of FF produce different error messages. // Different versions of FF produce different error messages.
expect(jasmineUnderTest.pp(err)).toMatch( expect(pp(err)).toMatch(
/Not enough arguments|CustomEvent requires at least 1 argument, but only 0 were passed/ /Not enough arguments|CustomEvent requires at least 1 argument, but only 0 were passed/
); );
} }
}); });
it('should stringify HTML element with text and attributes', function() { it('should stringify HTML element with text and attributes', function() {
var pp = jasmineUnderTest.makePrettyPrinter();
var el = document.createElement('div'); var el = document.createElement('div');
el.setAttribute('things', 'foo'); el.setAttribute('things', 'foo');
el.innerHTML = 'foo'; el.innerHTML = 'foo';
expect(jasmineUnderTest.pp(el)).toEqual('<div things="foo">...</div>'); expect(pp(el)).toEqual('<div things="foo">...</div>');
}); });
}); });

View File

@@ -23,7 +23,7 @@ describe('npm package', function() {
beforeEach(function() { beforeEach(function() {
jasmine.addMatchers({ jasmine.addMatchers({
toExistInPath: function(util, customEquality) { toExistInPath: function() {
return { return {
compare: function(actual, expected) { compare: function(actual, expected) {
var fullPath = path.resolve(expected, actual); var fullPath = path.resolve(expected, actual);

View File

@@ -276,6 +276,7 @@ getJasmineRequireObj().Env = function(j$) {
} }
var customMatchers = var customMatchers =
runnableResources[currentRunnable().id].customMatchers; runnableResources[currentRunnable().id].customMatchers;
for (var matcherName in matchersToAdd) { for (var matcherName in matchersToAdd) {
customMatchers[matcherName] = matchersToAdd[matcherName]; customMatchers[matcherName] = matchersToAdd[matcherName];
} }
@@ -289,11 +290,24 @@ getJasmineRequireObj().Env = function(j$) {
} }
var customAsyncMatchers = var customAsyncMatchers =
runnableResources[currentRunnable().id].customAsyncMatchers; runnableResources[currentRunnable().id].customAsyncMatchers;
for (var matcherName in matchersToAdd) { for (var matcherName in matchersToAdd) {
customAsyncMatchers[matcherName] = matchersToAdd[matcherName]; customAsyncMatchers[matcherName] = matchersToAdd[matcherName];
} }
}; };
this.addCustomObjectFormatter = function(formatter) {
if (!currentRunnable()) {
throw new Error(
'Custom object formatters must be added in a before function or a spec'
);
}
runnableResources[currentRunnable().id].customObjectFormatters.push(
formatter
);
};
j$.Expectation.addCoreMatchers(j$.matchers); j$.Expectation.addCoreMatchers(j$.matchers);
j$.Expectation.addAsyncCoreMatchers(j$.asyncMatchers); j$.Expectation.addAsyncCoreMatchers(j$.asyncMatchers);
@@ -307,10 +321,28 @@ getJasmineRequireObj().Env = function(j$) {
return 'suite' + nextSuiteId++; return 'suite' + nextSuiteId++;
}; };
var makePrettyPrinter = function() {
var customObjectFormatters =
runnableResources[currentRunnable().id].customObjectFormatters;
return j$.makePrettyPrinter(customObjectFormatters);
};
var makeMatchersUtil = function() {
var customEqualityTesters =
runnableResources[currentRunnable().id].customEqualityTesters;
return new j$.MatchersUtil({
customTesters: customEqualityTesters,
pp: makePrettyPrinter()
});
};
var expectationFactory = function(actual, spec) { var expectationFactory = function(actual, spec) {
var customEqualityTesters =
runnableResources[spec.id].customEqualityTesters;
return j$.Expectation.factory({ return j$.Expectation.factory({
util: j$.matchersUtil, matchersUtil: makeMatchersUtil(),
customEqualityTesters: runnableResources[spec.id].customEqualityTesters, customEqualityTesters: customEqualityTesters,
customMatchers: runnableResources[spec.id].customMatchers, customMatchers: runnableResources[spec.id].customMatchers,
actual: actual, actual: actual,
addExpectationResult: addExpectationResult addExpectationResult: addExpectationResult
@@ -349,7 +381,7 @@ getJasmineRequireObj().Env = function(j$) {
var asyncExpectationFactory = function(actual, spec, runableType) { var asyncExpectationFactory = function(actual, spec, runableType) {
return j$.Expectation.asyncFactory({ return j$.Expectation.asyncFactory({
util: j$.matchersUtil, matchersUtil: makeMatchersUtil(),
customEqualityTesters: runnableResources[spec.id].customEqualityTesters, customEqualityTesters: runnableResources[spec.id].customEqualityTesters,
customAsyncMatchers: runnableResources[spec.id].customAsyncMatchers, customAsyncMatchers: runnableResources[spec.id].customAsyncMatchers,
actual: actual, actual: actual,
@@ -378,7 +410,8 @@ getJasmineRequireObj().Env = function(j$) {
customMatchers: {}, customMatchers: {},
customAsyncMatchers: {}, customAsyncMatchers: {},
customSpyStrategies: {}, customSpyStrategies: {},
defaultStrategyFn: undefined defaultStrategyFn: undefined,
customObjectFormatters: []
}; };
if (runnableResources[parentRunnableId]) { if (runnableResources[parentRunnableId]) {
@@ -1171,7 +1204,7 @@ getJasmineRequireObj().Env = function(j$) {
message += error; message += error;
} else { } else {
// pretty print all kind of objects. This includes arrays. // pretty print all kind of objects. This includes arrays.
message += j$.pp(error); message += makePrettyPrinter()(error);
} }
} }

View File

@@ -129,7 +129,7 @@ getJasmineRequireObj().Expectation = function(j$) {
return result; return result;
} }
function negatedFailureMessage(result, matcherName, args, util) { function negatedFailureMessage(result, matcherName, args, matchersUtil) {
if (result.message) { if (result.message) {
if (j$.isFunction_(result.message)) { if (j$.isFunction_(result.message)) {
return result.message(); return result.message();
@@ -141,7 +141,7 @@ getJasmineRequireObj().Expectation = function(j$) {
args = args.slice(); args = args.slice();
args.unshift(true); args.unshift(true);
args.unshift(matcherName); args.unshift(matcherName);
return util.buildFailureMessage.apply(null, args); return matchersUtil.buildFailureMessage.apply(matchersUtil, args);
} }
function negate(result) { function negate(result) {

View File

@@ -16,7 +16,7 @@ getJasmineRequireObj().ExpectationFilterChain = function() {
result, result,
matcherName, matcherName,
args, args,
util matchersUtil
) { ) {
return this.callFirst_('buildFailureMessage', arguments).result; return this.callFirst_('buildFailureMessage', arguments).result;
}; };

View File

@@ -1,6 +1,8 @@
getJasmineRequireObj().Expector = function(j$) { getJasmineRequireObj().Expector = function(j$) {
function Expector(options) { function Expector(options) {
this.util = options.util || { buildFailureMessage: function() {} }; this.matchersUtil = options.matchersUtil || {
buildFailureMessage: function() {}
};
this.customEqualityTesters = options.customEqualityTesters || []; this.customEqualityTesters = options.customEqualityTesters || [];
this.actual = options.actual; this.actual = options.actual;
this.addExpectationResult = options.addExpectationResult || function() {}; this.addExpectationResult = options.addExpectationResult || function() {};
@@ -18,7 +20,7 @@ getJasmineRequireObj().Expector = function(j$) {
this.args.unshift(this.actual); this.args.unshift(this.actual);
var matcher = matcherFactory(this.util, this.customEqualityTesters); var matcher = matcherFactory(this.matchersUtil, this.customEqualityTesters);
var comparisonFunc = this.filters.selectComparisonFunc(matcher); var comparisonFunc = this.filters.selectComparisonFunc(matcher);
return comparisonFunc || matcher.compare; return comparisonFunc || matcher.compare;
}; };
@@ -34,7 +36,7 @@ getJasmineRequireObj().Expector = function(j$) {
result, result,
this.matcherName, this.matcherName,
this.args, this.args,
this.util, this.matchersUtil,
defaultMessage defaultMessage
); );
return this.filters.modifyFailureMessage(msg || defaultMessage()); return this.filters.modifyFailureMessage(msg || defaultMessage());
@@ -44,7 +46,10 @@ getJasmineRequireObj().Expector = function(j$) {
var args = self.args.slice(); var args = self.args.slice();
args.unshift(false); args.unshift(false);
args.unshift(self.matcherName); args.unshift(self.matcherName);
return self.util.buildFailureMessage.apply(null, args); return self.matchersUtil.buildFailureMessage.apply(
self.matchersUtil,
args
);
} else if (j$.isFunction_(result.message)) { } else if (j$.isFunction_(result.message)) {
return result.message(); return result.message();
} else { } else {

View File

@@ -1,9 +1,11 @@
getJasmineRequireObj().pp = function(j$) { getJasmineRequireObj().makePrettyPrinter = function(j$) {
function PrettyPrinter() { function SinglePrettyPrintRun(customObjectFormatters, pp) {
this.customObjectFormatters_ = customObjectFormatters;
this.ppNestLevel_ = 0; this.ppNestLevel_ = 0;
this.seen = []; this.seen = [];
this.length = 0; this.length = 0;
this.stringParts = []; this.stringParts = [];
this.pp_ = pp;
} }
function hasCustomToString(value) { function hasCustomToString(value) {
@@ -21,10 +23,14 @@ getJasmineRequireObj().pp = function(j$) {
} }
} }
PrettyPrinter.prototype.format = function(value) { SinglePrettyPrintRun.prototype.format = function(value) {
this.ppNestLevel_++; this.ppNestLevel_++;
try { try {
if (j$.util.isUndefined(value)) { var customFormatResult = this.applyCustomFormatters_(value);
if (customFormatResult) {
this.emitScalar(customFormatResult);
} else if (j$.util.isUndefined(value)) {
this.emitScalar('undefined'); this.emitScalar('undefined');
} else if (value === null) { } else if (value === null) {
this.emitScalar('null'); this.emitScalar('null');
@@ -33,7 +39,7 @@ getJasmineRequireObj().pp = function(j$) {
} else if (value === j$.getGlobal()) { } else if (value === j$.getGlobal()) {
this.emitScalar('<global>'); this.emitScalar('<global>');
} else if (value.jasmineToString) { } else if (value.jasmineToString) {
this.emitScalar(value.jasmineToString()); this.emitScalar(value.jasmineToString(this.pp_));
} else if (typeof value === 'string') { } else if (typeof value === 'string') {
this.emitString(value); this.emitString(value);
} else if (j$.isSpy(value)) { } else if (j$.isSpy(value)) {
@@ -95,7 +101,11 @@ getJasmineRequireObj().pp = function(j$) {
} }
}; };
PrettyPrinter.prototype.iterateObject = function(obj, fn) { SinglePrettyPrintRun.prototype.applyCustomFormatters_ = function(value) {
return customFormat(value, this.customObjectFormatters_);
};
SinglePrettyPrintRun.prototype.iterateObject = function(obj, fn) {
var objKeys = keys(obj, j$.isArray_(obj)); var objKeys = keys(obj, j$.isArray_(obj));
var isGetter = function isGetter(prop) {}; var isGetter = function isGetter(prop) {};
@@ -114,15 +124,15 @@ getJasmineRequireObj().pp = function(j$) {
return objKeys.length > length; return objKeys.length > length;
}; };
PrettyPrinter.prototype.emitScalar = function(value) { SinglePrettyPrintRun.prototype.emitScalar = function(value) {
this.append(value); this.append(value);
}; };
PrettyPrinter.prototype.emitString = function(value) { SinglePrettyPrintRun.prototype.emitString = function(value) {
this.append("'" + value + "'"); this.append("'" + value + "'");
}; };
PrettyPrinter.prototype.emitArray = function(array) { SinglePrettyPrintRun.prototype.emitArray = function(array) {
if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) { if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
this.append('Array'); this.append('Array');
return; return;
@@ -158,7 +168,7 @@ getJasmineRequireObj().pp = function(j$) {
this.append(' ]'); this.append(' ]');
}; };
PrettyPrinter.prototype.emitSet = function(set) { SinglePrettyPrintRun.prototype.emitSet = function(set) {
if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) { if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
this.append('Set'); this.append('Set');
return; return;
@@ -183,7 +193,7 @@ getJasmineRequireObj().pp = function(j$) {
this.append(' )'); this.append(' )');
}; };
PrettyPrinter.prototype.emitMap = function(map) { SinglePrettyPrintRun.prototype.emitMap = function(map) {
if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) { if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
this.append('Map'); this.append('Map');
return; return;
@@ -208,7 +218,7 @@ getJasmineRequireObj().pp = function(j$) {
this.append(' )'); this.append(' )');
}; };
PrettyPrinter.prototype.emitObject = function(obj) { SinglePrettyPrintRun.prototype.emitObject = function(obj) {
var ctor = obj.constructor, var ctor = obj.constructor,
constructorName; constructorName;
@@ -244,7 +254,7 @@ getJasmineRequireObj().pp = function(j$) {
this.append(' })'); this.append(' })');
}; };
PrettyPrinter.prototype.emitTypedArray = function(arr) { SinglePrettyPrintRun.prototype.emitTypedArray = function(arr) {
var constructorName = j$.fnNameFor(arr.constructor), var constructorName = j$.fnNameFor(arr.constructor),
limitedArray = Array.prototype.slice.call( limitedArray = Array.prototype.slice.call(
arr, arr,
@@ -260,7 +270,7 @@ getJasmineRequireObj().pp = function(j$) {
this.append(constructorName + ' [ ' + itemsString + ' ]'); this.append(constructorName + ' [ ' + itemsString + ' ]');
}; };
PrettyPrinter.prototype.emitDomElement = function(el) { SinglePrettyPrintRun.prototype.emitDomElement = function(el) {
var tagName = el.tagName.toLowerCase(), var tagName = el.tagName.toLowerCase(),
attrs = el.attributes, attrs = el.attributes,
i, i,
@@ -286,7 +296,11 @@ getJasmineRequireObj().pp = function(j$) {
this.append(out); this.append(out);
}; };
PrettyPrinter.prototype.formatProperty = function(obj, property, isGetter) { SinglePrettyPrintRun.prototype.formatProperty = function(
obj,
property,
isGetter
) {
this.append(property); this.append(property);
this.append(': '); this.append(': ');
if (isGetter) { if (isGetter) {
@@ -296,7 +310,7 @@ getJasmineRequireObj().pp = function(j$) {
} }
}; };
PrettyPrinter.prototype.append = function(value) { SinglePrettyPrintRun.prototype.append = function(value) {
// This check protects us from the rare case where an object has overriden // This check protects us from the rare case where an object has overriden
// `toString()` with an invalid implementation (returning a non-string). // `toString()` with an invalid implementation (returning a non-string).
if (typeof value !== 'string') { if (typeof value !== 'string') {
@@ -360,9 +374,32 @@ getJasmineRequireObj().pp = function(j$) {
return extraKeys; return extraKeys;
} }
return function(value) {
var prettyPrinter = new PrettyPrinter(); function customFormat(value, customObjectFormatters) {
prettyPrinter.format(value); var i, result;
return prettyPrinter.stringParts.join('');
for (i = 0; i < customObjectFormatters.length; i++) {
result = customObjectFormatters[i](value);
if (result !== undefined) {
return result;
}
}
}
return function(customObjectFormatters) {
customObjectFormatters = customObjectFormatters || [];
var pp = function(value) {
var prettyPrinter = new SinglePrettyPrintRun(customObjectFormatters, pp);
prettyPrinter.format(value);
return prettyPrinter.stringParts.join('');
};
pp.customFormat_ = function(value) {
return customFormat(value, customObjectFormatters);
};
return pp;
}; };
}; };

View File

@@ -7,6 +7,11 @@ getJasmineRequireObj().Spy = function(j$) {
}; };
})(); })();
var matchersUtil = new j$.MatchersUtil({
customTesters: [],
pp: j$.makePrettyPrinter()
});
/** /**
* _Note:_ Do not construct this directly, use {@link spyOn}, {@link spyOnProperty}, {@link jasmine.createSpy}, or {@link jasmine.createSpyObj} * _Note:_ Do not construct this directly, use {@link spyOn}, {@link spyOnProperty}, {@link jasmine.createSpy}, or {@link jasmine.createSpyObj}
* @constructor * @constructor
@@ -202,7 +207,7 @@ getJasmineRequireObj().Spy = function(j$) {
var i; var i;
for (i = 0; i < this.strategies.length; i++) { for (i = 0; i < this.strategies.length; i++) {
if (j$.matchersUtil.equals(args, this.strategies[i].args)) { if (matchersUtil.equals(args, this.strategies[i].args)) {
return this.strategies[i].strategy; return this.strategies[i].strategy;
} }
} }

View File

@@ -0,0 +1,105 @@
getJasmineRequireObj().asymmetricEqualityTesterArgCompatShim = function(j$) {
/*
Older versions of Jasmine passed an array of custom equality testers as the
second argument to each asymmetric equality tester's `asymmetricMatch`
method. Newer versions will pass a `MatchersUtil` instance. The
asymmetricEqualityTesterArgCompatShim allows for a graceful migration from
the old interface to the new by "being" both an array of custom equality
testers and a `MatchersUtil` at the same time.
This code should be removed in the next major release.
*/
var likelyArrayProps = [
'concat',
'constructor',
'copyWithin',
'entries',
'every',
'fill',
'filter',
'find',
'findIndex',
'flat',
'flatMap',
'forEach',
'includes',
'indexOf',
'join',
'keys',
'lastIndexOf',
'length',
'map',
'pop',
'push',
'reduce',
'reduceRight',
'reverse',
'shift',
'slice',
'some',
'sort',
'splice',
'toLocaleString',
'toSource',
'toString',
'unshift',
'values'
];
function asymmetricEqualityTesterArgCompatShim(
matchersUtil,
customEqualityTesters
) {
var self = Object.create(matchersUtil),
props,
i,
k;
copy(self, customEqualityTesters, 'length');
for (i = 0; i < customEqualityTesters.length; i++) {
copy(self, customEqualityTesters, i);
}
var props = arrayProps();
for (i = 0; i < props.length; i++) {
k = props[i];
if (k !== 'length') {
copy(self, Array.prototype, k);
}
}
return self;
}
function copy(dest, src, propName) {
Object.defineProperty(dest, propName, {
get: function() {
return src[propName];
}
});
}
function arrayProps() {
var props, a, k;
if (!Object.getOwnPropertyDescriptors) {
return likelyArrayProps.filter(function(k) {
return Array.prototype.hasOwnProperty(k);
});
}
props = Object.getOwnPropertyDescriptors(Array.prototype);
a = [];
for (k in props) {
a.push(k);
}
return a;
}
return asymmetricEqualityTesterArgCompatShim;
};

View File

@@ -3,7 +3,7 @@ getJasmineRequireObj().ArrayContaining = function(j$) {
this.sample = sample; this.sample = sample;
} }
ArrayContaining.prototype.asymmetricMatch = function(other, customTesters) { ArrayContaining.prototype.asymmetricMatch = function(other, matchersUtil) {
if (!j$.isArray_(this.sample)) { if (!j$.isArray_(this.sample)) {
throw new Error('You must provide an array to arrayContaining, not ' + j$.pp(this.sample) + '.'); throw new Error('You must provide an array to arrayContaining, not ' + j$.pp(this.sample) + '.');
} }
@@ -17,7 +17,7 @@ getJasmineRequireObj().ArrayContaining = function(j$) {
for (var i = 0; i < this.sample.length; i++) { for (var i = 0; i < this.sample.length; i++) {
var item = this.sample[i]; var item = this.sample[i];
if (!j$.matchersUtil.contains(other, item, customTesters)) { if (!matchersUtil.contains(other, item)) {
return false; return false;
} }
} }
@@ -25,8 +25,8 @@ getJasmineRequireObj().ArrayContaining = function(j$) {
return true; return true;
}; };
ArrayContaining.prototype.jasmineToString = function () { ArrayContaining.prototype.jasmineToString = function (pp) {
return '<jasmine.arrayContaining(' + j$.pp(this.sample) +')>'; return '<jasmine.arrayContaining(' + pp(this.sample) +')>';
}; };
return ArrayContaining; return ArrayContaining;

View File

@@ -4,7 +4,7 @@ getJasmineRequireObj().ArrayWithExactContents = function(j$) {
this.sample = sample; this.sample = sample;
} }
ArrayWithExactContents.prototype.asymmetricMatch = function(other, customTesters) { ArrayWithExactContents.prototype.asymmetricMatch = function(other, matchersUtil) {
if (!j$.isArray_(this.sample)) { if (!j$.isArray_(this.sample)) {
throw new Error('You must provide an array to arrayWithExactContents, not ' + j$.pp(this.sample) + '.'); throw new Error('You must provide an array to arrayWithExactContents, not ' + j$.pp(this.sample) + '.');
} }
@@ -15,7 +15,7 @@ getJasmineRequireObj().ArrayWithExactContents = function(j$) {
for (var i = 0; i < this.sample.length; i++) { for (var i = 0; i < this.sample.length; i++) {
var item = this.sample[i]; var item = this.sample[i];
if (!j$.matchersUtil.contains(other, item, customTesters)) { if (!matchersUtil.contains(other, item)) {
return false; return false;
} }
} }
@@ -23,8 +23,8 @@ getJasmineRequireObj().ArrayWithExactContents = function(j$) {
return true; return true;
}; };
ArrayWithExactContents.prototype.jasmineToString = function() { ArrayWithExactContents.prototype.jasmineToString = function(pp) {
return '<jasmine.arrayWithExactContents ' + j$.pp(this.sample) + '>'; return '<jasmine.arrayWithExactContents(' + pp(this.sample) + ')>';
}; };
return ArrayWithExactContents; return ArrayWithExactContents;

View File

@@ -7,7 +7,7 @@ getJasmineRequireObj().MapContaining = function(j$) {
this.sample = sample; this.sample = sample;
} }
MapContaining.prototype.asymmetricMatch = function(other, customTesters) { MapContaining.prototype.asymmetricMatch = function(other, matchersUtil) {
if (!j$.isMap(other)) return false; if (!j$.isMap(other)) return false;
var hasAllMatches = true; var hasAllMatches = true;
@@ -17,8 +17,8 @@ getJasmineRequireObj().MapContaining = function(j$) {
var hasMatch = false; var hasMatch = false;
j$.util.forEachBreakable(other, function(oBreakLoop, oValue, oKey) { j$.util.forEachBreakable(other, function(oBreakLoop, oValue, oKey) {
if ( if (
j$.matchersUtil.equals(oKey, key, customTesters) matchersUtil.equals(oKey, key)
&& j$.matchersUtil.equals(oValue, value, customTesters) && matchersUtil.equals(oValue, value)
) { ) {
hasMatch = true; hasMatch = true;
oBreakLoop(); oBreakLoop();
@@ -33,8 +33,8 @@ getJasmineRequireObj().MapContaining = function(j$) {
return hasAllMatches; return hasAllMatches;
}; };
MapContaining.prototype.jasmineToString = function() { MapContaining.prototype.jasmineToString = function(pp) {
return '<jasmine.mapContaining(' + j$.pp(this.sample) + ')>'; return '<jasmine.mapContaining(' + pp(this.sample) + ')>';
}; };
return MapContaining; return MapContaining;

View File

@@ -28,13 +28,13 @@ getJasmineRequireObj().ObjectContaining = function(j$) {
return hasProperty(getPrototype(obj), property); return hasProperty(getPrototype(obj), property);
} }
ObjectContaining.prototype.asymmetricMatch = function(other, customTesters) { ObjectContaining.prototype.asymmetricMatch = function(other, matchersUtil) {
if (typeof(this.sample) !== 'object') { throw new Error('You must provide an object to objectContaining, not \''+this.sample+'\'.'); } if (typeof(this.sample) !== 'object') { throw new Error('You must provide an object to objectContaining, not \''+this.sample+'\'.'); }
if (typeof(other) !== 'object') { return false; } if (typeof(other) !== 'object') { return false; }
for (var property in this.sample) { for (var property in this.sample) {
if (!hasProperty(other, property) || if (!hasProperty(other, property) ||
!j$.matchersUtil.equals(this.sample[property], other[property], customTesters)) { !matchersUtil.equals(this.sample[property], other[property])) {
return false; return false;
} }
} }
@@ -42,10 +42,10 @@ getJasmineRequireObj().ObjectContaining = function(j$) {
return true; return true;
}; };
ObjectContaining.prototype.valuesForDiff_ = function(other) { ObjectContaining.prototype.valuesForDiff_ = function(other, pp) {
if (!j$.isObject_(other)) { if (!j$.isObject_(other)) {
return { return {
self: this.jasmineToString(), self: this.jasmineToString(pp),
other: other other: other
}; };
} }
@@ -63,8 +63,8 @@ getJasmineRequireObj().ObjectContaining = function(j$) {
}; };
}; };
ObjectContaining.prototype.jasmineToString = function() { ObjectContaining.prototype.jasmineToString = function(pp) {
return '<jasmine.objectContaining(' + j$.pp(this.sample) + ')>'; return '<jasmine.objectContaining(' + pp(this.sample) + ')>';
}; };
return ObjectContaining; return ObjectContaining;

View File

@@ -7,17 +7,17 @@ getJasmineRequireObj().SetContaining = function(j$) {
this.sample = sample; this.sample = sample;
} }
SetContaining.prototype.asymmetricMatch = function(other, customTesters) { SetContaining.prototype.asymmetricMatch = function(other, matchersUtil) {
if (!j$.isSet(other)) return false; if (!j$.isSet(other)) return false;
var hasAllMatches = true; var hasAllMatches = true;
j$.util.forEachBreakable(this.sample, function(breakLoop, item) { j$.util.forEachBreakable(this.sample, function(breakLoop, item) {
// for each item in `sample` there should be at least one matching item in `other` // for each item in `sample` there should be at least one matching item in `other`
// (not using `j$.matchersUtil.contains` because it compares set members by reference, // (not using `matchersUtil.contains` because it compares set members by reference,
// not by deep value equality) // not by deep value equality)
var hasMatch = false; var hasMatch = false;
j$.util.forEachBreakable(other, function(oBreakLoop, oItem) { j$.util.forEachBreakable(other, function(oBreakLoop, oItem) {
if (j$.matchersUtil.equals(oItem, item, customTesters)) { if (matchersUtil.equals(oItem, item)) {
hasMatch = true; hasMatch = true;
oBreakLoop(); oBreakLoop();
} }
@@ -31,8 +31,8 @@ getJasmineRequireObj().SetContaining = function(j$) {
return hasAllMatches; return hasAllMatches;
}; };
SetContaining.prototype.jasmineToString = function() { SetContaining.prototype.jasmineToString = function(pp) {
return '<jasmine.setContaining(' + j$.pp(this.sample) + ')>'; return '<jasmine.setContaining(' + pp(this.sample) + ')>';
}; };
return SetContaining; return SetContaining;

View File

@@ -1,16 +1,51 @@
getJasmineRequireObj().DiffBuilder = function(j$) { getJasmineRequireObj().DiffBuilder = function (j$) {
return function DiffBuilder() { return function DiffBuilder(config) {
var path = new j$.ObjectPath(), var prettyPrinter = (config || {}).prettyPrinter || j$.makePrettyPrinter(),
mismatches = []; mismatches = new j$.MismatchTree(),
path = new j$.ObjectPath(),
actualRoot = undefined,
expectedRoot = undefined;
return { return {
record: function (actual, expected, formatter) { setRoots: function (actual, expected) {
formatter = formatter || defaultFormatter; actualRoot = actual;
mismatches.push(formatter(actual, expected, path)); expectedRoot = expected;
},
recordMismatch: function (formatter) {
mismatches.add(path, formatter);
}, },
getMessage: function () { getMessage: function () {
return mismatches.join('\n'); var messages = [];
mismatches.traverse(function (path, isLeaf, formatter) {
var actualCustom, expectedCustom, useCustom,
actual = path.dereference(actualRoot),
expected = path.dereference(expectedRoot);
if (formatter) {
messages.push(formatter(actual, expected, path, prettyPrinter));
return true;
}
actualCustom = prettyPrinter.customFormat_(actual);
expectedCustom = prettyPrinter.customFormat_(expected);
useCustom = !(j$.util.isUndefined(actualCustom) && j$.util.isUndefined(expectedCustom));
if (useCustom) {
messages.push(wrapPrettyPrinted(actualCustom, expectedCustom, path));
return false; // don't recurse further
}
if (isLeaf) {
messages.push(defaultFormatter(actual, expected, path, prettyPrinter));
}
return true;
});
return messages.join('\n');
}, },
withPath: function (pathComponent, block) { withPath: function (pathComponent, block) {
@@ -21,12 +56,16 @@ getJasmineRequireObj().DiffBuilder = function(j$) {
} }
}; };
function defaultFormatter (actual, expected, path) { function defaultFormatter(actual, expected, path, prettyPrinter) {
return wrapPrettyPrinted(prettyPrinter(actual), prettyPrinter(expected), path);
}
function wrapPrettyPrinted(actual, expected, path) {
return 'Expected ' + return 'Expected ' +
path + (path.depth() ? ' = ' : '') + path + (path.depth() ? ' = ' : '') +
j$.pp(actual) + actual +
' to equal ' + ' to equal ' +
j$.pp(expected) + expected +
'.'; '.';
} }
}; };

View File

@@ -0,0 +1,62 @@
getJasmineRequireObj().MismatchTree = function (j$) {
/*
To be able to apply custom object formatters at all possible levels of an
object graph, DiffBuilder needs to be able to know not just where the
mismatch occurred but also all ancestors of the mismatched value in both
the expected and actual object graphs. MismatchTree maintains that context
and provides it via the traverse method.
*/
function MismatchTree(path) {
this.path = path || new j$.ObjectPath([]);
this.formatter = undefined;
this.children = [];
this.isMismatch = false;
}
MismatchTree.prototype.add = function (path, formatter) {
var key, child;
if (path.depth() === 0) {
this.formatter = formatter;
this.isMismatch = true;
} else {
key = path.components[0];
path = path.shift();
child = this.child(key);
if (!child) {
child = new MismatchTree(this.path.add(key));
this.children.push(child);
}
child.add(path, formatter);
}
};
MismatchTree.prototype.traverse = function (visit) {
var i, hasChildren = this.children.length > 0;
if (this.isMismatch || hasChildren) {
if (visit(this.path, !hasChildren, this.formatter)) {
for (i = 0; i < this.children.length; i++) {
this.children[i].traverse(visit);
}
}
}
};
MismatchTree.prototype.child = function(key) {
var i, pathEls;
for (i = 0; i < this.children.length; i++) {
pathEls = this.children[i].path.components;
if (pathEls[pathEls.length - 1] === key) {
return this.children[i];
}
}
};
return MismatchTree;
};

View File

@@ -4,7 +4,8 @@ getJasmineRequireObj().NullDiffBuilder = function(j$) {
withPath: function(_, block) { withPath: function(_, block) {
block(); block();
}, },
record: function() {} setRoots: function() {},
recordMismatch: function() {}
}; };
}; };
}; };

View File

@@ -11,10 +11,24 @@ getJasmineRequireObj().ObjectPath = function(j$) {
} }
}; };
ObjectPath.prototype.dereference = function(obj) {
var i;
for (i = 0; i < this.components.length; i++) {
obj = obj[this.components[i]];
}
return obj;
};
ObjectPath.prototype.add = function(component) { ObjectPath.prototype.add = function(component) {
return new ObjectPath(this.components.concat([component])); return new ObjectPath(this.components.concat([component]));
}; };
ObjectPath.prototype.shift = function() {
return new ObjectPath(this.components.slice(1));
};
ObjectPath.prototype.depth = function() { ObjectPath.prototype.depth = function() {
return this.components.length; return this.components.length;
}; };

View File

@@ -10,7 +10,7 @@ getJasmineRequireObj().toBeRejected = function(j$) {
* @example * @example
* return expectAsync(aPromise).toBeRejected(); * return expectAsync(aPromise).toBeRejected();
*/ */
return function toBeRejected(util) { return function toBeRejected() {
return { return {
compare: function(actual) { compare: function(actual) {
if (!j$.isPromiseLike(actual)) { if (!j$.isPromiseLike(actual)) {

View File

@@ -11,7 +11,7 @@ getJasmineRequireObj().toBeRejectedWith = function(j$) {
* @example * @example
* return expectAsync(aPromise).toBeRejectedWith({prop: 'value'}); * return expectAsync(aPromise).toBeRejectedWith({prop: 'value'});
*/ */
return function toBeRejectedWith(util, customEqualityTesters) { return function toBeRejectedWith(matchersUtil) {
return { return {
compare: function(actualPromise, expectedValue) { compare: function(actualPromise, expectedValue) {
if (!j$.isPromiseLike(actualPromise)) { if (!j$.isPromiseLike(actualPromise)) {
@@ -21,7 +21,7 @@ getJasmineRequireObj().toBeRejectedWith = function(j$) {
function prefix(passed) { function prefix(passed) {
return 'Expected a promise ' + return 'Expected a promise ' +
(passed ? 'not ' : '') + (passed ? 'not ' : '') +
'to be rejected with ' + j$.pp(expectedValue); 'to be rejected with ' + matchersUtil.pp(expectedValue);
} }
return actualPromise.then( return actualPromise.then(
@@ -32,7 +32,7 @@ getJasmineRequireObj().toBeRejectedWith = function(j$) {
}; };
}, },
function(actualValue) { function(actualValue) {
if (util.equals(actualValue, expectedValue, customEqualityTesters)) { if (matchersUtil.equals(actualValue, expectedValue)) {
return { return {
pass: true, pass: true,
message: prefix(true) + '.' message: prefix(true) + '.'
@@ -40,7 +40,7 @@ getJasmineRequireObj().toBeRejectedWith = function(j$) {
} else { } else {
return { return {
pass: false, pass: false,
message: prefix(false) + ' but it was rejected with ' + j$.pp(actualValue) + '.' message: prefix(false) + ' but it was rejected with ' + matchersUtil.pp(actualValue) + '.'
}; };
} }
} }

View File

@@ -14,14 +14,14 @@ getJasmineRequireObj().toBeRejectedWithError = function(j$) {
* await expectAsync(aPromise).toBeRejectedWithError('Error message'); * await expectAsync(aPromise).toBeRejectedWithError('Error message');
* return expectAsync(aPromise).toBeRejectedWithError(/Error message/); * return expectAsync(aPromise).toBeRejectedWithError(/Error message/);
*/ */
return function toBeRejectedWithError() { return function toBeRejectedWithError(matchersUtil) {
return { return {
compare: function(actualPromise, arg1, arg2) { compare: function(actualPromise, arg1, arg2) {
if (!j$.isPromiseLike(actualPromise)) { if (!j$.isPromiseLike(actualPromise)) {
throw new Error('Expected toBeRejectedWithError to be called on a promise.'); throw new Error('Expected toBeRejectedWithError to be called on a promise.');
} }
var expected = getExpectedFromArgs(arg1, arg2); var expected = getExpectedFromArgs(arg1, arg2, matchersUtil);
return actualPromise.then( return actualPromise.then(
function() { function() {
@@ -30,15 +30,15 @@ getJasmineRequireObj().toBeRejectedWithError = function(j$) {
message: 'Expected a promise to be rejected but it was resolved.' message: 'Expected a promise to be rejected but it was resolved.'
}; };
}, },
function(actualValue) { return matchError(actualValue, expected); } function(actualValue) { return matchError(actualValue, expected, matchersUtil); }
); );
} }
}; };
}; };
function matchError(actual, expected) { function matchError(actual, expected, matchersUtil) {
if (!j$.isError_(actual)) { if (!j$.isError_(actual)) {
return fail(expected, 'rejected with ' + j$.pp(actual)); return fail(expected, 'rejected with ' + matchersUtil.pp(actual));
} }
if (!(actual instanceof expected.error)) { if (!(actual instanceof expected.error)) {
@@ -55,7 +55,7 @@ getJasmineRequireObj().toBeRejectedWithError = function(j$) {
return pass(expected); return pass(expected);
} }
return fail(expected, 'rejected with ' + j$.pp(actual)); return fail(expected, 'rejected with ' + matchersUtil.pp(actual));
} }
function pass(expected) { function pass(expected) {
@@ -73,7 +73,7 @@ getJasmineRequireObj().toBeRejectedWithError = function(j$) {
} }
function getExpectedFromArgs(arg1, arg2) { function getExpectedFromArgs(arg1, arg2, matchersUtil) {
var error, message; var error, message;
if (isErrorConstructor(arg1)) { if (isErrorConstructor(arg1)) {
@@ -87,7 +87,7 @@ getJasmineRequireObj().toBeRejectedWithError = function(j$) {
return { return {
error: error, error: error,
message: message, message: message,
printValue: j$.fnNameFor(error) + (typeof message === 'undefined' ? '' : ': ' + j$.pp(message)) printValue: j$.fnNameFor(error) + (typeof message === 'undefined' ? '' : ': ' + matchersUtil.pp(message))
}; };
} }

View File

@@ -10,7 +10,7 @@ getJasmineRequireObj().toBeResolved = function(j$) {
* @example * @example
* return expectAsync(aPromise).toBeResolved(); * return expectAsync(aPromise).toBeResolved();
*/ */
return function toBeResolved(util) { return function toBeResolved() {
return { return {
compare: function(actual) { compare: function(actual) {
if (!j$.isPromiseLike(actual)) { if (!j$.isPromiseLike(actual)) {

View File

@@ -11,7 +11,7 @@ getJasmineRequireObj().toBeResolvedTo = function(j$) {
* @example * @example
* return expectAsync(aPromise).toBeResolvedTo({prop: 'value'}); * return expectAsync(aPromise).toBeResolvedTo({prop: 'value'});
*/ */
return function toBeResolvedTo(util, customEqualityTesters) { return function toBeResolvedTo(matchersUtil) {
return { return {
compare: function(actualPromise, expectedValue) { compare: function(actualPromise, expectedValue) {
if (!j$.isPromiseLike(actualPromise)) { if (!j$.isPromiseLike(actualPromise)) {
@@ -21,12 +21,12 @@ getJasmineRequireObj().toBeResolvedTo = function(j$) {
function prefix(passed) { function prefix(passed) {
return 'Expected a promise ' + return 'Expected a promise ' +
(passed ? 'not ' : '') + (passed ? 'not ' : '') +
'to be resolved to ' + j$.pp(expectedValue); 'to be resolved to ' + matchersUtil.pp(expectedValue);
} }
return actualPromise.then( return actualPromise.then(
function(actualValue) { function(actualValue) {
if (util.equals(actualValue, expectedValue, customEqualityTesters)) { if (matchersUtil.equals(actualValue, expectedValue)) {
return { return {
pass: true, pass: true,
message: prefix(true) + '.' message: prefix(true) + '.'
@@ -34,7 +34,7 @@ getJasmineRequireObj().toBeResolvedTo = function(j$) {
} else { } else {
return { return {
pass: false, pass: false,
message: prefix(false) + ' but it was resolved to ' + j$.pp(actualValue) + '.' message: prefix(false) + ' but it was resolved to ' + matchersUtil.pp(actualValue) + '.'
}; };
} }
}, },

View File

@@ -1,72 +1,100 @@
getJasmineRequireObj().matchersUtil = function(j$) { getJasmineRequireObj().MatchersUtil = function(j$) {
// TODO: what to do about jasmine.pp not being inject? move to JSON.stringify? gut PrettyPrinter? // TODO: convert all uses of j$.pp to use the injected pp
return { /**
equals: equals, * _Note:_ Do not construct this directly. Jasmine will construct one and
* pass it to matchers and asymmetric equality testers.
* @name MatchersUtil
* @since 2.0.0
* @classdesc Utilities for use in implementing matchers
* @constructor
*/
function MatchersUtil(options) {
options = options || {};
this.customTesters_ = options.customTesters || [];
/**
* Formats a value for use in matcher failure messages and similar contexts,
* taking into account the current set of custom value formatters.
* @function
* @name MatchersUtil#pp
* @param {*} value The value to pretty-print
* @return {string} The pretty-printed value
*/
this.pp = options.pp || function() {};
};
contains: function(haystack, needle, customTesters) { /**
customTesters = customTesters || []; * Determines whether `haystack` contains `needle`, using the same comparison
* logic as {@link MatchersUtil#equals}.
if (j$.isSet(haystack)) { * @function
return haystack.has(needle); * @name MatchersUtil#contains
} * @param {*} haystack The collection to search
* @param {*} needle The value to search for
if ((Object.prototype.toString.apply(haystack) === '[object Array]') || * @param [customTesters] An array of custom equality testers
(!!haystack && !haystack.indexOf)) * @returns {boolean} True if `needle` was found in `haystack`
{ */
for (var i = 0; i < haystack.length; i++) { MatchersUtil.prototype.contains = function(haystack, needle, customTesters) {
if (equals(haystack[i], needle, customTesters)) { if (j$.isSet(haystack)) {
return true; return haystack.has(needle);
}
}
return false;
}
return !!haystack && haystack.indexOf(needle) >= 0;
},
buildFailureMessage: function() {
var args = Array.prototype.slice.call(arguments, 0),
matcherName = args[0],
isNot = args[1],
actual = args[2],
expected = args.slice(3),
englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); });
var message = 'Expected ' +
j$.pp(actual) +
(isNot ? ' not ' : ' ') +
englishyPredicate;
if (expected.length > 0) {
for (var i = 0; i < expected.length; i++) {
if (i > 0) {
message += ',';
}
message += ' ' + j$.pp(expected[i]);
}
}
return message + '.';
} }
if ((Object.prototype.toString.apply(haystack) === '[object Array]') ||
(!!haystack && !haystack.indexOf))
{
for (var i = 0; i < haystack.length; i++) {
if (this.equals(haystack[i], needle, customTesters)) {
return true;
}
}
return false;
}
return !!haystack && haystack.indexOf(needle) >= 0;
};
MatchersUtil.prototype.buildFailureMessage = function() {
var self = this;
var args = Array.prototype.slice.call(arguments, 0),
matcherName = args[0],
isNot = args[1],
actual = args[2],
expected = args.slice(3),
englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); });
var message = 'Expected ' +
self.pp(actual) +
(isNot ? ' not ' : ' ') +
englishyPredicate;
if (expected.length > 0) {
for (var i = 0; i < expected.length; i++) {
if (i > 0) {
message += ',';
}
message += ' ' + self.pp(expected[i]);
}
}
return message + '.';
}; };
function isAsymmetric(obj) { function isAsymmetric(obj) {
return obj && j$.isA_('Function', obj.asymmetricMatch); return obj && j$.isA_('Function', obj.asymmetricMatch);
} }
function asymmetricDiff(a, b, aStack, bStack, customTesters, diffBuilder) { MatchersUtil.prototype.asymmetricDiff_ = function(a, b, aStack, bStack, customTesters, diffBuilder) {
if (j$.isFunction_(b.valuesForDiff_)) { if (j$.isFunction_(b.valuesForDiff_)) {
var values = b.valuesForDiff_(a); var values = b.valuesForDiff_(a);
eq(values.other, values.self, aStack, bStack, customTesters, diffBuilder); this.eq_(values.other, values.self, aStack, bStack, customTesters, diffBuilder);
} else { } else {
diffBuilder.record(a, b); diffBuilder.recordMismatch();
} }
} };
function asymmetricMatch(a, b, aStack, bStack, customTesters, diffBuilder) { MatchersUtil.prototype.asymmetricMatch_ = function(a, b, aStack, bStack, customTesters, diffBuilder) {
var asymmetricA = isAsymmetric(a), var asymmetricA = isAsymmetric(a),
asymmetricB = isAsymmetric(b), asymmetricB = isAsymmetric(b),
shim = j$.asymmetricEqualityTesterArgCompatShim(this, customTesters),
result; result;
if (asymmetricA && asymmetricB) { if (asymmetricA && asymmetricB) {
@@ -74,37 +102,56 @@ getJasmineRequireObj().matchersUtil = function(j$) {
} }
if (asymmetricA) { if (asymmetricA) {
result = a.asymmetricMatch(b, customTesters); result = a.asymmetricMatch(b, shim);
if (!result) { if (!result) {
// TODO: Do we want to build an asymmetric diff when the actual was an // TODO: Do we want to build an asymmetric diff when the actual was an
// asymmeteric equality tester? Might be confusing. // asymmeteric equality tester? Might be confusing.
diffBuilder.record(a, b); diffBuilder.recordMismatch();
} }
return result; return result;
} }
if (asymmetricB) { if (asymmetricB) {
result = b.asymmetricMatch(a, customTesters); result = b.asymmetricMatch(a, shim);
if (!result) { if (!result) {
asymmetricDiff(a, b, aStack, bStack, customTesters, diffBuilder); this.asymmetricDiff_(a, b, aStack, bStack, customTesters, diffBuilder);
} }
return result; return result;
} }
} };
function equals(a, b, customTesters, diffBuilder) { /**
customTesters = customTesters || []; * Determines whether two values are deeply equal to each other.
* @function
* @name MatchersUtil#equals
* @param {*} a The first value to compare
* @param {*} b The second value to compare
* @param [customTesters] An array of custom equality testers
* @returns {boolean} True if the values are equal
*/
MatchersUtil.prototype.equals = function(a, b, customTestersOrDiffBuilder, diffBuilderOrNothing) {
var customTesters, diffBuilder;
if (isDiffBuilder(customTestersOrDiffBuilder)) {
diffBuilder = customTestersOrDiffBuilder;
} else {
customTesters = customTestersOrDiffBuilder;
diffBuilder = diffBuilderOrNothing;
}
customTesters = customTesters || this.customTesters_;
diffBuilder = diffBuilder || j$.NullDiffBuilder(); diffBuilder = diffBuilder || j$.NullDiffBuilder();
diffBuilder.setRoots(a, b);
return eq(a, b, [], [], customTesters, diffBuilder); return this.eq_(a, b, [], [], customTesters, diffBuilder);
} };
// Equality function lovingly adapted from isEqual in // Equality function lovingly adapted from isEqual in
// [Underscore](http://underscorejs.org) // [Underscore](http://underscorejs.org)
function eq(a, b, aStack, bStack, customTesters, diffBuilder) { MatchersUtil.prototype.eq_ = function(a, b, aStack, bStack, customTesters, diffBuilder) {
var result = true, i; var result = true, self = this, i;
var asymmetricResult = asymmetricMatch(a, b, aStack, bStack, customTesters, diffBuilder); var asymmetricResult = this.asymmetricMatch_(a, b, aStack, bStack, customTesters, diffBuilder);
if (!j$.util.isUndefined(asymmetricResult)) { if (!j$.util.isUndefined(asymmetricResult)) {
return asymmetricResult; return asymmetricResult;
} }
@@ -113,7 +160,7 @@ getJasmineRequireObj().matchersUtil = function(j$) {
var customTesterResult = customTesters[i](a, b); var customTesterResult = customTesters[i](a, b);
if (!j$.util.isUndefined(customTesterResult)) { if (!j$.util.isUndefined(customTesterResult)) {
if (!customTesterResult) { if (!customTesterResult) {
diffBuilder.record(a, b); diffBuilder.recordMismatch();
} }
return customTesterResult; return customTesterResult;
} }
@@ -122,7 +169,7 @@ getJasmineRequireObj().matchersUtil = function(j$) {
if (a instanceof Error && b instanceof Error) { if (a instanceof Error && b instanceof Error) {
result = a.message == b.message; result = a.message == b.message;
if (!result) { if (!result) {
diffBuilder.record(a, b); diffBuilder.recordMismatch();
} }
return result; return result;
} }
@@ -132,7 +179,7 @@ getJasmineRequireObj().matchersUtil = function(j$) {
if (a === b) { if (a === b) {
result = a !== 0 || 1 / a == 1 / b; result = a !== 0 || 1 / a == 1 / b;
if (!result) { if (!result) {
diffBuilder.record(a, b); diffBuilder.recordMismatch();
} }
return result; return result;
} }
@@ -140,13 +187,13 @@ getJasmineRequireObj().matchersUtil = function(j$) {
if (a === null || b === null) { if (a === null || b === null) {
result = a === b; result = a === b;
if (!result) { if (!result) {
diffBuilder.record(a, b); diffBuilder.recordMismatch();
} }
return result; return result;
} }
var className = Object.prototype.toString.call(a); var className = Object.prototype.toString.call(a);
if (className != Object.prototype.toString.call(b)) { if (className != Object.prototype.toString.call(b)) {
diffBuilder.record(a, b); diffBuilder.recordMismatch();
return false; return false;
} }
switch (className) { switch (className) {
@@ -156,7 +203,7 @@ getJasmineRequireObj().matchersUtil = function(j$) {
// equivalent to `new String("5")`. // equivalent to `new String("5")`.
result = a == String(b); result = a == String(b);
if (!result) { if (!result) {
diffBuilder.record(a, b); diffBuilder.recordMismatch();
} }
return result; return result;
case '[object Number]': case '[object Number]':
@@ -164,7 +211,7 @@ getJasmineRequireObj().matchersUtil = function(j$) {
// other numeric values. // other numeric values.
result = a != +a ? b != +b : (a === 0 && b === 0 ? 1 / a == 1 / b : a == +b); result = a != +a ? b != +b : (a === 0 && b === 0 ? 1 / a == 1 / b : a == +b);
if (!result) { if (!result) {
diffBuilder.record(a, b); diffBuilder.recordMismatch();
} }
return result; return result;
case '[object Date]': case '[object Date]':
@@ -174,7 +221,7 @@ getJasmineRequireObj().matchersUtil = function(j$) {
// of `NaN` are not equivalent. // of `NaN` are not equivalent.
result = +a == +b; result = +a == +b;
if (!result) { if (!result) {
diffBuilder.record(a, b); diffBuilder.recordMismatch();
} }
return result; return result;
// RegExps are compared by their source patterns and flags. // RegExps are compared by their source patterns and flags.
@@ -185,7 +232,7 @@ getJasmineRequireObj().matchersUtil = function(j$) {
a.ignoreCase == b.ignoreCase; a.ignoreCase == b.ignoreCase;
} }
if (typeof a != 'object' || typeof b != 'object') { if (typeof a != 'object' || typeof b != 'object') {
diffBuilder.record(a, b); diffBuilder.recordMismatch();
return false; return false;
} }
@@ -195,12 +242,12 @@ getJasmineRequireObj().matchersUtil = function(j$) {
// At first try to use DOM3 method isEqualNode // At first try to use DOM3 method isEqualNode
result = a.isEqualNode(b); result = a.isEqualNode(b);
if (!result) { if (!result) {
diffBuilder.record(a, b); diffBuilder.recordMismatch();
} }
return result; return result;
} }
if (aIsDomNode || bIsDomNode) { if (aIsDomNode || bIsDomNode) {
diffBuilder.record(a, b); diffBuilder.recordMismatch();
return false; return false;
} }
@@ -230,7 +277,7 @@ getJasmineRequireObj().matchersUtil = function(j$) {
diffBuilder.withPath('length', function() { diffBuilder.withPath('length', function() {
if (aLength !== bLength) { if (aLength !== bLength) {
diffBuilder.record(aLength, bLength); diffBuilder.recordMismatch();
result = false; result = false;
} }
}); });
@@ -238,10 +285,10 @@ getJasmineRequireObj().matchersUtil = function(j$) {
for (i = 0; i < aLength || i < bLength; i++) { for (i = 0; i < aLength || i < bLength; i++) {
diffBuilder.withPath(i, function() { diffBuilder.withPath(i, function() {
if (i >= bLength) { if (i >= bLength) {
diffBuilder.record(a[i], void 0, actualArrayIsLongerFormatter); diffBuilder.recordMismatch(actualArrayIsLongerFormatter.bind(null, self.pp));
result = false; result = false;
} else { } else {
result = eq(i < aLength ? a[i] : void 0, i < bLength ? b[i] : void 0, aStack, bStack, customTesters, diffBuilder) && result; result = self.eq_(i < aLength ? a[i] : void 0, i < bLength ? b[i] : void 0, aStack, bStack, customTesters, diffBuilder) && result;
} }
}); });
} }
@@ -250,7 +297,7 @@ getJasmineRequireObj().matchersUtil = function(j$) {
} }
} else if (j$.isMap(a) && j$.isMap(b)) { } else if (j$.isMap(a) && j$.isMap(b)) {
if (a.size != b.size) { if (a.size != b.size) {
diffBuilder.record(a, b); diffBuilder.recordMismatch();
return false; return false;
} }
@@ -282,22 +329,22 @@ getJasmineRequireObj().matchersUtil = function(j$) {
// otherwise explicitly look up the mapKey in the other Map since we want keys with unique // otherwise explicitly look up the mapKey in the other Map since we want keys with unique
// obj identity (that are otherwise equal) to not match. // obj identity (that are otherwise equal) to not match.
if (isAsymmetric(mapKey) || isAsymmetric(cmpKey) && if (isAsymmetric(mapKey) || isAsymmetric(cmpKey) &&
eq(mapKey, cmpKey, aStack, bStack, customTesters, j$.NullDiffBuilder())) { this.eq_(mapKey, cmpKey, aStack, bStack, customTesters, j$.NullDiffBuilder())) {
mapValueB = b.get(cmpKey); mapValueB = b.get(cmpKey);
} else { } else {
mapValueB = b.get(mapKey); mapValueB = b.get(mapKey);
} }
result = eq(mapValueA, mapValueB, aStack, bStack, customTesters, j$.NullDiffBuilder()); result = this.eq_(mapValueA, mapValueB, aStack, bStack, customTesters, j$.NullDiffBuilder());
} }
} }
if (!result) { if (!result) {
diffBuilder.record(a, b); diffBuilder.recordMismatch();
return false; return false;
} }
} else if (j$.isSet(a) && j$.isSet(b)) { } else if (j$.isSet(a) && j$.isSet(b)) {
if (a.size != b.size) { if (a.size != b.size) {
diffBuilder.record(a, b); diffBuilder.recordMismatch();
return false; return false;
} }
@@ -331,7 +378,7 @@ getJasmineRequireObj().matchersUtil = function(j$) {
otherValue = otherValues[l]; otherValue = otherValues[l];
prevStackSize = baseStack.length; prevStackSize = baseStack.length;
// compare by value equality // compare by value equality
found = eq(baseValue, otherValue, baseStack, otherStack, customTesters, j$.NullDiffBuilder()); found = this.eq_(baseValue, otherValue, baseStack, otherStack, customTesters, j$.NullDiffBuilder());
if (!found && prevStackSize !== baseStack.length) { if (!found && prevStackSize !== baseStack.length) {
baseStack.splice(prevStackSize); baseStack.splice(prevStackSize);
otherStack.splice(prevStackSize); otherStack.splice(prevStackSize);
@@ -342,7 +389,7 @@ getJasmineRequireObj().matchersUtil = function(j$) {
} }
if (!result) { if (!result) {
diffBuilder.record(a, b); diffBuilder.recordMismatch();
return false; return false;
} }
} else { } else {
@@ -355,7 +402,7 @@ getJasmineRequireObj().matchersUtil = function(j$) {
a instanceof aCtor && b instanceof bCtor && a instanceof aCtor && b instanceof bCtor &&
!(aCtor instanceof aCtor && bCtor instanceof bCtor)) { !(aCtor instanceof aCtor && bCtor instanceof bCtor)) {
diffBuilder.record(a, b, constructorsAreDifferentFormatter); diffBuilder.recordMismatch(constructorsAreDifferentFormatter.bind(null, this.pp));
return false; return false;
} }
} }
@@ -366,7 +413,7 @@ getJasmineRequireObj().matchersUtil = function(j$) {
// Ensure that both objects contain the same number of properties before comparing deep equality. // Ensure that both objects contain the same number of properties before comparing deep equality.
if (keys(b, className == '[object Array]').length !== size) { if (keys(b, className == '[object Array]').length !== size) {
diffBuilder.record(a, b, objectKeysAreDifferentFormatter); diffBuilder.recordMismatch(objectKeysAreDifferentFormatter.bind(null, this.pp));
return false; return false;
} }
@@ -374,13 +421,13 @@ getJasmineRequireObj().matchersUtil = function(j$) {
key = aKeys[i]; key = aKeys[i];
// Deep compare each member // Deep compare each member
if (!j$.util.has(b, key)) { if (!j$.util.has(b, key)) {
diffBuilder.record(a, b, objectKeysAreDifferentFormatter); diffBuilder.recordMismatch(objectKeysAreDifferentFormatter.bind(null, this.pp));
result = false; result = false;
continue; continue;
} }
diffBuilder.withPath(key, function() { diffBuilder.withPath(key, function() {
if(!eq(a[key], b[key], aStack, bStack, customTesters, diffBuilder)) { if(!self.eq_(a[key], b[key], aStack, bStack, customTesters, diffBuilder)) {
result = false; result = false;
} }
}); });
@@ -395,7 +442,7 @@ getJasmineRequireObj().matchersUtil = function(j$) {
bStack.pop(); bStack.pop();
return result; return result;
} };
function keys(obj, isArray) { function keys(obj, isArray) {
var allKeys = Object.keys ? Object.keys(obj) : var allKeys = Object.keys ? Object.keys(obj) :
@@ -431,11 +478,11 @@ getJasmineRequireObj().matchersUtil = function(j$) {
return typeof obj === 'function'; return typeof obj === 'function';
} }
function objectKeysAreDifferentFormatter(actual, expected, path) { function objectKeysAreDifferentFormatter(pp, actual, expected, path) {
var missingProperties = j$.util.objectDifference(expected, actual), var missingProperties = j$.util.objectDifference(expected, actual),
extraProperties = j$.util.objectDifference(actual, expected), extraProperties = j$.util.objectDifference(actual, expected),
missingPropertiesMessage = formatKeyValuePairs(missingProperties), missingPropertiesMessage = formatKeyValuePairs(pp, missingProperties),
extraPropertiesMessage = formatKeyValuePairs(extraProperties), extraPropertiesMessage = formatKeyValuePairs(pp, extraProperties),
messages = []; messages = [];
if (!path.depth()) { if (!path.depth()) {
@@ -453,7 +500,7 @@ getJasmineRequireObj().matchersUtil = function(j$) {
return messages.join('\n'); return messages.join('\n');
} }
function constructorsAreDifferentFormatter(actual, expected, path) { function constructorsAreDifferentFormatter(pp, actual, expected, path) {
if (!path.depth()) { if (!path.depth()) {
path = 'object'; path = 'object';
} }
@@ -461,21 +508,27 @@ getJasmineRequireObj().matchersUtil = function(j$) {
return 'Expected ' + return 'Expected ' +
path + ' to be a kind of ' + path + ' to be a kind of ' +
j$.fnNameFor(expected.constructor) + j$.fnNameFor(expected.constructor) +
', but was ' + j$.pp(actual) + '.'; ', but was ' + pp(actual) + '.';
} }
function actualArrayIsLongerFormatter(actual, expected, path) { function actualArrayIsLongerFormatter(pp, actual, expected, path) {
return 'Unexpected ' + return 'Unexpected ' +
path + (path.depth() ? ' = ' : '') + path + (path.depth() ? ' = ' : '') +
j$.pp(actual) + pp(actual) +
' in array.'; ' in array.';
} }
function formatKeyValuePairs(obj) { function formatKeyValuePairs(pp, obj) {
var formatted = ''; var formatted = '';
for (var key in obj) { for (var key in obj) {
formatted += '\n ' + key + ': ' + j$.pp(obj[key]); formatted += '\n ' + key + ': ' + pp(obj[key]);
} }
return formatted; return formatted;
} }
function isDiffBuilder(obj) {
return obj && typeof obj.recordMismatch === 'function';
}
return MatchersUtil;
}; };

View File

@@ -8,7 +8,7 @@ getJasmineRequireObj().toBe = function(j$) {
* @example * @example
* expect(thing).toBe(realThing); * expect(thing).toBe(realThing);
*/ */
function toBe(util) { function toBe(matchersUtil) {
var tip = ' Tip: To check for deep equality, use .toEqual() instead of .toBe().'; var tip = ' Tip: To check for deep equality, use .toEqual() instead of .toBe().';
return { return {
@@ -18,7 +18,7 @@ getJasmineRequireObj().toBe = function(j$) {
}; };
if (typeof expected === 'object') { if (typeof expected === 'object') {
result.message = util.buildFailureMessage('toBe', result.pass, actual, expected) + tip; result.message = matchersUtil.buildFailureMessage('toBe', result.pass, actual, expected) + tip;
} }
return result; return result;

View File

@@ -12,11 +12,11 @@ getJasmineRequireObj().toBeInstanceOf = function(j$) {
* expect(3).toBeInstanceOf(Number); * expect(3).toBeInstanceOf(Number);
* expect(new Error()).toBeInstanceOf(Error); * expect(new Error()).toBeInstanceOf(Error);
*/ */
function toBeInstanceOf(util, customEqualityTesters) { function toBeInstanceOf(matchersUtil) {
return { return {
compare: function(actual, expected) { compare: function(actual, expected) {
var actualType = actual && actual.constructor ? j$.fnNameFor(actual.constructor) : j$.pp(actual), var actualType = actual && actual.constructor ? j$.fnNameFor(actual.constructor) : matchersUtil.pp(actual),
expectedType = expected ? j$.fnNameFor(expected) : j$.pp(expected), expectedType = expected ? j$.fnNameFor(expected) : matchersUtil.pp(expected),
expectedMatcher, expectedMatcher,
pass; pass;

View File

@@ -7,7 +7,7 @@ getJasmineRequireObj().toBeNaN = function(j$) {
* @example * @example
* expect(thing).toBeNaN(); * expect(thing).toBeNaN();
*/ */
function toBeNaN() { function toBeNaN(matchersUtil) {
return { return {
compare: function(actual) { compare: function(actual) {
var result = { var result = {
@@ -17,7 +17,7 @@ getJasmineRequireObj().toBeNaN = function(j$) {
if (result.pass) { if (result.pass) {
result.message = 'Expected actual not to be NaN.'; result.message = 'Expected actual not to be NaN.';
} else { } else {
result.message = function() { return 'Expected ' + j$.pp(actual) + ' to be NaN.'; }; result.message = function() { return 'Expected ' + matchersUtil.pp(actual) + ' to be NaN.'; };
} }
return result; return result;

View File

@@ -7,7 +7,7 @@ getJasmineRequireObj().toBeNegativeInfinity = function(j$) {
* @example * @example
* expect(thing).toBeNegativeInfinity(); * expect(thing).toBeNegativeInfinity();
*/ */
function toBeNegativeInfinity() { function toBeNegativeInfinity(matchersUtil) {
return { return {
compare: function(actual) { compare: function(actual) {
var result = { var result = {
@@ -17,7 +17,7 @@ getJasmineRequireObj().toBeNegativeInfinity = function(j$) {
if (result.pass) { if (result.pass) {
result.message = 'Expected actual not to be -Infinity.'; result.message = 'Expected actual not to be -Infinity.';
} else { } else {
result.message = function() { return 'Expected ' + j$.pp(actual) + ' to be -Infinity.'; }; result.message = function() { return 'Expected ' + matchersUtil.pp(actual) + ' to be -Infinity.'; };
} }
return result; return result;

View File

@@ -7,7 +7,7 @@ getJasmineRequireObj().toBePositiveInfinity = function(j$) {
* @example * @example
* expect(thing).toBePositiveInfinity(); * expect(thing).toBePositiveInfinity();
*/ */
function toBePositiveInfinity() { function toBePositiveInfinity(matchersUtil) {
return { return {
compare: function(actual) { compare: function(actual) {
var result = { var result = {
@@ -17,7 +17,7 @@ getJasmineRequireObj().toBePositiveInfinity = function(j$) {
if (result.pass) { if (result.pass) {
result.message = 'Expected actual not to be Infinity.'; result.message = 'Expected actual not to be Infinity.';
} else { } else {
result.message = function() { return 'Expected ' + j$.pp(actual) + ' to be Infinity.'; }; result.message = function() { return 'Expected ' + matchersUtil.pp(actual) + ' to be Infinity.'; };
} }
return result; return result;

View File

@@ -9,14 +9,12 @@ getJasmineRequireObj().toContain = function() {
* expect(array).toContain(anElement); * expect(array).toContain(anElement);
* expect(string).toContain(substring); * expect(string).toContain(substring);
*/ */
function toContain(util, customEqualityTesters) { function toContain(matchersUtil) {
customEqualityTesters = customEqualityTesters || [];
return { return {
compare: function(actual, expected) { compare: function(actual, expected) {
return { return {
pass: util.contains(actual, expected, customEqualityTesters) pass: matchersUtil.contains(actual, expected)
}; };
} }
}; };

View File

@@ -8,17 +8,15 @@ getJasmineRequireObj().toEqual = function(j$) {
* @example * @example
* expect(bigObject).toEqual({"foo": ['bar', 'baz']}); * expect(bigObject).toEqual({"foo": ['bar', 'baz']});
*/ */
function toEqual(util, customEqualityTesters) { function toEqual(matchersUtil) {
customEqualityTesters = customEqualityTesters || [];
return { return {
compare: function(actual, expected) { compare: function(actual, expected) {
var result = { var result = {
pass: false pass: false
}, },
diffBuilder = j$.DiffBuilder(); diffBuilder = j$.DiffBuilder({prettyPrinter: matchersUtil.pp});
result.pass = util.equals(actual, expected, customEqualityTesters, diffBuilder); result.pass = matchersUtil.equals(actual, expected, diffBuilder);
// TODO: only set error message if test fails // TODO: only set error message if test fails
result.message = diffBuilder.getMessage(); result.message = diffBuilder.getMessage();

View File

@@ -11,13 +11,13 @@ getJasmineRequireObj().toHaveBeenCalled = function(j$) {
* expect(mySpy).toHaveBeenCalled(); * expect(mySpy).toHaveBeenCalled();
* expect(mySpy).not.toHaveBeenCalled(); * expect(mySpy).not.toHaveBeenCalled();
*/ */
function toHaveBeenCalled() { function toHaveBeenCalled(matchersUtil) {
return { return {
compare: function(actual) { compare: function(actual) {
var result = {}; var result = {};
if (!j$.isSpy(actual)) { if (!j$.isSpy(actual)) {
throw new Error(getErrorMsg('Expected a spy, but got ' + j$.pp(actual) + '.')); throw new Error(getErrorMsg('Expected a spy, but got ' + matchersUtil.pp(actual) + '.'));
} }
if (arguments.length > 1) { if (arguments.length > 1) {

View File

@@ -11,14 +11,14 @@ getJasmineRequireObj().toHaveBeenCalledBefore = function(j$) {
* @example * @example
* expect(mySpy).toHaveBeenCalledBefore(otherSpy); * expect(mySpy).toHaveBeenCalledBefore(otherSpy);
*/ */
function toHaveBeenCalledBefore() { function toHaveBeenCalledBefore(matchersUtil) {
return { return {
compare: function(firstSpy, latterSpy) { compare: function(firstSpy, latterSpy) {
if (!j$.isSpy(firstSpy)) { if (!j$.isSpy(firstSpy)) {
throw new Error(getErrorMsg('Expected a spy, but got ' + j$.pp(firstSpy) + '.')); throw new Error(getErrorMsg('Expected a spy, but got ' + matchersUtil.pp(firstSpy) + '.'));
} }
if (!j$.isSpy(latterSpy)) { if (!j$.isSpy(latterSpy)) {
throw new Error(getErrorMsg('Expected a spy, but got ' + j$.pp(latterSpy) + '.')); throw new Error(getErrorMsg('Expected a spy, but got ' + matchersUtil.pp(latterSpy) + '.'));
} }
var result = { pass: false }; var result = { pass: false };

View File

@@ -11,11 +11,11 @@ getJasmineRequireObj().toHaveBeenCalledTimes = function(j$) {
* @example * @example
* expect(mySpy).toHaveBeenCalledTimes(3); * expect(mySpy).toHaveBeenCalledTimes(3);
*/ */
function toHaveBeenCalledTimes() { function toHaveBeenCalledTimes(matchersUtil) {
return { return {
compare: function(actual, expected) { compare: function(actual, expected) {
if (!j$.isSpy(actual)) { if (!j$.isSpy(actual)) {
throw new Error(getErrorMsg('Expected a spy, but got ' + j$.pp(actual) + '.')); throw new Error(getErrorMsg('Expected a spy, but got ' + matchersUtil.pp(actual) + '.'));
} }
var args = Array.prototype.slice.call(arguments, 0), var args = Array.prototype.slice.call(arguments, 0),

View File

@@ -11,7 +11,7 @@ getJasmineRequireObj().toHaveBeenCalledWith = function(j$) {
* @example * @example
* expect(mySpy).toHaveBeenCalledWith('foo', 'bar', 2); * expect(mySpy).toHaveBeenCalledWith('foo', 'bar', 2);
*/ */
function toHaveBeenCalledWith(util, customEqualityTesters) { function toHaveBeenCalledWith(matchersUtil) {
return { return {
compare: function() { compare: function() {
var args = Array.prototype.slice.call(arguments, 0), var args = Array.prototype.slice.call(arguments, 0),
@@ -20,40 +20,40 @@ getJasmineRequireObj().toHaveBeenCalledWith = function(j$) {
result = { pass: false }; result = { pass: false };
if (!j$.isSpy(actual)) { if (!j$.isSpy(actual)) {
throw new Error(getErrorMsg('Expected a spy, but got ' + j$.pp(actual) + '.')); throw new Error(getErrorMsg('Expected a spy, but got ' + matchersUtil.pp(actual) + '.'));
} }
if (!actual.calls.any()) { if (!actual.calls.any()) {
result.message = function() { result.message = function() {
return 'Expected spy ' + actual.and.identity + ' to have been called with:\n' + return 'Expected spy ' + actual.and.identity + ' to have been called with:\n' +
' ' + j$.pp(expectedArgs) + ' ' + matchersUtil.pp(expectedArgs) +
'\nbut it was never called.'; '\nbut it was never called.';
}; };
return result; return result;
} }
if (util.contains(actual.calls.allArgs(), expectedArgs, customEqualityTesters)) { if (matchersUtil.contains(actual.calls.allArgs(), expectedArgs)) {
result.pass = true; result.pass = true;
result.message = function() { result.message = function() {
return 'Expected spy ' + actual.and.identity + ' not to have been called with:\n' + return 'Expected spy ' + actual.and.identity + ' not to have been called with:\n' +
' ' + j$.pp(expectedArgs) + ' ' + matchersUtil.pp(expectedArgs) +
'\nbut it was.'; '\nbut it was.';
}; };
} else { } else {
result.message = function() { result.message = function() {
var prettyPrintedCalls = actual.calls.allArgs().map(function(argsForCall) { var prettyPrintedCalls = actual.calls.allArgs().map(function(argsForCall) {
return ' ' + j$.pp(argsForCall); return ' ' + matchersUtil.pp(argsForCall);
}); });
var diffs = actual.calls.allArgs().map(function(argsForCall, callIx) { var diffs = actual.calls.allArgs().map(function(argsForCall, callIx) {
var diffBuilder = new j$.DiffBuilder(); var diffBuilder = new j$.DiffBuilder();
util.equals(argsForCall, expectedArgs, customEqualityTesters, diffBuilder); matchersUtil.equals(argsForCall, expectedArgs, diffBuilder);
return 'Call ' + callIx + ':\n' + return 'Call ' + callIx + ':\n' +
diffBuilder.getMessage().replace(/^/mg, ' '); diffBuilder.getMessage().replace(/^/mg, ' ');
}); });
return 'Expected spy ' + actual.and.identity + ' to have been called with:\n' + return 'Expected spy ' + actual.and.identity + ' to have been called with:\n' +
' ' + j$.pp(expectedArgs) + '\n' + '' + ' ' + matchersUtil.pp(expectedArgs) + '\n' + '' +
'but actual calls were:\n' + 'but actual calls were:\n' +
prettyPrintedCalls.join(',\n') + '.\n\n' + prettyPrintedCalls.join(',\n') + '.\n\n' +
diffs.join('\n'); diffs.join('\n');

View File

@@ -10,11 +10,11 @@ getJasmineRequireObj().toHaveClass = function(j$) {
* el.className = 'foo bar baz'; * el.className = 'foo bar baz';
* expect(el).toHaveClass('bar'); * expect(el).toHaveClass('bar');
*/ */
function toHaveClass(util, customEqualityTesters) { function toHaveClass(matchersUtil) {
return { return {
compare: function(actual, expected) { compare: function(actual, expected) {
if (!isElement(actual)) { if (!isElement(actual)) {
throw new Error(j$.pp(actual) + ' is not a DOM element'); throw new Error(matchersUtil.pp(actual) + ' is not a DOM element');
} }
return { return {

View File

@@ -12,7 +12,7 @@ getJasmineRequireObj().toThrow = function(j$) {
* expect(function() { return 'things'; }).toThrow('foo'); * expect(function() { return 'things'; }).toThrow('foo');
* expect(function() { return 'stuff'; }).toThrow(); * expect(function() { return 'stuff'; }).toThrow();
*/ */
function toThrow(util) { function toThrow(matchersUtil) {
return { return {
compare: function(actual, expected) { compare: function(actual, expected) {
var result = { pass: false }, var result = { pass: false },
@@ -37,16 +37,16 @@ getJasmineRequireObj().toThrow = function(j$) {
if (arguments.length == 1) { if (arguments.length == 1) {
result.pass = true; result.pass = true;
result.message = function() { return 'Expected function not to throw, but it threw ' + j$.pp(thrown) + '.'; }; result.message = function() { return 'Expected function not to throw, but it threw ' + matchersUtil.pp(thrown) + '.'; };
return result; return result;
} }
if (util.equals(thrown, expected)) { if (matchersUtil.equals(thrown, expected)) {
result.pass = true; result.pass = true;
result.message = function() { return 'Expected function not to throw ' + j$.pp(expected) + '.'; }; result.message = function() { return 'Expected function not to throw ' + matchersUtil.pp(expected) + '.'; };
} else { } else {
result.message = function() { return 'Expected function to throw ' + j$.pp(expected) + ', but it threw ' + j$.pp(thrown) + '.'; }; result.message = function() { return 'Expected function to throw ' + matchersUtil.pp(expected) + ', but it threw ' + matchersUtil.pp(thrown) + '.'; };
} }
return result; return result;

View File

@@ -16,7 +16,7 @@ getJasmineRequireObj().toThrowError = function(j$) {
* expect(function() { return 'other'; }).toThrowError(/foo/); * expect(function() { return 'other'; }).toThrowError(/foo/);
* expect(function() { return 'other'; }).toThrowError(); * expect(function() { return 'other'; }).toThrowError();
*/ */
function toThrowError () { function toThrowError(matchersUtil) {
return { return {
compare: function(actual) { compare: function(actual) {
var errorMatcher = getMatcher.apply(null, arguments), var errorMatcher = getMatcher.apply(null, arguments),
@@ -34,7 +34,7 @@ getJasmineRequireObj().toThrowError = function(j$) {
} }
if (!j$.isError_(thrown)) { if (!j$.isError_(thrown)) {
return fail(function() { return 'Expected function to throw an Error, but it threw ' + j$.pp(thrown) + '.'; }); return fail(function() { return 'Expected function to throw an Error, but it threw ' + matchersUtil.pp(thrown) + '.'; });
} }
return errorMatcher.match(thrown); return errorMatcher.match(thrown);
@@ -97,7 +97,7 @@ getJasmineRequireObj().toThrowError = function(j$) {
thrownMessage = ''; thrownMessage = '';
if (expected) { if (expected) {
thrownMessage = ' with message ' + j$.pp(thrown.message); thrownMessage = ' with message ' + matchersUtil.pp(thrown.message);
} }
return thrownName + thrownMessage; return thrownName + thrownMessage;
@@ -107,9 +107,9 @@ getJasmineRequireObj().toThrowError = function(j$) {
if (expected === null) { if (expected === null) {
return ''; return '';
} else if (expected instanceof RegExp) { } else if (expected instanceof RegExp) {
return ' with a message matching ' + j$.pp(expected); return ' with a message matching ' + matchersUtil.pp(expected);
} else { } else {
return ' with message ' + j$.pp(expected); return ' with message ' + matchersUtil.pp(expected);
} }
} }

View File

@@ -10,7 +10,7 @@ getJasmineRequireObj().toThrowMatching = function(j$) {
* @example * @example
* expect(function() { throw new Error('nope'); }).toThrowMatching(function(thrown) { return thrown.message === 'nope'; }); * expect(function() { throw new Error('nope'); }).toThrowMatching(function(thrown) { return thrown.message === 'nope'; });
*/ */
function toThrowMatching() { function toThrowMatching(matchersUtil) {
return { return {
compare: function(actual, predicate) { compare: function(actual, predicate) {
var thrown; var thrown;
@@ -40,14 +40,14 @@ getJasmineRequireObj().toThrowMatching = function(j$) {
} }
} }
}; };
}
function thrownDescription(thrown) { function thrownDescription(thrown) {
if (thrown && thrown.constructor) { if (thrown && thrown.constructor) {
return j$.fnNameFor(thrown.constructor) + ' with message ' + return j$.fnNameFor(thrown.constructor) + ' with message ' +
j$.pp(thrown.message); matchersUtil.pp(thrown.message);
} else { } else {
return j$.pp(thrown); return matchersUtil.pp(thrown);
}
} }
} }

View File

@@ -51,13 +51,22 @@ var getJasmineRequireObj = (function(jasmineGlobal) {
j$.buildExpectationResult = jRequire.buildExpectationResult(j$); j$.buildExpectationResult = jRequire.buildExpectationResult(j$);
j$.noopTimer = jRequire.noopTimer(); j$.noopTimer = jRequire.noopTimer();
j$.JsApiReporter = jRequire.JsApiReporter(j$); j$.JsApiReporter = jRequire.JsApiReporter(j$);
j$.matchersUtil = jRequire.matchersUtil(j$); j$.asymmetricEqualityTesterArgCompatShim = jRequire.asymmetricEqualityTesterArgCompatShim(
j$
);
j$.makePrettyPrinter = jRequire.makePrettyPrinter(j$);
j$.pp = j$.makePrettyPrinter();
j$.MatchersUtil = jRequire.MatchersUtil(j$);
j$.matchersUtil = new j$.MatchersUtil({
customTesters: [],
pp: j$.pp
});
j$.ObjectContaining = jRequire.ObjectContaining(j$); j$.ObjectContaining = jRequire.ObjectContaining(j$);
j$.ArrayContaining = jRequire.ArrayContaining(j$); j$.ArrayContaining = jRequire.ArrayContaining(j$);
j$.ArrayWithExactContents = jRequire.ArrayWithExactContents(j$); j$.ArrayWithExactContents = jRequire.ArrayWithExactContents(j$);
j$.MapContaining = jRequire.MapContaining(j$); j$.MapContaining = jRequire.MapContaining(j$);
j$.SetContaining = jRequire.SetContaining(j$); j$.SetContaining = jRequire.SetContaining(j$);
j$.pp = jRequire.pp(j$);
j$.QueueRunner = jRequire.QueueRunner(j$); j$.QueueRunner = jRequire.QueueRunner(j$);
j$.ReportDispatcher = jRequire.ReportDispatcher(j$); j$.ReportDispatcher = jRequire.ReportDispatcher(j$);
j$.Spec = jRequire.Spec(j$); j$.Spec = jRequire.Spec(j$);
@@ -75,6 +84,7 @@ var getJasmineRequireObj = (function(jasmineGlobal) {
j$.DiffBuilder = jRequire.DiffBuilder(j$); j$.DiffBuilder = jRequire.DiffBuilder(j$);
j$.NullDiffBuilder = jRequire.NullDiffBuilder(j$); j$.NullDiffBuilder = jRequire.NullDiffBuilder(j$);
j$.ObjectPath = jRequire.ObjectPath(j$); j$.ObjectPath = jRequire.ObjectPath(j$);
j$.MismatchTree = jRequire.MismatchTree(j$);
j$.GlobalErrors = jRequire.GlobalErrors(j$); j$.GlobalErrors = jRequire.GlobalErrors(j$);
j$.Truthy = jRequire.Truthy(j$); j$.Truthy = jRequire.Truthy(j$);

View File

@@ -319,6 +319,20 @@ getJasmineRequireObj().interface = function(jasmine, env) {
return env.addAsyncMatchers(matchers); return env.addAsyncMatchers(matchers);
}; };
/**
* Add a custom object formatter for the current scope of specs.
*
* _Note:_ This is only callable from within a {@link beforeEach}, {@link it}, or {@link beforeAll}.
* @name jasmine.addCustomObjectFormatter
* @since 3.6.0
* @function
* @param {Function} formatter - A function which takes a value to format and returns a string if it knows how to format it, and `undefined` otherwise.
* @see custom_object_formatter
*/
jasmine.addCustomObjectFormatter = function(formatter) {
return env.addCustomObjectFormatter(formatter);
};
/** /**
* Get the currently booted mock {Clock} for this Jasmine environment. * Get the currently booted mock {Clock} for this Jasmine environment.
* @name jasmine.clock * @name jasmine.clock