diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index 017417b2..d7154461 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -525,7 +525,7 @@ getJasmineRequireObj().Spec = function(j$) { return this.expectationFactory(actual, this); }; - Spec.prototype.execute = function(onComplete, enabled) { + Spec.prototype.execute = function(onComplete, excluded) { var self = this; this.onStart(this); @@ -542,17 +542,16 @@ getJasmineRequireObj().Spec = function(j$) { userContext: this.userContext() }; - if (!this.isExecutable() || this.markedPending || enabled === false) { + if (this.markedPending || excluded === true) { runnerConfig.queueableFns = []; runnerConfig.cleanupFns = []; - runnerConfig.onComplete = function() { complete(enabled); }; } this.queueRunnerFactory(runnerConfig); - function complete(enabledAgain) { + function complete() { self.queueableFn.fn = null; - self.result.status = self.status(enabledAgain); + self.result.status = self.status(excluded); self.resultCallback(self.result); if (onComplete) { @@ -580,10 +579,6 @@ getJasmineRequireObj().Spec = function(j$) { }, true); }; - Spec.prototype.disable = function() { - this.disabled = true; - }; - Spec.prototype.pend = function(message) { this.markedPending = true; if (message) { @@ -596,9 +591,9 @@ getJasmineRequireObj().Spec = function(j$) { return this.result; }; - Spec.prototype.status = function(enabled) { - if (this.disabled || enabled === false) { - return 'disabled'; + Spec.prototype.status = function(excluded) { + if (excluded === true) { + return 'excluded'; } if (this.markedPending) { @@ -612,10 +607,6 @@ getJasmineRequireObj().Spec = function(j$) { } }; - Spec.prototype.isExecutable = function() { - return !this.disabled; - }; - Spec.prototype.getFullName = function() { return this.getSpecName(this); }; @@ -976,6 +967,7 @@ getJasmineRequireObj().Env = function(j$) { }; this.execute = function(runnablesToRun) { + var self = this; this.suppressLoadErrors(); if(!runnablesToRun) { @@ -1005,9 +997,7 @@ getJasmineRequireObj().Env = function(j$) { throw new Error('Tried to complete the wrong suite'); } - if (!suite.markedPending) { - clearResourcesForRunnable(suite.id); - } + clearResourcesForRunnable(suite.id); currentlyExecutingSuites.pop(); reporter.suiteDone(result); @@ -1017,6 +1007,9 @@ getJasmineRequireObj().Env = function(j$) { }, orderChildren: function(node) { return order.sort(node.children); + }, + excludeNode: function(spec) { + return !self.specFilter(spec); } }); @@ -1267,10 +1260,6 @@ getJasmineRequireObj().Env = function(j$) { throwOnExpectationFailure: throwOnExpectationFailure }); - if (!self.specFilter(spec)) { - spec.disable(); - } - return spec; function specResultCallback(result) { @@ -5610,14 +5599,10 @@ getJasmineRequireObj().Suite = function(j$) { if (this.result.failedExpectations.length > 0) { return 'failed'; } else { - return 'finished'; + return 'passed'; } }; - Suite.prototype.isExecutable = function() { - return !this.markedPending; - }; - Suite.prototype.canBeReentered = function() { return this.beforeAllFns.length === 0 && this.afterAllFns.length === 0; }; @@ -5712,13 +5697,14 @@ getJasmineRequireObj().TreeProcessor = function() { nodeStart = attrs.nodeStart || function() {}, nodeComplete = attrs.nodeComplete || function() {}, orderChildren = attrs.orderChildren || function(node) { return node.children; }, + excludeNode = attrs.excludeNode || function(node) { return false; }, stats = { valid: true }, processed = false, defaultMin = Infinity, defaultMax = 1 - Infinity; this.processTree = function() { - processNode(tree, false); + processNode(tree, true); processed = true; return stats; }; @@ -5752,18 +5738,18 @@ getJasmineRequireObj().TreeProcessor = function() { } } - function processNode(node, parentEnabled) { + function processNode(node, parentExcluded) { var executableIndex = runnableIndex(node.id); if (executableIndex !== undefined) { - parentEnabled = true; + parentExcluded = false; } - parentEnabled = parentEnabled && node.isExecutable(); - if (!node.children) { + var excluded = parentExcluded || excludeNode(node); stats[node.id] = { - executable: parentEnabled && node.isExecutable(), + excluded: excluded, + willExecute: !excluded && !node.markedPending, segments: [{ index: 0, owner: node, @@ -5780,7 +5766,7 @@ getJasmineRequireObj().TreeProcessor = function() { for (var i = 0; i < orderedChildren.length; i++) { var child = orderedChildren[i]; - processNode(child, parentEnabled); + processNode(child, parentExcluded); if (!stats.valid) { return; @@ -5788,11 +5774,12 @@ getJasmineRequireObj().TreeProcessor = function() { var childStats = stats[child.id]; - hasExecutableChild = hasExecutableChild || childStats.executable; + hasExecutableChild = hasExecutableChild || childStats.willExecute; } stats[node.id] = { - executable: hasExecutableChild + excluded: parentExcluded, + willExecute: hasExecutableChild }; segmentChildren(node, orderedChildren, stats[node.id], executableIndex); @@ -5888,7 +5875,7 @@ getJasmineRequireObj().TreeProcessor = function() { }; } else { 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)); } - if (!stats[node.id].executable) { + if (!stats[node.id].willExecute) { return result; } diff --git a/spec/core/JsApiReporterSpec.js b/spec/core/JsApiReporterSpec.js index 8e6564d8..f7fe8141 100644 --- a/spec/core/JsApiReporterSpec.js +++ b/spec/core/JsApiReporterSpec.js @@ -192,7 +192,7 @@ describe("JsApiReporter", function() { }; suiteResult2 = { id: 2, - status: 'finished' + status: 'passed' }; reporter.suiteStarted(suiteStarted1); diff --git a/spec/core/SpecSpec.js b/spec/core/SpecSpec.js index 8bc538da..9a32101e 100644 --- a/spec/core/SpecSpec.js +++ b/spec/core/SpecSpec.js @@ -140,7 +140,7 @@ describe("Spec", function() { 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') .and.callFake(function(attrs) { attrs.onComplete(); }), startCallback = jasmine.createSpy('startCallback'), @@ -153,35 +153,9 @@ describe("Spec", function() { queueRunnerFactory: fakeQueueRunner }); - spec.disable(); + spec.execute(undefined, true); - expect(spec.status()).toBe('disabled'); - - 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(spec.result.status).toBe('excluded'); expect(fakeQueueRunner).toHaveBeenCalled(); expect(specBody).not.toHaveBeenCalled(); @@ -392,50 +366,4 @@ describe("Spec", function() { 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); - }); }); diff --git a/spec/core/SuiteSpec.js b/spec/core/SuiteSpec.js index 78e78565..fd9144d9 100644 --- a/spec/core/SuiteSpec.js +++ b/spec/core/SuiteSpec.js @@ -79,7 +79,7 @@ describe("Suite", function() { it("retrieves a result with updated status", function() { 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() { @@ -89,19 +89,6 @@ describe("Suite", function() { 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() { var suite = new jasmineUnderTest.Suite({ expectationResultFactory: function(data) { return data; }, diff --git a/spec/core/TreeProcessorSpec.js b/spec/core/TreeProcessorSpec.js index c702d0cc..d8426144 100644 --- a/spec/core/TreeProcessorSpec.js +++ b/spec/core/TreeProcessorSpec.js @@ -8,9 +8,7 @@ describe("TreeProcessor", function() { this.canBeReentered = function() { return !attrs.noReenter; }; - this.isExecutable = function() { - return attrs.executable !== false; - }; + this.markedPending = attrs.markedPending || false; this.sharedUserContext = function() { return attrs.userContext || {}; }; @@ -23,13 +21,11 @@ describe("TreeProcessor", function() { function Leaf(attrs) { attrs = attrs || {}; this.id = 'leaf' + leafNumber++; - this.isExecutable = function() { - return attrs.executable !== false; - }; + this.markedPending = attrs.markedPending || false; this.execute = jasmine.createSpy(this.id + '#execute'); } - it("processes a single executable leaf", function() { + it("processes a single leaf", function() { var leaf = new Leaf(), processor = new jasmineUnderTest.TreeProcessor({ tree: leaf, runnableIds: [leaf.id] }), result = processor.processTree(); @@ -37,20 +33,22 @@ describe("TreeProcessor", function() { expect(result.valid).toBe(true); expect(result[leaf.id]).toEqual({ - executable: true, + excluded: false, + willExecute: true, segments: jasmine.any(Array) }); }); - it("processes a single non-executable leaf", function() { - var leaf = new Leaf({ executable: false }), + it("processes a single pending leaf", function() { + var leaf = new Leaf({ markedPending: true }), processor = new jasmineUnderTest.TreeProcessor({ tree: leaf, runnableIds: [leaf.id] }), result = processor.processTree(); expect(result.valid).toBe(true); expect(result[leaf.id]).toEqual({ - executable: false, + excluded: false, + willExecute: false, segments: jasmine.any(Array) }); }); @@ -63,7 +61,26 @@ describe("TreeProcessor", function() { expect(result.valid).toBe(true); 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) }); }); @@ -77,18 +94,20 @@ describe("TreeProcessor", function() { expect(result.valid).toBe(true); expect(result[parent.id]).toEqual({ - executable: true, + excluded: false, + willExecute: true, segments: jasmine.any(Array) }); expect(result[leaf.id]).toEqual({ - executable: true, + excluded: false, + willExecute: true, segments: jasmine.any(Array) }); }); - it("processes a tree with a single non-executable leaf, with the root specified", function() { - var leaf = new Leaf({ executable: false }), + it("processes a tree with a single pending leaf, with the root specified", function() { + var leaf = new Leaf({ markedPending: true }), parent = new Node({ children: [leaf] }), processor = new jasmineUnderTest.TreeProcessor({ tree: parent, runnableIds: [parent.id] }), result = processor.processTree(); @@ -96,61 +115,77 @@ describe("TreeProcessor", function() { expect(result.valid).toBe(true); expect(result[parent.id]).toEqual({ - executable: false, + excluded: false, + willExecute: false, segments: jasmine.any(Array) }); expect(result[leaf.id]).toEqual({ - executable: false, + excluded: false, + willExecute: false, segments: jasmine.any(Array) }); }); it("processes a complicated tree with the root specified", function() { - var nonExecutable = new Leaf({ executable: false }), - executable = new Leaf({ executable: true }), - parent = new Node({ children: [nonExecutable, executable] }), + var pendingLeaf = new Leaf({ markedPending: true }), + executableLeaf = new Leaf({ markedPending: false }), + parent = new Node({ children: [pendingLeaf, executableLeaf] }), childless = new Node(), - childOfDisabled = new Leaf({ executable: true }), - disabledNode = new Node({ executable: false, children: [childOfDisabled] }), - root = new Node({ children: [parent, childless, disabledNode] }), + childOfPending = new Leaf({ markedPending: true }), + pendingNode = new Node({ markedPending: true, children: [childOfPending] }), + parentOfPendings = new Node({ markedPending: false, children: [childless, pendingNode] }), + root = new Node({ children: [parent, parentOfPendings] }), processor = new jasmineUnderTest.TreeProcessor({ tree: root, runnableIds: [root.id] }), result = processor.processTree(); expect(result.valid).toBe(true); 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) }); expect(result[childless.id]).toEqual({ - executable: false, + excluded: false, + willExecute: false, segments: jasmine.any(Array) }); - expect(result[nonExecutable.id]).toEqual({ - executable: false, + expect(result[pendingLeaf.id]).toEqual({ + excluded: false, + willExecute: false, segments: jasmine.any(Array) }); - expect(result[executable.id]).toEqual({ - executable: true, + expect(result[executableLeaf.id]).toEqual({ + excluded: false, + willExecute: true, segments: jasmine.any(Array) }); expect(result[parent.id]).toEqual({ - executable: true, + excluded: false, + willExecute: true, segments: jasmine.any(Array) }); - expect(result[disabledNode.id]).toEqual({ - executable: false, + expect(result[pendingNode.id]).toEqual({ + excluded: false, + willExecute: false, segments: jasmine.any(Array) }); - expect(result[childOfDisabled.id]).toEqual({ - executable: false, + expect(result[childOfPending.id]).toEqual({ + excluded: false, + willExecute: false, segments: jasmine.any(Array) }); }); @@ -219,7 +254,7 @@ describe("TreeProcessor", function() { 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() { @@ -286,22 +321,22 @@ describe("TreeProcessor", function() { expect(queueableFns.length).toBe(2); queueableFns[0].fn('foo'); - expect(leaf1.execute).toHaveBeenCalledWith('foo', true); + expect(leaf1.execute).toHaveBeenCalledWith('foo', false); 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(), - node = new Node({ children: [leaf1], executable: false }), + node = new Node({ children: [leaf1] }), root = new Node({ children: [node] }), queueRunner = jasmine.createSpy('queueRunner'), nodeStart = jasmine.createSpy('nodeStart'), nodeComplete = jasmine.createSpy('nodeComplete'), processor = new jasmineUnderTest.TreeProcessor({ tree: root, - runnableIds: [node.id], + runnableIds: [], queueRunnerFactory: queueRunner, nodeStart: nodeStart, nodeComplete: nodeComplete @@ -319,7 +354,7 @@ describe("TreeProcessor", function() { expect(queueableFns.length).toBe(1); queueableFns[0].fn('foo'); - expect(leaf1.execute).toHaveBeenCalledWith('foo', false); + expect(leaf1.execute).toHaveBeenCalledWith('foo', true); node.getResult.and.returnValue({ im: 'disabled' }); @@ -401,13 +436,13 @@ describe("TreeProcessor", function() { expect(queueableFns).toEqual([]); }); - it("does not run beforeAlls or afterAlls for a disabled node", function() { - var leaf = new Leaf(), + it("does not run beforeAlls or afterAlls for a node with only pending children", function() { + var leaf = new Leaf({ markedPending: true }), node = new Node({ children: [leaf], beforeAllFns: ['before'], afterAllFns: ['after'], - executable: false + markedPending: false }), root = new Node({ children: [node] }), queueRunner = jasmine.createSpy('queueRunner'), @@ -452,7 +487,7 @@ describe("TreeProcessor", function() { 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(), nonSpecified = new Leaf(), root = new Node({ children: [nonSpecified, specified] }), @@ -469,11 +504,11 @@ describe("TreeProcessor", function() { queueableFns[0].fn(); expect(nonSpecified.execute).not.toHaveBeenCalled(); - expect(specified.execute).toHaveBeenCalledWith(undefined, true); + expect(specified.execute).toHaveBeenCalledWith(undefined, false); 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() { @@ -692,7 +727,7 @@ describe("TreeProcessor", function() { 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(), leaf2 = new Leaf(), leaf3 = new Leaf(), diff --git a/spec/core/integration/EnvSpec.js b/spec/core/integration/EnvSpec.js index 44198f75..6e71d3c7 100644 --- a/spec/core/integration/EnvSpec.js +++ b/spec/core/integration/EnvSpec.js @@ -418,7 +418,7 @@ describe("Env integration", function() { env.describe('a suite', function() { env.it('has a spec', function() {}); - + env.afterAll(function() { throw 'nope'; }); @@ -747,6 +747,47 @@ describe("Env integration", function() { 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) { var env = new jasmineUnderTest.Env(); @@ -1508,7 +1549,7 @@ describe("Env integration", function() { 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.calls.count()).toBe(4); @@ -2011,12 +2052,12 @@ describe("Env integration", function() { it('is "passed"', function(done) { var env = new jasmineUnderTest.Env(), reporter = jasmine.createSpyObj('reporter', ['jasmineDone', 'suiteDone', 'specDone']); - + reporter.jasmineDone.and.callFake(function(e) { expect(e.overallStatus).toEqual('passed'); done(); }); - + env.addReporter(reporter); env.it('passes', function() {}); env.execute(); @@ -2027,12 +2068,12 @@ describe("Env integration", function() { it('is "failed"', function(done) { var env = new jasmineUnderTest.Env(), reporter = jasmine.createSpyObj('reporter', ['jasmineDone', 'suiteDone', 'specDone']); - + reporter.jasmineDone.and.callFake(function(e) { expect(e.overallStatus).toEqual('failed'); done(); }); - + env.addReporter(reporter); env.it('fails', function() { env.expect(true).toBe(false); @@ -2045,12 +2086,12 @@ describe("Env integration", function() { it('is "failed"', function(done) { var env = new jasmineUnderTest.Env(), reporter = jasmine.createSpyObj('reporter', ['jasmineDone', 'suiteDone', 'specDone']); - + reporter.jasmineDone.and.callFake(function(e) { expect(e.overallStatus).toEqual('failed'); done(); }); - + env.addReporter(reporter); env.beforeAll(function() { throw new Error('nope'); @@ -2064,12 +2105,12 @@ describe("Env integration", function() { it('is "failed"', function(done) { var env = new jasmineUnderTest.Env(), reporter = jasmine.createSpyObj('reporter', ['jasmineDone', 'suiteDone', 'specDone']); - + reporter.jasmineDone.and.callFake(function(e) { expect(e.overallStatus).toEqual('failed'); done(); }); - + env.addReporter(reporter); env.describe('something', function() { env.beforeAll(function() { @@ -2085,12 +2126,12 @@ describe("Env integration", function() { it('is "failed"', function(done) { var env = new jasmineUnderTest.Env(), reporter = jasmine.createSpyObj('reporter', ['jasmineDone', 'suiteDone', 'specDone']); - + reporter.jasmineDone.and.callFake(function(e) { expect(e.overallStatus).toEqual('failed'); done(); }); - + env.addReporter(reporter); env.afterAll(function() { throw new Error('nope'); @@ -2104,12 +2145,12 @@ describe("Env integration", function() { it('is "failed"', function(done) { var env = new jasmineUnderTest.Env(), reporter = jasmine.createSpyObj('reporter', ['jasmineDone', 'suiteDone', 'specDone']); - + reporter.jasmineDone.and.callFake(function(e) { expect(e.overallStatus).toEqual('failed'); done(); }); - + env.addReporter(reporter); env.describe('something', function() { env.afterAll(function() { @@ -2148,13 +2189,13 @@ describe("Env integration", function() { it('is "incomplete"', function(done) { var env = new jasmineUnderTest.Env(), reporter = jasmine.createSpyObj('reporter', ['jasmineDone', 'suiteDone', 'specDone']); - + reporter.jasmineDone.and.callFake(function(e) { expect(e.overallStatus).toEqual('incomplete'); expect(e.incompleteReason).toEqual('No specs found'); done(); }); - + env.addReporter(reporter); env.execute(); }); @@ -2164,13 +2205,13 @@ describe("Env integration", function() { it('is "incomplete"', function(done) { var env = new jasmineUnderTest.Env(), reporter = jasmine.createSpyObj('reporter', ['jasmineDone', 'suiteDone', 'specDone']); - + reporter.jasmineDone.and.callFake(function(e) { expect(e.overallStatus).toEqual('incomplete'); expect(e.incompleteReason).toEqual('fit() or fdescribe() was found'); done(); }); - + env.addReporter(reporter); env.fit('is focused', function() {}); env.execute(); @@ -2181,13 +2222,13 @@ describe("Env integration", function() { it('is "incomplete"', function(done) { var env = new jasmineUnderTest.Env(), reporter = jasmine.createSpyObj('reporter', ['jasmineDone', 'suiteDone', 'specDone']); - + reporter.jasmineDone.and.callFake(function(e) { expect(e.overallStatus).toEqual('incomplete'); expect(e.incompleteReason).toEqual('fit() or fdescribe() was found'); done(); }); - + env.addReporter(reporter); env.fdescribe('something focused', function() { env.it('does a thing', function() {}); @@ -2200,13 +2241,13 @@ describe("Env integration", function() { it('is "failed"', function(done) { var env = new jasmineUnderTest.Env(), reporter = jasmine.createSpyObj('reporter', ['jasmineDone', 'suiteDone', 'specDone']); - + reporter.jasmineDone.and.callFake(function(e) { expect(e.overallStatus).toEqual('failed'); expect(e.incompleteReason).toBeUndefined(); done(); }); - + env.addReporter(reporter); env.fit('is focused', function() { env.expect(true).toBe(false); diff --git a/src/core/Env.js b/src/core/Env.js index 28ab5edd..a3ce0dd3 100644 --- a/src/core/Env.js +++ b/src/core/Env.js @@ -286,6 +286,7 @@ getJasmineRequireObj().Env = function(j$) { }; this.execute = function(runnablesToRun) { + var self = this; this.suppressLoadErrors(); if(!runnablesToRun) { @@ -315,9 +316,7 @@ getJasmineRequireObj().Env = function(j$) { throw new Error('Tried to complete the wrong suite'); } - if (!suite.markedPending) { - clearResourcesForRunnable(suite.id); - } + clearResourcesForRunnable(suite.id); currentlyExecutingSuites.pop(); reporter.suiteDone(result); @@ -327,6 +326,9 @@ getJasmineRequireObj().Env = function(j$) { }, orderChildren: function(node) { return order.sort(node.children); + }, + excludeNode: function(spec) { + return !self.specFilter(spec); } }); @@ -577,10 +579,6 @@ getJasmineRequireObj().Env = function(j$) { throwOnExpectationFailure: throwOnExpectationFailure }); - if (!self.specFilter(spec)) { - spec.disable(); - } - return spec; function specResultCallback(result) { diff --git a/src/core/Spec.js b/src/core/Spec.js index 7f2c1513..7f918067 100644 --- a/src/core/Spec.js +++ b/src/core/Spec.js @@ -55,7 +55,7 @@ getJasmineRequireObj().Spec = function(j$) { return this.expectationFactory(actual, this); }; - Spec.prototype.execute = function(onComplete, enabled) { + Spec.prototype.execute = function(onComplete, excluded) { var self = this; this.onStart(this); @@ -72,17 +72,16 @@ getJasmineRequireObj().Spec = function(j$) { userContext: this.userContext() }; - if (!this.isExecutable() || this.markedPending || enabled === false) { + if (this.markedPending || excluded === true) { runnerConfig.queueableFns = []; runnerConfig.cleanupFns = []; - runnerConfig.onComplete = function() { complete(enabled); }; } this.queueRunnerFactory(runnerConfig); - function complete(enabledAgain) { + function complete() { self.queueableFn.fn = null; - self.result.status = self.status(enabledAgain); + self.result.status = self.status(excluded); self.resultCallback(self.result); if (onComplete) { @@ -110,10 +109,6 @@ getJasmineRequireObj().Spec = function(j$) { }, true); }; - Spec.prototype.disable = function() { - this.disabled = true; - }; - Spec.prototype.pend = function(message) { this.markedPending = true; if (message) { @@ -126,9 +121,9 @@ getJasmineRequireObj().Spec = function(j$) { return this.result; }; - Spec.prototype.status = function(enabled) { - if (this.disabled || enabled === false) { - return 'disabled'; + Spec.prototype.status = function(excluded) { + if (excluded === true) { + return 'excluded'; } if (this.markedPending) { @@ -142,10 +137,6 @@ getJasmineRequireObj().Spec = function(j$) { } }; - Spec.prototype.isExecutable = function() { - return !this.disabled; - }; - Spec.prototype.getFullName = function() { return this.getSpecName(this); }; diff --git a/src/core/Suite.js b/src/core/Suite.js index 9e2e0bb1..ca7906a8 100644 --- a/src/core/Suite.js +++ b/src/core/Suite.js @@ -90,14 +90,10 @@ getJasmineRequireObj().Suite = function(j$) { if (this.result.failedExpectations.length > 0) { return 'failed'; } else { - return 'finished'; + return 'passed'; } }; - Suite.prototype.isExecutable = function() { - return !this.markedPending; - }; - Suite.prototype.canBeReentered = function() { return this.beforeAllFns.length === 0 && this.afterAllFns.length === 0; }; diff --git a/src/core/TreeProcessor.js b/src/core/TreeProcessor.js index 137f23b4..f633094c 100644 --- a/src/core/TreeProcessor.js +++ b/src/core/TreeProcessor.js @@ -6,13 +6,14 @@ getJasmineRequireObj().TreeProcessor = function() { nodeStart = attrs.nodeStart || function() {}, nodeComplete = attrs.nodeComplete || function() {}, orderChildren = attrs.orderChildren || function(node) { return node.children; }, + excludeNode = attrs.excludeNode || function(node) { return false; }, stats = { valid: true }, processed = false, defaultMin = Infinity, defaultMax = 1 - Infinity; this.processTree = function() { - processNode(tree, false); + processNode(tree, true); processed = true; return stats; }; @@ -46,18 +47,18 @@ getJasmineRequireObj().TreeProcessor = function() { } } - function processNode(node, parentEnabled) { + function processNode(node, parentExcluded) { var executableIndex = runnableIndex(node.id); if (executableIndex !== undefined) { - parentEnabled = true; + parentExcluded = false; } - parentEnabled = parentEnabled && node.isExecutable(); - if (!node.children) { + var excluded = parentExcluded || excludeNode(node); stats[node.id] = { - executable: parentEnabled && node.isExecutable(), + excluded: excluded, + willExecute: !excluded && !node.markedPending, segments: [{ index: 0, owner: node, @@ -74,7 +75,7 @@ getJasmineRequireObj().TreeProcessor = function() { for (var i = 0; i < orderedChildren.length; i++) { var child = orderedChildren[i]; - processNode(child, parentEnabled); + processNode(child, parentExcluded); if (!stats.valid) { return; @@ -82,11 +83,12 @@ getJasmineRequireObj().TreeProcessor = function() { var childStats = stats[child.id]; - hasExecutableChild = hasExecutableChild || childStats.executable; + hasExecutableChild = hasExecutableChild || childStats.willExecute; } stats[node.id] = { - executable: hasExecutableChild + excluded: parentExcluded, + willExecute: hasExecutableChild }; segmentChildren(node, orderedChildren, stats[node.id], executableIndex); @@ -182,7 +184,7 @@ getJasmineRequireObj().TreeProcessor = function() { }; } else { 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)); } - if (!stats[node.id].executable) { + if (!stats[node.id].willExecute) { return result; }