| Index: third_party/pkg/angular/test/core_dom/selector_spec.dart
|
| diff --git a/third_party/pkg/angular/test/core_dom/selector_spec.dart b/third_party/pkg/angular/test/core_dom/selector_spec.dart
|
| index da45baa83d16db93c6ab0f7978a492c24fdb2868..5af3906e9b67cdfe0b65cc4418547b0541cb077c 100644
|
| --- a/third_party/pkg/angular/test/core_dom/selector_spec.dart
|
| +++ b/third_party/pkg/angular/test/core_dom/selector_spec.dart
|
| @@ -2,231 +2,277 @@ library angular.dom.selector_spec;
|
|
|
| import '../_specs.dart';
|
|
|
| -@NgDirective(selector:'b') class _BElement{}
|
| -@NgDirective(selector:'.b') class _BClass{}
|
| -@NgDirective(selector:'[directive]') class _DirectiveAttr{}
|
| -@NgDirective(selector:'[wildcard-*]') class _WildcardDirectiveAttr{}
|
| -@NgDirective(selector:'[directive=d][foo=f]') class _DirectiveFooAttr{}
|
| -@NgDirective(selector:'b[directive]') class _BElementDirectiveAttr{}
|
| -@NgDirective(selector:'[directive=value]') class _DirectiveValueAttr{}
|
| -@NgDirective(selector:'b[directive=value]') class _BElementDirectiveValue{}
|
| -@NgDirective(selector:':contains(/abc/)') class _ContainsAbc{}
|
| -@NgDirective(selector:'[*=/xyz/]') class _AttributeContainsXyz{}
|
| -
|
| -@NgComponent(selector:'component') class _Component{}
|
| -@NgDirective(selector:'[attribute]') class _Attribute{}
|
| -@NgDirective(selector:'[structural]',
|
| - children: NgAnnotation.TRANSCLUDE_CHILDREN)
|
| +@Decorator(selector:'b') class _BElement{}
|
| +@Decorator(selector:'.b') class _BClass{}
|
| +@Decorator(selector:'[directive]') class _DirectiveAttr{}
|
| +@Decorator(selector:'[wildcard-*]') class _WildcardDirectiveAttr{}
|
| +@Decorator(selector:'[directive=d][foo=f]') class _DirectiveFooAttr{}
|
| +@Decorator(selector:'b[directive]') class _BElementDirectiveAttr{}
|
| +@Decorator(selector:'[directive=value]') class _DirectiveValueAttr{}
|
| +@Decorator(selector:'b[directive=value]') class _BElementDirectiveValue{}
|
| +@Decorator(selector:':contains(/abc/)') class _ContainsAbc{}
|
| +@Decorator(selector:'[*=/xyz/]') class _AttributeContainsXyz{}
|
| +
|
| +@Component(selector:'component') class _Component{}
|
| +@Decorator(selector:'[attribute]') class _Attribute{}
|
| +@Decorator(selector:'[structural]',
|
| + children: Directive.TRANSCLUDE_CHILDREN)
|
| class _Structural{}
|
|
|
| -@NgDirective(selector:'[ignore-children]',
|
| - children: NgAnnotation.IGNORE_CHILDREN)
|
| +@Decorator(selector:'[ignore-children]',
|
| + children: Directive.IGNORE_CHILDREN)
|
| class _IgnoreChildren{}
|
|
|
| -@NgDirective(selector: '[my-model][required]')
|
| -@NgDirective(selector: '[my-model][my-required]')
|
| +@Decorator(selector: '[my-model][required]')
|
| +@Decorator(selector: '[my-model][my-required]')
|
| class _TwoDirectives {}
|
|
|
| -@NgDirective(selector: '[two-directives]') class _OneOfTwoDirectives {}
|
| -@NgDirective(selector: '[two-directives]') class _TwoOfTwoDirectives {}
|
| +@Decorator(selector: '[two-directives]') class _OneOfTwoDirectives {}
|
| +@Decorator(selector: '[two-directives]') class _TwoOfTwoDirectives {}
|
|
|
|
|
| main() {
|
| describe('Selector', () {
|
| - //TODO(karma): throwing error here gets ignored
|
| - // throw new Error();
|
| -
|
| var log;
|
| var selector;
|
| var element;
|
| var directives;
|
|
|
| beforeEach(() => log = []);
|
| - beforeEach(module((Module module) {
|
| + beforeEachModule((Module module) {
|
| module
|
| - ..type(_BElement)
|
| - ..type(_BClass)
|
| - ..type(_DirectiveAttr)
|
| - ..type(_WildcardDirectiveAttr)
|
| - ..type(_DirectiveFooAttr)
|
| - ..type(_BElementDirectiveAttr)
|
| - ..type(_DirectiveValueAttr)
|
| - ..type(_BElementDirectiveValue)
|
| - ..type(_ContainsAbc)
|
| - ..type(_AttributeContainsXyz)
|
| - ..type(_Component)
|
| - ..type(_Attribute)
|
| - ..type(_Structural)
|
| - ..type(_IgnoreChildren)
|
| - ..type(_TwoDirectives)
|
| - ..type(_OneOfTwoDirectives)
|
| - ..type(_TwoOfTwoDirectives);
|
| - }));
|
| - beforeEach(inject((DirectiveMap directives) {
|
| - selector = directiveSelectorFactory(directives);
|
| - }));
|
| -
|
| - it('should match directive on element', () {
|
| - expect(
|
| - selector(element = e('<b></b>')),
|
| - toEqualsDirectiveInfos([
|
| - { "selector": 'b', "value": null, "element": element}
|
| - ]));
|
| + ..type(_BElement)
|
| + ..type(_BClass)
|
| + ..type(_DirectiveAttr)
|
| + ..type(_WildcardDirectiveAttr)
|
| + ..type(_DirectiveFooAttr)
|
| + ..type(_BElementDirectiveAttr)
|
| + ..type(_DirectiveValueAttr)
|
| + ..type(_BElementDirectiveValue)
|
| + ..type(_ContainsAbc)
|
| + ..type(_AttributeContainsXyz)
|
| + ..type(_Component)
|
| + ..type(_Attribute)
|
| + ..type(_Structural)
|
| + ..type(_IgnoreChildren)
|
| + ..type(_TwoDirectives)
|
| + ..type(_OneOfTwoDirectives)
|
| + ..type(_TwoOfTwoDirectives);
|
| });
|
|
|
| - it('should match directive on class', () {
|
| - expect(selector(element = e('<div class="a b c"></div>')),
|
| + describe('matchElement', () {
|
| + beforeEach((DirectiveMap directives) {
|
| + selector = (node) => directives.selector.matchElement(node);
|
| + });
|
| +
|
| + it('should match directive on element', () {
|
| + expect(
|
| + selector(element = e('<b></b>')),
|
| + toEqualsDirectiveInfos([
|
| + { "selector": 'b', "value": null, "element": element}
|
| + ]));
|
| + });
|
| +
|
| + it('should match directive on class', () {
|
| + expect(selector(element = e('<div class="a b c"></div>')),
|
| toEqualsDirectiveInfos([
|
| - { "selector": '.b', "value": null, "element": element}
|
| - ]));
|
| - });
|
| -
|
| + { "selector": '.b', "value": null, "element": element}
|
| + ]));
|
| + });
|
|
|
| - it('should match directive on [attribute]', () {
|
| - expect(selector(element = e('<div directive=abc></div>')),
|
| + it('should match directive on [attribute]', () {
|
| + expect(selector(element = e('<div directive=abc></div>')),
|
| toEqualsDirectiveInfos([
|
| - { "selector": '[directive]', "value": 'abc', "element": element,
|
| - "name": 'directive' }]));
|
| + { "selector": '[directive]', "value": 'abc', "element": element,
|
| + "name": 'directive' }]));
|
|
|
| - expect(selector(element = e('<div directive></div>')),
|
| + expect(selector(element = e('<div directive></div>')),
|
| toEqualsDirectiveInfos([
|
| - { "selector": '[directive]', "value": '', "element": element,
|
| - "name": 'directive' }]));
|
| - });
|
| -
|
| + { "selector": '[directive]', "value": '', "element": element,
|
| + "name": 'directive' }]));
|
| + });
|
|
|
| - it('should match directive on element[attribute]', () {
|
| - expect(selector(element = e('<b directive=abc></b>')),
|
| + it('should match directive on element[attribute]', () {
|
| + expect(selector(element = e('<b directive=abc></b>')),
|
| toEqualsDirectiveInfos([
|
| - { "selector": 'b', "value": null, "element": element},
|
| - { "selector": '[directive]', "value": 'abc', "element": element},
|
| - { "selector": 'b[directive]', "value": 'abc', "element": element}
|
| + { "selector": 'b', "value": null, "element": element},
|
| + { "selector": '[directive]', "value": 'abc', "element": element},
|
| + { "selector": 'b[directive]', "value": 'abc', "element": element}
|
| ]));
|
| - });
|
| -
|
| + });
|
|
|
| - it('should match directive on [attribute=value]', () {
|
| - expect(selector(element = e('<div directive=value></div>')),
|
| + it('should match directive on [attribute=value]', () {
|
| + expect(selector(element = e('<div directive=value></div>')),
|
| toEqualsDirectiveInfos([
|
| - { "selector": '[directive]', "value": 'value', "element": element},
|
| - { "selector": '[directive=value]', "value": 'value', "element": element}
|
| + { "selector": '[directive]', "value": 'value', "element": element},
|
| + { "selector": '[directive=value]', "value": 'value', "element": element}
|
| ]));
|
| - });
|
| -
|
| + });
|
|
|
| - it('should match directive on element[attribute=value]', () {
|
| - expect(selector(element = e('<b directive=value></div>')),
|
| + it('should match directive on element[attribute=value]', () {
|
| + expect(selector(element = e('<b directive=value></div>')),
|
| toEqualsDirectiveInfos([
|
| - { "selector": 'b', "value": null, "element": element, "name": null},
|
| - { "selector": '[directive]', "value": 'value', "element": element},
|
| - { "selector": '[directive=value]', "value": 'value', "element": element},
|
| - { "selector": 'b[directive]', "value": 'value', "element": element},
|
| - { "selector": 'b[directive=value]', "value": 'value', "element": element}
|
| + { "selector": 'b', "value": null, "element": element, "name": null},
|
| + { "selector": '[directive]', "value": 'value', "element": element},
|
| + { "selector": '[directive=value]', "value": 'value', "element": element},
|
| + { "selector": 'b[directive]', "value": 'value', "element": element},
|
| + { "selector": 'b[directive=value]', "value": 'value', "element": element}
|
| ]));
|
| - });
|
| + });
|
|
|
| - it('should match attributes', () {
|
| - expect(selector(element = e('<div attr="before-xyz-after"></div>')),
|
| + it('should match attributes', () {
|
| + expect(selector(element = e('<div attr="before-xyz-after"></div>')),
|
| toEqualsDirectiveInfos([
|
| - { "selector": '[*=/xyz/]', "value": 'attr=before-xyz-after',
|
| - "element": element, "name": 'attr'}
|
| + { "selector": '[*=/xyz/]', "value": 'attr=before-xyz-after',
|
| + "element": element, "name": 'attr'}
|
| ]));
|
| - });
|
| + });
|
|
|
| - it('should match attribute names', () {
|
| - expect(selector(element = e('<div wildcard-match=ignored></div>')),
|
| + it('should match attribute names', () {
|
| + expect(selector(element = e('<div wildcard-match=ignored></div>')),
|
| toEqualsDirectiveInfos([
|
| - { "selector": '[wildcard-*]', "value": 'ignored',
|
| - "element": element, "name": 'wildcard-match'}
|
| + { "selector": '[wildcard-*]', "value": 'ignored',
|
| + "element": element, "name": 'wildcard-match'}
|
| ]));
|
| - });
|
| -
|
| - it('should match text', () {
|
| - expect(selector(element = e('before-abc-after')),
|
| + });
|
| +
|
| + it('should sort by priority', () {
|
| + TemplateElementBinder eb = selector(element = e(
|
| + '<component attribute ignore-children structural></component>'));
|
| + expect(eb,
|
| + toEqualsDirectiveInfos(
|
| + null,
|
| + template: {"selector": "[structural]", "value": "", "element": element}));
|
| +
|
| + expect(eb.templateBinder,
|
| + toEqualsDirectiveInfos(
|
| + [
|
| + { "selector": "[attribute]", "value": "", "element": element },
|
| + { "selector": "[ignore-children]", "value": "", "element": element }
|
| +
|
| + ],
|
| + component: { "selector": "component", "value": null, "element": element }));
|
| + });
|
| +
|
| + it('should match on multiple directives', () {
|
| + expect(selector(element = e('<div directive="d" foo="f"></div>')),
|
| toEqualsDirectiveInfos([
|
| - { "selector": ':contains(/abc/)', "value": 'before-abc-after',
|
| - "element": element, "name": '#text'}
|
| + { "selector": '[directive]', "value": 'd', "element": element},
|
| + { "selector": '[directive=d][foo=f]', "value": 'f', "element": element}
|
| ]));
|
| - });
|
| + });
|
| +
|
| + it('should match ng-model + required on the same element', () {
|
| + expect(
|
| + selector(element = e('<input type="text" ng-model="val" probe="i" required="true" />')),
|
| + toEqualsDirectiveInfos([
|
| + { "selector": '[ng-model]', "value": 'val', "element": element},
|
| + { "selector": '[probe]', "value": 'i', "element": element},
|
| + { "selector": '[ng-model][required]', "value": 'true', "element": element},
|
| + { "selector": 'input[type=text][ng-model]', "value": 'val', "element": element}
|
| + ]));
|
| + });
|
| +
|
| + it('should match two directives', () {
|
| + expect(
|
| + selector(element = e('<input type="text" my-model="val" required my-required />')),
|
| + toEqualsDirectiveInfos([
|
| + { "selector": '[my-model][required]', "value": '', "element": element},
|
| + { "selector": '[my-model][my-required]', "value": '', "element": element}
|
| + ]));
|
| + });
|
| +
|
| + it('should match an two directives with the same selector', () {
|
| + expect(selector(element = e('<div two-directives></div>')),
|
| + toEqualsDirectiveInfos([
|
| + { "selector": '[two-directives]', "value": '', "element": element},
|
| + { "selector": '[two-directives]', "value": '', "element": element}
|
| + ]));
|
| + });
|
|
|
| - it('should sort by priority', () {
|
| - expect(selector(element = e(
|
| - '<component attribute ignore-children structural></component>')),
|
| - toEqualsDirectiveInfos([
|
| - { "selector": "[structural]", "value": "", "element": element },
|
| - { "selector": "[attribute]", "value": "", "element": element },
|
| - { "selector": "[ignore-children]", "value": "", "element": element },
|
| - { "selector": "component", "value": null, "element": element }
|
| - ]));
|
| - });
|
| + it('should collect on-* attributes', () {
|
| + ElementBinder binder = selector(e('<input on-click="foo" on-blah="fad"></input>'));
|
| + expect(binder.onEvents).toEqual({'on-click': 'foo', 'on-blah': 'fad'});
|
| + });
|
|
|
| - it('should match on multiple directives', () {
|
| - expect(selector(element = e('<div directive="d" foo="f"></div>')),
|
| - toEqualsDirectiveInfos([
|
| - { "selector": '[directive]', "value": 'd', "element": element},
|
| - { "selector": '[directive=d][foo=f]', "value": 'f', "element": element}
|
| - ]));
|
| + it('should collect bind-* attributes', () {
|
| + ElementBinder binder = selector(e('<input bind-x="y" bind-z="yy"></input>'));
|
| + expect(binder.bindAttrs).toEqual({'bind-x': 'y', 'bind-z': 'yy'});
|
| + });
|
| });
|
|
|
| - it('should match ng-model + required on the same element', () {
|
| - expect(
|
| - selector(element = e('<input type="text" ng-model="val" probe="i" required="true" />')),
|
| + describe('matchText', () {
|
| + beforeEach((DirectiveMap directives) {
|
| + selector = (node) => directives.selector.matchText(node);
|
| + });
|
| +
|
| + it('should match text', () {
|
| + expect(selector(element = e('before-abc-after')),
|
| toEqualsDirectiveInfos([
|
| - { "selector": '[ng-model]', "value": 'val', "element": element},
|
| - { "selector": '[probe]', "value": 'i', "element": element},
|
| - { "selector": '[ng-model][required]', "value": 'true', "element": element},
|
| - { "selector": 'input[type=text][ng-model]', "value": 'val', "element": element}
|
| + { "selector": ':contains(/abc/)', "value": 'before-abc-after',
|
| + "element": element, "name": '#text'}
|
| ]));
|
| + });
|
| });
|
|
|
| - it('should match two directives', () {
|
| - expect(
|
| - selector(element = e('<input type="text" my-model="val" required my-required />')),
|
| - toEqualsDirectiveInfos([
|
| - { "selector": '[my-model][required]', "value": '', "element": element},
|
| - { "selector": '[my-model][my-required]', "value": '', "element": element}
|
| - ]));
|
| - });
|
| + describe('matchComment', () {
|
| + beforeEach((DirectiveMap directives) {
|
| + selector = (node) => directives.selector.matchComment(node);
|
| + });
|
|
|
| - it('should match an two directives with the same selector', () {
|
| - expect(selector(element = e('<div two-directives></div>')),
|
| - toEqualsDirectiveInfos([
|
| - { "selector": '[two-directives]', "value": '', "element": element},
|
| - { "selector": '[two-directives]', "value": '', "element": element}
|
| - ]));
|
| + it('should match comments', () {
|
| + expect(selector(element = e('<!-- nothing here -->')),
|
| + toEqualsDirectiveInfos([]));
|
| + });
|
| });
|
| });
|
| }
|
|
|
|
|
| class DirectiveInfosMatcher extends Matcher {
|
| - List<Map> expected;
|
| + final List<Map> expected;
|
| + Map expectedTemplate;
|
| + Map expectedComponent;
|
|
|
| - DirectiveInfosMatcher(this.expected);
|
| + safeToString(a) => "${a['element']} ${a['selector']} ${a['value']}";
|
| + safeToStringRef(a) => "${a.element} ${a.annotation.selector} ${a.value}";
|
|
|
| - Description describe(Description description) {
|
| - description.add(expected.toString());
|
| - return description;
|
| + DirectiveInfosMatcher(this.expected, {this.expectedTemplate, this.expectedComponent}) {
|
| + if (expected != null) {
|
| + expected.sort((a, b) => Comparable.compare(safeToString(a), safeToString(b)));
|
| + }
|
| }
|
|
|
| - bool matches(directiveRefs, matchState) {
|
| - var pass = expected.length == directiveRefs.length;
|
| - if (pass) {
|
| + Description describe(Description description) =>
|
| + description..add(expected.toString());
|
| +
|
| + bool _refMatches(directiveRef, expectedMap) =>
|
| + directiveRef.element == expectedMap['element'] &&
|
| + directiveRef.annotation.selector == expectedMap['selector'] &&
|
| + directiveRef.value == expectedMap['value'];
|
| +
|
| +
|
| + bool matches(ElementBinder binder, matchState) {
|
| + var pass = true;
|
| + if (expected != null) {
|
| + var decorators = new List.from(binder.decorators)
|
| + ..sort((a, b) => Comparable.compare(safeToStringRef(a), safeToStringRef(b)));
|
| + pass = expected.length == decorators.length;
|
| for (var i = 0, ii = expected.length; i < ii; i++) {
|
| - DirectiveRef directiveRef = directiveRefs[i];
|
| + DirectiveRef directiveRef = decorators[i];
|
| var expectedMap = expected[i];
|
| -
|
| - pass = pass &&
|
| - directiveRef.element == expectedMap['element'] &&
|
| - directiveRef.annotation.selector == expectedMap['selector'] &&
|
| - directiveRef.value == expectedMap['value'];
|
| + pass = pass && _refMatches(directiveRef, expectedMap);
|
| }
|
| }
|
| + if (pass && expectedTemplate != null) {
|
| + pass = pass && _refMatches((binder as TemplateElementBinder).template, expectedTemplate);
|
| + }
|
| + if (pass && expectedComponent != null) {
|
| + pass = pass && _refMatches(binder.component, expectedComponent);
|
| + }
|
| return pass;
|
| }
|
| }
|
|
|
| -Matcher toEqualsDirectiveInfos(List<Map> directives) {
|
| - return new DirectiveInfosMatcher(directives);
|
| -}
|
| -
|
| +Matcher toEqualsDirectiveInfos(List<Map> directives, {Map template, Map component}) =>
|
| + new DirectiveInfosMatcher(directives, expectedTemplate: template, expectedComponent: component);
|
|
|