diff options
| author | Misko Hevery | 2010-05-20 15:55:41 -0700 |
|---|---|---|
| committer | Misko Hevery | 2010-05-20 15:55:41 -0700 |
| commit | 5215e2095cfd42a0363eb02eded34e03fa2b0cd3 (patch) | |
| tree | 01ce02f1c5b7e544a6266d9a6f3b63a5184e88c8 /src/scenario | |
| parent | 31b35b141f52e6f5d3805d6ca4f2702aee05d61d (diff) | |
| download | angular.js-5215e2095cfd42a0363eb02eded34e03fa2b0cd3.tar.bz2 | |
basic end to end runner
Diffstat (limited to 'src/scenario')
| -rw-r--r-- | src/scenario/Runner.js | 250 | ||||
| -rw-r--r-- | src/scenario/Steps.js | 57 | ||||
| -rw-r--r-- | src/scenario/_namespace.js | 6 | ||||
| -rw-r--r-- | src/scenario/bootstrap.js | 19 |
4 files changed, 96 insertions, 236 deletions
diff --git a/src/scenario/Runner.js b/src/scenario/Runner.js index 7caddc98..eeb4330d 100644 --- a/src/scenario/Runner.js +++ b/src/scenario/Runner.js @@ -1,171 +1,109 @@ -var scenario = angular.scenario; -scenario.SuiteRunner = function(scenarios, body) { - this.scenarios = scenarios; - this.body = body; -}; +angular['scenario'] = (angular['scenario'] = {}); -scenario.SuiteRunner.prototype = { - run:function(){ - this.setUpUI(); - this.runScenarios(); - }, +angular.scenario.Runner = function(scope){ + var self = scope.$scenario = this; + this.scope = scope; + var specs = this.specs = {}; + var path = []; + this.scope.describe = function describe(name, body){ + path.push(name); + body(); + path.pop(); + }; + this.scope.it = function it(name, body) { + var specName = path.join(' ') + ': it ' + name; + self.currentSpec = specs[specName] = { + name: specName, + steps:[] + }; + body(); + self.currentSpec = null; + }; + this.beginSpec = function returnNoop(){ + return returnNoop; + }; +}; - setUpUI:function(){ - this.body.html( +angular.scenario.Runner.prototype = { + run: function(body){ + body.append( '<div id="runner">' + - '<div class="console"></div>' + + '<ul class="console"></ul>' + '</div>' + '<div id="testView">' + '<iframe></iframe>' + '</div>'); - this.console = this.body.find(".console"); - this.testFrame = this.body.find("iframe"); - this.console.find(".run").live("click", function(){ - jQuery(this).parent().find('.log').toggle(); - }); - }, - - - runScenarios:function(){ - var runner = new scenario.Runner(this.console, this.testFrame); - _.stepper(this.scenarios, function(next, scenarioObj, name){ - new scenario.Scenario(name, scenarioObj).run(runner, next); - }, function(){ - } - ); - } -}; - -scenario.Runner = function(console, frame){ - this.console = console; - this.current = null; - this.tests = []; - this.frame = frame; -}; -scenario.Runner.prototype = { - start:function(name){ - var current = this.current = { - name:name, - start:new Date().getTime(), - scenario:jQuery('<div class="scenario"></div>') + var console = body.find('#runner .console'); + this.testFrame = body.find('#testView iframe'); + this.testWindow = this.testFrame[0].contentWindow; + this.beginSpec = function(name){ + var specElement = jQuery('<li class="spec"></li>'); + var stepContainer = jQuery('<ul class="step"></ul>'); + console.append(specElement); + specElement.text(name); + specElement.append(stepContainer); + return function(name){ + var stepElement = jQuery('<li class="step"></li>'); + var logContainer = jQuery('<ul class="log"></ul>'); + stepContainer.append(stepElement); + stepElement.text(name); + stepElement.append(logContainer); + return function(message) { + var logElement = jQuery('<li class="log"></li>'); + logContainer.append(logElement); + logElement.text(message); + }; + }; }; - current.run = current.scenario.append( - '<div class="run">' + - '<span class="name">.</span>' + - '<span class="time">.</span>' + - '<span class="state">.</span>' + - '</run>').find(".run"); - current.log = current.scenario.append('<div class="log"></div>').find(".log"); - current.run.find(".name").text(name); - this.tests.push(current); - this.console.append(current.scenario); - }, - end:function(name){ - var current = this.current; - var run = current.run; - this.current = null; - current.end = new Date().getTime(); - current.time = current.end - current.start; - run.find(".time").text(current.time); - run.find(".state").text(current.error ? "FAIL" : "PASS"); - run.addClass(current.error ? "fail" : "pass"); - if (current.error) - run.find(".run").append('<span div="error"></span>').text(current.error); - current.scenario.find(".log").hide(); + this.execute("widgets: it should verify that basic widgets work"); }, - log:function(level) { - var buf = []; - for ( var i = 1; i < arguments.length; i++) { - var arg = arguments[i]; - buf.push(typeof arg == "string" ?arg:toJson(arg)); - } - var log = jQuery('<div class="' + level + '"></div>'); - log.text(buf.join(" ")); - this.current.log.append(log); - this.console.scrollTop(this.console[0].scrollHeight); - if (level == "error") - this.current.error = buf.join(" "); - } -}; -scenario.Scenario = function(name, scenario){ - this.name = name; - this.scenario = scenario; -}; -scenario.Scenario.prototype = { - run:function(runner, callback) { - var self = this; - _.stepper(this.scenario, function(next, steps, name){ - if (name.charAt(0) == '$') { - next(); - } else { - runner.start(self.name + "::" + name); - var allSteps = (self.scenario.$before||[]).concat(steps); - _.stepper(allSteps, function(next, step){ - self.executeStep(runner, step, next); - }, function(){ - runner.end(); - next(); - }); - } - }, callback); + addStep: function(name, step) { + this.currentSpec.steps.push({name:name, fn:step}); }, - - verb:function(step){ - var fn = null; - if (!step) fn = function (){ throw "Step is null!"; }; - else if (step.Given) fn = scenario.GIVEN[step.Given]; - else if (step.When) fn = scenario.WHEN[step.When]; - else if (step.Then) fn = scenario.THEN[step.Then]; - return fn || function (){ - throw "ERROR: Need Given/When/Then got: " + toJson(step); + execute: function(name, callback) { + var spec = this.specs[name], + result = { + passed: false, + failed: false, + finished: false, + fail: function(error) { + result.passed = false; + result.failed = true; + result.error = error; + result.log(angular.isString(error) ? error : angular.toJson(error)); + } + }; + specThis = { + result: result, + testWindow: this.testWindow, + testFrame: this.testFrame }; - }, - - - context: function(runner) { - var frame = runner.frame; - var window = frame[0].contentWindow; - var document; - if (window.jQuery) - document = window.jQuery(window.document); - var context = { - frame:frame, - window:window, - log:_.bind(runner.log, runner, "info"), - document:document, - assert:function(element, path){ - if (element.size() != 1) { - throw "Expected to find '1' found '"+ - element.size()+"' for '"+path+"'."; - } - return element; - }, - element:function(path){ - var exp = path.replace("{{","[ng-bind=").replace("}}", "]"); - var element = document.find(exp); - return context.assert(element, path); - } - }; - return context; - }, - - - executeStep:function(runner, step, callback) { - if (!step) { - callback(); - return; - } - runner.log("info", toJson(step)); - var fn = this.verb(step); - var context = this.context(runner); - _.extend(context, step); - try { - (fn.call(context)||function(c){c();})(callback); - } catch (e) { - runner.log("error", "ERROR: " + toJson(e)); - } + var beginStep = this.beginSpec(name); + spec.nextStepIndex = 0; + function done() { + result.finished = true; + (callback||angular.noop).call(specThis); + } + function next(){ + var step = spec.steps[spec.nextStepIndex]; + if (step) { + spec.nextStepIndex ++; + result.log = beginStep(step.name); + try { + step.fn.call(specThis, next); + } catch (e) { + result.fail(e); + done(); + } + } else { + result.passed = !result.failed; + done(); + } + }; + next(); + return specThis; } -}; +};
\ No newline at end of file diff --git a/src/scenario/Steps.js b/src/scenario/Steps.js deleted file mode 100644 index ffe75933..00000000 --- a/src/scenario/Steps.js +++ /dev/null @@ -1,57 +0,0 @@ -angular.scenario.GIVEN = { - browser:function(){ - var self = this; - if (jQuery.browser.safari && this.frame.attr('src') == this.at) { - this.window.location.reload(); - } else { - this.frame.attr('src', this.at); - } - return function(done){ - self.frame.load(function(){ - self.frame.unbind(); - done(); - }); - }; - }, - dataset:function(){ - this.frame.name="$DATASET:" + toJson({dataset:this.dataset}); - } -}; -angular.scenario.WHEN = { - enter:function(){ - var element = this.element(this.at); - element.attr('value', this.text); - element.change(); - }, - click:function(){ - var element = this.element(this.at); - var input = element[0]; - // emulate the browser behavior which causes it - // to be overridden at the end. - var checked = input.checked = !input.checked; - element.trigger('click'); - input.checked = checked; - }, - select:function(){ - var element = this.element(this.at); - var path = "option[value=" + this.option + "]"; - var option = this.assert(element.find(path)); - option[0].selected = !option[0].selected; - element.change(); - } -}; -angular.scenario.THEN = { - text:function(){ - var element = this.element(this.at); - if (typeof this.should_be != undefined ) { - var should_be = this.should_be; - if (_.isArray(this.should_be)) - should_be = JSON.stringify(should_be); - if (element.text() != should_be) - throw "Expected " + should_be + - " but was " + element.text() + "."; - } - }, - drainRequestQueue:function(){ - } -}; diff --git a/src/scenario/_namespace.js b/src/scenario/_namespace.js deleted file mode 100644 index 7da3a5d8..00000000 --- a/src/scenario/_namespace.js +++ /dev/null @@ -1,6 +0,0 @@ -if (!angular) var angular = window['angular'] = {}; -if (!angular['scenario']) var angularScenario = angular['scenario'] = {}; -if (!angular['scenarioDef']) var scenarioDef = angular['scenarioDef'] = {}; -if (!angular['scenario']['GIVEN']) angularScenario['GIVEN'] = {}; -if (!angular['scenario']['WHEN']) angularScenario['WHEN'] = {}; -if (!angular['scenario']['THEN']) angularScenario['THEN'] = {}; diff --git a/src/scenario/bootstrap.js b/src/scenario/bootstrap.js index 169f1860..81272bdd 100644 --- a/src/scenario/bootstrap.js +++ b/src/scenario/bootstrap.js @@ -19,22 +19,8 @@ } window.onload = function(){ - if (!_.stepper) { - _.stepper = function(collection, iterator, done){ - var keys = _.keys(collection); - function next() { - if (keys.length) { - var key = keys.shift(); - iterator(next, collection[key], key); - } else { - (done||_.identity)(); - } - } - next(); - }; - } _.defer(function(){ - new angular.scenario.SuiteRunner(angular.scenarioDef, jQuery(document.body)).run(); + $scenarioRunner.run(jQuery(document.body)); }); (onLoadDelegate||function(){})(); }; @@ -42,8 +28,7 @@ addScript("../../lib/underscore/underscore.js"); addScript("../../lib/jquery/jquery-1.4.2.js"); addScript("../angular-bootstrap.js"); - addScript("_namespace.js"); - addScript("Steps.js"); addScript("Runner.js"); + document.write('<script type="text/javascript">$scenarioRunner = new angular.scenario.Runner(window);</script>'); })(window.onload); |
