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

Commit e2ef7cf

Browse files
vicbchirayuk
authored andcommitted
fix(ElementBinderBuilder): throw if multiple transcluding directives per node
fixes #1306 Closes #1325
1 parent 1c4e9e7 commit e2ef7cf

File tree

2 files changed

+71
-48
lines changed

2 files changed

+71
-48
lines changed

lib/core_dom/element_binder_builder.dart

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

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

test/core_dom/element_binder_builder_spec.dart

Lines changed: 66 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -5,73 +5,91 @@ 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-
});
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);
3241

33-
beforeEach((DirectiveMap d, ElementBinderFactory f) {
34-
directives = d;
35-
b = f.builder(null, null);
36-
});
42+
});
3743

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));
44+
beforeEach((DirectiveMap d, ElementBinderFactory f) {
45+
directives = d;
46+
builder = f.builder(null, null);
4247
});
43-
b = b.binder;
44-
}
4548

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

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

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

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

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

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

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

67-
expect(b.template).toBeNotNull();
68-
});
78+
expect(binder.template).toBeNotNull();
79+
});
6980

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

73-
expect(b.decorators.length).toEqual(1);
74-
expect(b.componentData).toBeNull();
75-
expect(b.childMode).toEqual(Directive.IGNORE_CHILDREN);
90+
expect(binder.decorators.length).toEqual(1);
91+
expect(binder.componentData).toBeNull();
92+
expect(binder.childMode).toEqual(Directive.IGNORE_CHILDREN);
93+
});
7694
});
77-
});
95+
}

0 commit comments

Comments
 (0)