diff --git a/lib/core/formatter.dart b/lib/core/formatter.dart index 25f317414..21577a217 100644 --- a/lib/core/formatter.dart +++ b/lib/core/formatter.dart @@ -1,5 +1,6 @@ library angular.core_internal.formatter_map; +import 'dart:collection'; import 'package:di/di.dart'; import 'package:angular/core/annotation_src.dart'; import 'package:angular/core/registry.dart'; @@ -8,16 +9,30 @@ import 'package:angular/core/registry.dart'; * Registry of formatters at runtime. */ @Injectable() -class FormatterMap extends AnnotationMap { - Injector _injector; - FormatterMap(Injector injector, MetadataExtractor extractMetadata) - : this._injector = injector, - super(injector, extractMetadata); +class FormatterMap { + final Map _map = new HashMap(); + final Injector _injector; - call(String name) { - var formatter = new Formatter(name: name); - var formatterType = this[formatter]; - return _injector.get(formatterType); + FormatterMap(this._injector, MetadataExtractor extractMetadata) { + _injector.types.forEach((type) { + extractMetadata(type) + .where((annotation) => annotation is Formatter) + .forEach((Formatter formatter) { + _map[formatter.name] = type; + }); + }); + } + + call(String name) => _injector.get(this[name]); + + Type operator[](String name) { + Type formatterType = _map[name]; + if (formatterType == null) throw "No formatter '$name' found!"; + return formatterType; + } + + void forEach(fn(K, Type)) { + _map.forEach(fn); } } diff --git a/lib/core/registry.dart b/lib/core/registry.dart index 9d66de3ed..1db9cf61c 100644 --- a/lib/core/registry.dart +++ b/lib/core/registry.dart @@ -1,75 +1,5 @@ library angular.core.registry; -import 'package:di/di.dart' show Injector; - -abstract class AnnotationMap { - final Map _map = {}; - - AnnotationMap(Injector injector, MetadataExtractor extractMetadata) { - injector.types.forEach((type) { - extractMetadata(type) - .where((annotation) => annotation is K) - .forEach((annotation) { - _map[annotation] = type; - }); - }); - } - - Type operator[](K annotation) { - var value = _map[annotation]; - if (value == null) throw 'No $annotation found!'; - return value; - } - - void forEach(fn(K, Type)) { - _map.forEach(fn); - } - - List annotationsFor(Type type) { - final res = []; - forEach((ann, annType) { - if (annType == type) res.add(ann); - }); - return res; - } -} - -abstract class AnnotationsMap { - final Map> map = {}; - - AnnotationsMap(Injector injector, MetadataExtractor extractMetadata) { - injector.types.forEach((type) { - extractMetadata(type) - .where((annotation) => annotation is K) - .forEach((annotation) { - map.putIfAbsent(annotation, () => []).add(type); - }); - }); - } - - List operator[](K annotation) { - var value = map[annotation]; - if (value == null) throw 'No $annotation found!'; - return value; - } - - void forEach(fn(K, Type)) { - map.forEach((annotation, types) { - types.forEach((type) { - fn(annotation, type); - }); - }); - } - - List annotationsFor(Type type) { - var res = []; - forEach((ann, annType) { - if (annType == type) res.add(ann); - }); - return res; - } -} - abstract class MetadataExtractor { Iterable call(Type type); } diff --git a/lib/core/registry_static.dart b/lib/core/registry_static.dart index fcb287b13..a6758a5ba 100644 --- a/lib/core/registry_static.dart +++ b/lib/core/registry_static.dart @@ -1,6 +1,6 @@ library angular.core_static; -import 'package:angular/core/annotation_src.dart' show Injectable; +import 'package:angular/core/annotation_src.dart'; import 'package:angular/core/registry.dart'; @Injectable() diff --git a/lib/core_dom/directive_map.dart b/lib/core_dom/directive_map.dart index d1728f909..5bec04003 100644 --- a/lib/core_dom/directive_map.dart +++ b/lib/core_dom/directive_map.dart @@ -1,18 +1,48 @@ part of angular.core.dom_internal; +class DirectiveTypeTuple { + final Directive directive; + final Type type; + DirectiveTypeTuple(this.directive, this.type); + toString() => '@$directive#$type'; +} + @Injectable() -class DirectiveMap extends AnnotationsMap { +class DirectiveMap { + final Map> map = new HashMap>(); DirectiveSelectorFactory _directiveSelectorFactory; FormatterMap _formatters; DirectiveSelector _selector; + + DirectiveMap(Injector injector, + this._formatters, + MetadataExtractor metadataExtractor, + this._directiveSelectorFactory) { + injector.types.forEach((type) { + metadataExtractor(type) + .where((annotation) => annotation is Directive) + .forEach((Directive directive) { + map.putIfAbsent(directive.selector, () => []).add(new DirectiveTypeTuple(directive, type)); + }); + }); + } + DirectiveSelector get selector { if (_selector != null) return _selector; return _selector = _directiveSelectorFactory.selector(this, _formatters); } - DirectiveMap(Injector injector, - this._formatters, - MetadataExtractor metadataExtractor, - this._directiveSelectorFactory) - : super(injector, metadataExtractor); + List operator[](String key) { + var value = map[key]; + if (value == null) throw 'No Directive selector $key found!'; + return value; + } + + void forEach(fn(K, Type)) { + map.forEach((_, types) { + types.forEach((tuple) { + fn(tuple.directive, tuple.type); + }); + }); + } } diff --git a/lib/core_dom/selector.dart b/lib/core_dom/selector.dart index d6a19d976..7794694dc 100644 --- a/lib/core_dom/selector.dart +++ b/lib/core_dom/selector.dart @@ -41,9 +41,9 @@ class DirectiveSelector { } if ((match = _CONTAINS_REGEXP.firstMatch(selector)) != null) { - textSelector.add(new _ContainsSelector(annotation, match[1])); + textSelector.add(new _ContainsSelector(selector, match[1])); } else if ((match = _ATTR_CONTAINS_REGEXP.firstMatch(selector)) != null) { - attrSelector.add(new _ContainsSelector(annotation, match[1])); + attrSelector.add(new _ContainsSelector(selector, match[1])); } else if ((selectorParts = _splitCss(selector, type)) != null){ elementSelector.addDirective(selectorParts, new _Directive(type, annotation)); } else { @@ -97,12 +97,12 @@ class DirectiveSelector { // this directive is matched on any attribute name, and so // we need to pass the name to the directive by prefixing it to // the value. Yes it is a bit of a hack. - _directives[selectorRegExp.annotation].forEach((type) { + _directives[selectorRegExp.selector].forEach((DirectiveTypeTuple tuple) { // Pre-compute the AST to watch this value. String expression = _interpolate(value); AST valueAST = _astParser(expression, formatters: _formatters); builder.addDirective(new DirectiveRef( - node, type, selectorRegExp.annotation, new Key(type), attrName, valueAST)); + node, tuple.type, tuple.directive, new Key(tuple.type), attrName, valueAST)); }); } } @@ -135,13 +135,13 @@ class DirectiveSelector { for (var k = 0; k < textSelector.length; k++) { var selectorRegExp = textSelector[k]; if (selectorRegExp.regexp.hasMatch(value)) { - _directives[selectorRegExp.annotation].forEach((type) { + _directives[selectorRegExp.selector].forEach((tuple) { // Pre-compute the AST to watch this value. String expression = _interpolate(value); var valueAST = _astParser(expression, formatters: _formatters); - builder.addDirective(new DirectiveRef(node, type, - selectorRegExp.annotation, new Key(type), value, valueAST)); + builder.addDirective(new DirectiveRef(node, tuple.type, + tuple.directive, new Key(tuple.type), value, valueAST)); }); } } @@ -187,10 +187,10 @@ class _Directive { } class _ContainsSelector { - final Directive annotation; + final String selector; final RegExp regexp; - _ContainsSelector(this.annotation, String regexp) + _ContainsSelector(this.selector, String regexp) : regexp = new RegExp(regexp); } diff --git a/test/core/core_directive_spec.dart b/test/core/core_directive_spec.dart index ab4cd3149..12632dc14 100644 --- a/test/core/core_directive_spec.dart +++ b/test/core/core_directive_spec.dart @@ -11,11 +11,11 @@ void main() { }); it('should extract attr map from annotated component', (DirectiveMap directives) { - var annotations = directives.annotationsFor(AnnotatedIoComponent); - expect(annotations.length).toEqual(1); - expect(annotations[0] is Component).toBeTruthy(); + var tuples = directives['annotated-io']; + expect(tuples.length).toEqual(1); + expect(tuples[0].directive is Component).toBeTruthy(); - Component annotation = annotations[0]; + Component annotation = tuples[0].directive; expect(annotation.selector).toEqual('annotated-io'); expect(annotation.visibility).toEqual(Directive.LOCAL_VISIBILITY); expect(annotation.exportExpressions).toEqual(['exportExpressions']); @@ -77,11 +77,11 @@ void main() { }); it("should extract attr map from annotated component which inherits other component", (DirectiveMap directives) { - var annotations = directives.annotationsFor(Sub); - expect(annotations.length).toEqual(1); - expect(annotations[0] is Directive).toBeTruthy(); + var tupls = directives['[sub]']; + expect(tupls.length).toEqual(1); + expect(tupls[0].directive is Directive).toBeTruthy(); - Directive annotation = annotations[0]; + Directive annotation = tupls[0].directive; expect(annotation.selector).toEqual('[sub]'); expect(annotation.map).toEqual({ "foo": "=>foo", @@ -112,7 +112,7 @@ class NullParser implements Parser { 'foo': '=>foo' }) class AnnotatedIoComponent { - static module() => new Module()..bind(String, toFactory: (i) => i.get(AnnotatedIoComponent), + static module(i) => i.bind(String, toFactory: (i) => i.get(AnnotatedIoComponent), visibility: Directive.LOCAL_VISIBILITY); AnnotatedIoComponent(Scope scope) { diff --git a/test/core/parser/parser_spec.dart b/test/core/parser/parser_spec.dart index 5d9b8b3f2..cf6c8a029 100644 --- a/test/core/parser/parser_spec.dart +++ b/test/core/parser/parser_spec.dart @@ -456,7 +456,7 @@ main() { }); xdescribe('reserved words', () { - iit('should support reserved words in member get access', () { + it('should support reserved words in member get access', () { for (String reserved in RESERVED_WORDS) { expect(parser("o.$reserved").eval({ 'o': new Object() })).toEqual(null); expect(parser("o.$reserved").eval({ 'o': { reserved: reserved }})).toEqual(reserved); @@ -1139,10 +1139,10 @@ main() { it('should parse formatters', () { expect(() { eval("1|nonexistent"); - }).toThrow('No Formatter: nonexistent found!'); + }).toThrow('No formatter \'nonexistent\' found!'); expect(() { eval("1|nonexistent", formatters); - }).toThrow('No Formatter: nonexistent found!'); + }).toThrow('No formatter \'nonexistent\' found!'); context['offset'] = 3; expect(eval("'abcd'|substring:1:offset")).toEqual("bc"); @@ -1153,12 +1153,12 @@ main() { var expression = parser("'World'|hello"); expect(() { expression.eval({}, formatters); - }).toThrow('No Formatter: hello found!'); + }).toThrow('No formatter \'hello\' found!'); var module = new Module() + ..bind(FormatterMap) ..bind(HelloFormatter); - var childInjector = injector.createChild([module], - forceNewInstances: [FormatterMap]); + var childInjector = injector.createChild([module]); var newFormatters = childInjector.get(FormatterMap); expect(expression.eval({}, newFormatters)).toEqual('Hello, World!'); diff --git a/test/core/registry_spec.dart b/test/core/registry_spec.dart deleted file mode 100644 index 1a00d2af0..000000000 --- a/test/core/registry_spec.dart +++ /dev/null @@ -1,64 +0,0 @@ -library registry_spec; - -import '../_specs.dart'; -import 'package:angular/application_factory.dart'; - -main() { - describe('RegistryMap', () { - it('should allow for multiple registry keys to be added', () { - var module = new Module() - ..bind(MyMap) - ..bind(A1) - ..bind(A2); - - var injector = applicationFactory().addModule(module).createInjector(); - expect(() { - injector.get(MyMap); - }).not.toThrow(); - }); - - it('should iterate over all types', () { - var module = new Module() - ..bind(MyMap) - ..bind(A1); - - var injector = applicationFactory().addModule(module).createInjector(); - var keys = []; - var types = []; - var map = injector.get(MyMap); - map.forEach((k, t) { keys.add(k); types.add(t); }); - expect(keys).toEqual([new MyAnnotation('A'), new MyAnnotation('B')]); - expect(types).toEqual([A1, A1]); - }); - - it('should safely ignore typedefs', () { - var module = new Module() - ..bind(MyMap) - ..bind(MyTypedef, toValue: (String _) => null); - - var injector = applicationFactory().addModule(module).createInjector(); - expect(() => injector.get(MyMap), isNot(throws)); - }); - }); -} - -typedef void MyTypedef(String arg); - -class MyMap extends AnnotationMap { - MyMap(Injector injector, MetadataExtractor metadataExtractor) - : super(injector, metadataExtractor); -} - - -class MyAnnotation { - final String name; - - const MyAnnotation(String this.name); - - toString() => name; - get hashCode => name.hashCode; - operator==(other) => this.name == other.name; -} - -@MyAnnotation('A') @MyAnnotation('B') class A1 {} -@MyAnnotation('A') class A2 {} diff --git a/test/core_dom/compiler_spec.dart b/test/core_dom/compiler_spec.dart index 97c19d325..0345a9660 100644 --- a/test/core_dom/compiler_spec.dart +++ b/test/core_dom/compiler_spec.dart @@ -85,7 +85,9 @@ void main() { ..bind(TwoOfTwoDirectives) ..bind(MyController) ..bind(MyParentController) - ..bind(MyChildController); + ..bind(MyChildController) + ..bind(SameNameDecorator) + ..bind(SameNameTransclude); }); beforeEach(inject((TestBed tb) => _ = tb)); @@ -917,6 +919,16 @@ void main() { expect(_.rootScope.context['name']).toEqual('cover me'); expect(_.rootElement.text).toEqual('MyController'); }); + + it('should allow multiple directives with the same selector of different type', (DirectiveMap map) { + _.compile('
'); + _.rootScope.apply(); + SameNameTransclude transclude = _.rootScope.context['sameTransclude']; + SameNameDecorator decorator = _.rootScope.context['sameDecorator']; + + expect(transclude.valueTransclude).toEqual('worked'); + expect(decorator.valueDecorator).toEqual('worked'); + }); }); })); } @@ -1328,3 +1340,27 @@ class OneTimeDecorator { OneTimeDecorator(this.log); set value(v) => log(v); } + +@Decorator( + selector: '[same-name]', + children: Directive.TRANSCLUDE_CHILDREN, + map: const { '.': '@valueTransclude' } +) +class SameNameTransclude { + var valueTransclude; + SameNameTransclude(ViewPort port, ViewFactory factory, RootScope scope, Injector injector) { + port.insert(factory.call(injector)); + scope.context['sameTransclude'] = this; + } +} + +@Decorator( + selector: '[same-name]', + map: const { 'same-name': '@valueDecorator' } +) +class SameNameDecorator { + var valueDecorator; + SameNameDecorator(RootScope scope) { + scope.context['sameDecorator'] = this; + } +} diff --git a/test/core_dom/selector_spec.dart b/test/core_dom/selector_spec.dart index 35c8785a9..524359a4c 100644 --- a/test/core_dom/selector_spec.dart +++ b/test/core_dom/selector_spec.dart @@ -2,34 +2,47 @@ library angular.dom.selector_spec; import '../_specs.dart'; -@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{} - -@Decorator(selector:'[ignore-children]', - children: Directive.IGNORE_CHILDREN) - class _IgnoreChildren{} - -@Decorator(selector: '[my-model][required]') -@Decorator(selector: '[my-model][my-required]') - class _TwoDirectives {} - -@Decorator(selector: '[two-directives]') class _OneOfTwoDirectives {} -@Decorator(selector: '[two-directives]') class _TwoOfTwoDirectives {} - +const _aBElement = const Decorator(selector:'b'); +const _aBClass = const Decorator(selector:'.b'); +const _aDirectiveAttr = const Decorator(selector:'[directive]'); +const _aWildcardDirectiveAttr = const Decorator(selector:'[wildcard-*]'); +const _aDirectiveFooAttr = const Decorator(selector:'[directive=d][foo=f]'); +const _aBElementDirectiveAttr = const Decorator(selector:'b[directive]'); +const _aDirectiveValueAttr = const Decorator(selector:'[directive=value]'); +const _aBElementDirectiveValue = const Decorator(selector:'b[directive=value]'); +const _aContainsAbc = const Decorator(selector:':contains(/abc/)'); +const _aAttributeContainsXyz = const Decorator(selector:'[*=/xyz/]'); +const _aAttribute = const Decorator(selector:'[attribute]'); +const _aCComponent = const Component(selector:'component'); +const _aStructural = const Decorator(selector:'[structural]', + children: Directive.TRANSCLUDE_CHILDREN); +const _aIgnoreChildren = const Decorator(selector:'[ignore-children]', + children: Directive.IGNORE_CHILDREN); +const _aTwoDirectives0 = const Decorator(selector: '[my-model][required]'); +const _aTwoDirectives1 = const Decorator(selector: '[my-model][my-required]'); +const _aOneOfTwoDirectives = const Decorator(selector: '[two-directives]'); +const _aTwoOfTwoDirectives = const Decorator(selector: '[two-directives]'); + + +@_aBElement class _BElement{} +@_aBClass class _BClass{} +@_aDirectiveAttr class _DirectiveAttr{} +@_aWildcardDirectiveAttr class _WildcardDirectiveAttr{} +@_aDirectiveFooAttr class _DirectiveFooAttr{} +@_aBElementDirectiveAttr class _BElementDirectiveAttr{} +@_aDirectiveValueAttr class _DirectiveValueAttr{} +@_aBElementDirectiveValue class _BElementDirectiveValue{} +@_aContainsAbc class _ContainsAbc{} +@_aAttributeContainsXyz class _AttributeContainsXyz{} +@_aCComponent class _CComponent{} +@_aAttribute class _Attribute{} +@_aStructural class _Structural{} +@_aIgnoreChildren class _IgnoreChildren{} +@_aOneOfTwoDirectives class _OneOfTwoDirectives {} +@_aTwoOfTwoDirectives class _TwoOfTwoDirectives {} + +@_aTwoDirectives0 +@_aTwoDirectives1 class _TwoDirectives {} main() { describe('Selector', () { @@ -51,7 +64,7 @@ main() { ..bind(_BElementDirectiveValue) ..bind(_ContainsAbc) ..bind(_AttributeContainsXyz) - ..bind(_Component) + ..bind(_CComponent) ..bind(_Attribute) ..bind(_Structural) ..bind(_IgnoreChildren) @@ -69,14 +82,14 @@ main() { expect( selector(element = e('')), toEqualsDirectiveInfos([ - { "selector": 'b', "value": null, "element": element} + { "selector": 'b', "value": null, "element": element, "annotation": _aBElement} ])); }); it('should match directive on class', () { expect(selector(element = e('
')), toEqualsDirectiveInfos([ - { "selector": '.b', "value": null, "element": element} + { "selector": '.b', "value": null, "element": element, "annotation": _aBClass} ])); }); @@ -84,39 +97,39 @@ main() { expect(selector(element = e('
')), toEqualsDirectiveInfos([ { "selector": '[directive]', "value": 'abc', "element": element, - "name": 'directive' }])); + "name": 'directive', "annotation": _aDirectiveAttr }])); expect(selector(element = e('
')), toEqualsDirectiveInfos([ { "selector": '[directive]', "value": '', "element": element, - "name": 'directive' }])); + "name": 'directive', "annotation": _aDirectiveAttr }])); }); it('should match directive on element[attribute]', () { expect(selector(element = e('')), 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, "annotation": _aBElement}, + { "selector": '[directive]', "value": 'abc', "element": element, "annotation": _aDirectiveAttr}, + { "selector": 'b[directive]', "value": 'abc', "element": element, "annotation": _aBElementDirectiveAttr} ])); }); it('should match directive on [attribute=value]', () { expect(selector(element = e('
')), toEqualsDirectiveInfos([ - { "selector": '[directive]', "value": 'value', "element": element}, - { "selector": '[directive=value]', "value": 'value', "element": element} + { "selector": '[directive]', "value": 'value', "element": element, "annotation": _aDirectiveAttr}, + { "selector": '[directive=value]', "value": 'value', "element": element, "annotation": _aDirectiveValueAttr} ])); }); it('should match directive on element[attribute=value]', () { expect(selector(element = e('')), 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, "annotation": _aBElement}, + { "selector": '[directive]', "value": 'value', "element": element, "annotation": _aDirectiveAttr}, + { "selector": '[directive=value]', "value": 'value', "element": element, "annotation": _aDirectiveValueAttr}, + { "selector": 'b[directive]', "value": 'value', "element": element, "annotation": _aBElementDirectiveAttr}, + { "selector": 'b[directive=value]', "value": 'value', "element": element, "annotation": _aBElementDirectiveValue} ])); }); @@ -126,7 +139,9 @@ main() { { "selector": '[*=/xyz/]', "value": 'attr', "ast": '"before-xyz-after"', - "element": element, "name": 'attr'} + "element": element, + "name": 'attr', + "annotation": _aAttributeContainsXyz} ])); }); @@ -134,7 +149,7 @@ main() { expect(selector(element = e('
')), toEqualsDirectiveInfos([ { "selector": '[wildcard-*]', "value": 'ignored', - "element": element, "name": 'wildcard-match'} + "element": element, "name": 'wildcard-match', "annotation": _aWildcardDirectiveAttr} ])); }); @@ -144,23 +159,23 @@ main() { expect(eb, toEqualsDirectiveInfos( null, - template: {"selector": "[structural]", "value": "", "element": element})); + template: {"selector": "[structural]", "value": "", "element": element, "annotation": _aStructural})); expect(eb.templateBinder, toEqualsDirectiveInfos( [ - { "selector": "[attribute]", "value": "", "element": element }, - { "selector": "[ignore-children]", "value": "", "element": element } + { "selector": "[attribute]", "value": "", "element": element, "annotation": _aAttribute }, + { "selector": "[ignore-children]", "value": "", "element": element, "annotation": _aIgnoreChildren } ], - component: { "selector": "component", "value": null, "element": element })); + component: { "selector": "component", "value": null, "element": element, "annotation": _aCComponent })); })); it('should match on multiple directives', () { expect(selector(element = e('
')), toEqualsDirectiveInfos([ - { "selector": '[directive]', "value": 'd', "element": element}, - { "selector": '[directive=d][foo=f]', "value": 'f', "element": element} + { "selector": '[directive]', "value": 'd', "element": element, "annotation": _aDirectiveAttr}, + { "selector": '[directive=d][foo=f]', "value": 'f', "element": element, "annotation": _aDirectiveFooAttr} ])); }); @@ -187,8 +202,8 @@ main() { it('should match an two directives with the same selector', () { expect(selector(element = e('
')), toEqualsDirectiveInfos([ - { "selector": '[two-directives]', "value": '', "element": element}, - { "selector": '[two-directives]', "value": '', "element": element} + { "selector": '[two-directives]', "value": '', "element": element, "annotation": _aOneOfTwoDirectives}, + { "selector": '[two-directives]', "value": '', "element": element, "annotation": _aTwoOfTwoDirectives} ])); }); @@ -252,10 +267,11 @@ class DirectiveInfosMatcher extends Matcher { Description describe(Description description) => description..add(expected.toString()); - bool _refMatches(directiveRef, expectedMap) => + bool _refMatches(DirectiveRef directiveRef, Map expectedMap) => directiveRef.element == expectedMap['element'] && directiveRef.annotation.selector == expectedMap['selector'] && directiveRef.value == expectedMap['value'] && + (expectedMap['annotation'] == null || directiveRef.annotation == expectedMap['annotation']) && (directiveRef.valueAST == null || directiveRef.valueAST.expression == expectedMap['ast']); diff --git a/test/formatter/currency_spec.dart b/test/formatter/currency_spec.dart index a488c107f..f747959fa 100644 --- a/test/formatter/currency_spec.dart +++ b/test/formatter/currency_spec.dart @@ -8,7 +8,7 @@ void main() { var currency; beforeEach((FormatterMap map, Injector injector) { - currency = injector.get(map[new Formatter(name: 'currency')]); + currency = injector.get(map['currency']); }); diff --git a/test/formatter/date_spec.dart b/test/formatter/date_spec.dart index 124dcb2e4..f207b1e58 100644 --- a/test/formatter/date_spec.dart +++ b/test/formatter/date_spec.dart @@ -13,7 +13,7 @@ void main() { var date; beforeEach((FormatterMap map, Injector injector) { - date = injector.get(map[new Formatter(name: 'date')]); + date = injector.get(map['date']); }); it('should ignore falsy inputs', () { diff --git a/test/formatter/filter_spec.dart b/test/formatter/filter_spec.dart index 0c614912a..dfc168979 100644 --- a/test/formatter/filter_spec.dart +++ b/test/formatter/filter_spec.dart @@ -52,7 +52,7 @@ main() { var filter; beforeEach((Injector injector, FormatterMap filterMap) { - filter = injector.get(filterMap[new Formatter(name: 'filter')]); + filter = injector.get(filterMap['filter']); }); it('should formatter by string', () { diff --git a/test/formatter/number_spec.dart b/test/formatter/number_spec.dart index cf4889bdd..782418724 100644 --- a/test/formatter/number_spec.dart +++ b/test/formatter/number_spec.dart @@ -8,7 +8,7 @@ void main() { var number; beforeEach((FormatterMap map, Injector injector) { - number = injector.get(map[new Formatter(name: 'number')]); + number = injector.get(map['number']); });