', [createComp('div', ['a'])])))
.toEqual([['div', null], ['span', null], ['a', null], ['a', 0]]);
});
it('should project nodes of nested components', () => {
expect(humanizeContentProjection(
parse('hello', [createComp('a', ['*']), createComp('b', ['*'])])))
.toEqual([['a', null], ['b', 0], ['#text(hello)', 0]]);
});
});
describe('splitClasses', () => {
it('should keep an empty class', () => { expect(splitClasses('a')).toEqual(['a']); });
it('should split 2 classes', () => { expect(splitClasses('a b')).toEqual(['a', 'b']); });
it('should trim classes', () => { expect(splitClasses(' a b ')).toEqual(['a', 'b']); });
});
describe('error cases', () => {
it('should throw on invalid property names', () => {
expect(() => parse('', [])).toThrowError(`Template parse errors:
Can't bind to 'invalidProp' since it isn't a known native property in TestComp > div:nth-child(0)[[invalid-prop]=]`);
});
it('should report errors in expressions', () => {
expect(() => parse('', [])).toThrowErrorWith(`Template parse errors:
Parser Error: Unexpected token 'b' at column 3 in [a b] in TestComp > div:nth-child(0)[[prop]=a b]`);
});
it('should not throw on invalid property names if the property is used by a directive',
() => {
var dirA = CompileDirectiveMetadata.create({
selector: 'div',
type: new CompileTypeMetadata({name: 'DirA'}),
properties: ['invalidProp']
});
expect(() => parse('', [dirA])).not.toThrow();
});
it('should not allow more than 1 component per element', () => {
var dirA = CompileDirectiveMetadata.create({
selector: 'div',
isComponent: true,
type: new CompileTypeMetadata({name: 'DirA'}),
template: new CompileTemplateMetadata({ngContentSelectors: []})
});
var dirB = CompileDirectiveMetadata.create({
selector: 'div',
isComponent: true,
type: new CompileTypeMetadata({name: 'DirB'}),
template: new CompileTemplateMetadata({ngContentSelectors: []})
});
expect(() => parse('
', [dirB, dirA])).toThrowError(`Template parse errors:
More than one component: DirB,DirA in TestComp > div:nth-child(0)`);
});
it('should not allow components or element nor event bindings on explicit embedded templates',
() => {
var dirA = CompileDirectiveMetadata.create({
selector: '[a]',
isComponent: true,
type: new CompileTypeMetadata({name: 'DirA'}),
template: new CompileTemplateMetadata({ngContentSelectors: []})
});
expect(() => parse('', [dirA]))
.toThrowError(`Template parse errors:
Components on an embedded template: DirA in TestComp > template:nth-child(0)
Property binding a not used by any directive on an embedded template in TestComp > template:nth-child(0)[[a]=b]
Event binding e on an embedded template in TestComp > template:nth-child(0)[(e)=f]`);
});
it('should not allow components or element bindings on inline embedded templates', () => {
var dirA = CompileDirectiveMetadata.create({
selector: '[a]',
isComponent: true,
type: new CompileTypeMetadata({name: 'DirA'}),
template: new CompileTemplateMetadata({ngContentSelectors: []})
});
expect(() => parse('
', [dirA])).toThrowError(`Template parse errors:
Components on an embedded template: DirA in TestComp > div:nth-child(0)
Property binding a not used by any directive on an embedded template in TestComp > div:nth-child(0)[*a=b]`);
});
});
describe('ignore elements', () => {
it('should ignore a', [])))
.toEqual([[TextAst, 'a', 'TestComp > #text(a):nth-child(1)']]);
});
it('should ignore a', [])))
.toEqual([[TextAst, 'a', 'TestComp > #text(a):nth-child(1)']]);
});
it('should ignore elements but include them for source info', () => {
expect(humanizeTemplateAsts(parse('a', [])))
.toEqual([[TextAst, 'a', 'TestComp > #text(a):nth-child(1)']]);
});
it('should ignore elements with ng-non-bindable, including their children, but include them for source info',
() => {
expect(humanizeTemplateAsts(parse('