2014-11-11 20:33:47 -05:00
|
|
|
import {describe, beforeEach, it, expect, ddescribe, iit} from 'test_lib/test_lib';
|
|
|
|
import {DOM} from 'facade/dom';
|
|
|
|
import {List} from 'facade/collection';
|
|
|
|
|
2014-12-02 16:21:39 -05:00
|
|
|
import {Compiler, CompilerCache} from 'core/compiler/compiler';
|
2014-11-11 20:33:47 -05:00
|
|
|
import {ProtoView} from 'core/compiler/view';
|
2014-11-20 15:07:48 -05:00
|
|
|
import {DirectiveMetadataReader} from 'core/compiler/directive_metadata_reader';
|
2014-11-11 20:33:47 -05:00
|
|
|
import {TemplateLoader} from 'core/compiler/template_loader';
|
2014-11-22 00:19:23 -05:00
|
|
|
import {Component} from 'core/annotations/annotations';
|
2014-11-11 20:33:47 -05:00
|
|
|
import {TemplateConfig} from 'core/annotations/template_config';
|
|
|
|
import {CompileElement} from 'core/compiler/pipeline/compile_element';
|
|
|
|
import {CompileStep} from 'core/compiler/pipeline/compile_step'
|
|
|
|
import {CompileControl} from 'core/compiler/pipeline/compile_control';
|
|
|
|
|
|
|
|
import {Parser} from 'change_detection/parser/parser';
|
|
|
|
import {Lexer} from 'change_detection/parser/lexer';
|
2014-09-19 19:38:37 -04:00
|
|
|
|
2014-09-25 17:04:46 -04:00
|
|
|
export function main() {
|
2014-09-28 16:55:01 -04:00
|
|
|
describe('compiler', function() {
|
2014-12-01 13:19:07 -05:00
|
|
|
var reader;
|
2014-11-11 20:33:47 -05:00
|
|
|
|
|
|
|
beforeEach( () => {
|
2014-11-20 15:07:48 -05:00
|
|
|
reader = new DirectiveMetadataReader();
|
2014-11-11 20:33:47 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
function createCompiler(processClosure) {
|
|
|
|
var steps = [new MockStep(processClosure)];
|
2014-12-02 16:21:39 -05:00
|
|
|
return new TestableCompiler(reader, steps);
|
2014-11-11 20:33:47 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
it('should run the steps and return the ProtoView of the root element', (done) => {
|
|
|
|
var rootProtoView = new ProtoView(null, null);
|
|
|
|
var compiler = createCompiler( (parent, current, control) => {
|
|
|
|
current.inheritedProtoView = rootProtoView;
|
|
|
|
});
|
|
|
|
compiler.compile(MainComponent, createElement('<div></div>')).then( (protoView) => {
|
|
|
|
expect(protoView).toBe(rootProtoView);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should use the given element', (done) => {
|
|
|
|
var el = createElement('<div></div>');
|
|
|
|
var compiler = createCompiler( (parent, current, control) => {
|
|
|
|
current.inheritedProtoView = new ProtoView(current.element, null);
|
|
|
|
});
|
|
|
|
compiler.compile(MainComponent, el).then( (protoView) => {
|
|
|
|
expect(protoView.element).toBe(el);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should use the inline template if no element is given explicitly', (done) => {
|
|
|
|
var compiler = createCompiler( (parent, current, control) => {
|
|
|
|
current.inheritedProtoView = new ProtoView(current.element, null);
|
|
|
|
});
|
|
|
|
compiler.compile(MainComponent, null).then( (protoView) => {
|
|
|
|
expect(DOM.getInnerHTML(protoView.element)).toEqual('inline component');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should load nested components', (done) => {
|
|
|
|
var mainEl = createElement('<div></div>');
|
|
|
|
var compiler = createCompiler( (parent, current, control) => {
|
|
|
|
current.inheritedProtoView = new ProtoView(current.element, null);
|
|
|
|
current.inheritedElementBinder = current.inheritedProtoView.bindElement(null);
|
|
|
|
if (current.element === mainEl) {
|
2014-11-20 15:07:48 -05:00
|
|
|
current.componentDirective = reader.annotatedType(NestedComponent);
|
2014-11-11 20:33:47 -05:00
|
|
|
}
|
|
|
|
});
|
|
|
|
compiler.compile(MainComponent, mainEl).then( (protoView) => {
|
|
|
|
var nestedView = protoView.elementBinders[0].nestedProtoView;
|
|
|
|
expect(DOM.getInnerHTML(nestedView.element)).toEqual('nested component');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
|
2014-12-02 16:21:39 -05:00
|
|
|
it('should cache components', (done) => {
|
|
|
|
var el = createElement('<div></div>');
|
|
|
|
var compiler = createCompiler( (parent, current, control) => {
|
|
|
|
current.inheritedProtoView = new ProtoView(current.element, null);
|
|
|
|
});
|
|
|
|
var firstProtoView;
|
|
|
|
compiler.compile(MainComponent, el).then( (protoView) => {
|
|
|
|
firstProtoView = protoView;
|
|
|
|
return compiler.compile(MainComponent, el);
|
|
|
|
}).then( (protoView) => {
|
|
|
|
expect(firstProtoView).toBe(protoView);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should allow recursive components', (done) => {
|
|
|
|
var compiler = createCompiler( (parent, current, control) => {
|
|
|
|
current.inheritedProtoView = new ProtoView(current.element, null);
|
|
|
|
current.inheritedElementBinder = current.inheritedProtoView.bindElement(null);
|
|
|
|
current.componentDirective = reader.annotatedType(RecursiveComponent);
|
|
|
|
});
|
|
|
|
compiler.compile(RecursiveComponent, null).then( (protoView) => {
|
|
|
|
expect(protoView.elementBinders[0].nestedProtoView).toBe(protoView);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
|
2014-09-19 19:38:37 -04:00
|
|
|
});
|
2014-11-11 20:33:47 -05:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@Component({
|
|
|
|
template: new TemplateConfig({
|
|
|
|
inline: 'inline component'
|
|
|
|
})
|
|
|
|
})
|
|
|
|
class MainComponent {}
|
|
|
|
|
|
|
|
@Component({
|
|
|
|
template: new TemplateConfig({
|
|
|
|
inline: 'nested component'
|
|
|
|
})
|
|
|
|
})
|
|
|
|
class NestedComponent {}
|
|
|
|
|
2014-12-02 16:21:39 -05:00
|
|
|
@Component({
|
|
|
|
template: new TemplateConfig({
|
|
|
|
inline: '<div rec-comp></div>'
|
|
|
|
}),
|
|
|
|
selector: 'rec-comp'
|
|
|
|
})
|
|
|
|
class RecursiveComponent {}
|
|
|
|
|
2014-11-11 20:33:47 -05:00
|
|
|
class TestableCompiler extends Compiler {
|
2014-11-22 00:19:23 -05:00
|
|
|
steps:List;
|
2014-12-02 16:21:39 -05:00
|
|
|
constructor(reader:DirectiveMetadataReader, steps:List<CompileStep>) {
|
|
|
|
super(null, reader, new Parser(new Lexer()), new CompilerCache());
|
2014-11-11 20:33:47 -05:00
|
|
|
this.steps = steps;
|
|
|
|
}
|
|
|
|
createSteps(component):List<CompileStep> {
|
|
|
|
return this.steps;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class MockStep extends CompileStep {
|
2014-11-22 00:19:23 -05:00
|
|
|
processClosure:Function;
|
2014-11-11 20:33:47 -05:00
|
|
|
constructor(process) {
|
|
|
|
this.processClosure = process;
|
|
|
|
}
|
|
|
|
process(parent:CompileElement, current:CompileElement, control:CompileControl) {
|
|
|
|
this.processClosure(parent, current, control);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function createElement(html) {
|
|
|
|
return DOM.createTemplate(html).content.firstChild;
|
2014-09-19 19:38:37 -04:00
|
|
|
}
|