aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorElliott Sprehn2010-10-24 14:14:45 -0700
committerIgor Minar2010-10-26 15:17:57 -0700
commit40d7e66f408eaaa66efd8d7934ab2eb3324236a1 (patch)
treedaf88d70df9037416598307784eb83df93df4fed /test
parent1d52349440d40de527b5d7f3849070f525c1b79b (diff)
downloadangular.js-40d7e66f408eaaa66efd8d7934ab2eb3324236a1.tar.bz2
Lots of bug fixes in the scenario runner and a bunch of new features.
- By default the runner now creates multiple output formats as it runs. Nodes are created in the DOM with ids: json, xml, and html. ex. $('#json').html() => json output of the runner ex. $('#xml').html() => json output of the runner $result is also an object tree result. The permitted formats are html,json,xml,object. If you don't want certain formats you can select specific ones with the new ng:scenario-output attribute on the script tag. <script src="angular-scenario.js" ng:scenario-output="xml,json"> - Added element(...).count() that returns the number of matching elements for the selector. - repeater(...).count() now returns 0 if no elements matched which can be used to check if a repeater is empty. - Added toBe() matcher that does strict equality with === - Implement iit and ddescribe. If iit() is used instead of it() then only that test will run. If ddescribe() is used instead of describe() them only it() statements inside of it will run. Several iit/ddescribe() blocks can be used to run isolated tests. - Implement new event based model for SpecRunner. You can now listen for events in the runner. This is useful for writing your own UI or connecting a remote process (ex. WebDriver). Event callbacks execute on the Runner instance. Events, if fired, will always be in the below order. All events always happen except for Failure and Error events which only happen in error conditions. Events: RunnerBegin SpecBegin(spec) StepBegin(spec, step) StepError(spec, step, error) StepFailure(spec, step, error) StepEnd(spec, step) SpecError(spec, step, error) SpecEnd(spec) RunnerEnd - Only allow the browser to repaint every 10 steps. Cuts 700ms off Firefox in benchmark, 200ms off Chrome. - Bug Fix: Manually navigate anchors on click since trigger wont work in Firefox.
Diffstat (limited to 'test')
-rw-r--r--test/AngularSpec.js21
-rw-r--r--test/scenario/ApplicationSpec.js82
-rw-r--r--test/scenario/DescribeSpec.js21
-rw-r--r--test/scenario/HtmlUISpec.js98
-rw-r--r--test/scenario/ObjectModelSpec.js112
-rw-r--r--test/scenario/RunnerSpec.js11
-rw-r--r--test/scenario/SpecRunnerSpec.js123
-rw-r--r--test/scenario/dslSpec.js82
-rw-r--r--test/scenario/mocks.js41
-rw-r--r--test/scenario/output/HtmlSpec.js124
-rw-r--r--test/scenario/output/jsonSpec.js34
-rw-r--r--test/scenario/output/objectSpec.js37
-rw-r--r--test/scenario/output/xmlSpec.js33
13 files changed, 579 insertions, 240 deletions
diff --git a/test/AngularSpec.js b/test/AngularSpec.js
index b60b7bd8..bab7df18 100644
--- a/test/AngularSpec.js
+++ b/test/AngularSpec.js
@@ -196,6 +196,27 @@ describe ('rngScript', function() {
expect('my-angular-app-0.9.0-de0a8612.min.js'.match(rngScript)).toBeNull();
expect('foo/../my-angular-app-0.9.0-de0a8612.min.js'.match(rngScript)).toBeNull();
});
+
+ it('should match angular-scenario.js', function() {
+ expect('angular-scenario.js'.match(rngScript)).not.toBeNull();
+ expect('angular-scenario.min.js'.match(rngScript)).not.toBeNull();
+ expect('../angular-scenario.js'.match(rngScript)).not.toBeNull();
+ expect('foo/angular-scenario.min.js'.match(rngScript)).not.toBeNull();
+ });
+
+ it('should match angular-scenario-0.9.0(.min).js', function() {
+ expect('angular-scenario-0.9.0.js'.match(rngScript)).not.toBeNull();
+ expect('angular-scenario-0.9.0.min.js'.match(rngScript)).not.toBeNull();
+ expect('../angular-scenario-0.9.0.js'.match(rngScript)).not.toBeNull();
+ expect('foo/angular-scenario-0.9.0.min.js'.match(rngScript)).not.toBeNull();
+ });
+
+ it('should match angular-scenario-0.9.0-de0a8612(.min).js', function() {
+ expect('angular-scenario-0.9.0-de0a8612.js'.match(rngScript)).not.toBeNull();
+ expect('angular-scenario-0.9.0-de0a8612.min.js'.match(rngScript)).not.toBeNull();
+ expect('../angular-scenario-0.9.0-de0a8612.js'.match(rngScript)).not.toBeNull();
+ expect('foo/angular-scenario-0.9.0-de0a8612.min.js'.match(rngScript)).not.toBeNull();
+ });
});
diff --git a/test/scenario/ApplicationSpec.js b/test/scenario/ApplicationSpec.js
index 883701ba..122292c6 100644
--- a/test/scenario/ApplicationSpec.js
+++ b/test/scenario/ApplicationSpec.js
@@ -7,9 +7,10 @@ describe('angular.scenario.Application', function() {
});
it('should return new $window and $document after navigate', function() {
+ var called;
var testWindow, testDocument, counter = 0;
app.navigateTo = noop;
- app.getWindow = function() {
+ app.getWindow_ = function() {
return {x:counter++, document:{x:counter++}};
};
app.navigateTo('http://www.google.com/');
@@ -21,30 +22,45 @@ describe('angular.scenario.Application', function() {
app.executeAction(function($window, $document) {
expect($window).not.toEqual(testWindow);
expect($document).not.toEqual(testDocument);
+ called = true;
});
+ expect(called).toBeTruthy();
});
it('should execute callback with correct arguments', function() {
+ var called;
var testWindow = {document: {}};
- app.getWindow = function() {
+ app.getWindow_ = function() {
return testWindow;
};
app.executeAction(function($window, $document) {
expect(this).toEqual(app);
expect($document).toEqual(_jQuery($window.document));
expect($window).toEqual(testWindow);
+ called = true;
});
+ expect(called).toBeTruthy();
});
- it('should create a new iframe each time', function() {
+ it('should use a new iframe each time', function() {
app.navigateTo('about:blank');
- var frame = app.getFrame();
+ var frame = app.getFrame_();
frame.attr('test', true);
app.navigateTo('about:blank');
- expect(app.getFrame().attr('test')).toBeFalsy();
+ expect(app.getFrame_().attr('test')).toBeFalsy();
});
- it('should URL description bar', function() {
+ it('should hide old iframes and navigate to about:blank', function() {
+ app.navigateTo('about:blank#foo');
+ app.navigateTo('about:blank#bar');
+ var iframes = frames.find('iframe');
+ expect(iframes.length).toEqual(2);
+ expect(iframes[0].src).toEqual('about:blank');
+ expect(iframes[1].src).toEqual('about:blank#bar');
+ expect(_jQuery(iframes[0]).css('display')).toEqual('none');
+ });
+
+ it('should URL update description bar', function() {
app.navigateTo('about:blank');
var anchor = frames.find('> h2 a');
expect(anchor.attr('href')).toEqual('about:blank');
@@ -53,24 +69,48 @@ describe('angular.scenario.Application', function() {
it('should call onload handler when frame loads', function() {
var called;
- app.getFrame = function() {
- // Mock a little jQuery
- var result = {
- remove: function() {
- return result;
- },
- attr: function(key, value) {
- return (!value) ? 'attribute value' : result;
- },
- load: function() {
- called = true;
- }
- };
- return result;
+ app.getWindow_ = function() {
+ return {};
};
- app.navigateTo('about:blank', function() {
+ app.navigateTo('about:blank', function($window, $document) {
called = true;
});
+ var handlers = app.getFrame_().data('events').load;
+ expect(handlers).toBeDefined();
+ expect(handlers.length).toEqual(1);
+ handlers[0].handler();
expect(called).toBeTruthy();
});
+
+ it('should wait for pending requests in executeAction', function() {
+ var called, polled;
+ var handlers = [];
+ var testWindow = {
+ document: _jQuery('<div class="test-foo"></div>'),
+ angular: {
+ service: {},
+ }
+ };
+ testWindow.angular.service.$browser = function() {
+ return {
+ poll: function() {
+ polled = true;
+ },
+ notifyWhenNoOutstandingRequests: function(fn) {
+ handlers.push(fn);
+ }
+ }
+ };
+ app.getWindow_ = function() {
+ return testWindow;
+ };
+ app.executeAction(function($window, $document) {
+ expect($window).toEqual(testWindow);
+ expect($document).toBeDefined();
+ expect($document[0].className).toEqual('test-foo');
+ });
+ expect(polled).toBeTruthy();
+ expect(handlers.length).toEqual(1);
+ handlers[0]();
+ });
});
diff --git a/test/scenario/DescribeSpec.js b/test/scenario/DescribeSpec.js
index c2e7310e..6fcee731 100644
--- a/test/scenario/DescribeSpec.js
+++ b/test/scenario/DescribeSpec.js
@@ -80,6 +80,27 @@ describe('angular.scenario.Describe', function() {
expect(specs.length).toEqual(0);
});
+ it('should only return iit and ddescribe if present', function() {
+ root.describe('A', function() {
+ this.it('1', angular.noop);
+ this.iit('2', angular.noop);
+ this.describe('B', function() {
+ this.it('3', angular.noop);
+ this.ddescribe('C', function() {
+ this.it('4', angular.noop);
+ this.describe('D', function() {
+ this.it('5', angular.noop);
+ });
+ });
+ });
+ });
+ var specs = root.getSpecs();
+ expect(specs.length).toEqual(3);
+ expect(specs[0].name).toEqual('5');
+ expect(specs[1].name).toEqual('4');
+ expect(specs[2].name).toEqual('2');
+ });
+
it('should create uniqueIds in the tree', function() {
angular.scenario.Describe.id = 0;
var a = new angular.scenario.Describe();
diff --git a/test/scenario/HtmlUISpec.js b/test/scenario/HtmlUISpec.js
deleted file mode 100644
index 2c9ff080..00000000
--- a/test/scenario/HtmlUISpec.js
+++ /dev/null
@@ -1,98 +0,0 @@
-describe('angular.scenario.HtmlUI', function() {
- var ui;
- var context;
- var spec;
-
- function line() { return 'unknown:-1'; }
-
- beforeEach(function() {
- spec = {
- name: 'test spec',
- definition: {
- id: 10,
- name: 'child',
- children: [],
- parent: {
- id: 20,
- name: 'parent',
- children: []
- }
- }
- };
- context = _jQuery("<div></div>");
- ui = new angular.scenario.ui.Html(context);
- });
-
- it('should create nested describe context', function() {
- ui.addSpec(spec);
- expect(context.find('#describe-20 #describe-10 > h2').text()).
- toEqual('describe: child');
- expect(context.find('#describe-20 > h2').text()).toEqual('describe: parent');
- expect(context.find('#describe-10 .tests > li .test-info .test-name').text()).
- toEqual('it test spec');
- expect(context.find('#describe-10 .tests > li').hasClass('status-pending')).
- toBeTruthy();
- });
-
- it('should update totals when steps complete', function() {
- // Error
- ui.addSpec(spec).error('error');
- // Failure
- specUI = ui.addSpec(spec);
- specUI.addStep('some step', line).finish('failure');
- specUI.finish();
- // Failure
- specUI = ui.addSpec(spec);
- specUI.addStep('some step', line).finish('failure');
- specUI.finish();
- // Failure
- specUI = ui.addSpec(spec);
- specUI.addStep('some step', line).finish('failure');
- specUI.finish();
- // Success
- specUI = ui.addSpec(spec);
- 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-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', line).finish();
- specUI.finish();
-
- // Failure
- specUI = ui.addSpec(spec);
- specUI.addStep('some step', line).finish('failure');
- specUI.finish('failure');
-
- // Error
- specUI = ui.addSpec(spec).error('error');
-
- context.find('#describe-10 .tests > li .test-info .timer-result').
- each(function(index, timer) {
- 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/ObjectModelSpec.js b/test/scenario/ObjectModelSpec.js
new file mode 100644
index 00000000..8b83a52f
--- /dev/null
+++ b/test/scenario/ObjectModelSpec.js
@@ -0,0 +1,112 @@
+describe('angular.scenario.ObjectModel', function() {
+ var model;
+ var runner;
+ var spec, step;
+
+ beforeEach(function() {
+ spec = {
+ name: 'test spec',
+ definition: {
+ id: 10,
+ name: 'describe 1'
+ }
+ };
+ step = {
+ name: 'test step',
+ line: function() { return ''; }
+ };
+ runner = new angular.scenario.testing.MockRunner();
+ model = new angular.scenario.ObjectModel(runner);
+ });
+
+ it('should value default empty value', function() {
+ expect(model.value).toEqual({
+ name: '',
+ children: []
+ });
+ });
+
+ it('should add spec and create describe blocks on SpecBegin event', function() {
+ runner.emit('SpecBegin', {
+ name: 'test spec',
+ definition: {
+ id: 10,
+ name: 'describe 2',
+ parent: {
+ id: 12,
+ name: 'describe 1'
+ }
+ }
+ });
+
+ expect(model.value.children['describe 1']).toBeDefined();
+ expect(model.value.children['describe 1'].children['describe 2']).toBeDefined();
+ expect(model.value.children['describe 1'].children['describe 2'].specs['test spec']).toBeDefined();
+ });
+
+ it('should add step to spec on StepBegin', function() {
+ runner.emit('SpecBegin', spec);
+ runner.emit('StepBegin', spec, step);
+ runner.emit('StepEnd', spec, step);
+ runner.emit('SpecEnd', spec);
+
+ expect(model.value.children['describe 1'].specs['test spec'].steps.length).toEqual(1);
+ });
+
+ it('should update spec timer duration on SpecEnd event', function() {
+ runner.emit('SpecBegin', spec);
+ runner.emit('SpecEnd', spec);
+
+ expect(model.value.children['describe 1'].specs['test spec'].duration).toBeDefined();
+ });
+
+ it('should update step timer duration on StepEnd event', function() {
+ runner.emit('SpecBegin', spec);
+ runner.emit('StepBegin', spec, step);
+ runner.emit('StepEnd', spec, step);
+ runner.emit('SpecEnd', spec);
+
+ expect(model.value.children['describe 1'].specs['test spec'].steps[0].duration).toBeDefined();
+ });
+
+ it('should set spec status on SpecEnd to success if no status set', function() {
+ runner.emit('SpecBegin', spec);
+ runner.emit('SpecEnd', spec);
+
+ expect(model.value.children['describe 1'].specs['test spec'].status).toEqual('success');
+ });
+
+ it('should set status to error after SpecError', function() {
+ runner.emit('SpecBegin', spec);
+ runner.emit('SpecError', spec, 'error');
+
+ expect(model.value.children['describe 1'].specs['test spec'].status).toEqual('error');
+ });
+
+ it('should set spec status to failure if step fails', function() {
+ runner.emit('SpecBegin', spec);
+ runner.emit('StepBegin', spec, step);
+ runner.emit('StepEnd', spec, step);
+ runner.emit('StepBegin', spec, step);
+ runner.emit('StepFailure', spec, step, 'error');
+ runner.emit('StepEnd', spec, step);
+ runner.emit('StepBegin', spec, step);
+ runner.emit('StepEnd', spec, step);
+ runner.emit('SpecEnd', spec);
+
+ expect(model.value.children['describe 1'].specs['test spec'].status).toEqual('failure');
+ });
+
+ it('should set spec status to error if step errors', function() {
+ runner.emit('SpecBegin', spec);
+ runner.emit('StepBegin', spec, step);
+ runner.emit('StepError', spec, step, 'error');
+ runner.emit('StepEnd', spec, step);
+ runner.emit('StepBegin', spec, step);
+ runner.emit('StepFailure', spec, step, 'error');
+ runner.emit('StepEnd', spec, step);
+ runner.emit('SpecEnd', spec);
+
+ expect(model.value.children['describe 1'].specs['test spec'].status).toEqual('error');
+ });
+});
diff --git a/test/scenario/RunnerSpec.js b/test/scenario/RunnerSpec.js
index 1641a8f1..059dd874 100644
--- a/test/scenario/RunnerSpec.js
+++ b/test/scenario/RunnerSpec.js
@@ -2,7 +2,7 @@
* Mock spec runner.
*/
function MockSpecRunner() {}
-MockSpecRunner.prototype.run = function(ui, spec, specDone) {
+MockSpecRunner.prototype.run = function(spec, specDone) {
spec.before.call(this);
spec.body.call(this);
spec.after.call(this);
@@ -41,6 +41,11 @@ describe('angular.scenario.Runner', function() {
location: {}
};
runner = new angular.scenario.Runner($window);
+ runner.createSpecRunner_ = function(scope) {
+ return scope.$new(MockSpecRunner);
+ };
+ runner.on('SpecError', rethrow);
+ runner.on('StepError', rethrow);
});
afterEach(function() {
@@ -92,7 +97,7 @@ describe('angular.scenario.Runner', function() {
expect($window.dslScope).toBeDefined();
});
});
- runner.run(null/*ui*/, null/*application*/, MockSpecRunner, rethrow);
+ runner.run(null/*application*/);
});
it('should create a new scope for each DSL chain', function() {
@@ -107,6 +112,6 @@ describe('angular.scenario.Runner', function() {
expect(scope.chained).toEqual(2);
});
});
- runner.run(null/*ui*/, null/*application*/, MockSpecRunner, rethrow);
+ runner.run(null/*application*/);
});
});
diff --git a/test/scenario/SpecRunnerSpec.js b/test/scenario/SpecRunnerSpec.js
index 921d6853..7947a3ca 100644
--- a/test/scenario/SpecRunnerSpec.js
+++ b/test/scenario/SpecRunnerSpec.js
@@ -1,40 +1,4 @@
/**
- * Mock of all required UI classes/methods. (UI, Spec, Step).
- */
-function UIMock() {
- this.log = [];
-}
-UIMock.prototype = {
- addSpec: function(spec) {
- var log = this.log;
- log.push('addSpec:' + spec.name);
- return {
- addStep: function(name) {
- log.push('addStep:' + name);
- return {
- finish: function(e) {
- log.push('step finish:' + (e ? e : ''));
- return this;
- },
- error: function(e) {
- log.push('step error:' + (e ? e : ''));
- return this;
- }
- };
- },
- finish: function(e) {
- log.push('spec finish:' + (e ? e : ''));
- return this;
- },
- error: function(e) {
- log.push('spec error:' + (e ? e : ''));
- return this;
- }
- };
- }
-};
-
-/**
* Mock Application
*/
function ApplicationMock($window) {
@@ -47,7 +11,7 @@ ApplicationMock.prototype = {
};
describe('angular.scenario.SpecRunner', function() {
- var $window;
+ var $window, $root, log;
var runner;
function createSpec(name, body) {
@@ -60,14 +24,22 @@ describe('angular.scenario.SpecRunner', function() {
}
beforeEach(function() {
+ log = [];
$window = {};
$window.setTimeout = function(fn, timeout) {
fn();
};
- runner = angular.scope();
- runner.application = new ApplicationMock($window);
- runner.$window = $window;
- runner.$become(angular.scenario.SpecRunner);
+ $root = angular.scope({
+ emit: function(eventName) {
+ log.push(eventName);
+ },
+ on: function(eventName) {
+ log.push('Listener Added for ' + eventName);
+ }
+ });
+ $root.application = new ApplicationMock($window);
+ $root.$window = $window;
+ runner = $root.$new(angular.scenario.SpecRunner);
});
it('should bind futures to the spec', function() {
@@ -92,84 +64,82 @@ describe('angular.scenario.SpecRunner', function() {
it('should execute spec function and notify UI', function() {
var finished;
- var ui = new UIMock();
var spec = createSpec('test spec', function() {
this.test = 'some value';
});
runner.addFuture('test future', function(done) {
done();
});
- runner.run(ui, spec, function() {
+ runner.run(spec, function() {
finished = true;
});
expect(runner.test).toEqual('some value');
expect(finished).toBeTruthy();
- expect(ui.log).toEqual([
- 'addSpec:test spec',
- 'addStep:test future',
- 'step finish:',
- 'spec finish:'
+ expect(log).toEqual([
+ 'SpecBegin',
+ 'StepBegin',
+ 'StepEnd',
+ 'SpecEnd'
]);
});
it('should execute notify UI on spec setup error', function() {
var finished;
- var ui = new UIMock();
var spec = createSpec('test spec', function() {
throw 'message';
});
- runner.run(ui, spec, function() {
+ runner.run(spec, function() {
finished = true;
});
expect(finished).toBeTruthy();
- expect(ui.log).toEqual([
- 'addSpec:test spec',
- 'spec error:message'
+ expect(log).toEqual([
+ 'SpecBegin',
+ 'SpecError',
+ 'SpecEnd'
]);
});
it('should execute notify UI on step failure', function() {
var finished;
- var ui = new UIMock();
var spec = createSpec('test spec');
runner.addFuture('test future', function(done) {
done('failure message');
});
- runner.run(ui, spec, function() {
+ runner.run(spec, function() {
finished = true;
});
expect(finished).toBeTruthy();
- expect(ui.log).toEqual([
- 'addSpec:test spec',
- 'addStep:test future',
- 'step finish:failure message',
- 'spec finish:'
+ expect(log).toEqual([
+ 'SpecBegin',
+ 'StepBegin',
+ 'StepFailure',
+ 'StepEnd',
+ 'SpecEnd'
]);
});
it('should execute notify UI on step error', function() {
var finished;
- var ui = new UIMock();
var spec = createSpec('test spec', function() {
this.addFuture('test future', function(done) {
throw 'error message';
});
});
- runner.run(ui, spec, function() {
+ runner.run(spec, function() {
finished = true;
});
expect(finished).toBeTruthy();
- expect(ui.log).toEqual([
- 'addSpec:test spec',
- 'addStep:test future',
- 'step error:error message',
- 'spec finish:'
+ expect(log).toEqual([
+ 'SpecBegin',
+ 'StepBegin',
+ 'StepError',
+ 'StepEnd',
+ 'SpecEnd'
]);
});
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';
@@ -181,18 +151,19 @@ describe('angular.scenario.SpecRunner', function() {
done();
});
};
- runner.run(ui, spec, function() {
+ runner.run(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:'
+ expect(log).toEqual([
+ 'SpecBegin',
+ 'StepBegin',
+ 'StepError',
+ 'StepEnd',
+ 'StepBegin',
+ 'StepEnd',
+ 'SpecEnd'
]);
});
diff --git a/test/scenario/dslSpec.js b/test/scenario/dslSpec.js
index 14ca8b2c..bbba0b7d 100644
--- a/test/scenario/dslSpec.js
+++ b/test/scenario/dslSpec.js
@@ -1,41 +1,21 @@
-/**
- * Very basic Mock of angular.
- */
-function AngularMock() {
- this.reset();
- this.service = this;
-}
-
-AngularMock.prototype.reset = function() {
- this.log = [];
-};
-
-AngularMock.prototype.$browser = function() {
- this.log.push('$brower()');
- return this;
-};
-
-AngularMock.prototype.poll = function() {
- this.log.push('$brower.poll()');
- return this;
-};
-
-AngularMock.prototype.notifyWhenNoOutstandingRequests = function(fn) {
- this.log.push('$brower.notifyWhenNoOutstandingRequests()');
- fn();
-};
-
describe("angular.scenario.dsl", function() {
- var $window;
- var $root;
- var application;
+ var $window, $root;
+ var application, eventLog;
beforeEach(function() {
+ eventLog = [];
$window = {
document: _jQuery("<div></div>"),
- angular: new AngularMock()
+ angular: new angular.scenario.testing.MockAngular()
};
- $root = angular.scope();
+ $root = angular.scope({
+ emit: function(eventName) {
+ eventLog.push(eventName);
+ },
+ on: function(eventName) {
+ eventLog.push('Listener Added for ' + eventName);
+ }
+ });
$root.futures = [];
$root.futureLog = [];
$root.$window = $window;
@@ -54,7 +34,7 @@ describe("angular.scenario.dsl", function() {
};
});
$root.application = new angular.scenario.Application($window.document);
- $root.application.getWindow = function() {
+ $root.application.getWindow_ = function() {
return $window;
};
$root.application.navigateTo = function(url, callback) {
@@ -74,13 +54,14 @@ describe("angular.scenario.dsl", function() {
expect($root.futureLog).toEqual([]);
$window.resume();
expect($root.futureLog).
- toEqual(['waiting for you to call resume() in the console']);
+ toEqual(['waiting for you to resume']);
+ expect(eventLog).toContain('InteractiveWait');
});
});
describe('Pause', function() {
beforeEach(function() {
- $root.setTimeout = function(fn, value) {
+ $root.$window.setTimeout = function(fn, value) {
$root.timerValue = value;
fn();
};
@@ -127,13 +108,6 @@ describe("angular.scenario.dsl", function() {
expect($window.location).toEqual('http://myurl');
expect($root.futureResult).toEqual('http://myurl');
});
-
- it('should wait for angular notify when no requests pending', function() {
- $root.dsl.navigateTo('url');
- expect($window.angular.log).toContain('$brower.poll()');
- expect($window.angular.log).
- toContain('$brower.notifyWhenNoOutstandingRequests()');
- });
});
describe('Element Finding', function() {
@@ -199,6 +173,24 @@ describe("angular.scenario.dsl", function() {
$root.dsl.element('a').click();
});
+ it('should navigate page if click on anchor', function() {
+ expect($window.location).not.toEqual('#foo');
+ doc.append('<a href="#foo"></a>');
+ $root.dsl.element('a').click();
+ expect($window.location).toEqual('#foo');
+ });
+
+ it('should count matching elements', function() {
+ doc.append('<span></span><span></span>');
+ $root.dsl.element('span').count();
+ expect($root.futureResult).toEqual(2);
+ });
+
+ it('should return count of 0 if no matching elements', function() {
+ $root.dsl.element('span').count();
+ expect($root.futureResult).toEqual(0);
+ });
+
it('should get attribute', function() {
doc.append('<div id="test" class="foo"></div>');
$root.dsl.element('#test').attr('class');
@@ -249,6 +241,12 @@ describe("angular.scenario.dsl", function() {
expect($root.futureResult).toEqual(2);
});
+ it('should return 0 if repeater doesnt match', function() {
+ doc.find('ul').html('');
+ chain.count();
+ expect($root.futureResult).toEqual(0);
+ });
+
it('should get a row of bindings', function() {
chain.row(1);
expect($root.futureResult).toEqual(['felisa', 'female']);
diff --git a/test/scenario/mocks.js b/test/scenario/mocks.js
new file mode 100644
index 00000000..5cd2f30a
--- /dev/null
+++ b/test/scenario/mocks.js
@@ -0,0 +1,41 @@
+angular.scenario.testing = angular.scenario.testing || {};
+
+angular.scenario.testing.MockAngular = function() {
+ this.reset();
+ this.service = this;
+};
+
+angular.scenario.testing.MockAngular.prototype.reset = function() {
+ this.log = [];
+};
+
+angular.scenario.testing.MockAngular.prototype.$browser = function() {
+ this.log.push('$brower()');
+ return this;
+};
+
+angular.scenario.testing.MockAngular.prototype.poll = function() {
+ this.log.push('$brower.poll()');
+ return this;
+};
+
+angular.scenario.testing.MockAngular.prototype.notifyWhenNoOutstandingRequests = function(fn) {
+ this.log.push('$brower.notifyWhenNoOutstandingRequests()');
+ fn();
+};
+
+angular.scenario.testing.MockRunner = function() {
+ this.listeners = [];
+};
+
+angular.scenario.testing.MockRunner.prototype.on = function(eventName, fn) {
+ this.listeners[eventName] = this.listeners[eventName] || [];
+ this.listeners[eventName].push(fn);
+};
+
+angular.scenario.testing.MockRunner.prototype.emit = function(eventName) {
+ var args = Array.prototype.slice.call(arguments, 1);
+ angular.foreach(this.listeners[eventName] || [], function(fn) {
+ fn.apply(this, args);
+ });
+};
diff --git a/test/scenario/output/HtmlSpec.js b/test/scenario/output/HtmlSpec.js
new file mode 100644
index 00000000..f5bb90b0
--- /dev/null
+++ b/test/scenario/output/HtmlSpec.js
@@ -0,0 +1,124 @@
+describe('angular.scenario.output.html', function() {
+ var runner, spec, listeners;
+ var ui, context;
+
+ beforeEach(function() {
+ listeners = [];
+ spec = {
+ name: 'test spec',
+ definition: {
+ id: 10,
+ name: 'child',
+ children: [],
+ parent: {
+ id: 20,
+ name: 'parent',
+ children: []
+ }
+ }
+ };
+ step = {
+ name: 'some step',
+ line: function() { return 'unknown:-1'; },
+ };
+ runner = new angular.scenario.testing.MockRunner();
+ context = _jQuery("<div></div>");
+ ui = angular.scenario.output.html(context, runner);
+ });
+
+ it('should create nested describe context', function() {
+ runner.emit('SpecBegin', spec);
+ expect(context.find('#describe-20 #describe-10 > h2').text()).
+ toEqual('describe: child');
+ expect(context.find('#describe-20 > h2').text()).toEqual('describe: parent');
+ expect(context.find('#describe-10 .tests > li .test-info .test-name').text()).
+ toEqual('test spec');
+ expect(context.find('#describe-10 .tests > li').hasClass('status-pending')).
+ toBeTruthy();
+ });
+
+ it('should add link on InteractiveWait', function() {
+ runner.emit('SpecBegin', spec);
+ runner.emit('StepBegin', spec, step);
+ runner.emit('StepEnd', spec, step);
+ runner.emit('StepBegin', spec, step);
+ runner.emit('InteractiveWait', spec, step);
+ expect(context.find('.test-actions .test-title:first').text()).toEqual('some step');
+ expect(context.find('.test-actions .test-title:last').html()).toEqual(
+ 'waiting for you to <a href="javascript:resume()">resume</a>.'
+ );
+ });
+
+ it('should update totals when steps complete', function() {
+ // Failure
+ for (var i=0; i < 3; ++i) {
+ runner.emit('SpecBegin', spec);
+ runner.emit('StepBegin', spec, step);
+ runner.emit('StepFailure', spec, step, 'error');
+ runner.emit('StepEnd', spec, step);
+ runner.emit('SpecEnd', spec);
+ }
+
+ // Error
+ runner.emit('SpecBegin', spec);
+ runner.emit('SpecError', spec, 'error');
+ runner.emit('SpecEnd', spec);
+
+ // Error
+ runner.emit('SpecBegin', spec);
+ runner.emit('StepBegin', spec, step);
+ runner.emit('StepError', spec, step, 'error');
+ runner.emit('StepEnd', spec, step);
+ runner.emit('SpecEnd', spec);
+
+ // Success
+ runner.emit('SpecBegin', spec);
+ runner.emit('StepBegin', spec, step);
+ runner.emit('StepEnd', spec, step);
+ runner.emit('SpecEnd', spec);
+
+ 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(1);
+ });
+
+ it('should update timer when test completes', function() {
+ // Success
+ runner.emit('SpecBegin', spec);
+ runner.emit('StepBegin', spec, step);
+ runner.emit('StepEnd', spec, step);
+ runner.emit('SpecEnd', spec);
+
+ // Failure
+ runner.emit('SpecBegin', spec);
+ runner.emit('StepBegin', spec, step);
+ runner.emit('StepFailure', spec, step, 'error');
+ runner.emit('StepEnd', spec, step);
+ runner.emit('SpecEnd', spec);
+
+ // Error
+ runner.emit('SpecBegin', spec);
+ runner.emit('SpecError', spec, 'error');
+ runner.emit('SpecEnd', spec);
+
+ context.find('#describe-10 .tests > li .test-info .timer-result').
+ each(function(index, timer) {
+ expect(timer.innerHTML).toMatch(/ms$/);
+ });
+ });
+
+ it('should include line if provided', function() {
+ runner.emit('SpecBegin', spec);
+ runner.emit('StepBegin', spec, step);
+ runner.emit('StepFailure', spec, step, 'error');
+ runner.emit('StepEnd', spec, step);
+ runner.emit('SpecEnd', spec);
+
+ var errorHtml = context.find('#describe-10 .tests li pre').html();
+ expect(errorHtml.indexOf('unknown:-1')).toEqual(0);
+ });
+
+});
diff --git a/test/scenario/output/jsonSpec.js b/test/scenario/output/jsonSpec.js
new file mode 100644
index 00000000..b3592608
--- /dev/null
+++ b/test/scenario/output/jsonSpec.js
@@ -0,0 +1,34 @@
+describe('angular.scenario.output.json', function() {
+ var output, context;
+ var runner, $window;
+ var spec, step;
+
+ beforeEach(function() {
+ $window = {};
+ context = _jQuery('<div></div>');
+ runner = new angular.scenario.testing.MockRunner();
+ output = angular.scenario.output.json(context, runner);
+ spec = {
+ name: 'test spec',
+ definition: {
+ id: 10,
+ name: 'describe',
+ }
+ };
+ step = {
+ name: 'some step',
+ line: function() { return 'unknown:-1'; },
+ };
+ });
+
+ it('should put json in context on RunnerEnd', function() {
+ runner.emit('SpecBegin', spec);
+ runner.emit('StepBegin', spec, step);
+ runner.emit('StepEnd', spec, step);
+ runner.emit('SpecEnd', spec);
+ runner.emit('RunnerEnd');
+
+ expect(angular.fromJson(context.html()).children['describe']
+ .specs['test spec'].status).toEqual('success');
+ });
+});
diff --git a/test/scenario/output/objectSpec.js b/test/scenario/output/objectSpec.js
new file mode 100644
index 00000000..c4e8d451
--- /dev/null
+++ b/test/scenario/output/objectSpec.js
@@ -0,0 +1,37 @@
+describe('angular.scenario.output.object', function() {
+ var output;
+ var runner, $window;
+ var spec, step;
+
+ beforeEach(function() {
+ $window = {};
+ runner = new angular.scenario.testing.MockRunner();
+ runner.$window = $window;
+ output = angular.scenario.output.object(null, runner);
+ spec = {
+ name: 'test spec',
+ definition: {
+ id: 10,
+ name: 'describe',
+ children: []
+ }
+ };
+ step = {
+ name: 'some step',
+ line: function() { return 'unknown:-1'; },
+ };
+ });
+
+ it('should create a global variable $result', function() {
+ expect($window.$result).toBeDefined();
+ });
+
+ it('should maintain live state in $result', function() {
+ runner.emit('SpecBegin', spec);
+ runner.emit('StepBegin', spec, step);
+ runner.emit('StepEnd', spec, step);
+
+ expect($window.$result.children['describe']
+ .specs['test spec'].steps[0].duration).toBeDefined();
+ });
+});
diff --git a/test/scenario/output/xmlSpec.js b/test/scenario/output/xmlSpec.js
new file mode 100644
index 00000000..448c8d10
--- /dev/null
+++ b/test/scenario/output/xmlSpec.js
@@ -0,0 +1,33 @@
+describe('angular.scenario.output.json', function() {
+ var output, context;
+ var runner, $window;
+ var spec, step;
+
+ beforeEach(function() {
+ $window = {};
+ context = _jQuery('<div></div>');
+ runner = new angular.scenario.testing.MockRunner();
+ output = angular.scenario.output.xml(context, runner);
+ spec = {
+ name: 'test spec',
+ definition: {
+ id: 10,
+ name: 'describe',
+ }
+ };
+ step = {
+ name: 'some step',
+ line: function() { return 'unknown:-1'; },
+ };
+ });
+
+ it('should create XML nodes for object model', function() {
+ runner.emit('SpecBegin', spec);
+ runner.emit('StepBegin', spec, step);
+ runner.emit('StepEnd', spec, step);
+ runner.emit('SpecEnd', spec);
+ runner.emit('RunnerEnd');
+ expect(_jQuery(context).find('it').attr('status')).toEqual('success');
+ expect(_jQuery(context).find('it step').attr('status')).toEqual('success');
+ });
+});