diff options
| author | Elliott Sprehn | 2010-10-19 13:17:49 -0700 |
|---|---|---|
| committer | Elliott Sprehn | 2010-10-20 14:38:00 -0700 |
| commit | 2115db69035c5993533fe7a3825e64cf6e9068ad (patch) | |
| tree | 796a502b28cd2bda8108a672eac0bf28c8bc21d4 /test | |
| parent | 9c8b1800b90e14b643bab6ada8e96f8f850e84a6 (diff) | |
| download | angular.js-2115db69035c5993533fe7a3825e64cf6e9068ad.tar.bz2 | |
Lots of stability and performance updates and UI polish too.
Polish the Scenario Runner UI to include:
- a scroll pane that steps appear in since the list can be very long
- Collapse successful tests
- Show the line where the DSL statements were when there's an error (Chrome, Firefox)
Also:
- Remove lots angular.bind calls to reduce the amount of stack space used.
- Use setTimeout(...,0) to schedule the next future to let the browser breathe and have it repaint the steps. Also prevents overflowing the stack when an it() creates many futures.
- Run afterEach() handlers even if the it() block fails.
- Make navigateTo() take a function as the second argument so you can compute a URL in the future.
- Add wait() DSL statement to allow interactive debugging of tests.
- Allow custom jQuery selectors with element(...).query(fn) DSL statement.
Known Issues:
- All afterEach() handlers run even if a beforeEach() handler fails. Only after handlers for the same level as the failure and above should run.
Diffstat (limited to 'test')
| -rw-r--r-- | test/scenario/DescribeSpec.js | 8 | ||||
| -rw-r--r-- | test/scenario/FutureSpec.js | 3 | ||||
| -rw-r--r-- | test/scenario/HtmlUISpec.js | 41 | ||||
| -rw-r--r-- | test/scenario/RunnerSpec.js | 22 | ||||
| -rw-r--r-- | test/scenario/SpecRunnerSpec.js | 73 | ||||
| -rw-r--r-- | test/scenario/dslSpec.js | 33 |
6 files changed, 139 insertions, 41 deletions
diff --git a/test/scenario/DescribeSpec.js b/test/scenario/DescribeSpec.js index 05129cfe..417a0d2e 100644 --- a/test/scenario/DescribeSpec.js +++ b/test/scenario/DescribeSpec.js @@ -38,12 +38,16 @@ describe('angular.scenario.Describe', function() { expect(specs.length).toEqual(2); expect(specs[0].name).toEqual('2'); - specs[0].fn(); + specs[0].before(); + specs[0].body(); + specs[0].after(); expect(log.text).toEqual('{(2)}'); log.reset(); expect(specs[1].name).toEqual('1'); - specs[1].fn(); + specs[1].before(); + specs[1].body(); + specs[1].after(); expect(log.text).toEqual('{1}'); }); diff --git a/test/scenario/FutureSpec.js b/test/scenario/FutureSpec.js index 1e6af7a1..52bd9c66 100644 --- a/test/scenario/FutureSpec.js +++ b/test/scenario/FutureSpec.js @@ -3,9 +3,10 @@ describe('angular.scenario.Future', function() { it('should set the sane defaults', function() { var behavior = function() {}; - var future = new angular.scenario.Future('test name', behavior); + var future = new angular.scenario.Future('test name', behavior, 'foo'); expect(future.name).toEqual('test name'); expect(future.behavior).toEqual(behavior); + expect(future.line).toEqual('foo'); expect(future.value).toBeUndefined(); expect(future.fulfilled).toBeFalsy(); expect(future.parser).toEqual(angular.identity); diff --git a/test/scenario/HtmlUISpec.js b/test/scenario/HtmlUISpec.js index 5b800fca..9357e00b 100644 --- a/test/scenario/HtmlUISpec.js +++ b/test/scenario/HtmlUISpec.js @@ -2,6 +2,8 @@ describe('angular.scenario.HtmlUI', function() { var ui; var context; var spec; + + function line() { return 'unknown:-1'; } beforeEach(function() { spec = { @@ -35,44 +37,44 @@ describe('angular.scenario.HtmlUI', function() { it('should update totals when steps complete', function() { // Error ui.addSpec(spec).error('error'); - // Error - specUI = ui.addSpec(spec); - specUI.addStep('some step').finish(); - specUI.finish('error'); // Failure specUI = ui.addSpec(spec); - specUI.addStep('some step').finish('failure'); - specUI.finish('failure'); + specUI.addStep('some step', line).finish('failure'); + specUI.finish(); // Failure specUI = ui.addSpec(spec); - specUI.addStep('some step').finish('failure'); - specUI.finish('failure'); + specUI.addStep('some step', line).finish('failure'); + specUI.finish(); // Failure specUI = ui.addSpec(spec); - specUI.addStep('some step').finish('failure'); - specUI.finish('failure'); + specUI.addStep('some step', line).finish('failure'); + specUI.finish(); // Success specUI = ui.addSpec(spec); - specUI.addStep('some step').finish(); + specUI.addStep('some step', line).finish(); + specUI.finish(); + // Success + specUI = ui.addSpec(spec); + specUI.addStep('another step', line).finish(); specUI.finish(); expect(parseInt(context.find('#status-legend .status-failure').text(), 10)). toEqual(3); - expect(parseInt(context.find('#status-legend .status-error').text(), 10)). - toEqual(2); expect(parseInt(context.find('#status-legend .status-success').text(), 10)). + toEqual(2); + expect(parseInt(context.find('#status-legend .status-error').text(), 10)). toEqual(1); }); it('should update timer when test completes', function() { // Success specUI = ui.addSpec(spec); - specUI.addStep('some step').finish(); + specUI.addStep('some step', line).finish(); specUI.finish(); // Failure specUI = ui.addSpec(spec); - specUI.addStep('some step').finish('failure'); + specUI.addStep('some step', line).finish('failure'); specUI.finish('failure'); // Error @@ -83,5 +85,14 @@ describe('angular.scenario.HtmlUI', function() { expect(timer.innerHTML).toMatch(/ms$/); }); }); + + it('should include line if provided', function() { + specUI = ui.addSpec(spec); + specUI.addStep('some step', line).finish('error!'); + specUI.finish(); + + var errorHtml = context.find('#describe-10 .tests li pre').html(); + expect(errorHtml.indexOf('unknown:-1')).toEqual(0); + }); }); diff --git a/test/scenario/RunnerSpec.js b/test/scenario/RunnerSpec.js index 43d97257..d34a228c 100644 --- a/test/scenario/RunnerSpec.js +++ b/test/scenario/RunnerSpec.js @@ -3,16 +3,28 @@ */ function MockSpecRunner() {} MockSpecRunner.prototype.run = function(ui, spec, specDone) { - spec.fn.call(this); + spec.before.call(this); + spec.body.call(this); + spec.after.call(this); specDone(); }; +MockSpecRunner.prototype.addFuture = function(name, fn, line) { + return {name: name, fn: fn, line: line}; +}; + describe('angular.scenario.Runner', function() { var $window; var runner; beforeEach(function() { // Trick to get the scope out of a DSL statement + angular.scenario.dsl('dslAddFuture', function() { + return function() { + return this.addFuture('future name', angular.noop); + }; + }); + // Trick to get the scope out of a DSL statement angular.scenario.dsl('dslScope', function() { var scope = this; return function() { return scope; }; @@ -25,7 +37,9 @@ describe('angular.scenario.Runner', function() { return this; }; }); - $window = {}; + $window = { + location: {} + }; runner = new angular.scenario.Runner($window); }); @@ -63,7 +77,9 @@ describe('angular.scenario.Runner', function() { }); }); var specs = runner.rootDescribe.getSpecs(); - specs[0].fn(); + specs[0].before(); + specs[0].body(); + specs[0].after(); expect(before).toEqual(['A', 'B', 'C']); expect(after).toEqual(['C', 'B', 'A']); expect(specs[2].definition.parent).toEqual(runner.rootDescribe); diff --git a/test/scenario/SpecRunnerSpec.js b/test/scenario/SpecRunnerSpec.js index e62bb392..dd7a1b72 100644 --- a/test/scenario/SpecRunnerSpec.js +++ b/test/scenario/SpecRunnerSpec.js @@ -49,11 +49,24 @@ ApplicationMock.prototype = { describe('angular.scenario.SpecRunner', function() { var $window; var runner; + + function createSpec(name, body) { + return { + name: name, + before: angular.noop, + body: body || angular.noop, + after: angular.noop + }; + } beforeEach(function() { $window = {}; + $window.setTimeout = function(fn, timeout) { + fn(); + }; runner = angular.scope(); runner.application = new ApplicationMock($window); + runner.$window = $window; runner.$become(angular.scenario.SpecRunner); }); @@ -78,11 +91,11 @@ describe('angular.scenario.SpecRunner', function() { }); it('should execute spec function and notify UI', function() { - var finished = false; + var finished; var ui = new UIMock(); - var spec = {name: 'test spec', fn: function() { - this.test = 'some value'; - }}; + var spec = createSpec('test spec', function() { + this.test = 'some value'; + }); runner.addFuture('test future', function(done) { done(); }); @@ -100,11 +113,11 @@ describe('angular.scenario.SpecRunner', function() { }); it('should execute notify UI on spec setup error', function() { - var finished = false; + var finished; var ui = new UIMock(); - var spec = {name: 'test spec', fn: function() { + var spec = createSpec('test spec', function() { throw 'message'; - }}; + }); runner.run(ui, spec, function() { finished = true; }); @@ -116,9 +129,9 @@ describe('angular.scenario.SpecRunner', function() { }); it('should execute notify UI on step failure', function() { - var finished = false; + var finished; var ui = new UIMock(); - var spec = {name: 'test spec', fn: angular.noop}; + var spec = createSpec('test spec'); runner.addFuture('test future', function(done) { done('failure message'); }); @@ -130,16 +143,17 @@ describe('angular.scenario.SpecRunner', function() { 'addSpec:test spec', 'addStep:test future', 'step finish:failure message', - 'spec finish:failure message' + 'spec finish:' ]); }); it('should execute notify UI on step error', function() { - var finished = false; + var finished; var ui = new UIMock(); - var spec = {name: 'test spec', fn: angular.noop}; - runner.addFuture('test future', function(done) { - throw 'error message'; + var spec = createSpec('test spec', function() { + this.addFuture('test future', function(done) { + throw 'error message'; + }); }); runner.run(ui, spec, function() { finished = true; @@ -149,7 +163,36 @@ describe('angular.scenario.SpecRunner', function() { 'addSpec:test spec', 'addStep:test future', 'step error:error message', - 'spec finish:error message' + 'spec finish:' + ]); + }); + + it('should run after handlers even if error in body of spec', function() { + var finished, after; + var ui = new UIMock(); + var spec = createSpec('test spec', function() { + this.addFuture('body', function(done) { + throw 'error message'; + }); + }); + spec.after = function() { + this.addFuture('after', function(done) { + after = true; + done(); + }); + }; + runner.run(ui, spec, function() { + finished = true; + }); + expect(finished).toBeTruthy(); + expect(after).toBeTruthy(); + expect(ui.log).toEqual([ + 'addSpec:test spec', + 'addStep:body', + 'step error:error message', + 'addStep:after', + 'step finish:', + 'spec finish:' ]); }); diff --git a/test/scenario/dslSpec.js b/test/scenario/dslSpec.js index dd489d86..0d523ad3 100644 --- a/test/scenario/dslSpec.js +++ b/test/scenario/dslSpec.js @@ -35,13 +35,16 @@ describe("angular.scenario.dsl", function() { document: _jQuery("<div></div>"), angular: new AngularMock() }; - $root = angular.scope({}, angular.service); + $root = angular.scope(); $root.futures = []; + $root.futureLog = []; + $root.$window = $window; $root.addFuture = function(name, fn) { this.futures.push(name); fn.call(this, function(error, result) { $root.futureError = error; $root.futureResult = result; + $root.futureLog.push(name); }); }; $root.dsl = {}; @@ -63,6 +66,18 @@ describe("angular.scenario.dsl", function() { SpecRunner.prototype.addFutureAction; }); + describe('Wait', function() { + it('should wait until resume to complete', function() { + expect($window.resume).toBeUndefined(); + $root.dsl.wait(); + expect(angular.isFunction($window.resume)).toBeTruthy(); + expect($root.futureLog).toEqual([]); + $window.resume(); + expect($root.futureLog). + toEqual(['waiting for you to call resume() in the console']); + }); + }); + describe('Pause', function() { beforeEach(function() { $root.setTimeout = function(fn, value) { @@ -99,10 +114,11 @@ describe("angular.scenario.dsl", function() { }); it('should allow a future url', function() { - var future = {name: 'future name', value: 'http://myurl'}; - $root.dsl.navigateTo(future); - expect($window.location).toEqual('http://myurl'); - expect($root.futureResult).toEqual('http://myurl'); + $root.dsl.navigateTo('http://myurl', function() { + return 'http://futureUrl/'; + }); + expect($window.location).toEqual('http://futureUrl/'); + expect($root.futureResult).toEqual('http://futureUrl/'); }); it('should complete if angular is missing from app frame', function() { @@ -205,6 +221,13 @@ describe("angular.scenario.dsl", function() { expect(doc.find('input').val()).toEqual('baz'); }); + it('should execute custom query', function() { + doc.append('<a id="test" href="myUrl"></a>'); + $root.dsl.element('#test').query(function(elements, done) { + done(null, elements.attr('href')); + }); + expect($root.futureResult).toEqual('myUrl'); + }); }); describe('Repeater', function() { |
