| 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 |