aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMisko Hevery2010-08-10 11:46:37 -0700
committerMisko Hevery2010-08-10 11:46:37 -0700
commit8d635cfb876e844302f24b8d08744cf44d5e7070 (patch)
treeafa3c5531c38d81c000c69601648743878c726c5 /src
parent7673b2a2b291a4fc627e1cbdb8201f116a97b016 (diff)
parent86c2ef87d5069f0836079e171c0f33efcf2b5d24 (diff)
downloadangular.js-8d635cfb876e844302f24b8d08744cf44d5e7070.tar.bz2
Merge branch 'master' of github.com:angular/angular.js
Diffstat (limited to 'src')
-rw-r--r--src/scenario/DSL.js90
-rw-r--r--src/scenario/Future.js13
-rw-r--r--src/scenario/Matcher.js21
-rw-r--r--src/scenario/Runner.js44
4 files changed, 123 insertions, 45 deletions
diff --git a/src/scenario/DSL.js b/src/scenario/DSL.js
index b713cfd6..d57a61df 100644
--- a/src/scenario/DSL.js
+++ b/src/scenario/DSL.js
@@ -1,13 +1,14 @@
angular.scenario.dsl.browser = {
navigateTo: function(url){
- $scenario.addStep('Navigate to: ' + url, function(done){
+ return $scenario.addFuture('Navigate to: ' + url, function(done){
var self = this;
this.testFrame.load(function(){
self.testFrame.unbind();
self.testWindow = self.testFrame[0].contentWindow;
- self.testDocument = jQuery(self.testWindow.document);
+ self.testDocument = self.jQuery(self.testWindow.document);
self.$browser = self.testWindow.angular.service.$browser();
- self.notifyWhenNoOutstandingRequests = bind(self.$browser, self.$browser.notifyWhenNoOutstandingRequests);
+ self.notifyWhenNoOutstandingRequests =
+ bind(self.$browser, self.$browser.notifyWhenNoOutstandingRequests);
self.notifyWhenNoOutstandingRequests(done);
});
if (this.testFrame.attr('src') == url) {
@@ -20,19 +21,18 @@ angular.scenario.dsl.browser = {
};
angular.scenario.dsl.input = function(selector) {
+ var namePrefix = "input '" + selector + "'";
return {
- enter: function(value){
- $scenario.addStep("Set input text of '" + selector + "' to '" +
- value + "'", function(done){
- var input = this.testDocument.find('input[name=' + selector + ']');
- input.val(value);
- this.testWindow.angular.element(input[0]).trigger('change');
- done();
+ enter: function(value) {
+ return $scenario.addFuture(namePrefix + " enter '" + value + "'", function(done) {
+ var input = this.testDocument.find('input[name=' + selector + ']');
+ input.val(value);
+ this.testWindow.angular.element(input[0]).trigger('change');
+ done();
});
},
- select: function(value){
- $scenario.addStep("Select radio '" + selector + "' to '" +
- value + "'", function(done){
+ select: function(value) {
+ return $scenario.addFuture(namePrefix + " select '" + value + "'", function(done) {
var input = this.testDocument.
find(':radio[name$=@' + selector + '][value=' + value + ']');
jqLiteWrap(input[0]).trigger('click');
@@ -41,22 +41,56 @@ angular.scenario.dsl.input = function(selector) {
});
}
};
-};
+},
-angular.scenario.dsl.expect = {
- repeater: function(selector) {
- return {
- count: {
- toEqual: function(number) {
- $scenario.addStep("Expect that there are " + number + " items in Repeater with selector '" + selector + "'", function(done) {
- var items = this.testDocument.find(selector);
- if (items.length != number) {
- this.result.fail("Expected " + number + " but was " + items.length);
- }
- done();
+angular.scenario.dsl.repeater = function(selector) {
+ var namePrefix = "repeater '" + selector + "'";
+ return {
+ count: function() {
+ return $scenario.addFuture(namePrefix + ' count', function(done) {
+ done(this.testDocument.find(selector).size());
+ });
+ },
+ collect: function() {
+ return $scenario.addFuture(namePrefix + ' collect', function(done) {
+ var self = this;
+ var doCollect = bind(this, function() {
+ var repeaterArray = [];
+ this.testDocument.find(selector).each(function(index) {
+ var element = angular.extend(self.jQuery(this),
+ {bindings: [],
+ boundTo: function(name) { return this.bindings[name]; }}
+ );
+ element.find('*').each(function(index) {
+ var bindName = self.jQuery(this).attr('ng:bind');
+ if (bindName) {
+ element.bindings[bindName] = self.jQuery(this).text();
+ }
+ });
+ repeaterArray[index] = element;
});
- }
+ return repeaterArray;
+ });
+ done(doCollect());
+ });
+ }
+ };
+};
+
+angular.scenario.dsl.element = function(selector) {
+ var nameSuffix = "element '" + selector + "'";
+ return $scenario.addFuture('Find ' + nameSuffix, function(done) {
+ var self = this;
+ var element = angular.extend(this.testDocument.find(selector), {
+ bindings: [],
+ boundTo: function(name) { return this.bindings[name]; }
+ });
+ element.find('*').each(function(index) {
+ var bindName = self.jQuery(this).attr('ng:bind');
+ if (bindName) {
+ element.bindings[bindName] = self.jQuery(this).text();
}
- };
- }
+ });
+ done(element);
+ });
};
diff --git a/src/scenario/Future.js b/src/scenario/Future.js
new file mode 100644
index 00000000..d70e8e6e
--- /dev/null
+++ b/src/scenario/Future.js
@@ -0,0 +1,13 @@
+function Future(name, behavior) {
+ this.name = name;
+ this.behavior = behavior;
+ this.fulfilled = false;
+ this.value = undefined;
+}
+
+Future.prototype = {
+ fulfill: function(value) {
+ this.fulfilled = true;
+ this.value = value;
+ }
+};
diff --git a/src/scenario/Matcher.js b/src/scenario/Matcher.js
new file mode 100644
index 00000000..62f094c8
--- /dev/null
+++ b/src/scenario/Matcher.js
@@ -0,0 +1,21 @@
+function Matcher(scope, future, logger) {
+ var self = scope.$scenario = this;
+ this.logger = logger;
+ this.future = future;
+}
+
+Matcher.addMatcher = function(name, matcher) {
+ Matcher.prototype[name] = function(expected) {
+ var future = this.future;
+ $scenario.addFuture(
+ 'expect ' + future.name + ' ' + name + ' ' + expected,
+ function(done){
+ if (!matcher(future.value, expected))
+ throw "Expected " + expected + ' but was ' + future.value;
+ done();
+ }
+ );
+ };
+};
+
+Matcher.addMatcher('toEqual', function(a,b) { return a == b; });
diff --git a/src/scenario/Runner.js b/src/scenario/Runner.js
index 13ba5af0..ac32559c 100644
--- a/src/scenario/Runner.js
+++ b/src/scenario/Runner.js
@@ -8,6 +8,7 @@ angular.scenario.Runner = function(scope, jQuery){
this.scope.$testrun = {done: false, results: []};
var specs = this.specs = {};
+ this.currentSpec = {name: '', futures: []};
var path = [];
this.scope.describe = function(name, body){
path.push(name);
@@ -22,17 +23,20 @@ angular.scenario.Runner = function(scope, jQuery){
this.scope.afterEach = function(body) {
afterEach = body;
};
+ this.scope.expect = function(future) {
+ return new Matcher(self, future, self.logger);
+ };
this.scope.it = function(name, body) {
var specName = path.join(' ') + ': it ' + name;
self.currentSpec = specs[specName] = {
name: specName,
- steps:[]
+ futures: []
};
try {
beforeEach();
body();
} catch(err) {
- self.addStep(err.message || 'ERROR', function(){
+ self.addFuture(err.message || 'ERROR', function(){
throw err;
});
} finally {
@@ -107,14 +111,16 @@ angular.scenario.Runner.prototype = {
callback();
},
- addStep: function(name, step) {
- this.currentSpec.steps.push({name:name, fn:step});
+ addFuture: function(name, behavior) {
+ var future = new Future(name, behavior);
+ this.currentSpec.futures.push(future);
+ return future;
},
execute: function(name, callback) {
var spec = this.specs[name],
self = this,
- stepsDone = [],
+ futuresFulfilled = [],
result = {
passed: false,
failed: false,
@@ -128,33 +134,37 @@ angular.scenario.Runner.prototype = {
},
specThis = createScope({
result: result,
+ jQuery: this.jQuery,
testFrame: this.testFrame,
testWindow: this.testWindow
}, angularService, {});
this.self = specThis;
- var stepLogger = this.logger('spec', name);
- spec.nextStepIndex = 0;
+ var futureLogger = this.logger('spec', name);
+ spec.nextFutureIndex = 0;
function done() {
result.finished = true;
- stepLogger.close();
+ futureLogger.close();
self.self = null;
(callback||noop).call(specThis);
}
- function next(){
- var step = spec.steps[spec.nextStepIndex];
+ function next(value){
+ if (spec.nextFutureIndex > 0) {
+ spec.futures[spec.nextFutureIndex - 1].fulfill(value);
+ }
+ var future = spec.futures[spec.nextFutureIndex];
(result.log || {close:noop}).close();
result.log = null;
- if (step) {
- spec.nextStepIndex ++;
- result.log = stepLogger('step', step.name);
- stepsDone.push(step.name);
+ if (future) {
+ spec.nextFutureIndex ++;
+ result.log = futureLogger('future', future.name);
+ futuresFulfilled.push(future.name);
try {
- step.fn.call(specThis, next);
+ future.behavior.call(specThis, next);
} catch (e) {
console.error(e);
result.fail(e);
self.scope.$testrun.results.push(
- {name: name, passed: false, error: e, steps: stepsDone});
+ {name: name, passed: false, error: e, steps: futuresFulfilled});
done();
}
} else {
@@ -163,7 +173,7 @@ angular.scenario.Runner.prototype = {
name: name,
passed: !result.failed,
error: result.error,
- steps: stepsDone});
+ steps: futuresFulfilled});
done();
}
};