Unify status for xdescribe and xit

- Ensure *All's only execute if at least one child will run
- Specs will report a status of `excluded` instead of disabled

[finishes #153967580]
- #1418

Signed-off-by: Elenore Bastian <ebastian@pivotal.io>
This commit is contained in:
Gregg Van Hove
2018-01-25 16:17:31 -08:00
committed by Elenore Bastian
parent 07996b567f
commit 6b156ca6d1
10 changed files with 204 additions and 239 deletions

View File

@@ -525,7 +525,7 @@ getJasmineRequireObj().Spec = function(j$) {
return this.expectationFactory(actual, this); return this.expectationFactory(actual, this);
}; };
Spec.prototype.execute = function(onComplete, enabled) { Spec.prototype.execute = function(onComplete, excluded) {
var self = this; var self = this;
this.onStart(this); this.onStart(this);
@@ -542,17 +542,16 @@ getJasmineRequireObj().Spec = function(j$) {
userContext: this.userContext() userContext: this.userContext()
}; };
if (!this.isExecutable() || this.markedPending || enabled === false) { if (this.markedPending || excluded === true) {
runnerConfig.queueableFns = []; runnerConfig.queueableFns = [];
runnerConfig.cleanupFns = []; runnerConfig.cleanupFns = [];
runnerConfig.onComplete = function() { complete(enabled); };
} }
this.queueRunnerFactory(runnerConfig); this.queueRunnerFactory(runnerConfig);
function complete(enabledAgain) { function complete() {
self.queueableFn.fn = null; self.queueableFn.fn = null;
self.result.status = self.status(enabledAgain); self.result.status = self.status(excluded);
self.resultCallback(self.result); self.resultCallback(self.result);
if (onComplete) { if (onComplete) {
@@ -580,10 +579,6 @@ getJasmineRequireObj().Spec = function(j$) {
}, true); }, true);
}; };
Spec.prototype.disable = function() {
this.disabled = true;
};
Spec.prototype.pend = function(message) { Spec.prototype.pend = function(message) {
this.markedPending = true; this.markedPending = true;
if (message) { if (message) {
@@ -596,9 +591,9 @@ getJasmineRequireObj().Spec = function(j$) {
return this.result; return this.result;
}; };
Spec.prototype.status = function(enabled) { Spec.prototype.status = function(excluded) {
if (this.disabled || enabled === false) { if (excluded === true) {
return 'disabled'; return 'excluded';
} }
if (this.markedPending) { if (this.markedPending) {
@@ -612,10 +607,6 @@ getJasmineRequireObj().Spec = function(j$) {
} }
}; };
Spec.prototype.isExecutable = function() {
return !this.disabled;
};
Spec.prototype.getFullName = function() { Spec.prototype.getFullName = function() {
return this.getSpecName(this); return this.getSpecName(this);
}; };
@@ -976,6 +967,7 @@ getJasmineRequireObj().Env = function(j$) {
}; };
this.execute = function(runnablesToRun) { this.execute = function(runnablesToRun) {
var self = this;
this.suppressLoadErrors(); this.suppressLoadErrors();
if(!runnablesToRun) { if(!runnablesToRun) {
@@ -1005,9 +997,7 @@ getJasmineRequireObj().Env = function(j$) {
throw new Error('Tried to complete the wrong suite'); throw new Error('Tried to complete the wrong suite');
} }
if (!suite.markedPending) { clearResourcesForRunnable(suite.id);
clearResourcesForRunnable(suite.id);
}
currentlyExecutingSuites.pop(); currentlyExecutingSuites.pop();
reporter.suiteDone(result); reporter.suiteDone(result);
@@ -1017,6 +1007,9 @@ getJasmineRequireObj().Env = function(j$) {
}, },
orderChildren: function(node) { orderChildren: function(node) {
return order.sort(node.children); return order.sort(node.children);
},
excludeNode: function(spec) {
return !self.specFilter(spec);
} }
}); });
@@ -1267,10 +1260,6 @@ getJasmineRequireObj().Env = function(j$) {
throwOnExpectationFailure: throwOnExpectationFailure throwOnExpectationFailure: throwOnExpectationFailure
}); });
if (!self.specFilter(spec)) {
spec.disable();
}
return spec; return spec;
function specResultCallback(result) { function specResultCallback(result) {
@@ -5610,14 +5599,10 @@ getJasmineRequireObj().Suite = function(j$) {
if (this.result.failedExpectations.length > 0) { if (this.result.failedExpectations.length > 0) {
return 'failed'; return 'failed';
} else { } else {
return 'finished'; return 'passed';
} }
}; };
Suite.prototype.isExecutable = function() {
return !this.markedPending;
};
Suite.prototype.canBeReentered = function() { Suite.prototype.canBeReentered = function() {
return this.beforeAllFns.length === 0 && this.afterAllFns.length === 0; return this.beforeAllFns.length === 0 && this.afterAllFns.length === 0;
}; };
@@ -5712,13 +5697,14 @@ getJasmineRequireObj().TreeProcessor = function() {
nodeStart = attrs.nodeStart || function() {}, nodeStart = attrs.nodeStart || function() {},
nodeComplete = attrs.nodeComplete || function() {}, nodeComplete = attrs.nodeComplete || function() {},
orderChildren = attrs.orderChildren || function(node) { return node.children; }, orderChildren = attrs.orderChildren || function(node) { return node.children; },
excludeNode = attrs.excludeNode || function(node) { return false; },
stats = { valid: true }, stats = { valid: true },
processed = false, processed = false,
defaultMin = Infinity, defaultMin = Infinity,
defaultMax = 1 - Infinity; defaultMax = 1 - Infinity;
this.processTree = function() { this.processTree = function() {
processNode(tree, false); processNode(tree, true);
processed = true; processed = true;
return stats; return stats;
}; };
@@ -5752,18 +5738,18 @@ getJasmineRequireObj().TreeProcessor = function() {
} }
} }
function processNode(node, parentEnabled) { function processNode(node, parentExcluded) {
var executableIndex = runnableIndex(node.id); var executableIndex = runnableIndex(node.id);
if (executableIndex !== undefined) { if (executableIndex !== undefined) {
parentEnabled = true; parentExcluded = false;
} }
parentEnabled = parentEnabled && node.isExecutable();
if (!node.children) { if (!node.children) {
var excluded = parentExcluded || excludeNode(node);
stats[node.id] = { stats[node.id] = {
executable: parentEnabled && node.isExecutable(), excluded: excluded,
willExecute: !excluded && !node.markedPending,
segments: [{ segments: [{
index: 0, index: 0,
owner: node, owner: node,
@@ -5780,7 +5766,7 @@ getJasmineRequireObj().TreeProcessor = function() {
for (var i = 0; i < orderedChildren.length; i++) { for (var i = 0; i < orderedChildren.length; i++) {
var child = orderedChildren[i]; var child = orderedChildren[i];
processNode(child, parentEnabled); processNode(child, parentExcluded);
if (!stats.valid) { if (!stats.valid) {
return; return;
@@ -5788,11 +5774,12 @@ getJasmineRequireObj().TreeProcessor = function() {
var childStats = stats[child.id]; var childStats = stats[child.id];
hasExecutableChild = hasExecutableChild || childStats.executable; hasExecutableChild = hasExecutableChild || childStats.willExecute;
} }
stats[node.id] = { stats[node.id] = {
executable: hasExecutableChild excluded: parentExcluded,
willExecute: hasExecutableChild
}; };
segmentChildren(node, orderedChildren, stats[node.id], executableIndex); segmentChildren(node, orderedChildren, stats[node.id], executableIndex);
@@ -5888,7 +5875,7 @@ getJasmineRequireObj().TreeProcessor = function() {
}; };
} else { } else {
return { return {
fn: function(done) { node.execute(done, stats[node.id].executable); } fn: function(done) { node.execute(done, stats[node.id].excluded); }
}; };
} }
} }
@@ -5901,7 +5888,7 @@ getJasmineRequireObj().TreeProcessor = function() {
result.push(executeNode(segmentChildren[i].owner, segmentChildren[i].index)); result.push(executeNode(segmentChildren[i].owner, segmentChildren[i].index));
} }
if (!stats[node.id].executable) { if (!stats[node.id].willExecute) {
return result; return result;
} }

View File

@@ -192,7 +192,7 @@ describe("JsApiReporter", function() {
}; };
suiteResult2 = { suiteResult2 = {
id: 2, id: 2,
status: 'finished' status: 'passed'
}; };
reporter.suiteStarted(suiteStarted1); reporter.suiteStarted(suiteStarted1);

View File

@@ -140,7 +140,7 @@ describe("Spec", function() {
expect(spec.status()).toBe('pending'); expect(spec.status()).toBe('pending');
}); });
it("can be disabled, but still calls callbacks", function() { it("can be excluded at execution time by a parent", function() {
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner') var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner')
.and.callFake(function(attrs) { attrs.onComplete(); }), .and.callFake(function(attrs) { attrs.onComplete(); }),
startCallback = jasmine.createSpy('startCallback'), startCallback = jasmine.createSpy('startCallback'),
@@ -153,35 +153,9 @@ describe("Spec", function() {
queueRunnerFactory: fakeQueueRunner queueRunnerFactory: fakeQueueRunner
}); });
spec.disable(); spec.execute(undefined, true);
expect(spec.status()).toBe('disabled'); expect(spec.result.status).toBe('excluded');
spec.execute();
expect(fakeQueueRunner).toHaveBeenCalled();
expect(specBody).not.toHaveBeenCalled();
expect(startCallback).toHaveBeenCalled();
expect(resultCallback).toHaveBeenCalled();
});
it("can be disabled at execution time by a parent", function() {
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner')
.and.callFake(function(attrs) { attrs.onComplete(); }),
startCallback = jasmine.createSpy('startCallback'),
specBody = jasmine.createSpy('specBody'),
resultCallback = jasmine.createSpy('resultCallback'),
spec = new jasmineUnderTest.Spec({
onStart:startCallback,
queueableFn: { fn: specBody },
resultCallback: resultCallback,
queueRunnerFactory: fakeQueueRunner
});
spec.execute(undefined, false);
expect(spec.result.status).toBe('disabled');
expect(fakeQueueRunner).toHaveBeenCalled(); expect(fakeQueueRunner).toHaveBeenCalled();
expect(specBody).not.toHaveBeenCalled(); expect(specBody).not.toHaveBeenCalled();
@@ -392,50 +366,4 @@ describe("Spec", function() {
expect(resultCallback.calls.first().args[0].failedExpectations).toEqual([]); expect(resultCallback.calls.first().args[0].failedExpectations).toEqual([]);
}); });
it("retrieves a result with updated status", function() {
var spec = new jasmineUnderTest.Spec({ queueableFn: { fn: function() {} } });
expect(spec.getResult().status).toBe('passed');
});
it("retrives a result with disabled status", function() {
var spec = new jasmineUnderTest.Spec({ queueableFn: { fn: function() {} } });
spec.disable();
expect(spec.getResult().status).toBe('disabled');
});
it("retrives a result with pending status", function() {
var spec = new jasmineUnderTest.Spec({ queueableFn: { fn: function() {} } });
spec.pend();
expect(spec.getResult().status).toBe('pending');
});
it("should not be executable when disabled", function() {
var spec = new jasmineUnderTest.Spec({
queueableFn: { fn: function() {} }
});
spec.disable();
expect(spec.isExecutable()).toBe(false);
});
it("should be executable when pending", function() {
var spec = new jasmineUnderTest.Spec({
queueableFn: { fn: function() {} }
});
spec.pend();
expect(spec.isExecutable()).toBe(true);
});
it("should be executable when not disabled or pending", function() {
var spec = new jasmineUnderTest.Spec({
queueableFn: { fn: function() {} }
});
expect(spec.isExecutable()).toBe(true);
});
}); });

View File

@@ -79,7 +79,7 @@ describe("Suite", function() {
it("retrieves a result with updated status", function() { it("retrieves a result with updated status", function() {
var suite = new jasmineUnderTest.Suite({}); var suite = new jasmineUnderTest.Suite({});
expect(suite.getResult().status).toBe('finished'); expect(suite.getResult().status).toBe('passed');
}); });
it("retrieves a result with pending status", function() { it("retrieves a result with pending status", function() {
@@ -89,19 +89,6 @@ describe("Suite", function() {
expect(suite.getResult().status).toBe('pending'); expect(suite.getResult().status).toBe('pending');
}); });
it("is executable if not pending", function() {
var suite = new jasmineUnderTest.Suite({});
expect(suite.isExecutable()).toBe(true);
});
it("is not executable if pending", function() {
var suite = new jasmineUnderTest.Suite({});
suite.pend();
expect(suite.isExecutable()).toBe(false);
});
it("throws an ExpectationFailed when receiving a failed expectation when throwOnExpectationFailure is set", function() { it("throws an ExpectationFailed when receiving a failed expectation when throwOnExpectationFailure is set", function() {
var suite = new jasmineUnderTest.Suite({ var suite = new jasmineUnderTest.Suite({
expectationResultFactory: function(data) { return data; }, expectationResultFactory: function(data) { return data; },

View File

@@ -8,9 +8,7 @@ describe("TreeProcessor", function() {
this.canBeReentered = function() { this.canBeReentered = function() {
return !attrs.noReenter; return !attrs.noReenter;
}; };
this.isExecutable = function() { this.markedPending = attrs.markedPending || false;
return attrs.executable !== false;
};
this.sharedUserContext = function() { this.sharedUserContext = function() {
return attrs.userContext || {}; return attrs.userContext || {};
}; };
@@ -23,13 +21,11 @@ describe("TreeProcessor", function() {
function Leaf(attrs) { function Leaf(attrs) {
attrs = attrs || {}; attrs = attrs || {};
this.id = 'leaf' + leafNumber++; this.id = 'leaf' + leafNumber++;
this.isExecutable = function() { this.markedPending = attrs.markedPending || false;
return attrs.executable !== false;
};
this.execute = jasmine.createSpy(this.id + '#execute'); this.execute = jasmine.createSpy(this.id + '#execute');
} }
it("processes a single executable leaf", function() { it("processes a single leaf", function() {
var leaf = new Leaf(), var leaf = new Leaf(),
processor = new jasmineUnderTest.TreeProcessor({ tree: leaf, runnableIds: [leaf.id] }), processor = new jasmineUnderTest.TreeProcessor({ tree: leaf, runnableIds: [leaf.id] }),
result = processor.processTree(); result = processor.processTree();
@@ -37,20 +33,22 @@ describe("TreeProcessor", function() {
expect(result.valid).toBe(true); expect(result.valid).toBe(true);
expect(result[leaf.id]).toEqual({ expect(result[leaf.id]).toEqual({
executable: true, excluded: false,
willExecute: true,
segments: jasmine.any(Array) segments: jasmine.any(Array)
}); });
}); });
it("processes a single non-executable leaf", function() { it("processes a single pending leaf", function() {
var leaf = new Leaf({ executable: false }), var leaf = new Leaf({ markedPending: true }),
processor = new jasmineUnderTest.TreeProcessor({ tree: leaf, runnableIds: [leaf.id] }), processor = new jasmineUnderTest.TreeProcessor({ tree: leaf, runnableIds: [leaf.id] }),
result = processor.processTree(); result = processor.processTree();
expect(result.valid).toBe(true); expect(result.valid).toBe(true);
expect(result[leaf.id]).toEqual({ expect(result[leaf.id]).toEqual({
executable: false, excluded: false,
willExecute: false,
segments: jasmine.any(Array) segments: jasmine.any(Array)
}); });
}); });
@@ -63,7 +61,26 @@ describe("TreeProcessor", function() {
expect(result.valid).toBe(true); expect(result.valid).toBe(true);
expect(result[leaf.id]).toEqual({ expect(result[leaf.id]).toEqual({
executable: false, excluded: true,
willExecute: false,
segments: jasmine.any(Array)
});
});
it("processes a single excluded leaf", function() {
var leaf = new Leaf(),
processor = new jasmineUnderTest.TreeProcessor({
tree: leaf,
runnableIds: [leaf.id],
excludeNode: function(node) { return true; }
}),
result = processor.processTree();
expect(result.valid).toBe(true);
expect(result[leaf.id]).toEqual({
excluded: true,
willExecute: false,
segments: jasmine.any(Array) segments: jasmine.any(Array)
}); });
}); });
@@ -77,18 +94,20 @@ describe("TreeProcessor", function() {
expect(result.valid).toBe(true); expect(result.valid).toBe(true);
expect(result[parent.id]).toEqual({ expect(result[parent.id]).toEqual({
executable: true, excluded: false,
willExecute: true,
segments: jasmine.any(Array) segments: jasmine.any(Array)
}); });
expect(result[leaf.id]).toEqual({ expect(result[leaf.id]).toEqual({
executable: true, excluded: false,
willExecute: true,
segments: jasmine.any(Array) segments: jasmine.any(Array)
}); });
}); });
it("processes a tree with a single non-executable leaf, with the root specified", function() { it("processes a tree with a single pending leaf, with the root specified", function() {
var leaf = new Leaf({ executable: false }), var leaf = new Leaf({ markedPending: true }),
parent = new Node({ children: [leaf] }), parent = new Node({ children: [leaf] }),
processor = new jasmineUnderTest.TreeProcessor({ tree: parent, runnableIds: [parent.id] }), processor = new jasmineUnderTest.TreeProcessor({ tree: parent, runnableIds: [parent.id] }),
result = processor.processTree(); result = processor.processTree();
@@ -96,61 +115,77 @@ describe("TreeProcessor", function() {
expect(result.valid).toBe(true); expect(result.valid).toBe(true);
expect(result[parent.id]).toEqual({ expect(result[parent.id]).toEqual({
executable: false, excluded: false,
willExecute: false,
segments: jasmine.any(Array) segments: jasmine.any(Array)
}); });
expect(result[leaf.id]).toEqual({ expect(result[leaf.id]).toEqual({
executable: false, excluded: false,
willExecute: false,
segments: jasmine.any(Array) segments: jasmine.any(Array)
}); });
}); });
it("processes a complicated tree with the root specified", function() { it("processes a complicated tree with the root specified", function() {
var nonExecutable = new Leaf({ executable: false }), var pendingLeaf = new Leaf({ markedPending: true }),
executable = new Leaf({ executable: true }), executableLeaf = new Leaf({ markedPending: false }),
parent = new Node({ children: [nonExecutable, executable] }), parent = new Node({ children: [pendingLeaf, executableLeaf] }),
childless = new Node(), childless = new Node(),
childOfDisabled = new Leaf({ executable: true }), childOfPending = new Leaf({ markedPending: true }),
disabledNode = new Node({ executable: false, children: [childOfDisabled] }), pendingNode = new Node({ markedPending: true, children: [childOfPending] }),
root = new Node({ children: [parent, childless, disabledNode] }), parentOfPendings = new Node({ markedPending: false, children: [childless, pendingNode] }),
root = new Node({ children: [parent, parentOfPendings] }),
processor = new jasmineUnderTest.TreeProcessor({ tree: root, runnableIds: [root.id] }), processor = new jasmineUnderTest.TreeProcessor({ tree: root, runnableIds: [root.id] }),
result = processor.processTree(); result = processor.processTree();
expect(result.valid).toBe(true); expect(result.valid).toBe(true);
expect(result[root.id]).toEqual({ expect(result[root.id]).toEqual({
executable: true, excluded: false,
willExecute: true,
segments: jasmine.any(Array)
});
expect(result[parentOfPendings.id]).toEqual({
excluded: false,
willExecute: false,
segments: jasmine.any(Array) segments: jasmine.any(Array)
}); });
expect(result[childless.id]).toEqual({ expect(result[childless.id]).toEqual({
executable: false, excluded: false,
willExecute: false,
segments: jasmine.any(Array) segments: jasmine.any(Array)
}); });
expect(result[nonExecutable.id]).toEqual({ expect(result[pendingLeaf.id]).toEqual({
executable: false, excluded: false,
willExecute: false,
segments: jasmine.any(Array) segments: jasmine.any(Array)
}); });
expect(result[executable.id]).toEqual({ expect(result[executableLeaf.id]).toEqual({
executable: true, excluded: false,
willExecute: true,
segments: jasmine.any(Array) segments: jasmine.any(Array)
}); });
expect(result[parent.id]).toEqual({ expect(result[parent.id]).toEqual({
executable: true, excluded: false,
willExecute: true,
segments: jasmine.any(Array) segments: jasmine.any(Array)
}); });
expect(result[disabledNode.id]).toEqual({ expect(result[pendingNode.id]).toEqual({
executable: false, excluded: false,
willExecute: false,
segments: jasmine.any(Array) segments: jasmine.any(Array)
}); });
expect(result[childOfDisabled.id]).toEqual({ expect(result[childOfPending.id]).toEqual({
executable: false, excluded: false,
willExecute: false,
segments: jasmine.any(Array) segments: jasmine.any(Array)
}); });
}); });
@@ -219,7 +254,7 @@ describe("TreeProcessor", function() {
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn('foo'); queueRunner.calls.mostRecent().args[0].queueableFns[0].fn('foo');
expect(leaf.execute).toHaveBeenCalledWith('foo', true); expect(leaf.execute).toHaveBeenCalledWith('foo', false);
}); });
it("runs a node with no children", function() { it("runs a node with no children", function() {
@@ -286,22 +321,22 @@ describe("TreeProcessor", function() {
expect(queueableFns.length).toBe(2); expect(queueableFns.length).toBe(2);
queueableFns[0].fn('foo'); queueableFns[0].fn('foo');
expect(leaf1.execute).toHaveBeenCalledWith('foo', true); expect(leaf1.execute).toHaveBeenCalledWith('foo', false);
queueableFns[1].fn('bar'); queueableFns[1].fn('bar');
expect(leaf2.execute).toHaveBeenCalledWith('bar', true); expect(leaf2.execute).toHaveBeenCalledWith('bar', false);
}); });
it("runs a disabled node", function() { it("runs an excluded node with leaf", function() {
var leaf1 = new Leaf(), var leaf1 = new Leaf(),
node = new Node({ children: [leaf1], executable: false }), node = new Node({ children: [leaf1] }),
root = new Node({ children: [node] }), root = new Node({ children: [node] }),
queueRunner = jasmine.createSpy('queueRunner'), queueRunner = jasmine.createSpy('queueRunner'),
nodeStart = jasmine.createSpy('nodeStart'), nodeStart = jasmine.createSpy('nodeStart'),
nodeComplete = jasmine.createSpy('nodeComplete'), nodeComplete = jasmine.createSpy('nodeComplete'),
processor = new jasmineUnderTest.TreeProcessor({ processor = new jasmineUnderTest.TreeProcessor({
tree: root, tree: root,
runnableIds: [node.id], runnableIds: [],
queueRunnerFactory: queueRunner, queueRunnerFactory: queueRunner,
nodeStart: nodeStart, nodeStart: nodeStart,
nodeComplete: nodeComplete nodeComplete: nodeComplete
@@ -319,7 +354,7 @@ describe("TreeProcessor", function() {
expect(queueableFns.length).toBe(1); expect(queueableFns.length).toBe(1);
queueableFns[0].fn('foo'); queueableFns[0].fn('foo');
expect(leaf1.execute).toHaveBeenCalledWith('foo', false); expect(leaf1.execute).toHaveBeenCalledWith('foo', true);
node.getResult.and.returnValue({ im: 'disabled' }); node.getResult.and.returnValue({ im: 'disabled' });
@@ -401,13 +436,13 @@ describe("TreeProcessor", function() {
expect(queueableFns).toEqual([]); expect(queueableFns).toEqual([]);
}); });
it("does not run beforeAlls or afterAlls for a disabled node", function() { it("does not run beforeAlls or afterAlls for a node with only pending children", function() {
var leaf = new Leaf(), var leaf = new Leaf({ markedPending: true }),
node = new Node({ node = new Node({
children: [leaf], children: [leaf],
beforeAllFns: ['before'], beforeAllFns: ['before'],
afterAllFns: ['after'], afterAllFns: ['after'],
executable: false markedPending: false
}), }),
root = new Node({ children: [node] }), root = new Node({ children: [node] }),
queueRunner = jasmine.createSpy('queueRunner'), queueRunner = jasmine.createSpy('queueRunner'),
@@ -452,7 +487,7 @@ describe("TreeProcessor", function() {
expect(leaf1.execute).toHaveBeenCalled(); expect(leaf1.execute).toHaveBeenCalled();
}); });
it("runs specified leaves before non-specified leaves", function() { it("runs specified leaves before non-specified leaves within a parent node", function() {
var specified = new Leaf(), var specified = new Leaf(),
nonSpecified = new Leaf(), nonSpecified = new Leaf(),
root = new Node({ children: [nonSpecified, specified] }), root = new Node({ children: [nonSpecified, specified] }),
@@ -469,11 +504,11 @@ describe("TreeProcessor", function() {
queueableFns[0].fn(); queueableFns[0].fn();
expect(nonSpecified.execute).not.toHaveBeenCalled(); expect(nonSpecified.execute).not.toHaveBeenCalled();
expect(specified.execute).toHaveBeenCalledWith(undefined, true); expect(specified.execute).toHaveBeenCalledWith(undefined, false);
queueableFns[1].fn(); queueableFns[1].fn();
expect(nonSpecified.execute).toHaveBeenCalledWith(undefined, false); expect(nonSpecified.execute).toHaveBeenCalledWith(undefined, true);
}); });
it("runs nodes and leaves with a specified order", function() { it("runs nodes and leaves with a specified order", function() {
@@ -692,7 +727,7 @@ describe("TreeProcessor", function() {
expect(leaf11.execute).toHaveBeenCalled(); expect(leaf11.execute).toHaveBeenCalled();
}); });
it("runs nodes in a custom order when orderChildren is overrided", function() { it("runs nodes in a custom order when orderChildren is overridden", function() {
var leaf1 = new Leaf(), var leaf1 = new Leaf(),
leaf2 = new Leaf(), leaf2 = new Leaf(),
leaf3 = new Leaf(), leaf3 = new Leaf(),

View File

@@ -747,6 +747,47 @@ describe("Env integration", function() {
env.execute([first_spec.id, second_spec.id]); env.execute([first_spec.id, second_spec.id]);
}); });
it("Allows filtering out specs and suites to run programmatically", function(done) {
var env = new jasmineUnderTest.Env(),
calls = [],
suiteCallback = jasmine.createSpy('suite callback'),
firstSpec,
secondSuite;
var assertions = function() {
expect(calls.length).toEqual(2);
expect(calls).toEqual(jasmine.arrayContaining([
'first spec',
'second spec'
]));
expect(suiteCallback).toHaveBeenCalled();
done();
};
env.addReporter({jasmineDone: assertions, suiteDone: suiteCallback});
env.describe("first suite", function() {
env.it("first spec", function() {
calls.push('first spec');
});
env.it("second spec", function() {
calls.push('second spec');
});
});
secondSuite = env.describe("second suite", function() {
env.it("third spec", function() {
calls.push('third spec');
});
});
env.specFilter = function(spec) {
return /^first suite/.test(spec.getFullName());
};
env.execute();
});
it("Functions can be spied on and have their calls tracked", function (done) { it("Functions can be spied on and have their calls tracked", function (done) {
var env = new jasmineUnderTest.Env(); var env = new jasmineUnderTest.Env();
@@ -1508,7 +1549,7 @@ describe("Env integration", function() {
order: jasmine.any(jasmineUnderTest.Order) order: jasmine.any(jasmineUnderTest.Order)
}); });
expect(reporter.specDone).toHaveBeenCalledWith(jasmine.objectContaining({ status: 'disabled' })); expect(reporter.specDone).toHaveBeenCalledWith(jasmine.objectContaining({ status: 'pending' }));
expect(reporter.suiteDone).toHaveBeenCalledWith(jasmine.objectContaining({ description: 'xd out', status: 'pending' })); expect(reporter.suiteDone).toHaveBeenCalledWith(jasmine.objectContaining({ description: 'xd out', status: 'pending' }));
expect(reporter.suiteDone.calls.count()).toBe(4); expect(reporter.suiteDone.calls.count()).toBe(4);

View File

@@ -286,6 +286,7 @@ getJasmineRequireObj().Env = function(j$) {
}; };
this.execute = function(runnablesToRun) { this.execute = function(runnablesToRun) {
var self = this;
this.suppressLoadErrors(); this.suppressLoadErrors();
if(!runnablesToRun) { if(!runnablesToRun) {
@@ -315,9 +316,7 @@ getJasmineRequireObj().Env = function(j$) {
throw new Error('Tried to complete the wrong suite'); throw new Error('Tried to complete the wrong suite');
} }
if (!suite.markedPending) { clearResourcesForRunnable(suite.id);
clearResourcesForRunnable(suite.id);
}
currentlyExecutingSuites.pop(); currentlyExecutingSuites.pop();
reporter.suiteDone(result); reporter.suiteDone(result);
@@ -327,6 +326,9 @@ getJasmineRequireObj().Env = function(j$) {
}, },
orderChildren: function(node) { orderChildren: function(node) {
return order.sort(node.children); return order.sort(node.children);
},
excludeNode: function(spec) {
return !self.specFilter(spec);
} }
}); });
@@ -577,10 +579,6 @@ getJasmineRequireObj().Env = function(j$) {
throwOnExpectationFailure: throwOnExpectationFailure throwOnExpectationFailure: throwOnExpectationFailure
}); });
if (!self.specFilter(spec)) {
spec.disable();
}
return spec; return spec;
function specResultCallback(result) { function specResultCallback(result) {

View File

@@ -55,7 +55,7 @@ getJasmineRequireObj().Spec = function(j$) {
return this.expectationFactory(actual, this); return this.expectationFactory(actual, this);
}; };
Spec.prototype.execute = function(onComplete, enabled) { Spec.prototype.execute = function(onComplete, excluded) {
var self = this; var self = this;
this.onStart(this); this.onStart(this);
@@ -72,17 +72,16 @@ getJasmineRequireObj().Spec = function(j$) {
userContext: this.userContext() userContext: this.userContext()
}; };
if (!this.isExecutable() || this.markedPending || enabled === false) { if (this.markedPending || excluded === true) {
runnerConfig.queueableFns = []; runnerConfig.queueableFns = [];
runnerConfig.cleanupFns = []; runnerConfig.cleanupFns = [];
runnerConfig.onComplete = function() { complete(enabled); };
} }
this.queueRunnerFactory(runnerConfig); this.queueRunnerFactory(runnerConfig);
function complete(enabledAgain) { function complete() {
self.queueableFn.fn = null; self.queueableFn.fn = null;
self.result.status = self.status(enabledAgain); self.result.status = self.status(excluded);
self.resultCallback(self.result); self.resultCallback(self.result);
if (onComplete) { if (onComplete) {
@@ -110,10 +109,6 @@ getJasmineRequireObj().Spec = function(j$) {
}, true); }, true);
}; };
Spec.prototype.disable = function() {
this.disabled = true;
};
Spec.prototype.pend = function(message) { Spec.prototype.pend = function(message) {
this.markedPending = true; this.markedPending = true;
if (message) { if (message) {
@@ -126,9 +121,9 @@ getJasmineRequireObj().Spec = function(j$) {
return this.result; return this.result;
}; };
Spec.prototype.status = function(enabled) { Spec.prototype.status = function(excluded) {
if (this.disabled || enabled === false) { if (excluded === true) {
return 'disabled'; return 'excluded';
} }
if (this.markedPending) { if (this.markedPending) {
@@ -142,10 +137,6 @@ getJasmineRequireObj().Spec = function(j$) {
} }
}; };
Spec.prototype.isExecutable = function() {
return !this.disabled;
};
Spec.prototype.getFullName = function() { Spec.prototype.getFullName = function() {
return this.getSpecName(this); return this.getSpecName(this);
}; };

View File

@@ -90,14 +90,10 @@ getJasmineRequireObj().Suite = function(j$) {
if (this.result.failedExpectations.length > 0) { if (this.result.failedExpectations.length > 0) {
return 'failed'; return 'failed';
} else { } else {
return 'finished'; return 'passed';
} }
}; };
Suite.prototype.isExecutable = function() {
return !this.markedPending;
};
Suite.prototype.canBeReentered = function() { Suite.prototype.canBeReentered = function() {
return this.beforeAllFns.length === 0 && this.afterAllFns.length === 0; return this.beforeAllFns.length === 0 && this.afterAllFns.length === 0;
}; };

View File

@@ -6,13 +6,14 @@ getJasmineRequireObj().TreeProcessor = function() {
nodeStart = attrs.nodeStart || function() {}, nodeStart = attrs.nodeStart || function() {},
nodeComplete = attrs.nodeComplete || function() {}, nodeComplete = attrs.nodeComplete || function() {},
orderChildren = attrs.orderChildren || function(node) { return node.children; }, orderChildren = attrs.orderChildren || function(node) { return node.children; },
excludeNode = attrs.excludeNode || function(node) { return false; },
stats = { valid: true }, stats = { valid: true },
processed = false, processed = false,
defaultMin = Infinity, defaultMin = Infinity,
defaultMax = 1 - Infinity; defaultMax = 1 - Infinity;
this.processTree = function() { this.processTree = function() {
processNode(tree, false); processNode(tree, true);
processed = true; processed = true;
return stats; return stats;
}; };
@@ -46,18 +47,18 @@ getJasmineRequireObj().TreeProcessor = function() {
} }
} }
function processNode(node, parentEnabled) { function processNode(node, parentExcluded) {
var executableIndex = runnableIndex(node.id); var executableIndex = runnableIndex(node.id);
if (executableIndex !== undefined) { if (executableIndex !== undefined) {
parentEnabled = true; parentExcluded = false;
} }
parentEnabled = parentEnabled && node.isExecutable();
if (!node.children) { if (!node.children) {
var excluded = parentExcluded || excludeNode(node);
stats[node.id] = { stats[node.id] = {
executable: parentEnabled && node.isExecutable(), excluded: excluded,
willExecute: !excluded && !node.markedPending,
segments: [{ segments: [{
index: 0, index: 0,
owner: node, owner: node,
@@ -74,7 +75,7 @@ getJasmineRequireObj().TreeProcessor = function() {
for (var i = 0; i < orderedChildren.length; i++) { for (var i = 0; i < orderedChildren.length; i++) {
var child = orderedChildren[i]; var child = orderedChildren[i];
processNode(child, parentEnabled); processNode(child, parentExcluded);
if (!stats.valid) { if (!stats.valid) {
return; return;
@@ -82,11 +83,12 @@ getJasmineRequireObj().TreeProcessor = function() {
var childStats = stats[child.id]; var childStats = stats[child.id];
hasExecutableChild = hasExecutableChild || childStats.executable; hasExecutableChild = hasExecutableChild || childStats.willExecute;
} }
stats[node.id] = { stats[node.id] = {
executable: hasExecutableChild excluded: parentExcluded,
willExecute: hasExecutableChild
}; };
segmentChildren(node, orderedChildren, stats[node.id], executableIndex); segmentChildren(node, orderedChildren, stats[node.id], executableIndex);
@@ -182,7 +184,7 @@ getJasmineRequireObj().TreeProcessor = function() {
}; };
} else { } else {
return { return {
fn: function(done) { node.execute(done, stats[node.id].executable); } fn: function(done) { node.execute(done, stats[node.id].excluded); }
}; };
} }
} }
@@ -195,7 +197,7 @@ getJasmineRequireObj().TreeProcessor = function() {
result.push(executeNode(segmentChildren[i].owner, segmentChildren[i].index)); result.push(executeNode(segmentChildren[i].owner, segmentChildren[i].index));
} }
if (!stats[node.id].executable) { if (!stats[node.id].willExecute) {
return result; return result;
} }