diff options
| author | Misko Hevery | 2010-08-10 11:46:37 -0700 |
|---|---|---|
| committer | Misko Hevery | 2010-08-10 11:46:37 -0700 |
| commit | 8d635cfb876e844302f24b8d08744cf44d5e7070 (patch) | |
| tree | afa3c5531c38d81c000c69601648743878c726c5 /src | |
| parent | 7673b2a2b291a4fc627e1cbdb8201f116a97b016 (diff) | |
| parent | 86c2ef87d5069f0836079e171c0f33efcf2b5d24 (diff) | |
| download | angular.js-8d635cfb876e844302f24b8d08744cf44d5e7070.tar.bz2 | |
Merge branch 'master' of github.com:angular/angular.js
Diffstat (limited to 'src')
| -rw-r--r-- | src/scenario/DSL.js | 90 | ||||
| -rw-r--r-- | src/scenario/Future.js | 13 | ||||
| -rw-r--r-- | src/scenario/Matcher.js | 21 | ||||
| -rw-r--r-- | src/scenario/Runner.js | 44 |
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(); } }; |
