mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-16 23:30:23 +00:00
basic end to end runner
This commit is contained in:
parent
31b35b141f
commit
5215e2095c
13 changed files with 289 additions and 278 deletions
|
|
@ -2,26 +2,13 @@
|
||||||
/* CSS Document */
|
/* CSS Document */
|
||||||
|
|
||||||
#runner {
|
#runner {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top:5px;
|
top:5px;
|
||||||
left:10px;
|
left:10px;
|
||||||
right:10px;
|
right:10px;
|
||||||
height: 200px;
|
height: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#testView {
|
|
||||||
position: absolute;
|
|
||||||
bottom:10px;
|
|
||||||
top:210px;
|
|
||||||
left:10px;
|
|
||||||
right:10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#testView iframe {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.console {
|
.console {
|
||||||
display: block;
|
display: block;
|
||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
|
|
@ -29,6 +16,22 @@
|
||||||
border: 1px solid black;
|
border: 1px solid black;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#testView {
|
||||||
|
position: absolute;
|
||||||
|
bottom:10px;
|
||||||
|
top:230px;
|
||||||
|
left:10px;
|
||||||
|
right:10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#testView iframe {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////
|
||||||
|
|
||||||
.collapsed .log {
|
.collapsed .log {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ load:
|
||||||
- lib/jquery/jquery-1.4.2.js
|
- lib/jquery/jquery-1.4.2.js
|
||||||
- src/Angular.js
|
- src/Angular.js
|
||||||
- src/*.js
|
- src/*.js
|
||||||
- src/scenario/_namespace.js
|
|
||||||
- src/scenario/*.js
|
- src/scenario/*.js
|
||||||
- test/testabilityPatch.js
|
- test/testabilityPatch.js
|
||||||
- test/angular-mocks.js
|
- test/angular-mocks.js
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ load:
|
||||||
# - lib/jquery/jquery-1.4.2.js
|
# - lib/jquery/jquery-1.4.2.js
|
||||||
- src/Angular.js
|
- src/Angular.js
|
||||||
- src/*.js
|
- src/*.js
|
||||||
- src/scenario/_namespace.js
|
|
||||||
- src/scenario/*.js
|
- src/scenario/*.js
|
||||||
- test/testabilityPatch.js
|
- test/testabilityPatch.js
|
||||||
- test/angular-mocks.js
|
- test/angular-mocks.js
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,7 @@
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||||
<head>
|
<head>
|
||||||
<script type="text/javascript" src="../src/scenario/bootstrap.js"></script>
|
<script type="text/javascript" src="../src/scenario/bootstrap.js"></script>
|
||||||
<script type="text/javascript" src="widgets-scenarios.js"></script>
|
<script type="text/javascript" src="widgets-scenario2.js"></script>
|
||||||
<script type="text/javascript" src="datastore-scenarios.js"></script>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
||||||
54
scenario/widgets-scenario2.js
Normal file
54
scenario/widgets-scenario2.js
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
browser = {
|
||||||
|
navigateTo: function(url){
|
||||||
|
$scenario.addStep('Navigate to: ' + url, function(done){
|
||||||
|
var self = this;
|
||||||
|
self.testFrame.load(function(){
|
||||||
|
self.testFrame.unbind();
|
||||||
|
self.testDocument = self.testWindow.angular.element(self.testWindow.document);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
if (this.testFrame.attr('src') == url) {
|
||||||
|
this.testWindow.location.reload();
|
||||||
|
} else {
|
||||||
|
this.testFrame.attr('src', url);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function input(selector) {
|
||||||
|
return {
|
||||||
|
enter: function(value){
|
||||||
|
$scenario.addStep("Set input text of '" + selector + "' to value '" + value + "'", function(done){
|
||||||
|
var input = this.testDocument.find('input[name=' + selector + ']');
|
||||||
|
input.val(value);
|
||||||
|
input.trigger('change');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function expect(selector) {
|
||||||
|
return {
|
||||||
|
toEqual: function(expected) {
|
||||||
|
$scenario.addStep("Expect that " + selector + " equals '" + expected + "'", function(done){
|
||||||
|
var attrName = selector.substring(2, selector.length - 2);
|
||||||
|
var binding = this.testDocument.find('span[ng-bind=' + attrName + ']');
|
||||||
|
if (binding.text() != expected) {
|
||||||
|
this.result.fail("Expected '" + expected + "' but was '" + binding.text() + "'");
|
||||||
|
}
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('widgets', function(){
|
||||||
|
it('should verify that basic widgets work', function(){
|
||||||
|
browser.navigateTo('widgets.html');
|
||||||
|
expect('{{text.basic}}').toEqual('');
|
||||||
|
input('text.basic').enter('John');
|
||||||
|
expect('{{text.basic}}').toEqual('JohnXX');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -3,28 +3,28 @@ angular.scenarioDef.widgets = {
|
||||||
{Given:"browser", at:"widgets.html"}
|
{Given:"browser", at:"widgets.html"}
|
||||||
],
|
],
|
||||||
checkWidgetBinding:[
|
checkWidgetBinding:[
|
||||||
{Then:"text", at:"{{name}}", should_be:""},
|
{Then:"text", at:"{{text.basic}}", should_be:""},
|
||||||
{When:"enter", text:"John", at:":input[name=name]"},
|
{When:"enter", text:"John", at:":input[name=text.basic]"},
|
||||||
{Then:"text", at:"{{name}}", should_be:"John"},
|
{Then:"text", at:"{{text.basic}}", should_be:"John"},
|
||||||
|
|
||||||
{Then:"text", at:"{{gender}}", should_be:""},
|
|
||||||
{When:"click", at:"input:radio[value=male]"},
|
|
||||||
{Then:"text", at:"{{gender}}", should_be:"male"},
|
{Then:"text", at:"{{gender}}", should_be:"male"},
|
||||||
|
{When:"click", at:"input:radio[value=female]"},
|
||||||
|
{Then:"text", at:"{{gender}}", should_be:"female"},
|
||||||
|
|
||||||
{Then:"text", at:"{{tea}}", should_be:"on"},
|
{Then:"text", at:"{{tea}}", should_be:"on"},
|
||||||
{When:"click", at:"input[name=tea]"},
|
{When:"click", at:"input[name=tea]"},
|
||||||
{Then:"text", at:"{{tea}}", should_be:""},
|
{Then:"text", at:"{{tea}}", should_be:""},
|
||||||
|
|
||||||
{Then:"text", at:"{{coffee}}", should_be:""},
|
{Then:"text", at:"{{coffee}}", should_be:""},
|
||||||
{When:"click", at:"input[name=coffee]"},
|
{When:"click", at:"input[name=coffee]"},
|
||||||
{Then:"text", at:"{{coffee}}", should_be:"on"},
|
{Then:"text", at:"{{coffee}}", should_be:"on"},
|
||||||
|
|
||||||
{Then:"text", at:"{{count}}", should_be:0},
|
{Then:"text", at:"{{count}}", should_be:0},
|
||||||
{When:"click", at:"form :button"},
|
{When:"click", at:"form :button"},
|
||||||
{When:"click", at:"form :submit"},
|
{When:"click", at:"form :submit"},
|
||||||
{When:"click", at:"form :image"},
|
{When:"click", at:"form :image"},
|
||||||
{Then:"text", at:"{{count}}", should_be:3},
|
{Then:"text", at:"{{count}}", should_be:3},
|
||||||
|
|
||||||
{Then:"text", at:"{{select}}", should_be:"A"},
|
{Then:"text", at:"{{select}}", should_be:"A"},
|
||||||
{When:"select", at:"select[name=select]", option:"B"},
|
{When:"select", at:"select[name=select]", option:"B"},
|
||||||
{Then:"text", at:"{{select}}", should_be:"B"},
|
{Then:"text", at:"{{select}}", should_be:"B"},
|
||||||
|
|
@ -36,7 +36,7 @@ angular.scenarioDef.widgets = {
|
||||||
{Then:"text", at:"{{multiple}}", should_be:["A", "B"]},
|
{Then:"text", at:"{{multiple}}", should_be:["A", "B"]},
|
||||||
{When:"select", at:"select[name=multiple]", option:"A"},
|
{When:"select", at:"select[name=multiple]", option:"A"},
|
||||||
{Then:"text", at:"{{multiple}}", should_be:["B"]},
|
{Then:"text", at:"{{multiple}}", should_be:["B"]},
|
||||||
|
|
||||||
{Then:"text", at:"{{hidden}}", should_be:"hiddenValue"},
|
{Then:"text", at:"{{hidden}}", should_be:"hiddenValue"},
|
||||||
|
|
||||||
{Then:"text", at:"{{password}}", should_be:"passwordValue"},
|
{Then:"text", at:"{{password}}", should_be:"passwordValue"},
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,7 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td>basic</td>
|
<td>basic</td>
|
||||||
<td>
|
<td>
|
||||||
<input type="text" name="text.basic" ng-required ng-validate="number" ng-format="number"/>
|
<input type="text" name="text.basic"/>
|
||||||
<input type="text" name="text.basic" ng-format="number"/>
|
|
||||||
</td>
|
</td>
|
||||||
<td>text.basic={{text.basic}}</td>
|
<td>text.basic={{text.basic}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
||||||
|
|
@ -1,171 +1,109 @@
|
||||||
var scenario = angular.scenario;
|
angular['scenario'] = (angular['scenario'] = {});
|
||||||
scenario.SuiteRunner = function(scenarios, body) {
|
|
||||||
this.scenarios = scenarios;
|
angular.scenario.Runner = function(scope){
|
||||||
this.body = body;
|
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;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
scenario.SuiteRunner.prototype = {
|
angular.scenario.Runner.prototype = {
|
||||||
run:function(){
|
run: function(body){
|
||||||
this.setUpUI();
|
body.append(
|
||||||
this.runScenarios();
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
setUpUI:function(){
|
|
||||||
this.body.html(
|
|
||||||
'<div id="runner">' +
|
'<div id="runner">' +
|
||||||
'<div class="console"></div>' +
|
'<ul class="console"></ul>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'<div id="testView">' +
|
'<div id="testView">' +
|
||||||
'<iframe></iframe>' +
|
'<iframe></iframe>' +
|
||||||
'</div>');
|
'</div>');
|
||||||
this.console = this.body.find(".console");
|
var console = body.find('#runner .console');
|
||||||
this.testFrame = this.body.find("iframe");
|
this.testFrame = body.find('#testView iframe');
|
||||||
this.console.find(".run").live("click", function(){
|
this.testWindow = this.testFrame[0].contentWindow;
|
||||||
jQuery(this).parent().find('.log').toggle();
|
this.beginSpec = function(name){
|
||||||
});
|
var specElement = jQuery('<li class="spec"></li>');
|
||||||
},
|
var stepContainer = jQuery('<ul class="step"></ul>');
|
||||||
|
console.append(specElement);
|
||||||
|
specElement.text(name);
|
||||||
runScenarios:function(){
|
specElement.append(stepContainer);
|
||||||
var runner = new scenario.Runner(this.console, this.testFrame);
|
return function(name){
|
||||||
_.stepper(this.scenarios, function(next, scenarioObj, name){
|
var stepElement = jQuery('<li class="step"></li>');
|
||||||
new scenario.Scenario(name, scenarioObj).run(runner, next);
|
var logContainer = jQuery('<ul class="log"></ul>');
|
||||||
}, function(){
|
stepContainer.append(stepElement);
|
||||||
}
|
stepElement.text(name);
|
||||||
);
|
stepElement.append(logContainer);
|
||||||
}
|
return function(message) {
|
||||||
};
|
var logElement = jQuery('<li class="log"></li>');
|
||||||
|
logContainer.append(logElement);
|
||||||
scenario.Runner = function(console, frame){
|
logElement.text(message);
|
||||||
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>')
|
|
||||||
};
|
};
|
||||||
current.run = current.scenario.append(
|
this.execute("widgets: it should verify that basic widgets work");
|
||||||
'<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();
|
|
||||||
},
|
|
||||||
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){
|
execute: function(name, callback) {
|
||||||
var fn = null;
|
var spec = this.specs[name],
|
||||||
if (!step) fn = function (){ throw "Step is null!"; };
|
result = {
|
||||||
else if (step.Given) fn = scenario.GIVEN[step.Given];
|
passed: false,
|
||||||
else if (step.When) fn = scenario.WHEN[step.When];
|
failed: false,
|
||||||
else if (step.Then) fn = scenario.THEN[step.Then];
|
finished: false,
|
||||||
return fn || function (){
|
fail: function(error) {
|
||||||
throw "ERROR: Need Given/When/Then got: " + toJson(step);
|
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
|
||||||
};
|
};
|
||||||
},
|
var beginStep = this.beginSpec(name);
|
||||||
|
spec.nextStepIndex = 0;
|
||||||
|
function done() {
|
||||||
context: function(runner) {
|
result.finished = true;
|
||||||
var frame = runner.frame;
|
(callback||angular.noop).call(specThis);
|
||||||
var window = frame[0].contentWindow;
|
}
|
||||||
var document;
|
function next(){
|
||||||
if (window.jQuery)
|
var step = spec.steps[spec.nextStepIndex];
|
||||||
document = window.jQuery(window.document);
|
if (step) {
|
||||||
var context = {
|
spec.nextStepIndex ++;
|
||||||
frame:frame,
|
result.log = beginStep(step.name);
|
||||||
window:window,
|
try {
|
||||||
log:_.bind(runner.log, runner, "info"),
|
step.fn.call(specThis, next);
|
||||||
document:document,
|
} catch (e) {
|
||||||
assert:function(element, path){
|
result.fail(e);
|
||||||
if (element.size() != 1) {
|
done();
|
||||||
throw "Expected to find '1' found '"+
|
}
|
||||||
element.size()+"' for '"+path+"'.";
|
} else {
|
||||||
}
|
result.passed = !result.failed;
|
||||||
return element;
|
done();
|
||||||
},
|
}
|
||||||
element:function(path){
|
};
|
||||||
var exp = path.replace("{{","[ng-bind=").replace("}}", "]");
|
next();
|
||||||
var element = document.find(exp);
|
return specThis;
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -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(){
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
@ -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'] = {};
|
|
||||||
19
src/scenario/bootstrap.js
vendored
19
src/scenario/bootstrap.js
vendored
|
|
@ -19,22 +19,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
window.onload = function(){
|
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(){
|
_.defer(function(){
|
||||||
new angular.scenario.SuiteRunner(angular.scenarioDef, jQuery(document.body)).run();
|
$scenarioRunner.run(jQuery(document.body));
|
||||||
});
|
});
|
||||||
(onLoadDelegate||function(){})();
|
(onLoadDelegate||function(){})();
|
||||||
};
|
};
|
||||||
|
|
@ -42,8 +28,7 @@
|
||||||
addScript("../../lib/underscore/underscore.js");
|
addScript("../../lib/underscore/underscore.js");
|
||||||
addScript("../../lib/jquery/jquery-1.4.2.js");
|
addScript("../../lib/jquery/jquery-1.4.2.js");
|
||||||
addScript("../angular-bootstrap.js");
|
addScript("../angular-bootstrap.js");
|
||||||
addScript("_namespace.js");
|
|
||||||
addScript("Steps.js");
|
|
||||||
addScript("Runner.js");
|
addScript("Runner.js");
|
||||||
|
document.write('<script type="text/javascript">$scenarioRunner = new angular.scenario.Runner(window);</script>');
|
||||||
})(window.onload);
|
})(window.onload);
|
||||||
|
|
||||||
|
|
|
||||||
105
test/scenario/RunnerSpec.js
Normal file
105
test/scenario/RunnerSpec.js
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
describe('Runner', function(){
|
||||||
|
var scenario, runner, log, Describe, It, $scenario;
|
||||||
|
|
||||||
|
function logger(text) {
|
||||||
|
return function(){log += text;};
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeEach(function(){
|
||||||
|
log = '';
|
||||||
|
scenario = {};
|
||||||
|
runner = new angular.scenario.Runner(scenario);
|
||||||
|
Describe = scenario.describe;
|
||||||
|
It = scenario.it;
|
||||||
|
$scenario = scenario.$scenario;
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('describe', function(){
|
||||||
|
it('should consume the describe functions', function(){
|
||||||
|
Describe('describe name', logger('body'));
|
||||||
|
|
||||||
|
expect(log).toEqual('body');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('it', function(){
|
||||||
|
it('should consume it', function(){
|
||||||
|
Describe('describe name', function(){
|
||||||
|
It('should text', logger('body'));
|
||||||
|
});
|
||||||
|
expect(log).toEqual('body');
|
||||||
|
var spec = $scenario.specs['describe name: it should text'];
|
||||||
|
expect(spec.steps).toEqual([]);
|
||||||
|
expect(spec.name).toEqual('describe name: it should text');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('steps building', function(){
|
||||||
|
it('should queue steps', function(){
|
||||||
|
function step(){};
|
||||||
|
Describe('name', function(){
|
||||||
|
It('should', function(){
|
||||||
|
$scenario.addStep('stepname', step);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
expect($scenario.specs['name: it should'].steps).toEqual([{name:'stepname', fn:step}]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('execution', function(){
|
||||||
|
it('should execute the queued steps', function(){
|
||||||
|
var next, firstThis, secondThis, doneThis, spec;
|
||||||
|
$scenario.specs['spec'] = {
|
||||||
|
steps: [
|
||||||
|
{name:'step1', fn: function(done) {
|
||||||
|
next = done;
|
||||||
|
log += 'first;';
|
||||||
|
firstThis = this;
|
||||||
|
}},
|
||||||
|
{name:'step2', fn:function(done){
|
||||||
|
next = done;
|
||||||
|
log += 'second;';
|
||||||
|
secondThis = this;
|
||||||
|
}}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
spec = $scenario.execute('spec', function(done){
|
||||||
|
log += 'done;';
|
||||||
|
doneThis = this;
|
||||||
|
});
|
||||||
|
expect(log).toEqual('first;');
|
||||||
|
next();
|
||||||
|
expect(log).toEqual('first;second;');
|
||||||
|
next();
|
||||||
|
expect(log).toEqual('first;second;done;');
|
||||||
|
expect(spec).not.toEqual(window);
|
||||||
|
expect(spec).toEqual(firstThis);
|
||||||
|
expect(spec).toEqual(secondThis);
|
||||||
|
expect(spec).toEqual(doneThis);
|
||||||
|
|
||||||
|
expect(spec.result.failed).toEqual(false);
|
||||||
|
expect(spec.result.finished).toEqual(true);
|
||||||
|
expect(spec.result.error).toBeUndefined();
|
||||||
|
expect(spec.result.passed).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle exceptions in a step', function(){
|
||||||
|
$scenario.specs['spec'] = {
|
||||||
|
steps: [
|
||||||
|
{name:'error', fn:function(done) {
|
||||||
|
throw "MyError";
|
||||||
|
}}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
var spec = $scenario.execute('spec');
|
||||||
|
|
||||||
|
expect(spec.result.passed).toEqual(false);
|
||||||
|
expect(spec.result.failed).toEqual(true);
|
||||||
|
expect(spec.result.finished).toEqual(true);
|
||||||
|
expect(spec.result.error).toEqual("MyError");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
StepsTest = TestCase("StepsTest");
|
|
||||||
|
|
||||||
StepsTest.prototype.testGivenDataset=function(){
|
|
||||||
var self = {frame:{}, dataset:[]};
|
|
||||||
angular.scenario.GIVEN.dataset.call(self);
|
|
||||||
assertEquals('$DATASET:{"dataset":[]}', self.frame.name);
|
|
||||||
};
|
|
||||||
Loading…
Reference in a new issue