| Index: third_party/pkg/angular/test/_specs.dart
|
| diff --git a/third_party/pkg/angular/test/_specs.dart b/third_party/pkg/angular/test/_specs.dart
|
| index 88b46e6e95d925229fc52e321adac3b9c4fdf935..75b19770b6ffafd217809d87238c0e315d86788f 100644
|
| --- a/third_party/pkg/angular/test/_specs.dart
|
| +++ b/third_party/pkg/angular/test/_specs.dart
|
| @@ -1,58 +1,51 @@
|
| library ng_specs;
|
|
|
| -import 'dart:html';
|
| -import 'package:unittest/unittest.dart' as unit;
|
| +import 'dart:html' hide Animation;
|
| +
|
| import 'package:angular/angular.dart';
|
| import 'package:angular/mock/module.dart';
|
| -import 'package:collection/wrappers.dart' show DelegatingList;
|
| +import 'package:unittest/unittest.dart' as unit;
|
|
|
| -import 'jasmine_syntax.dart';
|
| +import 'jasmine_syntax.dart' as jasmine_syntax;
|
|
|
| -export 'dart:html';
|
| -export 'jasmine_syntax.dart' hide main;
|
| +export 'dart:html' hide Animation;
|
| export 'package:unittest/unittest.dart';
|
| -export 'package:unittest/mock.dart';
|
| +export 'package:mock/mock.dart';
|
| +export 'package:di/di.dart';
|
| export 'package:di/dynamic_injector.dart';
|
| export 'package:angular/angular.dart';
|
| +export 'package:angular/application.dart';
|
| +export 'package:angular/introspection.dart';
|
| +export 'package:angular/core/annotation.dart';
|
| +export 'package:angular/core/registry.dart';
|
| +export 'package:angular/core/module_internal.dart';
|
| +export 'package:angular/core_dom/module_internal.dart';
|
| +export 'package:angular/core/parser/parser.dart';
|
| +export 'package:angular/core/parser/lexer.dart';
|
| +export 'package:angular/directive/module.dart';
|
| +export 'package:angular/formatter/module.dart';
|
| +export 'package:angular/routing/module.dart';
|
| +export 'package:angular/animate/module.dart';
|
| export 'package:angular/mock/module.dart';
|
| export 'package:perf_api/perf_api.dart';
|
|
|
| es(String html) {
|
| var div = new DivElement();
|
| div.setInnerHtml(html, treeSanitizer: new NullTreeSanitizer());
|
| - return div.nodes;
|
| + return new List.from(div.nodes);
|
| }
|
|
|
| e(String html) => es(html).first;
|
|
|
| -renderedText(n, [bool notShadow = false]) {
|
| - if (n is List) {
|
| - return n.map((nn) => renderedText(nn)).join("");
|
| - }
|
| -
|
| - if (n is Comment) return '';
|
| -
|
| - if (!notShadow && n is Element && n.shadowRoot != null) {
|
| - var shadowText = n.shadowRoot.text;
|
| - var domText = renderedText(n, true);
|
| - return shadowText.replaceFirst("SHADOW-CONTENT", domText);
|
| - }
|
| -
|
| - if (n.nodes == null || n.nodes.length == 0) return n.text;
|
| -
|
| - return n.nodes.map((cn) => renderedText(cn)).join("");
|
| -}
|
| -
|
| Expect expect(actual, [unit.Matcher matcher = null]) {
|
| - if (matcher != null) {
|
| - unit.expect(actual, matcher);
|
| - }
|
| + if (matcher != null) unit.expect(actual, matcher);
|
| return new Expect(actual);
|
| }
|
|
|
| class Expect {
|
| var actual;
|
| - var not;
|
| + NotExpect not;
|
| +
|
| Expect(this.actual) {
|
| not = new NotExpect(this);
|
| }
|
| @@ -61,67 +54,152 @@ class Expect {
|
| toContain(expected) => unit.expect(actual, unit.contains(expected));
|
| toBe(expected) => unit.expect(actual,
|
| unit.predicate((actual) => identical(expected, actual), '$expected'));
|
| - toThrow([exception]) => unit.expect(actual, exception == null ? unit.throws : unit.throwsA(new ExceptionContains(exception)));
|
| - toBeFalsy() => unit.expect(actual, (v) => v == null ? true : v is bool ? v == false : false);
|
| - toBeTruthy() => unit.expect(actual, (v) => v is bool ? v == true : true);
|
| - toBeDefined() => unit.expect(actual, (v) => v != null);
|
| + toThrow([exception]) => unit.expect(actual, exception == null ?
|
| + unit.throws:
|
| + unit.throwsA(new ExceptionContains(exception)));
|
| + toBeFalsy() => unit.expect(actual, _isFalsy,
|
| + reason: '"$actual" is not Falsy');
|
| + toBeTruthy() => unit.expect(actual, (v) => !_isFalsy(v),
|
| + reason: '"$actual" is not Truthy');
|
| + toBeDefined() => unit.expect(actual, unit.isNotNull);
|
| toBeNull() => unit.expect(actual, unit.isNull);
|
| toBeNotNull() => unit.expect(actual, unit.isNotNull);
|
|
|
| - toHaveBeenCalled() => unit.expect(actual.called, true, reason: 'method not called');
|
| - toHaveBeenCalledOnce() => unit.expect(actual.count, 1, reason: 'method invoked ${actual.count} expected once');
|
| + toHaveHtml(expected) => unit.expect(_toHtml(actual), unit.equals(expected));
|
| + toHaveText(expected) =>
|
| + unit.expect(_elementText(actual), unit.equals(expected));
|
| +
|
| + toHaveBeenCalled() =>
|
| + unit.expect(actual.called, true, reason: 'method not called');
|
| + toHaveBeenCalledOnce() => unit.expect(actual.count, 1,
|
| + reason: 'method invoked ${actual.count} expected once');
|
| toHaveBeenCalledWith([a,b,c,d,e,f]) =>
|
| unit.expect(actual.firstArgsMatch(a,b,c,d,e,f), true,
|
| - reason: 'method invoked with correct arguments');
|
| + reason: 'method invoked with correct arguments');
|
| toHaveBeenCalledOnceWith([a,b,c,d,e,f]) =>
|
| unit.expect(actual.count == 1 && actual.firstArgsMatch(a,b,c,d,e,f),
|
| - true,
|
| - reason: 'method invoked once with correct arguments. (Called ${actual.count} times)');
|
| -
|
| - toHaveClass(cls) => unit.expect(actual.classes.contains(cls), true, reason: ' Expected ${actual} to have css class ${cls}');
|
| + true,
|
| + reason: 'method invoked once with correct arguments. '
|
| + '(Called ${actual.count} times)');
|
| +
|
| + toHaveClass(cls) => unit.expect(actual.classes.contains(cls), true,
|
| + reason: ' Expected ${actual} to have css class ${cls}');
|
| +
|
| + toHaveAttribute(name, [value = null]) {
|
| + unit.expect(actual.attributes.containsKey(name), true,
|
| + reason: 'Epxected $actual to have attribute $name');
|
| + if (value != null) {
|
| + unit.expect(actual.attributes[name], value,
|
| + reason: 'Epxected $actual attribute "$name" to be "$value"');
|
| + }
|
| + }
|
|
|
| toEqualSelect(options) {
|
| var actualOptions = [];
|
|
|
| for (var option in actual.querySelectorAll('option')) {
|
| - if (option.selected) {
|
| - actualOptions.add([option.value]);
|
| - } else {
|
| - actualOptions.add(option.value);
|
| - }
|
| + actualOptions.add(option.selected ? [option.value] : option.value);
|
| }
|
| return unit.expect(actualOptions, options);
|
| }
|
|
|
| - toEqualValid() {
|
| - // TODO: implement onece we have forms
|
| - }
|
| - toEqualInvalid() {
|
| - // TODO: implement onece we have forms
|
| - }
|
| - toEqualPristine() {
|
| - // TODO: implement onece we have forms
|
| + toBeValid() => unit.expect(actual.valid && !actual.invalid, true,
|
| + reason: 'Form is not valid');
|
| + toBePristine() =>
|
| + unit.expect(actual.pristine && !actual.dirty, true,
|
| + reason: 'Form is dirty');
|
| +
|
| + _isFalsy(v) => v == null ? true: v is bool ? v == false : false;
|
| +
|
| + _toHtml(node, [bool outer = false]) {
|
| + if (node is Comment) {
|
| + return '<!--${node.text}-->';
|
| + } else if (node is DocumentFragment) {
|
| + var acc = '';
|
| + node.childNodes.forEach((n) { acc += _toHtml(n, true); });
|
| + return acc;
|
| + } else if (node is List) {
|
| + var acc = '';
|
| + node.forEach((n) { acc += _toHtml(n); });
|
| + return acc;
|
| + } else if (node is Element) {
|
| + // Remove all the "ng-binding" internal classes
|
| + node = node.clone(true) as Element;
|
| + node.classes.remove('ng-binding');
|
| + node.querySelectorAll(".ng-binding").forEach((Element e) {
|
| + e.classes.remove('ng-binding');
|
| + });
|
| + var htmlString = outer ? node.outerHtml : node.innerHtml;
|
| + // Strip out empty class attributes. This seems like a Dart bug...
|
| + return htmlString.replaceAll(' class=""', '').trim();
|
| + } else if (node is Text) {
|
| + return node.text;
|
| + } else {
|
| + throw "JQuery._toHtml not implemented for node type [${node.nodeType}]";
|
| + }
|
| }
|
| - toEqualDirty() {
|
| - // TODO: implement onece we have forms
|
| +
|
| + _elementText(n, [bool notShadow = false]) {
|
| + if (n is Iterable) {
|
| + return n.map((nn) => _elementText(nn)).join("");
|
| + }
|
| +
|
| + if (n is Comment) return '';
|
| +
|
| + if (!notShadow && n is Element && n.shadowRoot != null) {
|
| + var cShadows = n.shadowRoot.nodes.map((n) => n.clone(true)).toList();
|
| + for (var i = 0, ii = cShadows.length; i < ii; i++) {
|
| + var n = cShadows[i];
|
| + if (n is Element) {
|
| + var updateElement = (e) {
|
| + var text = new Text('SHADOW-CONTENT');
|
| + if (e.parent == null) {
|
| + cShadows[i] = text;
|
| + } else {
|
| + e.parent.insertBefore(text, e);
|
| + }
|
| + e.nodes = [];
|
| + };
|
| + if (n is ContentElement) { updateElement(n); }
|
| + n.querySelectorAll('content').forEach(updateElement);
|
| + }
|
| + };
|
| + var shadowText = _elementText(cShadows, true);
|
| + var domText = _elementText(n, true);
|
| +
|
| + return shadowText.replaceFirst("SHADOW-CONTENT", domText);
|
| + }
|
| +
|
| + if (n.nodes == null || n.nodes.length == 0) return n.text;
|
| +
|
| + return n.nodes.map((cn) => _elementText(cn)).join("");
|
| }
|
| }
|
|
|
| class NotExpect {
|
| - Expect expect;
|
| - get actual => expect.actual;
|
| - NotExpect(this.expect);
|
| + Expect _expect;
|
| + get actual => _expect.actual;
|
| +
|
| + NotExpect(this._expect);
|
|
|
| - toHaveBeenCalled() => unit.expect(actual.called, false, reason: 'method called');
|
| + toHaveBeenCalled() =>
|
| + unit.expect(actual.called, false, reason: 'method called');
|
| toThrow() => actual();
|
|
|
| - toHaveClass(cls) => unit.expect(actual.classes.contains(cls), false, reason: ' Expected ${actual} to not have css class ${cls}');
|
| + toHaveClass(cls) => unit.expect(actual.classes.contains(cls), false,
|
| + reason: ' Expected ${actual} to not have css class ${cls}');
|
| + toHaveAttribute(name) => unit.expect(actual.attributes.containsKey(name),
|
| + false, reason: ' Expected $actual to not have attribute "$name"');
|
| toBe(expected) => unit.expect(actual,
|
| unit.predicate((actual) => !identical(expected, actual), 'not $expected'));
|
| toEqual(expected) => unit.expect(actual,
|
| unit.predicate((actual) => expected != actual, 'not $expected'));
|
| toContain(expected) => unit.expect(actual,
|
| unit.predicate((actual) => !actual.contains(expected), 'not $expected'));
|
| + toBePristine() => unit.expect(actual.pristine && !actual.dirty, false,
|
| + reason: 'Form is pristine');
|
| + toBeValid() => unit.expect(actual.valid && !actual.invalid, false,
|
| + reason: 'Form is valid');
|
| }
|
|
|
| class ExceptionContains extends unit.Matcher {
|
| @@ -147,92 +225,31 @@ class ExceptionContains extends unit.Matcher {
|
| }
|
| }
|
|
|
| -$(selector) {
|
| - return new JQuery(selector);
|
| -}
|
| -
|
| -
|
| -class GetterSetter {
|
| - Getter getter(String key) => null;
|
| - Setter setter(String key) => null;
|
| +_injectify(fn) {
|
| + // The function does two things:
|
| + // First: if the it() passed a function, we wrap it in
|
| + // the "sync" FunctionComposition.
|
| + // Second: when we are calling the FunctionComposition,
|
| + // we inject "inject" into the middle of the
|
| + // composition.
|
| + if (fn is! FunctionComposition) fn = sync(fn);
|
| + return fn.outer(inject(fn.inner));
|
| }
|
| -var getterSetter = new GetterSetter();
|
| -
|
| -class JQuery extends DelegatingList<Node> {
|
| - JQuery([selector]) : super([]) {
|
| - if (selector == null) {
|
| - // do nothing;
|
| - } else if (selector is String) {
|
| - addAll(es(selector));
|
| - } else if (selector is List) {
|
| - addAll(selector);
|
| - } else if (selector is Node) {
|
| - add(selector);
|
| - } else {
|
| - throw selector;
|
| - }
|
| - }
|
| -
|
| - _toHtml(node, [bool outer = false]) {
|
| - if (node is Comment) {
|
| - return '<!--${node.text}-->';
|
| - } else {
|
| - return outer ? node.outerHtml : node.innerHtml;
|
| - }
|
| - }
|
|
|
| - accessor(Function getter, Function setter, [value, single=false]) {
|
| - // TODO(dart): ?value does not work, since value was passed. :-(
|
| - var setterMode = value != null;
|
| - var result = setterMode ? this : '';
|
| - forEach((node) {
|
| - if (setterMode) {
|
| - setter(node, value);
|
| - } else {
|
| - result = single ? getter(node) : '$result${getter(node)}';
|
| - }
|
| - });
|
| - return result;
|
| - }
|
| -
|
| - html([String html]) => accessor(
|
| - (n) => _toHtml(n),
|
| - (n, v) => n.setInnerHtml(v, treeSanitizer: new NullTreeSanitizer()),
|
| - html);
|
| - val([String text]) => accessor((n) => n.value, (n, v) => n.value = v);
|
| - text([String text]) => accessor((n) => n.text, (n, v) => n.text = v, text);
|
| - contents() => fold(new JQuery(), (jq, node) => jq..addAll(node.nodes));
|
| - toString() => fold('', (html, node) => '$html${_toHtml(node, true)}');
|
| - eq(num childIndex) => $(this[childIndex]);
|
| - remove(_) => forEach((n) => n.remove());
|
| - attr([String name, String value]) => accessor(
|
| - (n) => n.attributes[name],
|
| - (n, v) => n.attributes[name] = v,
|
| - value,
|
| - true);
|
| - prop([String name]) => accessor(
|
| - (n) => getterSetter.getter(name)(n),
|
| - (n, v) => getterSetter.setter(name)(n, v),
|
| - null,
|
| - true);
|
| - textWithShadow() => fold('', (t, n) => '${t}${renderedText(n)}');
|
| - find(selector) => fold(new JQuery(), (jq, n) => jq..addAll(
|
| - (n is Element ? (n as Element).querySelectorAll(selector) : [])));
|
| - hasClass(String name) => fold(false, (hasClass, node) =>
|
| - hasClass || (node is Element && (node as Element).classes.contains(name)));
|
| - addClass(String name) => forEach((node) =>
|
| - (node is Element) ? (node as Element).classes.add(name) : null);
|
| - removeClass(String name) => forEach((node) =>
|
| - (node is Element) ? (node as Element).classes.remove(name) : null);
|
| - css(String name, [String value]) => accessor(
|
| - (Element n) => n.style.getPropertyValue(name),
|
| - (Element n, v) => n.style.setProperty(name, value), value);
|
| - children() => new JQuery(this[0].childNodes);
|
| -}
|
| +// Jasmine syntax
|
| +beforeEachModule(fn) => jasmine_syntax.beforeEach(module(fn), priority:1);
|
| +beforeEach(fn) => jasmine_syntax.beforeEach(_injectify(fn));
|
| +afterEach(fn) => jasmine_syntax.afterEach(_injectify(fn));
|
| +it(name, fn) => jasmine_syntax.it(name, _injectify(fn));
|
| +iit(name, fn) => jasmine_syntax.iit(name, _injectify(fn));
|
| +xit(name, fn) => jasmine_syntax.xit(name, fn);
|
| +xdescribe(name, fn) => jasmine_syntax.xdescribe(name, fn);
|
| +ddescribe(name, fn) => jasmine_syntax.ddescribe(name, fn);
|
| +describe(name, fn) => jasmine_syntax.describe(name, fn);
|
|
|
| +var jasmine = jasmine_syntax.jasmine;
|
|
|
| main() {
|
| - beforeEach(setUpInjector);
|
| - beforeEach(() => wrapFn(sync));
|
| - afterEach(tearDownInjector);
|
| + jasmine_syntax.beforeEach(setUpInjector, priority:3);
|
| + jasmine_syntax.afterEach(tearDownInjector);
|
| }
|
|
|