X Tutup
Skip to content

Commit e7e894a

Browse files
committed
Significantly clean up the way the scenario DSL works and implement many more DSL statements.
- "this" always means the current chain scope inside a DSL - addFutureAction callbacks now take ($window, $document, done) - $document has a special method elements() that uses the currently selected nodes in the document as defined by using() statements. - $document.elements() allows placeholder insertion into selectors to make them more readable. ex. $document.elements('input[name="$1"]', myVar) will substitute the value of myVar for $1 in the selector. Subsequent arguments are $2 and so on. - $document.elements() results have a special method trigger(event) which should be used to events. This method implements some hacks to make sure browser UI controls update and the correct angular events fire. - futures now allow custom formatting. By default any chain that results in a future can use toJson() or fromJson() to convert the future value to and from json. A custom parser can be provided with parsedWith(fn) where fn is a callback(value) that must return the parsed result. Note: The entire widgets.html UI is now able to be controlled and asserted through DSL statements!!! Victory! :)
1 parent a1fa233 commit e7e894a

File tree

13 files changed

+648
-256
lines changed

13 files changed

+648
-256
lines changed

scenario/widgets-scenario.js

Lines changed: 42 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,55 @@
11
describe('widgets', function() {
22
it('should verify that basic widgets work', function(){
33
navigateTo('widgets.html');
4-
input('text.basic').enter('Carlos');
4+
5+
using('#text-basic-box').input('text.basic').enter('Carlos');
56
expect(binding('text.basic')).toEqual('Carlos');
6-
pause(2);
77
input('text.basic').enter('Carlos Santana');
8-
pause(2);
98
expect(binding('text.basic')).not().toEqual('Carlos Boozer');
10-
pause(2);
9+
1110
input('text.password').enter('secret');
1211
expect(binding('text.password')).toEqual('secret');
12+
1313
expect(binding('text.hidden')).toEqual('hiddenValue');
14+
1415
expect(binding('gender')).toEqual('male');
15-
pause(2);
1616
input('gender').select('female');
17-
expect(binding('gender')).toEqual('female');
18-
pause(2);
19-
});
20-
describe('do it again', function() {
21-
it('should verify that basic widgets work', function(){
22-
navigateTo('widgets.html');
23-
input('text.basic').enter('Carlos');
24-
expect(binding('text.basic')).toEqual('Carlos');
25-
pause(2);
26-
input('text.basic').enter('Carlos Santana');
27-
pause(2);
28-
expect(binding('text.basic')).toEqual('Carlos Santana');
29-
pause(2);
30-
input('text.password').enter('secret');
31-
expect(binding('text.password')).toEqual('secret');
32-
expect(binding('text.hidden')).toEqual('hiddenValue');
33-
expect(binding('gender')).toEqual('male');
34-
pause(2);
35-
input('gender').select('female');
36-
expect(binding('gender')).toEqual('female');
37-
pause(2);
38-
});
39-
});
40-
it('should verify that basic widgets work', function(){
41-
navigateTo('widgets.html');
42-
input('text.basic').enter('Carlos');
43-
expect(binding('text.basic')).toEqual('Carlos');
44-
pause(2);
45-
input('text.basic').enter('Carlos Santana');
46-
pause(2);
47-
expect(binding('text.basic')).toEqual('Carlos Santana');
48-
pause(2);
49-
input('text.password').enter('secret');
50-
expect(binding('text.password')).toEqual('secret');
51-
expect(binding('text.hidden')).toEqual('hiddenValue');
52-
expect(binding('gender')).toEqual('male');
53-
pause(2);
54-
input('gender').select('female');
55-
expect(binding('gender')).toEqual('female');
56-
pause(2);
17+
expect(using('#gender-box').binding('gender')).toEqual('female');
18+
19+
expect(repeater('#repeater-row ul li').count()).toEqual(2);
20+
expect(repeater('#repeater-row ul li').row(1)).toEqual(['adam']);
21+
expect(repeater('#repeater-row ul li').column('name')).toEqual(['misko', 'adam']);
22+
23+
select('select').option('B');
24+
expect(binding('select')).toEqual('B');
25+
26+
select('multiselect').options('A', 'C');
27+
expect(binding('multiselect').fromJson()).toEqual(['A', 'C']);
28+
29+
expect(binding('button').fromJson()).toEqual({'count': 0});
30+
element('form a').click();
31+
expect(binding('button').fromJson()).toEqual({'count': 1});
32+
element('input[value="submit"]').click();
33+
expect(binding('button').fromJson()).toEqual({'count': 2});
34+
element('input[value="button"]').click();
35+
expect(binding('button').fromJson()).toEqual({'count': 3});
36+
element('input[type="image"]').click();
37+
expect(binding('button').fromJson()).toEqual({'count': 4});
38+
39+
/**
40+
* Custom value parser for futures.
41+
*/
42+
function checkboxParser(value) {
43+
return angular.fromJson(value.substring(value.indexOf('=')+1));
44+
}
45+
46+
input('checkbox.tea').check();
47+
expect(binding('checkbox').parsedWith(checkboxParser)).toEqual({coffee: false, tea: false});
48+
input('checkbox.coffee').check();
49+
expect(binding('checkbox').parsedWith(checkboxParser)).toEqual({coffee: true, tea: false});
50+
input('checkbox.tea').check();
51+
input('checkbox.tea').check();
52+
input('checkbox.tea').check();
53+
expect(binding('checkbox').parsedWith(checkboxParser)).toEqual({coffee: true, tea: true});
5754
});
5855
});

