Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.

Commit 693536b

Browse files
vicbrkirov
authored andcommitted
fix(ElementBinderBuilder): throw if multiple transcluding directives per node
fixes #1306 Closes #1325
1 parent 5424b4d commit 693536b

File tree

2 files changed

+71
-49
lines changed

2 files changed

+71
-49
lines changed

lib/core_dom/element_binder_builder.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ class ElementBinderBuilder {
6969
var children = annotation.children;
7070

7171
if (annotation.children == Directive.TRANSCLUDE_CHILDREN) {
72+
if (template != null) {
73+
throw "There could be at most one transcluding directive on a node. The node "
74+
"'${ref.element.outerHtml}' has both '${ref.annotation.selector}' and "
75+
"'${template.annotation.selector}'.";
76+
}
7277
template = ref;
7378
} else if (annotation is Component) {
7479
ComponentFactory factory;

test/core_dom/element_binder_builder_spec.dart

Lines changed: 66 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -5,73 +5,90 @@ import 'dart:mirrors';
55

66
@Component(selector:'component') class _Component{}
77
@Decorator(selector:'[ignore-children]',
8-
children: Directive.IGNORE_CHILDREN)
9-
class _IgnoreChildren{}
8+
children: Directive.IGNORE_CHILDREN)
9+
class _IgnoreChildren{}
1010
@Decorator(selector:'[structural]',
11-
children: Directive.TRANSCLUDE_CHILDREN)
12-
class _Structural{}
11+
children: Directive.TRANSCLUDE_CHILDREN)
12+
class _Structural{}
1313
@Decorator(selector:'[directive]') class _DirectiveAttr{}
1414

15+
@Decorator(selector: '[templates]',
16+
children: Directive.TRANSCLUDE_CHILDREN)
17+
class _Template1{}
18+
@Decorator(selector: '[templates]',
19+
children: Directive.TRANSCLUDE_CHILDREN)
20+
class _Template2{}
21+
1522

1623
directiveFor(i) {
1724
ClassMirror cm = reflectType(i);
1825

1926
}
20-
main() => describe('ElementBinderBuilder', () {
21-
var b;
22-
var directives;
23-
var node = null;
24-
25-
beforeEachModule((Module module) {
26-
module
27-
..bind(_DirectiveAttr)
28-
..bind(_Component)
29-
..bind(_IgnoreChildren)
30-
..bind(_Structural);
31-
});
32-
33-
beforeEach((DirectiveMap d, ElementBinderFactory f, Injector i) {
34-
directives = d;
35-
b = f.builder(null, null, i);
36-
});
27+
void main() {
28+
describe('ElementBinderBuilder', () {
29+
ElementBinderBuilder builder;
30+
ElementBinder binder;
31+
var directives;
32+
var node = new DivElement();
33+
34+
beforeEachModule((Module module) {
35+
module..bind(_DirectiveAttr)
36+
..bind(_Component)
37+
..bind(_IgnoreChildren)
38+
..bind(_Structural)
39+
..bind(_Template1)
40+
..bind(_Template2);
41+
});
3742

38-
addDirective(selector) {
39-
directives.forEach((Directive annotation, Type type) {
40-
if (annotation.selector == selector)
41-
b.addDirective(new DirectiveRef(node, type, annotation, new Key(type), null));
43+
beforeEach((DirectiveMap d, ElementBinderFactory f, Injector i) {
44+
directives = d;
45+
builder = f.builder(null, null, i);
4246
});
43-
b = b.binder;
44-
}
4547

46-
it('should add a decorator', () {
47-
expect(b.decorators.length).toEqual(0);
48+
addDirective(selector) {
49+
directives.forEach((Directive annotation, Type type) {
50+
if (annotation.selector == selector)
51+
builder.addDirective(new DirectiveRef(node, type, annotation, new Key(type), null));
52+
});
53+
binder = builder.binder;
54+
}
4855

49-
addDirective('[directive]');
56+
it('should add a decorator', () {
57+
expect(builder.decorators.length).toEqual(0);
5058

51-
expect(b.decorators.length).toEqual(1);
52-
expect(b.componentData).toBeNull();
53-
expect(b.childMode).toEqual(Directive.COMPILE_CHILDREN);
59+
addDirective('[directive]');
5460

55-
});
61+
expect(binder.decorators.length).toEqual(1);
62+
expect(binder.componentData).toBeNull();
63+
expect(binder.childMode).toEqual(Directive.COMPILE_CHILDREN);
64+
65+
});
5666

57-
it('should add a component', async(() {
58-
addDirective('component');
67+
it('should add a component', async(() {
68+
addDirective('component');
5969

60-
expect(b.decorators.length).toEqual(0);
61-
expect(b.componentData).toBeNotNull();
62-
}));
70+
expect(binder.decorators.length).toEqual(0);
71+
expect(binder.componentData).toBeNotNull();
72+
}));
6373

64-
it('should add a template', () {
65-
addDirective('[structural]');
74+
it('should add a template', () {
75+
addDirective('[structural]');
6676

67-
expect(b.template).toBeNotNull();
68-
});
77+
expect(binder.template).toBeNotNull();
78+
});
6979

70-
it('should add a directive that ignores children', () {
71-
addDirective('[ignore-children]');
80+
it('could have at most one template', () {
81+
expect(() => addDirective(('[templates]')))
82+
.toThrowWith(message: "There could be at most one transcluding directive on a node. The "
83+
"node '<div></div>' has both '[templates]' and '[templates]'.");
84+
});
7285

73-
expect(b.decorators.length).toEqual(1);
74-
expect(b.componentData).toBeNull();
75-
expect(b.childMode).toEqual(Directive.IGNORE_CHILDREN);
86+
it('should add a directive that ignores children', () {
87+
addDirective('[ignore-children]');
88+
89+
expect(binder.decorators.length).toEqual(1);
90+
expect(binder.componentData).toBeNull();
91+
expect(binder.childMode).toEqual(Directive.IGNORE_CHILDREN);
92+
});
7693
});
77-
});
94+
}

0 commit comments

Comments
 (0)