Manage spys/matchers/custom equalities for beforeAll

- Refactor expectations to take list of matchers
- Add spyRegistry to manage runnables' spies
- Add clone util

[#66789174]
This commit is contained in:
Christopher Amavisca, Greg Cobb and Sheel Choksi
2014-03-05 10:28:37 -08:00
parent 52026fb0f7
commit 752a36d3ff
12 changed files with 441 additions and 272 deletions

View File

@@ -5,68 +5,6 @@ describe("Env", function() {
env = new j$.Env();
});
it('removes all spies when env is executed', function(done) {
var originalFoo = function() {},
testObj = {
foo: originalFoo
},
firstSpec = jasmine.createSpy('firstSpec').and.callFake(function() {
env.spyOn(testObj, 'foo');
}),
secondSpec = jasmine.createSpy('secondSpec').and.callFake(function() {
expect(testObj.foo).toBe(originalFoo);
});
env.describe('test suite', function() {
env.it('spec 0', firstSpec);
env.it('spec 1', secondSpec);
});
var assertions = function() {
expect(firstSpec).toHaveBeenCalled();
expect(secondSpec).toHaveBeenCalled();
done();
};
env.addReporter({ jasmineDone: assertions });
env.execute();
});
describe("#spyOn", function() {
it("checks for the existence of the object", function() {
expect(function() {
env.spyOn(void 0, 'pants');
}).toThrowError(/could not find an object/);
});
it("checks for the existence of the method", function() {
var subject = {};
expect(function() {
env.spyOn(subject, 'pants');
}).toThrowError(/method does not exist/);
});
it("checks if it has already been spied upon", function() {
var subject = { spiedFunc: function() {} };
env.spyOn(subject, 'spiedFunc');
expect(function() {
env.spyOn(subject, 'spiedFunc');
}).toThrowError(/has already been spied upon/);
});
it("overrides the method on the object and returns the spy", function() {
var originalFunctionWasCalled = false;
var subject = { spiedFunc: function() { originalFunctionWasCalled = true; } };
var spy = env.spyOn(subject, 'spiedFunc');
expect(subject.spiedFunc).toEqual(spy);
});
});
describe("#pending", function() {
it("throws the Pending Spec exception", function() {
expect(function() {
@@ -82,4 +20,3 @@ describe("Env", function() {
});
});
});

View File

@@ -1,14 +1,14 @@
describe("Expectation", function() {
it(".addMatchers makes matchers available to any expectation", function() {
it("makes custom matchers available to this expectation", function() {
var matchers = {
toFoo: function() {},
toBar: function() {}
},
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({});
expectation = new j$.Expectation({
customMatchers: matchers
});
expect(expectation.toFoo).toBeDefined();
expect(expectation.toBar).toBeDefined();
@@ -27,25 +27,6 @@ describe("Expectation", function() {
expect(expectation.toQuux).toBeDefined();
});
it(".resetMatchers should keep only core matchers", function() {
var matchers = {
toFoo: function() {}
},
coreMatchers = {
toQuux: function() {}
},
expectation;
j$.Expectation.addCoreMatchers(coreMatchers);
j$.Expectation.addMatchers(matchers);
j$.Expectation.resetMatchers();
expectation = new j$.Expectation({});
expect(expectation.toQuux).toBeDefined();
expect(expectation.toFoo).toBeUndefined();
});
it("Factory builds an expectation/negative expectation", function() {
var builtExpectation = j$.Expectation.Factory();
@@ -65,10 +46,9 @@ describe("Expectation", function() {
addExpectationResult = jasmine.createSpy("addExpectationResult"),
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({
util: util,
customMatchers: matchers,
customEqualityTesters: customEqualityTesters,
actual: "an actual",
addExpectationResult: addExpectationResult
@@ -94,10 +74,9 @@ describe("Expectation", function() {
addExpectationResult = jasmine.createSpy("addExpectationResult"),
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({
util: util,
customMatchers: matchers,
actual: "an actual",
addExpectationResult: addExpectationResult
});
@@ -121,10 +100,8 @@ describe("Expectation", function() {
addExpectationResult = jasmine.createSpy("addExpectationResult"),
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({
matchers: matchers,
customMatchers: matchers,
util: util,
actual: "an actual",
addExpectationResult: addExpectationResult
@@ -155,10 +132,8 @@ describe("Expectation", function() {
addExpectationResult = jasmine.createSpy("addExpectationResult"),
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({
matchers: matchers,
customMatchers: matchers,
util: util,
actual: "an actual",
addExpectationResult: addExpectationResult
@@ -191,10 +166,9 @@ describe("Expectation", function() {
addExpectationResult = jasmine.createSpy("addExpectationResult"),
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({
actual: "an actual",
customMatchers: matchers,
addExpectationResult: addExpectationResult
});
@@ -225,10 +199,8 @@ describe("Expectation", function() {
addExpectationResult = jasmine.createSpy("addExpectationResult"),
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({
matchers: matchers,
customMatchers: matchers,
actual: "an actual",
addExpectationResult: addExpectationResult
});
@@ -259,10 +231,8 @@ describe("Expectation", function() {
actual = "an actual",
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({
matchers: matchers,
customMatchers: matchers,
actual: "an actual",
addExpectationResult: addExpectationResult,
isNot: true
@@ -294,10 +264,8 @@ describe("Expectation", function() {
actual = "an actual",
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({
matchers: matchers,
customMatchers: matchers,
actual: "an actual",
util: util,
addExpectationResult: addExpectationResult,
@@ -332,10 +300,8 @@ describe("Expectation", function() {
actual = "an actual",
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({
matchers: matchers,
customMatchers: matchers,
actual: "an actual",
addExpectationResult: addExpectationResult,
isNot: true
@@ -365,10 +331,8 @@ describe("Expectation", function() {
actual = "an actual",
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({
matchers: matchers,
customMatchers: matchers,
actual: "an actual",
addExpectationResult: addExpectationResult,
isNot: true
@@ -403,10 +367,8 @@ describe("Expectation", function() {
actual = "an actual",
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({
matchers: matchers,
customMatchers: matchers,
actual: "an actual",
addExpectationResult: addExpectationResult,
isNot: true

View File

@@ -109,7 +109,9 @@ describe("j$.pp", function () {
},
env = new j$.Env();
env.spyOn(TestObject, 'someFunction');
var spyRegistry = new j$.SpyRegistry({currentSpies: function() {return [];}});
spyRegistry.spyOn(TestObject, 'someFunction');
expect(j$.pp(TestObject.someFunction)).toEqual("spy on someFunction");
expect(j$.pp(j$.createSpy("something"))).toEqual("spy on something");
@@ -132,4 +134,3 @@ describe("j$.pp", function () {
expect(j$.pp(obj)).toEqual("{ foo : 'bar' }");
});
});

View File

@@ -0,0 +1,55 @@
describe("SpyRegistry", function() {
describe("#spyOn", function() {
it("checks for the existence of the object", function() {
var spyRegistry = new j$.SpyRegistry();
expect(function() {
spyRegistry.spyOn(void 0, 'pants');
}).toThrowError(/could not find an object/);
});
it("checks for the existence of the method", function() {
var spyRegistry = new j$.SpyRegistry(),
subject = {};
expect(function() {
spyRegistry.spyOn(subject, 'pants');
}).toThrowError(/method does not exist/);
});
it("checks if it has already been spied upon", function() {
var spies = [],
spyRegistry = new j$.SpyRegistry({currentSpies: function() { return spies; }}),
subject = { spiedFunc: function() {} };
spyRegistry.spyOn(subject, 'spiedFunc');
expect(function() {
spyRegistry.spyOn(subject, 'spiedFunc');
}).toThrowError(/has already been spied upon/);
});
it("overrides the method on the object and returns the spy", function() {
var originalFunctionWasCalled = false,
spyRegistry = new j$.SpyRegistry(),
subject = { spiedFunc: function() { originalFunctionWasCalled = true; } };
var spy = spyRegistry.spyOn(subject, 'spiedFunc');
expect(subject.spiedFunc).toEqual(spy);
});
});
describe("#clearSpies", function() {
it("restores the original functions on the spied-upon objects", function() {
var spies = [],
spyRegistry = new j$.SpyRegistry({currentSpies: function() { return spies; }}),
originalFunction = function() {},
subject = { spiedFunc: originalFunction };
spyRegistry.spyOn(subject, 'spiedFunc');
spyRegistry.clearSpies();
expect(subject.spiedFunc).toBe(originalFunction);
});
});
});

View File

@@ -38,13 +38,13 @@ describe("Custom Matchers (Integration)", function() {
});
it("passes the spec if the custom matcher passes", function(done) {
env.addMatchers({
toBeReal: function() {
return { compare: function() { return { pass: true }; } };
}
});
env.it("spec using custom matcher", function() {
env.addMatchers({
toBeReal: function() {
return { compare: function() { return { pass: true }; } };
}
});
env.expect(true).toBeReal();
});
@@ -57,16 +57,16 @@ describe("Custom Matchers (Integration)", function() {
});
it("uses the negative compare function for a negative comparison, if provided", function(done) {
env.addMatchers({
toBeReal: function() {
return {
compare: function() { return { pass: true }; },
negativeCompare: function() { return { pass: true }; }
};
}
});
env.it("spec with custom negative comparison matcher", function() {
env.addMatchers({
toBeReal: function() {
return {
compare: function() { return { pass: true }; },
negativeCompare: function() { return { pass: true }; }
};
}
});
env.expect(true).not.toBeReal();
});
@@ -79,17 +79,17 @@ describe("Custom Matchers (Integration)", function() {
});
it("generates messages with the same rules as built in matchers absent a custom message", function(done) {
env.addMatchers({
toBeReal: function() {
return {
compare: function() {
return { pass: false };
env.it('spec with an expectation', function() {
env.addMatchers({
toBeReal: function() {
return {
compare: function() {
return { pass: false };
}
}
}
}
});
});
env.it('spec with an expectation', function() {
env.expect("a").toBeReal();
});
@@ -103,13 +103,14 @@ describe("Custom Matchers (Integration)", function() {
it("passes the expected and actual arguments to the comparison function", function(done) {
var argumentSpy = jasmine.createSpy("argument spy").and.returnValue({ pass: true });
env.addMatchers({
toBeReal: function() {
return { compare: argumentSpy };
}
});
env.it('spec with an expectation', function () {
env.addMatchers({
toBeReal: function() {
return { compare: argumentSpy };
}
});
env.expect(true).toBeReal();
env.expect(true).toBeReal("arg");
env.expect(true).toBeReal("arg1", "arg2");
@@ -130,12 +131,13 @@ describe("Custom Matchers (Integration)", function() {
argumentSpy = jasmine.createSpy("argument spy").and.returnValue(matcherFactory),
customEqualityFn = function() { return true; };
env.addCustomEqualityTester(customEqualityFn);
env.addMatchers({
toBeReal: argumentSpy
});
env.it("spec with expectation", function() {
env.addCustomEqualityTester(customEqualityFn);
env.addMatchers({
toBeReal: argumentSpy
});
env.expect(true).toBeReal();
});

View File

@@ -326,30 +326,93 @@ describe("Env integration", function() {
env.execute([secondSuite.id, firstSpec.id]);
});
it("Functions can be spied on and have their calls tracked", function () {
it("Functions can be spied on and have their calls tracked", function (done) {
var env = new j$.Env();
var originalFunctionWasCalled = false;
var subject = { spiedFunc: function() { originalFunctionWasCalled = true; } };
var spy = env.spyOn(subject, 'spiedFunc');
env.addReporter({jasmineDone: done});
expect(subject.spiedFunc).toEqual(spy);
env.it("works with spies", function() {
var spy = env.spyOn(subject, 'spiedFunc');
expect(subject.spiedFunc.calls.any()).toEqual(false);
expect(subject.spiedFunc.calls.count()).toEqual(0);
expect(subject.spiedFunc).toEqual(spy);
expect(subject.spiedFunc.calls.any()).toEqual(false);
expect(subject.spiedFunc.calls.count()).toEqual(0);
subject.spiedFunc('foo');
subject.spiedFunc('foo');
expect(subject.spiedFunc.calls.any()).toEqual(true);
expect(subject.spiedFunc.calls.count()).toEqual(1);
expect(subject.spiedFunc.calls.mostRecent().args).toEqual(['foo']);
expect(subject.spiedFunc.calls.mostRecent().object).toEqual(subject);
expect(originalFunctionWasCalled).toEqual(false);
expect(subject.spiedFunc.calls.any()).toEqual(true);
expect(subject.spiedFunc.calls.count()).toEqual(1);
expect(subject.spiedFunc.calls.mostRecent().args).toEqual(['foo']);
expect(subject.spiedFunc.calls.mostRecent().object).toEqual(subject);
expect(originalFunctionWasCalled).toEqual(false);
subject.spiedFunc('bar');
expect(subject.spiedFunc.calls.count()).toEqual(2);
expect(subject.spiedFunc.calls.mostRecent().args).toEqual(['bar']);
subject.spiedFunc('bar');
expect(subject.spiedFunc.calls.count()).toEqual(2);
expect(subject.spiedFunc.calls.mostRecent().args).toEqual(['bar']);
});
env.execute();
});
it('removes all spies added in a spec after the spec is complete', function(done) {
var env = new j$.Env(),
originalFoo = function() {},
testObj = {
foo: originalFoo
},
firstSpec = jasmine.createSpy('firstSpec').and.callFake(function() {
env.spyOn(testObj, 'foo');
}),
secondSpec = jasmine.createSpy('secondSpec').and.callFake(function() {
expect(testObj.foo).toBe(originalFoo);
});
env.describe('test suite', function() {
env.it('spec 0', firstSpec);
env.it('spec 1', secondSpec);
});
var assertions = function() {
expect(firstSpec).toHaveBeenCalled();
expect(secondSpec).toHaveBeenCalled();
done();
};
env.addReporter({ jasmineDone: assertions });
env.execute();
});
it('removes all spies added in a suite after the suite is complete', function(done) {
var env = new j$.Env(),
originalFoo = function() {},
testObj = {
foo: originalFoo
};
env.describe('test suite', function() {
env.beforeAll(function() { env.spyOn(testObj, 'foo');})
env.it('spec 0', function() {
expect(j$.isSpy(testObj.foo)).toBe(true);
});
env.it('spec 1', function() {
expect(j$.isSpy(testObj.foo)).toBe(true);
});
});
env.describe('another suite', function() {
env.it('spec 2', function() {
expect(j$.isSpy(testObj.foo)).toBe(false);
});
});
env.addReporter({ jasmineDone: done });
env.execute();
});
it("Mock clock can be installed and used in tests", function(done) {
@@ -542,11 +605,7 @@ describe("Env integration", function() {
it("Custom equality testers should be per spec", function(done) {
var env = new j$.Env({global: { setTimeout: setTimeout }}),
reporter = jasmine.createSpyObj('fakeReporter', [
"jasmineStarted",
"jasmineDone",
"suiteStarted",
"suiteDone",
"specStarted",
"specDone"
]);
@@ -576,30 +635,42 @@ describe("Env integration", function() {
env.execute();
});
it("Custom matchers should be per spec", function() {
it("Custom equality testers should be per suite", function(done) {
var env = new j$.Env({global: { setTimeout: setTimeout }}),
matchers = {
toFoo: function() {}
},
reporter = jasmine.createSpyObj('fakeReporter', [
"jasmineStarted",
"jasmineDone",
"suiteStarted",
"suiteDone",
"specStarted",
"specDone"
]);
reporter.jasmineDone.and.callFake(function() {
var firstSpecResult = reporter.specDone.calls.first().args[0],
secondSpecResult = reporter.specDone.calls.argsFor(0)[0],
thirdSpecResult = reporter.specDone.calls.mostRecent().args[0];
expect(firstSpecResult.status).toEqual("passed");
expect(secondSpecResult.status).toEqual("passed");
expect(thirdSpecResult.status).toEqual("failed");
done();
});
env.addReporter(reporter);
env.describe("testing custom matchers", function() {
env.it("with a custom matcher", function() {
env.addMatchers(matchers);
expect(env.expect().toFoo).toBeDefined();
env.describe("testing custom equality testers", function() {
env.beforeAll(function() { env.addCustomEqualityTester(function(a, b) { return true; }); });
env.it("with a custom tester", function() {
env.expect("a").toEqual("b");
});
env.it("without a custom matcher", function() {
expect(env.expect().toFoo).toBeUndefined();
env.it("with the same custom tester", function() {
env.expect("a").toEqual("b");
});
});
env.describe("another suite", function() {
env.it("without the custom tester", function(){
env.expect("a").toEqual("b");
});
});
@@ -609,11 +680,7 @@ describe("Env integration", function() {
it("Custom equality testers for toContain should be per spec", function(done) {
var env = new j$.Env({global: { setTimeout: setTimeout }}),
reporter = jasmine.createSpyObj('fakeReporter', [
"jasmineStarted",
"jasmineDone",
"suiteStarted",
"suiteDone",
"specStarted",
"specDone"
]);
@@ -636,11 +703,104 @@ describe("Env integration", function() {
});
env.it("without a custom tester", function() {
env.expect("a").toContain("b");
env.expect(["a"]).toContain("b");
});
});
env.execute();
});
it("Custom equality testers for toContain should be per suite", function(done) {
var env = new j$.Env({global: { setTimeout: setTimeout }}),
reporter = jasmine.createSpyObj('fakeReporter', [
"jasmineDone",
"specDone"
]);
reporter.jasmineDone.and.callFake(function() {
var firstSpecResult = reporter.specDone.calls.first().args[0],
secondSpecResult = reporter.specDone.calls.argsFor(1)[0],
thirdSpecResult = reporter.specDone.calls.mostRecent().args[0];
expect(firstSpecResult.status).toEqual("passed");
expect(secondSpecResult.status).toEqual("passed");
expect(thirdSpecResult.status).toEqual("failed");
done();
});
env.addReporter(reporter);
env.describe("testing custom equality testers", function() {
env.beforeAll(function() { env.addCustomEqualityTester(function(a, b) { return true; })});
env.it("with a custom tester", function() {
env.expect(["a"]).toContain("b");
});
env.it("also with the custom tester", function() {
env.expect(["a"]).toContain("b");
});
});
env.describe("another suite", function() {
env.it("without the custom tester", function() {
env.expect(["a"]).toContain("b");
});
});
env.execute();
});
it("Custom matchers should be per spec", function(done) {
var env = new j$.Env({global: { setTimeout: setTimeout }}),
matchers = {
toFoo: function() {}
};
env.describe("testing custom matchers", function() {
env.it("with a custom matcher", function() {
env.addMatchers(matchers);
expect(env.expect().toFoo).toBeDefined();
});
env.it("without a custom matcher", function() {
expect(env.expect().toFoo).toBeUndefined();
});
});
env.addReporter({jasmineDone: done});
env.execute();
});
it("Custom matchers should be per suite", function(done) {
var env = new j$.Env({global: { setTimeout: setTimeout }}),
matchers = {
toFoo: function() {}
};
env.describe("testing custom matchers", function() {
env.beforeAll(function() { env.addMatchers(matchers); });
env.it("with a custom matcher", function() {
expect(env.expect().toFoo).toBeDefined();
});
env.it("with the same custom matcher", function() {
expect(env.expect().toFoo).toBeDefined();
});
});
env.describe("another suite", function() {
env.it("no longer has the custom matcher", function() {
expect(env.expect().toFoo).not.toBeDefined();
});
});
env.addReporter({jasmineDone: done});
env.execute();
});
});

View File

@@ -236,11 +236,14 @@ describe("jasmine spec running", function () {
});
});
suite.execute(function() {
var assertions = function() {
expect(specInADisabledSuite).not.toHaveBeenCalled();
done();
});
});
};
env.addReporter({jasmineDone: assertions});
env.execute();
it("should set all pending specs to pending when a suite is run", function(done) {
var pendingSpec,

View File

@@ -14,11 +14,19 @@ getJasmineRequireObj().Env = function(j$) {
this.clock = new j$.Clock(global, new j$.DelayedFunctionScheduler(), new j$.MockDate(global));
var runnableLookupTable = {};
var spies = [];
var runnableResources = {};
var currentSpec = null;
var currentSuite = null;
var currentlyExecutingSuites = [];
var currentDeclarationSuite = null;
var currentSuite = function() {
return currentlyExecutingSuites[currentlyExecutingSuites.length - 1];
}
var currentRunnable = function() {
return currentSpec || currentSuite();
}
var reporter = new j$.ReportDispatcher([
'jasmineStarted',
@@ -33,11 +41,15 @@ getJasmineRequireObj().Env = function(j$) {
return true;
};
var equalityTesters = [];
var customEqualityTesters = [];
this.addCustomEqualityTester = function(tester) {
customEqualityTesters.push(tester);
runnableResources[currentRunnable().id].customEqualityTesters.push(tester);
};
this.addMatchers = function(matchersToAdd) {
var customMatchers = runnableResources[currentRunnable().id].customMatchers;
for (var matcherName in matchersToAdd) {
customMatchers[matcherName] = matchersToAdd[matcherName];
}
};
j$.Expectation.addCoreMatchers(j$.matchers);
@@ -55,7 +67,8 @@ getJasmineRequireObj().Env = function(j$) {
var expectationFactory = function(actual, spec) {
return j$.Expectation.Factory({
util: j$.matchersUtil,
customEqualityTesters: customEqualityTesters,
customEqualityTesters: runnableResources[spec.id].customEqualityTesters,
customMatchers: runnableResources[spec.id].customMatchers,
actual: actual,
addExpectationResult: addExpectationResult
});
@@ -65,9 +78,20 @@ getJasmineRequireObj().Env = function(j$) {
}
};
var specStarted = function(spec) {
currentSpec = spec;
reporter.specStarted(spec.result);
var defaultResourcesForRunnable = function(id, parentRunnableId) {
var resources = {spies: [], customEqualityTesters: [], customMatchers: {}};
if(runnableResources[parentRunnableId]){
resources.customEqualityTesters = j$.util.clone(runnableResources[parentRunnableId].customEqualityTesters);
resources.customMatchers = j$.util.clone(runnableResources[parentRunnableId].customMatchers);
}
runnableResources[id] = resources;
};
var clearResourcesForRunnable = function(id) {
spyRegistry.clearSpies();
delete runnableResources[id];
};
var beforeFns = function(suite) {
@@ -149,7 +173,8 @@ getJasmineRequireObj().Env = function(j$) {
resultCallback: function() {} // TODO - hook this up
});
runnableLookupTable[topSuite.id] = topSuite;
currentSuite = topSuite;
defaultResourcesForRunnable(topSuite.id);
currentDeclarationSuite = topSuite;
this.topSuite = function() {
return topSuite;
@@ -175,36 +200,12 @@ getJasmineRequireObj().Env = function(j$) {
reporter.addReporter(reporterToAdd);
};
this.addMatchers = function(matchersToAdd) {
j$.Expectation.addMatchers(matchersToAdd);
};
var spyRegistry = new j$.SpyRegistry({currentSpies: function() {
return runnableResources[currentRunnable().id].spies;
}});
this.spyOn = function(obj, methodName) {
if (j$.util.isUndefined(obj)) {
throw new Error('spyOn could not find an object to spy upon for ' + methodName + '()');
}
if (j$.util.isUndefined(obj[methodName])) {
throw new Error(methodName + '() method does not exist');
}
if (obj[methodName] && j$.isSpy(obj[methodName])) {
//TODO?: should this return the current spy? Downside: may cause user confusion about spy state
throw new Error(methodName + ' has already been spied upon');
}
var spy = j$.createSpy(methodName, obj[methodName]);
spies.push({
spy: spy,
baseObj: obj,
methodName: methodName,
originalValue: obj[methodName]
});
obj[methodName] = spy;
return spy;
this.spyOn = function() {
return spyRegistry.spyOn.apply(spyRegistry, arguments);
};
var suiteFactory = function(description) {
@@ -212,24 +213,32 @@ getJasmineRequireObj().Env = function(j$) {
env: self,
id: getNextSuiteId(),
description: description,
parentSuite: currentSuite,
parentSuite: currentDeclarationSuite,
queueRunner: queueRunnerFactory,
onStart: suiteStarted,
resultCallback: function(attrs) {
clearResourcesForRunnable(suite.id);
currentlyExecutingSuites.pop();
reporter.suiteDone(attrs);
}
});
runnableLookupTable[suite.id] = suite;
return suite;
function suiteStarted(suite) {
currentlyExecutingSuites.push(suite);
defaultResourcesForRunnable(suite.id, suite.parentSuite.id);
reporter.suiteStarted(suite.result);
}
};
this.describe = function(description, specDefinitions) {
var suite = suiteFactory(description);
var parentSuite = currentSuite;
var parentSuite = currentDeclarationSuite;
parentSuite.addChild(suite);
currentSuite = suite;
currentDeclarationSuite = suite;
var declarationError = null;
try {
@@ -244,7 +253,7 @@ getJasmineRequireObj().Env = function(j$) {
});
}
currentSuite = parentSuite;
currentDeclarationSuite = parentSuite;
return suite;
};
@@ -284,30 +293,22 @@ getJasmineRequireObj().Env = function(j$) {
return spec;
function removeAllSpies() {
for (var i = 0; i < spies.length; i++) {
var spyEntry = spies[i];
spyEntry.baseObj[spyEntry.methodName] = spyEntry.originalValue;
}
spies = [];
}
function specResultCallback(result) {
removeAllSpies();
j$.Expectation.resetMatchers();
customEqualityTesters = [];
clearResourcesForRunnable(spec.id);
currentSpec = null;
reporter.specDone(result);
}
};
var suiteStarted = function(suite) {
reporter.suiteStarted(suite.result);
function specStarted(spec) {
currentSpec = spec;
defaultResourcesForRunnable(spec.id, suite.id);
reporter.specStarted(spec.result);
}
};
this.it = function(description, fn) {
var spec = specFactory(description, fn, currentSuite);
currentSuite.addChild(spec);
var spec = specFactory(description, fn, currentDeclarationSuite);
currentDeclarationSuite.addChild(spec);
return spec;
};
@@ -322,19 +323,19 @@ getJasmineRequireObj().Env = function(j$) {
};
this.beforeEach = function(beforeEachFunction) {
currentSuite.beforeEach({ fn: beforeEachFunction, timeout: function() { return j$.DEFAULT_TIMEOUT_INTERVAL; } });
currentDeclarationSuite.beforeEach({ fn: beforeEachFunction, timeout: function() { return j$.DEFAULT_TIMEOUT_INTERVAL; } });
};
this.beforeAll = function(beforeAllFunction) {
currentSuite.beforeAll({ fn: beforeAllFunction, timeout: function() { return j$.DEFAULT_TIMEOUT_INTERVAL; } });
currentDeclarationSuite.beforeAll({ fn: beforeAllFunction, timeout: function() { return j$.DEFAULT_TIMEOUT_INTERVAL; } });
};
this.afterEach = function(afterEachFunction) {
currentSuite.afterEach({ fn: afterEachFunction, timeout: function() { return j$.DEFAULT_TIMEOUT_INTERVAL; } });
currentDeclarationSuite.afterEach({ fn: afterEachFunction, timeout: function() { return j$.DEFAULT_TIMEOUT_INTERVAL; } });
};
this.afterAll = function(afterAllFunction) {
currentSuite.afterAll({ fn: afterAllFunction, timeout: function() { return j$.DEFAULT_TIMEOUT_INTERVAL; } });
currentDeclarationSuite.afterAll({ fn: afterAllFunction, timeout: function() { return j$.DEFAULT_TIMEOUT_INTERVAL; } });
};
this.pending = function() {

View File

@@ -1,7 +1,5 @@
getJasmineRequireObj().Expectation = function() {
var matchers = {};
function Expectation(options) {
this.util = options.util || { buildFailureMessage: function() {} };
this.customEqualityTesters = options.customEqualityTesters || [];
@@ -9,8 +7,9 @@ getJasmineRequireObj().Expectation = function() {
this.addExpectationResult = options.addExpectationResult || function(){};
this.isNot = options.isNot;
for (var matcherName in matchers) {
this[matcherName] = matchers[matcherName];
var customMatchers = options.customMatchers || {};
for (var matcherName in customMatchers) {
this[matcherName] = Expectation.prototype.wrapCompare(matcherName, customMatchers[matcherName]);
}
}
@@ -77,19 +76,6 @@ getJasmineRequireObj().Expectation = function() {
}
};
Expectation.addMatchers = function(matchersToAdd) {
for (var name in matchersToAdd) {
var matcher = matchersToAdd[name];
matchers[name] = Expectation.prototype.wrapCompare(name, matcher);
}
};
Expectation.resetMatchers = function() {
for (var name in matchers) {
delete matchers[name];
}
};
Expectation.Factory = function(options) {
options = options || {};

46
src/core/SpyRegistry.js Normal file
View File

@@ -0,0 +1,46 @@
getJasmineRequireObj().SpyRegistry = function(j$) {
function SpyRegistry(options) {
var options = options || {};
var currentSpies = options.currentSpies || function() { return []; };
this.spyOn = function(obj, methodName) {
if (j$.util.isUndefined(obj)) {
throw new Error('spyOn could not find an object to spy upon for ' + methodName + '()');
}
if (j$.util.isUndefined(obj[methodName])) {
throw new Error(methodName + '() method does not exist');
}
if (obj[methodName] && j$.isSpy(obj[methodName])) {
//TODO?: should this return the current spy? Downside: may cause user confusion about spy state
throw new Error(methodName + ' has already been spied upon');
}
var spy = j$.createSpy(methodName, obj[methodName]);
currentSpies().push({
spy: spy,
baseObj: obj,
methodName: methodName,
originalValue: obj[methodName]
});
obj[methodName] = spy;
return spy;
};
this.clearSpies = function() {
var spies = currentSpies();
for (var i = 0; i < spies.length; i++) {
var spyEntry = spies[i];
spyEntry.baseObj[spyEntry.methodName] = spyEntry.originalValue;
}
};
}
return SpyRegistry;
};

View File

@@ -28,6 +28,7 @@ getJasmineRequireObj().core = function(jRequire) {
j$.QueueRunner = jRequire.QueueRunner(j$);
j$.ReportDispatcher = jRequire.ReportDispatcher();
j$.Spec = jRequire.Spec(j$);
j$.SpyRegistry = jRequire.SpyRegistry(j$);
j$.SpyStrategy = jRequire.SpyStrategy();
j$.Suite = jRequire.Suite();
j$.Timer = jRequire.Timer();

View File

@@ -30,5 +30,20 @@ getJasmineRequireObj().util = function() {
return obj === void 0;
};
util.clone = function(obj) {
if (Object.prototype.toString.apply(obj) === "[object Array]") {
return obj.slice();
}
var cloned = {};
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
cloned[prop] = obj[prop];
}
}
return cloned;
}
return util;
};