scenario/widgets.html

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
<html xmlns:ng="http://angularjs.org">
33
<head>
44
<link rel="stylesheet" type="text/css" href="style.css"/>
5+
<script type="text/javascript" src="../lib/jquery/jquery-1.4.2.js"></script>
56
<script type="text/javascript" src="../src/angular-bootstrap.js" ng:autobind></script>
67
</head>
78
<body ng:init="$window.$scope = this">
@@ -14,7 +15,7 @@
1415
<tr><th colspan="3">Input text field</th></tr>
1516
<tr>
1617
<td>basic</td>
17-
<td>
18+
<td id="text-basic-box">
1819
<input type="text" name="text.basic"/>
1920
</td>
2021
<td>text.basic={{text.basic}}</td>
@@ -30,7 +31,7 @@
3031
<td>text.hidden={{text.hidden}}</td>
3132
</tr>
3233
<tr><th colspan="3">Input selection field</th></tr>
33-
<tr>
34+
<tr id="gender-box">
3435
<td>radio</td>
3536
<td>
3637
<input type="radio" name="gender" value="female"/> Female <br/>
@@ -78,13 +79,13 @@
7879
<input type="button" value="button" ng:change="button.count = button.count + 1"/> <br/>
7980
<input type="submit" value="submit" ng:change="button.count = button.count + 1"/><br/>
8081
<input type="image" src="" ng:change="button.count = button.count + 1"/><br/>
81-
<a href="" ng:click="button.count = button.count + 1">action</a>
82+
<a href="" ng:click="button.count = button.count + 1">action</a>
8283
</form>
8384
</td>
8485
<td>button={{button}}</td>
8586
</tr>
8687
<tr><th colspan="3">Repeaters</th></tr>
87-
<tr>
88+
<tr id="repeater-row">
8889
<td>ng:repeat</td>
8990
<td>
9091
<ul>

src/jqLite.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,14 @@ JQLite.prototype = {
119119
},
120120

121121
trigger: function(type) {
122-
var evnt = document.createEvent('MouseEvents'),
123-
element = this[0];
124-
evnt.initMouseEvent(type, true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, element);
125-
element.dispatchEvent(evnt);
122+
if (msie) {
123+
this[0].fireEvent('on' + type);
124+
} else {
125+
var evnt = document.createEvent('MouseEvents'),
126+
element = this[0];
127+
evnt.initMouseEvent(type, true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, element);
128+
element.dispatchEvent(evnt);
129+
}
126130
},
127131

128132
replaceWith: function(replaceNode) {
@@ -249,10 +253,6 @@ if (msie) {
249253
if (isDefined(value)) e.innerText = value;
250254
return e.innerText;
251255
}
252-
},
253-
254-
trigger: function(type) {
255-
this[0].fireEvent('on' + type);
256256
}
257257
});
258258
}

src/scenario/Application.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,5 @@ angular.scenario.Application.prototype.navigateTo = function(url, onloadFn) {
4747
*/
4848
angular.scenario.Application.prototype.executeAction = function(action) {
4949
var $window = this.getWindow();
50-
return action.call($window, _jQuery($window.document), $window);
50+
return action.call(this, $window, _jQuery($window.document));
5151
};

src/scenario/DSL.js

Lines changed: 0 additions & 134 deletions
This file was deleted.

src/scenario/Future.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ angular.scenario.Future = function(name, behavior) {
66
this.behavior = behavior;
77
this.fulfilled = false;
88
this.value = undefined;
9+
this.parser = angular.identity;
910
};
1011

1112
/**
@@ -16,7 +17,38 @@ angular.scenario.Future = function(name, behavior) {
1617
angular.scenario.Future.prototype.execute = function(doneFn) {
1718
this.behavior(angular.bind(this, function(error, result) {
1819
this.fulfilled = true;
20+
if (result) {
21+
try {
22+
result = this.parser(result);
23+
} catch(e) {
24+
error = e;
25+
}
26+
}
1927
this.value = error || result;
2028
doneFn(error, result);
2129
}));
2230
};
31+
32+
/**
33+
* Configures the future to convert it's final with a function fn(value)
34+
*/
35+
angular.scenario.Future.prototype.parsedWith = function(fn) {
36+
this.parser = fn;
37+
return this;
38+
};
39+
40+
/**
41+
* Configures the future to parse it's final value from JSON
42+
* into objects.
43+
*/
44+
angular.scenario.Future.prototype.fromJson = function() {
45+
return this.parsedWith(angular.fromJson);
46+
};
47+
48+
/**
49+
* Configures the future to convert it's final value from objects
50+
* into JSON.
51+
*/
52+
angular.scenario.Future.prototype.toJson = function() {
53+
return this.parsedWith(angular.toJson);
54+
};

0 commit comments

Comments
 (0)
X Tutup