OLD | NEW |
| (Empty) |
1 library ng_specs; | |
2 | |
3 import 'dart:html'; | |
4 import 'package:unittest/unittest.dart' as unit; | |
5 import 'package:angular/angular.dart'; | |
6 import 'package:angular/mock/module.dart'; | |
7 import 'package:collection/wrappers.dart' show DelegatingList; | |
8 | |
9 import 'jasmine_syntax.dart'; | |
10 | |
11 export 'dart:html'; | |
12 export 'jasmine_syntax.dart' hide main; | |
13 export 'package:unittest/unittest.dart'; | |
14 export 'package:mock/mock.dart'; | |
15 export 'package:di/dynamic_injector.dart'; | |
16 export 'package:angular/angular.dart'; | |
17 export 'package:angular/mock/module.dart'; | |
18 export 'package:perf_api/perf_api.dart'; | |
19 | |
20 es(String html) { | |
21 var div = new DivElement(); | |
22 div.setInnerHtml(html, treeSanitizer: new NullTreeSanitizer()); | |
23 return div.nodes; | |
24 } | |
25 | |
26 e(String html) => es(html).first; | |
27 | |
28 renderedText(n, [bool notShadow = false]) { | |
29 if (n is List) { | |
30 return n.map((nn) => renderedText(nn)).join(""); | |
31 } | |
32 | |
33 if (n is Comment) return ''; | |
34 | |
35 if (!notShadow && n is Element && n.shadowRoot != null) { | |
36 var shadowText = n.shadowRoot.text; | |
37 var domText = renderedText(n, true); | |
38 return shadowText.replaceFirst("SHADOW-CONTENT", domText); | |
39 } | |
40 | |
41 if (n.nodes == null || n.nodes.length == 0) return n.text; | |
42 | |
43 return n.nodes.map((cn) => renderedText(cn)).join(""); | |
44 } | |
45 | |
46 Expect expect(actual, [unit.Matcher matcher = null]) { | |
47 if (matcher != null) { | |
48 unit.expect(actual, matcher); | |
49 } | |
50 return new Expect(actual); | |
51 } | |
52 | |
53 class Expect { | |
54 var actual; | |
55 var not; | |
56 Expect(this.actual) { | |
57 not = new NotExpect(this); | |
58 } | |
59 | |
60 toEqual(expected) => unit.expect(actual, unit.equals(expected)); | |
61 toContain(expected) => unit.expect(actual, unit.contains(expected)); | |
62 toBe(expected) => unit.expect(actual, | |
63 unit.predicate((actual) => identical(expected, actual), '$expected')); | |
64 toThrow([exception]) => unit.expect(actual, exception == null ? unit.throws :
unit.throwsA(new ExceptionContains(exception))); | |
65 toBeFalsy() => unit.expect(actual, (v) => v == null ? true : v is bool ? v ==
false : false); | |
66 toBeTruthy() => unit.expect(actual, (v) => v is bool ? v == true : true); | |
67 toBeDefined() => unit.expect(actual, (v) => v != null); | |
68 toBeNull() => unit.expect(actual, unit.isNull); | |
69 toBeNotNull() => unit.expect(actual, unit.isNotNull); | |
70 | |
71 toHaveBeenCalled() => unit.expect(actual.called, true, reason: 'method not cal
led'); | |
72 toHaveBeenCalledOnce() => unit.expect(actual.count, 1, reason: 'method invoked
${actual.count} expected once'); | |
73 toHaveBeenCalledWith([a,b,c,d,e,f]) => | |
74 unit.expect(actual.firstArgsMatch(a,b,c,d,e,f), true, | |
75 reason: 'method invoked with correct arguments'); | |
76 toHaveBeenCalledOnceWith([a,b,c,d,e,f]) => | |
77 unit.expect(actual.count == 1 && actual.firstArgsMatch(a,b,c,d,e,f), | |
78 true, | |
79 reason: 'method invoked once with correct arguments. (Called ${
actual.count} times)'); | |
80 | |
81 toHaveClass(cls) => unit.expect(actual.classes.contains(cls), true, reason: '
Expected ${actual} to have css class ${cls}'); | |
82 | |
83 toEqualSelect(options) { | |
84 var actualOptions = []; | |
85 | |
86 for (var option in actual.querySelectorAll('option')) { | |
87 if (option.selected) { | |
88 actualOptions.add([option.value]); | |
89 } else { | |
90 actualOptions.add(option.value); | |
91 } | |
92 } | |
93 return unit.expect(actualOptions, options); | |
94 } | |
95 | |
96 toEqualValid() { | |
97 // TODO: implement onece we have forms | |
98 } | |
99 toEqualInvalid() { | |
100 // TODO: implement onece we have forms | |
101 } | |
102 toEqualPristine() { | |
103 // TODO: implement onece we have forms | |
104 } | |
105 toEqualDirty() { | |
106 // TODO: implement onece we have forms | |
107 } | |
108 } | |
109 | |
110 class NotExpect { | |
111 Expect expect; | |
112 get actual => expect.actual; | |
113 NotExpect(this.expect); | |
114 | |
115 toHaveBeenCalled() => unit.expect(actual.called, false, reason: 'method called
'); | |
116 toThrow() => actual(); | |
117 | |
118 toHaveClass(cls) => unit.expect(actual.classes.contains(cls), false, reason: '
Expected ${actual} to not have css class ${cls}'); | |
119 toBe(expected) => unit.expect(actual, | |
120 unit.predicate((actual) => !identical(expected, actual), 'not $expected'))
; | |
121 toEqual(expected) => unit.expect(actual, | |
122 unit.predicate((actual) => expected != actual, 'not $expected')); | |
123 toContain(expected) => unit.expect(actual, | |
124 unit.predicate((actual) => !actual.contains(expected), 'not $expected')); | |
125 } | |
126 | |
127 class ExceptionContains extends unit.Matcher { | |
128 | |
129 final _expected; | |
130 | |
131 const ExceptionContains(this._expected); | |
132 | |
133 bool matches(item, Map matchState) { | |
134 if (item is String) { | |
135 return item.indexOf(_expected) >= 0; | |
136 } | |
137 return matches('$item', matchState); | |
138 } | |
139 | |
140 unit.Description describe(unit.Description description) => | |
141 description.add('exception contains ').addDescriptionOf(_expected); | |
142 | |
143 unit.Description describeMismatch(item, unit.Description mismatchDescription, | |
144 Map matchState, bool verbose) { | |
145 return super.describeMismatch('$item', mismatchDescription, matchState, | |
146 verbose); | |
147 } | |
148 } | |
149 | |
150 $(selector) { | |
151 return new JQuery(selector); | |
152 } | |
153 | |
154 | |
155 class GetterSetter { | |
156 Getter getter(String key) => null; | |
157 Setter setter(String key) => null; | |
158 } | |
159 var getterSetter = new GetterSetter(); | |
160 | |
161 class JQuery extends DelegatingList<Node> { | |
162 JQuery([selector]) : super([]) { | |
163 if (selector == null) { | |
164 // do nothing; | |
165 } else if (selector is String) { | |
166 addAll(es(selector)); | |
167 } else if (selector is List) { | |
168 addAll(selector); | |
169 } else if (selector is Node) { | |
170 add(selector); | |
171 } else { | |
172 throw selector; | |
173 } | |
174 } | |
175 | |
176 _toHtml(node, [bool outer = false]) { | |
177 if (node is Comment) { | |
178 return '<!--${node.text}-->'; | |
179 } else { | |
180 return outer ? node.outerHtml : node.innerHtml; | |
181 } | |
182 } | |
183 | |
184 accessor(Function getter, Function setter, [value, single=false]) { | |
185 // TODO(dart): ?value does not work, since value was passed. :-( | |
186 var setterMode = value != null; | |
187 var result = setterMode ? this : ''; | |
188 forEach((node) { | |
189 if (setterMode) { | |
190 setter(node, value); | |
191 } else { | |
192 result = single ? getter(node) : '$result${getter(node)}'; | |
193 } | |
194 }); | |
195 return result; | |
196 } | |
197 | |
198 html([String html]) => accessor( | |
199 (n) => _toHtml(n), | |
200 (n, v) => n.setInnerHtml(v, treeSanitizer: new NullTreeSanitizer()), | |
201 html); | |
202 val([String text]) => accessor((n) => n.value, (n, v) => n.value = v); | |
203 text([String text]) => accessor((n) => n.text, (n, v) => n.text = v, text); | |
204 contents() => fold(new JQuery(), (jq, node) => jq..addAll(node.nodes)); | |
205 toString() => fold('', (html, node) => '$html${_toHtml(node, true)}'); | |
206 eq(num childIndex) => $(this[childIndex]); | |
207 remove(_) => forEach((n) => n.remove()); | |
208 attr([String name, String value]) => accessor( | |
209 (n) => n.attributes[name], | |
210 (n, v) => n.attributes[name] = v, | |
211 value, | |
212 true); | |
213 prop([String name]) => accessor( | |
214 (n) => getterSetter.getter(name)(n), | |
215 (n, v) => getterSetter.setter(name)(n, v), | |
216 null, | |
217 true); | |
218 textWithShadow() => fold('', (t, n) => '${t}${renderedText(n)}'); | |
219 find(selector) => fold(new JQuery(), (jq, n) => jq..addAll( | |
220 (n is Element ? (n as Element).querySelectorAll(selector) : []))); | |
221 hasClass(String name) => fold(false, (hasClass, node) => | |
222 hasClass || (node is Element && (node as Element).classes.contains(name)))
; | |
223 addClass(String name) => forEach((node) => | |
224 (node is Element) ? (node as Element).classes.add(name) : null); | |
225 removeClass(String name) => forEach((node) => | |
226 (node is Element) ? (node as Element).classes.remove(name) : null); | |
227 css(String name, [String value]) => accessor( | |
228 (Element n) => n.style.getPropertyValue(name), | |
229 (Element n, v) => n.style.setProperty(name, value), value); | |
230 children() => new JQuery(this[0].childNodes); | |
231 } | |
232 | |
233 | |
234 main() { | |
235 beforeEach(setUpInjector); | |
236 beforeEach(() => wrapFn(sync)); | |
237 afterEach(tearDownInjector); | |
238 } | |
OLD | NEW |