all tests passing with new futures concept

This commit is contained in:
Andres Ornelas 2010-06-30 09:51:54 -07:00
parent e664186f93
commit 9d8646b0d1
5 changed files with 111 additions and 102 deletions

View file

@ -1,6 +1,6 @@
angular.scenario.dsl.browser = { angular.scenario.dsl.browser = {
navigateTo: function(url){ navigateTo: function(url){
$scenario.addStep('Navigate to: ' + url, function(done){ $scenario.addFuture('Navigate to: ' + url, function(done){
var self = this; var self = this;
this.testFrame.load(function(){ this.testFrame.load(function(){
self.testFrame.unbind(); self.testFrame.unbind();
@ -22,7 +22,7 @@ angular.scenario.dsl.browser = {
angular.scenario.dsl.input = function(selector) { angular.scenario.dsl.input = function(selector) {
return { return {
enter: function(value){ enter: function(value){
$scenario.addStep("Set input text of '" + selector + "' to '" + $scenario.addFuture("Set input text of '" + selector + "' to '" +
value + "'", function(done){ value + "'", function(done){
var input = this.testDocument.find('input[name=' + selector + ']'); var input = this.testDocument.find('input[name=' + selector + ']');
input.val(value); input.val(value);
@ -31,7 +31,7 @@ angular.scenario.dsl.input = function(selector) {
}); });
}, },
select: function(value){ select: function(value){
$scenario.addStep("Select radio '" + selector + "' to '" + $scenario.addFuture("Select radio '" + selector + "' to '" +
value + "'", function(done){ value + "'", function(done){
var input = this.testDocument. var input = this.testDocument.
find(':radio[name$=@' + selector + '][value=' + value + ']'); find(':radio[name$=@' + selector + '][value=' + value + ']');
@ -49,7 +49,7 @@ angular.scenario.dsl.expect = {
return { return {
count: { count: {
toEqual: function(number) { toEqual: function(number) {
$scenario.addStep("Expect that there are " + number + " items in Repeater with selector '" + selector + "'", function(done) { $scenario.addFuture("Expect that there are " + number + " items in Repeater with selector '" + selector + "'", function(done) {
var items = this.testDocument.find(selector); var items = this.testDocument.find(selector);
if (items.length != number) { if (items.length != number) {
this.result.fail("Expected " + number + " but was " + items.length); this.result.fail("Expected " + number + " but was " + items.length);

View file

@ -1,8 +1,8 @@
function Future(name, behavior) { function Future(name, behavior) {
this.value = undefined;
this.name = name; this.name = name;
this.behavior = behavior; this.behavior = behavior;
this.fulfilled = false; this.fulfilled = false;
this.value = undefined;
} }
Future.prototype = { Future.prototype = {
@ -11,25 +11,6 @@ Future.prototype = {
this.value = value; this.value = value;
} }
}; };
function future(name, behavior) {
return new Future(name, behavior);
};
function repeater(selector) {
var repeaterFuture = future('repeater ' + selector, function(done) {
done($(selector));
});
repeaterFuture.count = function(){
return future(repeaterFuture.name + ' count', function(done) {
done(repeaterFuture.value.size());
});
};
return repeaterFuture;
}
function Matcher(future, logger) { function Matcher(future, logger) {
var self = this; var self = this;
this.logger = logger; this.logger = logger;
@ -52,6 +33,28 @@ Matcher.addMatcher = function(name, matcher){
Matcher.addMatcher('toEqual', function(a,b){ return a == b; }); Matcher.addMatcher('toEqual', function(a,b){ return a == b; });
function expect(future) { /*
function future(name, behavior) {
return new Future(name, behavior);
};
function repeater(selector) {
var repeaterFuture = future('repeater ' + selector, function(done) {
done($(selector));
});
repeaterFuture.count = function(){
return future(repeaterFuture.name + ' count', function(done) {
done(repeaterFuture.value.size());
});
};
return repeaterFuture;
}
function expectX(future) {
return new Matcher(future, window.alert); return new Matcher(future, window.alert);
} }
*/

View file

@ -26,13 +26,13 @@ angular.scenario.Runner = function(scope, jQuery){
var specName = path.join(' ') + ': it ' + name; var specName = path.join(' ') + ': it ' + name;
self.currentSpec = specs[specName] = { self.currentSpec = specs[specName] = {
name: specName, name: specName,
steps:[] futures: []
}; };
try { try {
beforeEach(); beforeEach();
body(); body();
} catch(err) { } catch(err) {
self.addStep(err.message || 'ERROR', function(){ self.addFuture(err.message || 'ERROR', function(){
throw err; throw err;
}); });
} finally { } finally {
@ -107,14 +107,16 @@ angular.scenario.Runner.prototype = {
callback(); callback();
}, },
addStep: function(name, step) { addFuture: function(name, behavior) {
this.currentSpec.steps.push({name:name, fn:step}); var future = new Future(name, behavior);
this.currentSpec.futures.push(future);
return future;
}, },
execute: function(name, callback) { execute: function(name, callback) {
var spec = this.specs[name], var spec = this.specs[name],
self = this, self = this,
stepsDone = [], futuresFulfilled = [],
result = { result = {
passed: false, passed: false,
failed: false, failed: false,
@ -132,29 +134,32 @@ angular.scenario.Runner.prototype = {
testWindow: this.testWindow testWindow: this.testWindow
}, angularService, {}); }, angularService, {});
this.self = specThis; this.self = specThis;
var stepLogger = this.logger('spec', name); var futureLogger = this.logger('spec', name);
spec.nextStepIndex = 0; spec.nextFutureIndex = 0;
function done() { function done() {
result.finished = true; result.finished = true;
stepLogger.close(); futureLogger.close();
self.self = null; self.self = null;
(callback||noop).call(specThis); (callback||noop).call(specThis);
} }
function next(){ function next(value){
var step = spec.steps[spec.nextStepIndex]; if (spec.nextFutureIndex > 0) {
spec.futures[spec.nextFutureIndex - 1].fulfill(value);
}
var future = spec.futures[spec.nextFutureIndex];
(result.log || {close:noop}).close(); (result.log || {close:noop}).close();
result.log = null; result.log = null;
if (step) { if (future) {
spec.nextStepIndex ++; spec.nextFutureIndex ++;
result.log = stepLogger('step', step.name); result.log = futureLogger('future', future.name);
stepsDone.push(step.name); futuresFulfilled.push(future.name);
try { try {
step.fn.call(specThis, next); future.behavior.call(specThis, next);
} catch (e) { } catch (e) {
console.error(e); console.error(e);
result.fail(e); result.fail(e);
self.scope.$testrun.results.push( self.scope.$testrun.results.push(
{name: name, passed: false, error: e, steps: stepsDone}); {name: name, passed: false, error: e, steps: futuresFulfilled});
done(); done();
} }
} else { } else {
@ -163,7 +168,7 @@ angular.scenario.Runner.prototype = {
name: name, name: name,
passed: !result.failed, passed: !result.failed,
error: result.error, error: result.error,
steps: stepsDone}); steps: futuresFulfilled});
done(); done();
} }
}; };

View file

@ -1,22 +1,22 @@
describe("DSL", function() { describe("DSL", function() {
var lastStep, executeStep, lastDocument; var lastFuture, executeFuture, lastDocument;
beforeEach(function() { beforeEach(function() {
lastStep = null; lastFuture = null;
$scenario = { $scenario = {
addStep: function(name, stepFunction) { addFuture: function(name, behavior) {
lastStep = { name:name, fn: stepFunction}; lastFuture = { name:name, behavior: behavior};
} }
}; };
executeStep = function(step, html, callback) { executeFuture = function(future, html, callback) {
lastDocument =_jQuery('<div>' + html + '</div>'); lastDocument =_jQuery('<div>' + html + '</div>');
_jQuery(document.body).append(lastDocument); _jQuery(document.body).append(lastDocument);
var specThis = { var specThis = {
testWindow: window, testWindow: window,
testDocument: lastDocument testDocument: lastDocument
}; };
step.fn.call(specThis, callback || noop); future.behavior.call(specThis, callback || noop);
}; };
}); });
@ -25,15 +25,15 @@ describe("DSL", function() {
var input = angular.scenario.dsl.input; var input = angular.scenario.dsl.input;
it('should enter', function() { it('should enter', function() {
input('name').enter('John'); input('name').enter('John');
expect(lastStep.name).toEqual("Set input text of 'name' to 'John'"); expect(lastFuture.name).toEqual("Set input text of 'name' to 'John'");
executeStep(lastStep, '<input type="text" name="name" />'); executeFuture(lastFuture, '<input type="text" name="name" />');
expect(lastDocument.find('input').val()).toEqual('John'); expect(lastDocument.find('input').val()).toEqual('John');
}); });
it('should select', function() { it('should select', function() {
input('gender').select('female'); input('gender').select('female');
expect(lastStep.name).toEqual("Select radio 'gender' to 'female'"); expect(lastFuture.name).toEqual("Select radio 'gender' to 'female'");
executeStep(lastStep, executeFuture(lastFuture,
'<input type="radio" name="0@gender" value="male" checked/>' + '<input type="radio" name="0@gender" value="male" checked/>' +
'<input type="radio" name="0@gender" value="female"/>'); '<input type="radio" name="0@gender" value="female"/>');
expect(lastDocument.find(':radio:checked').length).toEqual(1); expect(lastDocument.find(':radio:checked').length).toEqual(1);
@ -46,9 +46,9 @@ describe("DSL", function() {
describe('repeater', function() { describe('repeater', function() {
it('should check the count of repeated elements', function() { it('should check the count of repeated elements', function() {
dslExpect.repeater('.repeater-row').count.toEqual(2); dslExpect.repeater('.repeater-row').count.toEqual(2);
expect(lastStep.name).toEqual("Expect that there are 2 items in Repeater with selector '.repeater-row'"); expect(lastFuture.name).toEqual("Expect that there are 2 items in Repeater with selector '.repeater-row'");
var html = "<div class='repeater-row'>a</div><div class='repeater-row'>b</div>"; var html = "<div class='repeater-row'>a</div><div class='repeater-row'>b</div>";
executeStep(lastStep, html); executeFuture(lastFuture, html);
}); });
}); });
}); });

View file

@ -34,7 +34,7 @@ describe('Runner', function(){
}); });
expect(log).toEqual('body'); expect(log).toEqual('body');
var spec = $scenario.specs['describe name: it should text']; var spec = $scenario.specs['describe name: it should text'];
expect(spec.steps).toEqual([]); expect(spec.futures).toEqual([]);
expect(spec.name).toEqual('describe name: it should text'); expect(spec.name).toEqual('describe name: it should text');
}); });
@ -42,7 +42,7 @@ describe('Runner', function(){
// WRITE ME!!!! // WRITE ME!!!!
}); });
it('should create a failing step if there is a javascript error', function(){ it('should create a failing future if there is a javascript error', function(){
var spec; var spec;
Describe('D1', function(){ Describe('D1', function(){
It('I1', function(){ It('I1', function(){
@ -50,10 +50,10 @@ describe('Runner', function(){
throw {message: 'blah'}; throw {message: 'blah'};
}); });
}); });
var step = spec.steps[0]; var future = spec.futures[0];
expect(step.name).toEqual('blah'); expect(future.name).toEqual('blah');
try { try {
step.fn(); future.behavior();
fail(); fail();
} catch (e) { } catch (e) {
expect(e.message).toEqual('blah'); expect(e.message).toEqual('blah');
@ -97,60 +97,61 @@ describe('Runner', function(){
var next; var next;
Describe('describe name', function(){ Describe('describe name', function(){
AfterEach(function() { AfterEach(function() {
$scenario.addStep('afterEachLog', logger('after;')); $scenario.addFuture('afterEachLog', logger('after;'));
$scenario.addStep('afterEachThrow', function() { $scenario.addFuture('afterEachThrow', function() {
throw "AfterError"; throw "AfterError";
}); });
}); });
It('should text1', function() { It('should text1', function() {
$scenario.addStep('step1', logger('step1;')); $scenario.addFuture('future1', logger('future1;'));
}); });
It('should text2', function() { It('should text2', function() {
$scenario.addStep('step2', logger('step2;')); $scenario.addFuture('future2', logger('future2;'));
}); });
}); });
$scenario.run(body); $scenario.run(body);
expect(log).toEqual('step1;after;step2;after;'); expect(log).toEqual('future1;after;future2;after;');
expect(scenario.$testrun.results).toEqual([ expect(scenario.$testrun.results).toEqual([
{ name : 'describe name: it should text1', { name : 'describe name: it should text1',
passed : false, passed : false,
error : 'AfterError', error : 'AfterError',
steps : [ 'step1', 'afterEachLog', 'afterEachThrow' ] }, steps : [ 'future1', 'afterEachLog', 'afterEachThrow' ] },
{ name : 'describe name: it should text2', { name : 'describe name: it should text2',
passed : false, passed : false,
error : 'AfterError', error : 'AfterError',
steps : [ 'step2', 'afterEachLog', 'afterEachThrow' ] }]); steps : [ 'future2', 'afterEachLog', 'afterEachThrow' ] }]);
}); });
}); });
}); });
describe('steps building', function(){ describe('future building', function(){
it('should queue steps', function(){ it('should queue futures', function(){
function step(){}; function behavior(){};
Describe('name', function(){ Describe('name', function(){
It('should', function(){ It('should', function(){
$scenario.addStep('stepname', step); $scenario.addFuture('futureName', behavior);
}); });
}); });
expect($scenario.specs['name: it should'].steps).toEqual([{name:'stepname', fn:step}]); expect($scenario.specs['name: it should'].futures[0].name).
toEqual('futureName');
}); });
}); });
describe('execution', function(){ describe('execution', function(){
it('should execute the queued steps', function(){ it('should execute the queued futures', function(){
var next, firstThis, secondThis, doneThis, spec; var next, firstThis, secondThis, doneThis, spec;
$scenario.specs['spec'] = { $scenario.specs['spec'] = {
steps: [ futures: [
{name:'step1', fn: function(done) { new Future('future1', function(done) {
next = done; next = done;
log += 'first;'; log += 'first;';
firstThis = this; firstThis = this;
}}, }),
{name:'step2', fn:function(done){ new Future('future2', function(done) {
next = done; next = done;
log += 'second;'; log += 'second;';
secondThis = this; secondThis = this;
}} })
] ]
}; };
@ -174,18 +175,18 @@ describe('Runner', function(){
expect(spec.result.passed).toEqual(true); expect(spec.result.passed).toEqual(true);
}); });
it('should handle exceptions in a step', function(){ it('should handle exceptions in a future', function(){
$scenario.specs['spec'] = { $scenario.specs['spec'] = {
steps: [ futures: [
{name: 'first step', fn: function(done) { new Future('first future', function(done) {
done(); done();
}}, }),
{name:'error', fn:function(done) { new Future('error', function(done) {
throw "MyError"; throw "MyError";
}}, }),
{name: 'should not execute', fn: function(done) { new Future('should not execute', function(done) {
done(); done();
}} })
] ]
}; };
@ -199,7 +200,7 @@ describe('Runner', function(){
name: 'spec', name: 'spec',
passed: false, passed: false,
error: 'MyError', error: 'MyError',
steps: ['first step', 'error']}]); steps: ['first future', 'error']}]);
}); });
}); });
@ -207,15 +208,15 @@ describe('Runner', function(){
var next; var next;
beforeEach(function() { beforeEach(function() {
Describe('d1', function(){ Describe('d1', function(){
It('it1', function(){ $scenario.addStep('s1', logger('s1,')); }); It('it1', function(){ $scenario.addFuture('s1', logger('s1,')); });
It('it2', function(){ It('it2', function(){
$scenario.addStep('s2', logger('s2,')); $scenario.addFuture('s2', logger('s2,'));
$scenario.addStep('s2.2', function(done){ next = done; }); $scenario.addFuture('s2.2', function(done){ next = done; });
}); });
}); });
Describe('d2', function(){ Describe('d2', function(){
It('it3', function(){ $scenario.addStep('s3', logger('s3,')); }); It('it3', function(){ $scenario.addFuture('s3', logger('s3,')); });
It('it4', function(){ $scenario.addStep('s4', logger('s4,')); }); It('it4', function(){ $scenario.addFuture('s4', logger('s4,')); });
}); });
}); });
it('should execute all specs', function(){ it('should execute all specs', function(){
@ -231,15 +232,15 @@ describe('Runner', function(){
$scenario.run(body); $scenario.run(body);
expect(scenario.$testrun.done).toBeFalsy(); expect(scenario.$testrun.done).toBeFalsy();
expect(scenario.$testrun.results).toEqual([ expect(scenario.$testrun.results).toEqual([
{name: 'd1: it it1', passed: true, steps: ['s1']} {name: 'd1: it it1', passed: true, error: undefined, steps: ['s1']}
]); ]);
next(); next();
expect(scenario.$testrun.done).toBeTruthy(); expect(scenario.$testrun.done).toBeTruthy();
expect(scenario.$testrun.results).toEqual([ expect(scenario.$testrun.results).toEqual([
{name: 'd1: it it1', passed: true, steps: ['s1']}, {name: 'd1: it it1', passed: true, error: undefined, steps: ['s1']},
{name: 'd1: it it2', passed: true, steps: ['s2', 's2.2']}, {name: 'd1: it it2', passed: true, error: undefined, steps: ['s2', 's2.2']},
{name: 'd2: it it3', passed: true, steps: ['s3']}, {name: 'd2: it it3', passed: true, error: undefined, steps: ['s3']},
{name: 'd2: it it4', passed: true, steps: ['s4']} {name: 'd2: it it4', passed: true, error: undefined, steps: ['s4']}
]); ]);
}); });
}); });