Consistent 'this' between befores/it/afters
Change the 'this' user functions are called with to be an empty object
instead of the QueueRunner so that if the user puts properties on it,
they won't conflict.
Also, changes async specs to be called with a proper 'this', as pointed
out by @Eric-Wright in #419 and #420.
[finishes #56030080]
This commit is contained in:
@@ -288,7 +288,7 @@ getJasmineRequireObj().Spec = function() {
|
|||||||
done();
|
done();
|
||||||
};
|
};
|
||||||
|
|
||||||
fn(callDone); //TODO: do we care about more than 1 arg?
|
fn.call(this, callDone); //TODO: do we care about more than 1 arg?
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1440,6 +1440,7 @@ getJasmineRequireObj().QueueRunner = function() {
|
|||||||
this.clearStack = attrs.clearStack || function(fn) {fn();};
|
this.clearStack = attrs.clearStack || function(fn) {fn();};
|
||||||
this.onException = attrs.onException || function() {};
|
this.onException = attrs.onException || function() {};
|
||||||
this.catchException = attrs.catchException || function() { return true; };
|
this.catchException = attrs.catchException || function() { return true; };
|
||||||
|
this.userContext = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
QueueRunner.prototype.execute = function() {
|
QueueRunner.prototype.execute = function() {
|
||||||
@@ -1468,7 +1469,7 @@ getJasmineRequireObj().QueueRunner = function() {
|
|||||||
|
|
||||||
function attemptSync(fn) {
|
function attemptSync(fn) {
|
||||||
try {
|
try {
|
||||||
fn.call(self);
|
fn.call(self.userContext);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
handleException(e);
|
handleException(e);
|
||||||
}
|
}
|
||||||
@@ -1478,7 +1479,7 @@ getJasmineRequireObj().QueueRunner = function() {
|
|||||||
var next = function () { self.run(fns, iterativeIndex + 1); };
|
var next = function () { self.run(fns, iterativeIndex + 1); };
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fn.call(self, next);
|
fn.call(self.userContext, next);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
handleException(e);
|
handleException(e);
|
||||||
next();
|
next();
|
||||||
|
|||||||
@@ -236,6 +236,70 @@ describe("Env integration", function() {
|
|||||||
env.execute();
|
env.execute();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("calls associated befores/specs/afters with the same 'this'", function(done) {
|
||||||
|
var env = new j$.Env();
|
||||||
|
|
||||||
|
env.addReporter({jasmineDone: done});
|
||||||
|
|
||||||
|
env.describe("tests", function() {
|
||||||
|
var firstTimeThrough = true, firstSpecContext, secondSpecContext;
|
||||||
|
|
||||||
|
env.beforeEach(function() {
|
||||||
|
if (firstTimeThrough) {
|
||||||
|
firstSpecContext = this;
|
||||||
|
} else {
|
||||||
|
secondSpecContext = this;
|
||||||
|
}
|
||||||
|
expect(this).toEqual({});
|
||||||
|
});
|
||||||
|
|
||||||
|
env.it("sync spec", function() {
|
||||||
|
expect(this).toBe(firstSpecContext);
|
||||||
|
});
|
||||||
|
|
||||||
|
env.it("another sync spec", function() {
|
||||||
|
expect(this).toBe(secondSpecContext);
|
||||||
|
});
|
||||||
|
|
||||||
|
env.afterEach(function() {
|
||||||
|
if (firstTimeThrough) {
|
||||||
|
expect(this).toBe(firstSpecContext);
|
||||||
|
firstTimeThrough = false;
|
||||||
|
} else {
|
||||||
|
expect(this).toBe(secondSpecContext);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
env.execute();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("calls associated befores/its/afters with the same 'this' for an async spec", function(done) {
|
||||||
|
var env = new j$.Env();
|
||||||
|
|
||||||
|
env.addReporter({jasmineDone: done});
|
||||||
|
|
||||||
|
env.describe("with an async spec", function() {
|
||||||
|
var specContext;
|
||||||
|
|
||||||
|
env.beforeEach(function() {
|
||||||
|
specContext = this;
|
||||||
|
expect(this).toEqual({});
|
||||||
|
});
|
||||||
|
|
||||||
|
env.it("sync spec", function(underTestCallback) {
|
||||||
|
expect(this).toBe(specContext);
|
||||||
|
underTestCallback();
|
||||||
|
});
|
||||||
|
|
||||||
|
env.afterEach(function() {
|
||||||
|
expect(this).toBe(specContext);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
env.execute();
|
||||||
|
});
|
||||||
|
|
||||||
it("Mock clock can be installed and used in tests", function(done) {
|
it("Mock clock can be installed and used in tests", function(done) {
|
||||||
var globalSetTimeout = jasmine.createSpy('globalSetTimeout'),
|
var globalSetTimeout = jasmine.createSpy('globalSetTimeout'),
|
||||||
delayedFunctionForGlobalClock = jasmine.createSpy('delayedFunctionForGlobalClock'),
|
delayedFunctionForGlobalClock = jasmine.createSpy('delayedFunctionForGlobalClock'),
|
||||||
|
|||||||
@@ -19,6 +19,23 @@ describe("QueueRunner", function() {
|
|||||||
expect(calls).toEqual(['fn1', 'fn2']);
|
expect(calls).toEqual(['fn1', 'fn2']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("calls each function with a consistent 'this'-- an empty object", function() {
|
||||||
|
var fn1 = jasmine.createSpy('fn1'),
|
||||||
|
fn2 = jasmine.createSpy('fn2'),
|
||||||
|
fn3 = function(done) { asyncContext = this; done(); },
|
||||||
|
queueRunner = new j$.QueueRunner({
|
||||||
|
fns: [fn1, fn2, fn3]
|
||||||
|
}),
|
||||||
|
asyncContext;
|
||||||
|
|
||||||
|
queueRunner.execute();
|
||||||
|
|
||||||
|
var context = fn1.calls.first().object;
|
||||||
|
expect(context).toEqual({});
|
||||||
|
expect(fn2.calls.first().object).toBe(context);
|
||||||
|
expect(asyncContext).toBe(context);
|
||||||
|
});
|
||||||
|
|
||||||
it("supports asynchronous functions, only advancing to next function after a done() callback", function() {
|
it("supports asynchronous functions, only advancing to next function after a done() callback", function() {
|
||||||
//TODO: it would be nice if spy arity could match the fake, so we could do something like:
|
//TODO: it would be nice if spy arity could match the fake, so we could do something like:
|
||||||
//createSpy('asyncfn').and.callFake(function(done) {});
|
//createSpy('asyncfn').and.callFake(function(done) {});
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ getJasmineRequireObj().QueueRunner = function() {
|
|||||||
this.clearStack = attrs.clearStack || function(fn) {fn();};
|
this.clearStack = attrs.clearStack || function(fn) {fn();};
|
||||||
this.onException = attrs.onException || function() {};
|
this.onException = attrs.onException || function() {};
|
||||||
this.catchException = attrs.catchException || function() { return true; };
|
this.catchException = attrs.catchException || function() { return true; };
|
||||||
|
this.userContext = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
QueueRunner.prototype.execute = function() {
|
QueueRunner.prototype.execute = function() {
|
||||||
@@ -34,7 +35,7 @@ getJasmineRequireObj().QueueRunner = function() {
|
|||||||
|
|
||||||
function attemptSync(fn) {
|
function attemptSync(fn) {
|
||||||
try {
|
try {
|
||||||
fn.call(self);
|
fn.call(self.userContext);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
handleException(e);
|
handleException(e);
|
||||||
}
|
}
|
||||||
@@ -44,7 +45,7 @@ getJasmineRequireObj().QueueRunner = function() {
|
|||||||
var next = function () { self.run(fns, iterativeIndex + 1); };
|
var next = function () { self.run(fns, iterativeIndex + 1); };
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fn.call(self, next);
|
fn.call(self.userContext, next);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
handleException(e);
|
handleException(e);
|
||||||
next();
|
next();
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ getJasmineRequireObj().Spec = function() {
|
|||||||
done();
|
done();
|
||||||
};
|
};
|
||||||
|
|
||||||
fn(callDone); //TODO: do we care about more than 1 arg?
|
fn.call(this, callDone); //TODO: do we care about more than 1 arg?
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user