refactor(core): rename angular2/src/compiler -> angular2/src/core/compiler
This commit is contained in:
@ -1,196 +0,0 @@
|
||||
import {
|
||||
AsyncTestCompleter,
|
||||
beforeEach,
|
||||
ddescribe,
|
||||
describe,
|
||||
el,
|
||||
expect,
|
||||
iit,
|
||||
inject,
|
||||
it,
|
||||
xit,
|
||||
TestComponentBuilder,
|
||||
beforeEachBindings
|
||||
} from 'angular2/test_lib';
|
||||
import {MapWrapper} from 'angular2/src/core/facade/collection';
|
||||
import {
|
||||
CompileDirectiveMetadata,
|
||||
CompileTypeMetadata
|
||||
} from 'angular2/src/compiler/directive_metadata';
|
||||
import {TemplateParser} from 'angular2/src/compiler/template_parser';
|
||||
import {
|
||||
Parser,
|
||||
Lexer,
|
||||
ChangeDetectorDefinition,
|
||||
ChangeDetectorGenConfig,
|
||||
DynamicProtoChangeDetector,
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDispatcher,
|
||||
DirectiveIndex,
|
||||
Locals,
|
||||
BindingTarget,
|
||||
ChangeDetector
|
||||
} from 'angular2/src/core/change_detection/change_detection';
|
||||
import {Pipes} from 'angular2/src/core/change_detection/pipes';
|
||||
import {createChangeDetectorDefinitions} from 'angular2/src/compiler/change_definition_factory';
|
||||
import {TestDirective, TestDispatcher, TestPipes} from './change_detector_mocks';
|
||||
|
||||
import {TEST_BINDINGS} from './test_bindings';
|
||||
|
||||
export function main() {
|
||||
describe('ChangeDefinitionFactory', () => {
|
||||
beforeEachBindings(() => TEST_BINDINGS);
|
||||
|
||||
var parser: TemplateParser;
|
||||
var dispatcher: TestDispatcher;
|
||||
var context: TestContext;
|
||||
var directive: TestDirective;
|
||||
var locals: Locals;
|
||||
var pipes: Pipes;
|
||||
var eventLocals: Locals;
|
||||
|
||||
beforeEach(inject([TemplateParser], (_templateParser) => {
|
||||
parser = _templateParser;
|
||||
context = new TestContext();
|
||||
directive = new TestDirective();
|
||||
dispatcher = new TestDispatcher([directive], []);
|
||||
locals = new Locals(null, MapWrapper.createFromStringMap({'someVar': null}));
|
||||
eventLocals = new Locals(null, MapWrapper.createFromStringMap({'$event': null}));
|
||||
pipes = new TestPipes();
|
||||
}));
|
||||
|
||||
function createChangeDetector(template: string, directives: CompileDirectiveMetadata[],
|
||||
protoViewIndex: number = 0): ChangeDetector {
|
||||
var protoChangeDetectors =
|
||||
createChangeDetectorDefinitions(new CompileTypeMetadata({name: 'SomeComp'}),
|
||||
ChangeDetectionStrategy.Default,
|
||||
new ChangeDetectorGenConfig(true, true, false, false),
|
||||
parser.parse(template, directives, 'TestComp'))
|
||||
.map(definition => new DynamicProtoChangeDetector(definition));
|
||||
var changeDetector = protoChangeDetectors[protoViewIndex].instantiate(dispatcher);
|
||||
changeDetector.hydrate(context, locals, dispatcher, pipes);
|
||||
return changeDetector;
|
||||
}
|
||||
|
||||
it('should watch element properties', () => {
|
||||
var changeDetector = createChangeDetector('<div [el-prop]="someProp">', [], 0);
|
||||
|
||||
context.someProp = 'someValue';
|
||||
changeDetector.detectChanges();
|
||||
expect(dispatcher.log).toEqual(['elementProperty(elProp)=someValue']);
|
||||
});
|
||||
|
||||
it('should watch text nodes', () => {
|
||||
var changeDetector = createChangeDetector('{{someProp}}', [], 0);
|
||||
|
||||
context.someProp = 'someValue';
|
||||
changeDetector.detectChanges();
|
||||
expect(dispatcher.log).toEqual(['textNode(null)=someValue']);
|
||||
});
|
||||
|
||||
it('should handle events', () => {
|
||||
var changeDetector = createChangeDetector('<div on-click="onEvent($event)">', [], 0);
|
||||
|
||||
eventLocals.set('$event', 'click');
|
||||
changeDetector.handleEvent('click', 0, eventLocals);
|
||||
expect(context.eventLog).toEqual(['click']);
|
||||
});
|
||||
|
||||
it('should handle events with targets', () => {
|
||||
var changeDetector = createChangeDetector('<div (window:click)="onEvent($event)">', [], 0);
|
||||
|
||||
eventLocals.set('$event', 'click');
|
||||
changeDetector.handleEvent('window:click', 0, eventLocals);
|
||||
expect(context.eventLog).toEqual(['click']);
|
||||
});
|
||||
|
||||
it('should watch variables', () => {
|
||||
var changeDetector = createChangeDetector('<div #some-var [el-prop]="someVar">', [], 0);
|
||||
|
||||
locals.set('someVar', 'someValue');
|
||||
changeDetector.detectChanges();
|
||||
expect(dispatcher.log).toEqual(['elementProperty(elProp)=someValue']);
|
||||
});
|
||||
|
||||
it('should write directive properties', () => {
|
||||
var dirMeta = CompileDirectiveMetadata.create({
|
||||
type: new CompileTypeMetadata({name: 'SomeDir'}),
|
||||
selector: '[dir-prop]',
|
||||
inputs: ['dirProp']
|
||||
});
|
||||
|
||||
var changeDetector = createChangeDetector('<div [dir-prop]="someProp">', [dirMeta], 0);
|
||||
|
||||
context.someProp = 'someValue';
|
||||
changeDetector.detectChanges();
|
||||
expect(directive.dirProp).toEqual('someValue');
|
||||
});
|
||||
|
||||
it('should write template directive properties', () => {
|
||||
var dirMeta = CompileDirectiveMetadata.create({
|
||||
type: new CompileTypeMetadata({name: 'SomeDir'}),
|
||||
selector: '[dir-prop]',
|
||||
inputs: ['dirProp']
|
||||
});
|
||||
|
||||
var changeDetector = createChangeDetector('<template [dir-prop]="someProp">', [dirMeta], 0);
|
||||
|
||||
context.someProp = 'someValue';
|
||||
changeDetector.detectChanges();
|
||||
expect(directive.dirProp).toEqual('someValue');
|
||||
});
|
||||
|
||||
it('should watch directive host properties', () => {
|
||||
var dirMeta = CompileDirectiveMetadata.create({
|
||||
type: new CompileTypeMetadata({name: 'SomeDir'}),
|
||||
selector: 'div',
|
||||
host: {'[elProp]': 'dirProp'}
|
||||
});
|
||||
|
||||
var changeDetector = createChangeDetector('<div>', [dirMeta], 0);
|
||||
|
||||
directive.dirProp = 'someValue';
|
||||
changeDetector.detectChanges();
|
||||
expect(dispatcher.log).toEqual(['elementProperty(elProp)=someValue']);
|
||||
});
|
||||
|
||||
it('should handle directive events', () => {
|
||||
var dirMeta = CompileDirectiveMetadata.create({
|
||||
type: new CompileTypeMetadata({name: 'SomeDir'}),
|
||||
selector: 'div',
|
||||
host: {'(click)': 'onEvent($event)'}
|
||||
});
|
||||
|
||||
var changeDetector = createChangeDetector('<div>', [dirMeta], 0);
|
||||
|
||||
eventLocals.set('$event', 'click');
|
||||
changeDetector.handleEvent('click', 0, eventLocals);
|
||||
expect(directive.eventLog).toEqual(['click']);
|
||||
});
|
||||
|
||||
it('should create change detectors for embedded templates', () => {
|
||||
var changeDetector = createChangeDetector('<template>{{someProp}}<template>', [], 1);
|
||||
|
||||
context.someProp = 'someValue';
|
||||
changeDetector.detectChanges();
|
||||
expect(dispatcher.log).toEqual(['textNode(null)=someValue']);
|
||||
});
|
||||
|
||||
it('should watch expressions after embedded templates', () => {
|
||||
var changeDetector =
|
||||
createChangeDetector('<template>{{someProp2}}</template>{{someProp}}', [], 0);
|
||||
|
||||
context.someProp = 'someValue';
|
||||
changeDetector.detectChanges();
|
||||
expect(dispatcher.log).toEqual(['textNode(null)=someValue']);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
class TestContext {
|
||||
eventLog: string[] = [];
|
||||
someProp: string;
|
||||
someProp2: string;
|
||||
|
||||
onEvent(value: string) { this.eventLog.push(value); }
|
||||
}
|
@ -1,154 +0,0 @@
|
||||
import {
|
||||
ddescribe,
|
||||
describe,
|
||||
xdescribe,
|
||||
it,
|
||||
iit,
|
||||
xit,
|
||||
expect,
|
||||
beforeEach,
|
||||
afterEach,
|
||||
AsyncTestCompleter,
|
||||
inject,
|
||||
beforeEachBindings
|
||||
} from 'angular2/test_lib';
|
||||
import {bind} from 'angular2/src/core/di';
|
||||
|
||||
import {CONST_EXPR, stringify} from 'angular2/src/core/facade/lang';
|
||||
import {MapWrapper} from 'angular2/src/core/facade/collection';
|
||||
import {Promise} from 'angular2/src/core/facade/async';
|
||||
|
||||
import {ChangeDetectionCompiler} from 'angular2/src/compiler/change_detector_compiler';
|
||||
|
||||
import {
|
||||
CompileDirectiveMetadata,
|
||||
CompileTypeMetadata
|
||||
} from 'angular2/src/compiler/directive_metadata';
|
||||
import {
|
||||
SourceModule,
|
||||
SourceExpression,
|
||||
SourceExpressions,
|
||||
moduleRef
|
||||
} from 'angular2/src/compiler/source_module';
|
||||
|
||||
import {TemplateParser} from 'angular2/src/compiler/template_parser';
|
||||
|
||||
import {
|
||||
ChangeDetectorGenConfig,
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDispatcher,
|
||||
DirectiveIndex,
|
||||
Locals,
|
||||
BindingTarget,
|
||||
ChangeDetector
|
||||
} from 'angular2/src/core/change_detection/change_detection';
|
||||
|
||||
import {evalModule} from './eval_module';
|
||||
|
||||
import {TEST_BINDINGS} from './test_bindings';
|
||||
import {TestDispatcher, TestPipes} from './change_detector_mocks';
|
||||
import {codeGenValueFn, codeGenExportVariable, MODULE_SUFFIX} from 'angular2/src/compiler/util';
|
||||
|
||||
// Attention: These module names have to correspond to real modules!
|
||||
var THIS_MODULE_ID = 'angular2/test/compiler/change_detector_compiler_spec';
|
||||
var THIS_MODULE_URL = `package:${THIS_MODULE_ID}${MODULE_SUFFIX}`;
|
||||
var THIS_MODULE_REF = moduleRef(THIS_MODULE_URL);
|
||||
|
||||
export function main() {
|
||||
describe('ChangeDetectorCompiler', () => {
|
||||
beforeEachBindings(() => TEST_BINDINGS);
|
||||
|
||||
var parser: TemplateParser;
|
||||
var compiler: ChangeDetectionCompiler;
|
||||
|
||||
beforeEach(inject([TemplateParser, ChangeDetectionCompiler], (_parser, _compiler) => {
|
||||
parser = _parser;
|
||||
compiler = _compiler;
|
||||
}));
|
||||
|
||||
describe('compileComponentRuntime', () => {
|
||||
function detectChanges(compiler: ChangeDetectionCompiler, template: string,
|
||||
directives: CompileDirectiveMetadata[] = CONST_EXPR([])): string[] {
|
||||
var type =
|
||||
new CompileTypeMetadata({name: stringify(SomeComponent), moduleUrl: THIS_MODULE_URL});
|
||||
var parsedTemplate = parser.parse(template, directives, 'TestComp');
|
||||
var factories =
|
||||
compiler.compileComponentRuntime(type, ChangeDetectionStrategy.Default, parsedTemplate);
|
||||
return testChangeDetector(factories[0]);
|
||||
}
|
||||
|
||||
describe('no jit', () => {
|
||||
beforeEachBindings(() => [
|
||||
bind(ChangeDetectorGenConfig)
|
||||
.toValue(new ChangeDetectorGenConfig(true, true, false, false))
|
||||
]);
|
||||
it('should watch element properties', () => {
|
||||
expect(detectChanges(compiler, '<div [el-prop]="someProp">'))
|
||||
.toEqual(['elementProperty(elProp)=someValue']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('jit', () => {
|
||||
beforeEachBindings(() => [
|
||||
bind(ChangeDetectorGenConfig)
|
||||
.toValue(new ChangeDetectorGenConfig(true, true, false, true))
|
||||
]);
|
||||
it('should watch element properties', () => {
|
||||
expect(detectChanges(compiler, '<div [el-prop]="someProp">'))
|
||||
.toEqual(['elementProperty(elProp)=someValue']);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
describe('compileComponentCodeGen', () => {
|
||||
function detectChanges(compiler: ChangeDetectionCompiler, template: string,
|
||||
directives: CompileDirectiveMetadata[] = CONST_EXPR([])):
|
||||
Promise<string[]> {
|
||||
var type =
|
||||
new CompileTypeMetadata({name: stringify(SomeComponent), moduleUrl: THIS_MODULE_URL});
|
||||
var parsedTemplate = parser.parse(template, directives, 'TestComp');
|
||||
var sourceExpressions =
|
||||
compiler.compileComponentCodeGen(type, ChangeDetectionStrategy.Default, parsedTemplate);
|
||||
var testableModule = createTestableModule(sourceExpressions, 0).getSourceWithImports();
|
||||
return evalModule(testableModule.source, testableModule.imports, null);
|
||||
}
|
||||
|
||||
it('should watch element properties', inject([AsyncTestCompleter], (async) => {
|
||||
detectChanges(compiler, '<div [el-prop]="someProp">')
|
||||
.then((value) => {
|
||||
expect(value).toEqual(['elementProperty(elProp)=someValue']);
|
||||
async.done();
|
||||
});
|
||||
|
||||
}));
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
function createTestableModule(source: SourceExpressions, changeDetectorIndex: number):
|
||||
SourceModule {
|
||||
var resultExpression =
|
||||
`${THIS_MODULE_REF}testChangeDetector(([${source.expressions.join(',')}])[${changeDetectorIndex}])`;
|
||||
var testableSource = `${source.declarations.join('\n')}
|
||||
${codeGenExportVariable('run')}${codeGenValueFn(['_'], resultExpression)};`;
|
||||
return new SourceModule(null, testableSource);
|
||||
}
|
||||
|
||||
export function testChangeDetector(changeDetectorFactory: Function): string[] {
|
||||
var dispatcher = new TestDispatcher([], []);
|
||||
var cd = changeDetectorFactory(dispatcher);
|
||||
var ctx = new SomeComponent();
|
||||
ctx.someProp = 'someValue';
|
||||
var locals = new Locals(null, MapWrapper.createFromStringMap({'someVar': null}));
|
||||
cd.hydrate(ctx, locals, dispatcher, new TestPipes());
|
||||
cd.detectChanges();
|
||||
return dispatcher.log;
|
||||
}
|
||||
|
||||
class SomeComponent {
|
||||
someProp: string;
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
import {isBlank} from 'angular2/src/core/facade/lang';
|
||||
import {Pipes} from 'angular2/src/core/change_detection/pipes';
|
||||
import {
|
||||
ProtoChangeDetector,
|
||||
ChangeDispatcher,
|
||||
DirectiveIndex,
|
||||
BindingTarget
|
||||
} from 'angular2/src/core/change_detection/change_detection';
|
||||
|
||||
export class TestDirective {
|
||||
eventLog: string[] = [];
|
||||
dirProp: string;
|
||||
|
||||
onEvent(value: string) { this.eventLog.push(value); }
|
||||
}
|
||||
|
||||
export class TestDispatcher implements ChangeDispatcher {
|
||||
log: string[];
|
||||
|
||||
constructor(public directives: any[], public detectors: ProtoChangeDetector[]) { this.clear(); }
|
||||
|
||||
getDirectiveFor(di: DirectiveIndex) { return this.directives[di.directiveIndex]; }
|
||||
|
||||
getDetectorFor(di: DirectiveIndex) { return this.detectors[di.directiveIndex]; }
|
||||
|
||||
clear() { this.log = []; }
|
||||
|
||||
notifyOnBinding(target: BindingTarget, value) {
|
||||
this.log.push(`${target.mode}(${target.name})=${this._asString(value)}`);
|
||||
}
|
||||
|
||||
logBindingUpdate(target, value) {}
|
||||
|
||||
notifyAfterContentChecked() {}
|
||||
notifyAfterViewChecked() {}
|
||||
|
||||
getDebugContext(a, b) { return null; }
|
||||
|
||||
_asString(value) { return (isBlank(value) ? 'null' : value.toString()); }
|
||||
}
|
||||
|
||||
export class TestPipes implements Pipes {
|
||||
get(type: string) { return null; }
|
||||
}
|
@ -1,560 +0,0 @@
|
||||
import {
|
||||
ddescribe,
|
||||
describe,
|
||||
xdescribe,
|
||||
it,
|
||||
iit,
|
||||
xit,
|
||||
expect,
|
||||
beforeEach,
|
||||
afterEach,
|
||||
AsyncTestCompleter,
|
||||
inject,
|
||||
beforeEachBindings
|
||||
} from 'angular2/test_lib';
|
||||
|
||||
import {CONST_EXPR, stringify, isType, Type, isBlank} from 'angular2/src/core/facade/lang';
|
||||
import {MapWrapper} from 'angular2/src/core/facade/collection';
|
||||
import {PromiseWrapper, Promise} from 'angular2/src/core/facade/async';
|
||||
import {TemplateParser} from 'angular2/src/compiler/template_parser';
|
||||
import {
|
||||
CommandVisitor,
|
||||
TextCmd,
|
||||
NgContentCmd,
|
||||
BeginElementCmd,
|
||||
BeginComponentCmd,
|
||||
EmbeddedTemplateCmd,
|
||||
TemplateCmd,
|
||||
visitAllCommands,
|
||||
CompiledTemplate
|
||||
} from 'angular2/src/core/linker/template_commands';
|
||||
import {CommandCompiler} from 'angular2/src/compiler/command_compiler';
|
||||
import {
|
||||
CompileDirectiveMetadata,
|
||||
CompileTypeMetadata,
|
||||
CompileTemplateMetadata
|
||||
} from 'angular2/src/compiler/directive_metadata';
|
||||
import {SourceModule, SourceExpression, moduleRef} from 'angular2/src/compiler/source_module';
|
||||
import {ViewEncapsulation} from 'angular2/src/core/render/api';
|
||||
import {evalModule} from './eval_module';
|
||||
import {
|
||||
escapeSingleQuoteString,
|
||||
codeGenValueFn,
|
||||
codeGenExportVariable,
|
||||
MODULE_SUFFIX
|
||||
} from 'angular2/src/compiler/util';
|
||||
import {TEST_BINDINGS} from './test_bindings';
|
||||
|
||||
const BEGIN_ELEMENT = 'BEGIN_ELEMENT';
|
||||
const END_ELEMENT = 'END_ELEMENT';
|
||||
const BEGIN_COMPONENT = 'BEGIN_COMPONENT';
|
||||
const END_COMPONENT = 'END_COMPONENT';
|
||||
const TEXT = 'TEXT';
|
||||
const NG_CONTENT = 'NG_CONTENT';
|
||||
const EMBEDDED_TEMPLATE = 'EMBEDDED_TEMPLATE';
|
||||
|
||||
// Attention: These module names have to correspond to real modules!
|
||||
var THIS_MODULE_URL = `package:angular2/test/compiler/command_compiler_spec${MODULE_SUFFIX}`;
|
||||
var THIS_MODULE_REF = moduleRef(THIS_MODULE_URL);
|
||||
var TEMPLATE_COMMANDS_MODULE_REF =
|
||||
moduleRef(`package:angular2/src/core/linker/template_commands${MODULE_SUFFIX}`);
|
||||
|
||||
// Attention: read by eval!
|
||||
export class RootComp {}
|
||||
export class SomeDir {}
|
||||
export class AComp {}
|
||||
|
||||
var RootCompTypeMeta =
|
||||
new CompileTypeMetadata({name: 'RootComp', runtime: RootComp, moduleUrl: THIS_MODULE_URL});
|
||||
var SomeDirTypeMeta =
|
||||
new CompileTypeMetadata({name: 'SomeDir', runtime: SomeDir, moduleUrl: THIS_MODULE_URL});
|
||||
var ACompTypeMeta =
|
||||
new CompileTypeMetadata({name: 'AComp', runtime: AComp, moduleUrl: THIS_MODULE_URL});
|
||||
var compTypeTemplateId: Map<CompileTypeMetadata, number> =
|
||||
MapWrapper.createFromPairs([[RootCompTypeMeta, 1], [SomeDirTypeMeta, 2], [ACompTypeMeta, 3]]);
|
||||
const APP_ID = 'app1';
|
||||
|
||||
var NESTED_COMPONENT = new CompiledTemplate(45, () => []);
|
||||
|
||||
export function main() {
|
||||
describe('CommandCompiler', () => {
|
||||
beforeEachBindings(() => TEST_BINDINGS);
|
||||
|
||||
var parser: TemplateParser;
|
||||
var commandCompiler: CommandCompiler;
|
||||
var componentTemplateFactory: Function;
|
||||
|
||||
beforeEach(inject([TemplateParser, CommandCompiler], (_templateParser, _commandCompiler) => {
|
||||
parser = _templateParser;
|
||||
commandCompiler = _commandCompiler;
|
||||
}));
|
||||
|
||||
function createComp({type, selector, template, encapsulation, ngContentSelectors}: {
|
||||
type?: CompileTypeMetadata,
|
||||
selector?: string,
|
||||
template?: string,
|
||||
encapsulation?: ViewEncapsulation,
|
||||
ngContentSelectors?: string[]
|
||||
}): CompileDirectiveMetadata {
|
||||
if (isBlank(encapsulation)) {
|
||||
encapsulation = ViewEncapsulation.None;
|
||||
}
|
||||
if (isBlank(selector)) {
|
||||
selector = 'root';
|
||||
}
|
||||
if (isBlank(ngContentSelectors)) {
|
||||
ngContentSelectors = [];
|
||||
}
|
||||
if (isBlank(template)) {
|
||||
template = '';
|
||||
}
|
||||
return CompileDirectiveMetadata.create({
|
||||
selector: selector,
|
||||
isComponent: true,
|
||||
type: type,
|
||||
template: new CompileTemplateMetadata({
|
||||
template: template,
|
||||
ngContentSelectors: ngContentSelectors,
|
||||
encapsulation: encapsulation
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function createDirective(type: CompileTypeMetadata, selector: string, exportAs: string = null):
|
||||
CompileDirectiveMetadata {
|
||||
return CompileDirectiveMetadata.create(
|
||||
{selector: selector, exportAs: exportAs, isComponent: false, type: type});
|
||||
}
|
||||
|
||||
|
||||
function createTests(run: Function) {
|
||||
describe('text', () => {
|
||||
|
||||
it('should create unbound text commands', inject([AsyncTestCompleter], (async) => {
|
||||
var rootComp = createComp({type: RootCompTypeMeta, template: 'a'});
|
||||
run(rootComp, [])
|
||||
.then((data) => {
|
||||
expect(data).toEqual([[TEXT, 'a', false, null]]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should create bound text commands', inject([AsyncTestCompleter], (async) => {
|
||||
var rootComp = createComp({type: RootCompTypeMeta, template: '{{a}}'});
|
||||
run(rootComp, [])
|
||||
.then((data) => {
|
||||
expect(data).toEqual([[TEXT, null, true, null]]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
describe('elements', () => {
|
||||
|
||||
it('should create unbound element commands', inject([AsyncTestCompleter], (async) => {
|
||||
var rootComp = createComp({type: RootCompTypeMeta, template: '<div a="b">'});
|
||||
run(rootComp, [])
|
||||
.then((data) => {
|
||||
expect(data).toEqual([
|
||||
[BEGIN_ELEMENT, 'div', ['a', 'b'], [], [], [], false, null],
|
||||
[END_ELEMENT]
|
||||
]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should create bound element commands', inject([AsyncTestCompleter], (async) => {
|
||||
var rootComp = createComp({
|
||||
type: RootCompTypeMeta,
|
||||
template: '<div a="b" #some-var (click)="someHandler" (window:scroll)="scrollTo()">'
|
||||
});
|
||||
run(rootComp, [])
|
||||
.then((data) => {
|
||||
expect(data).toEqual([
|
||||
[
|
||||
BEGIN_ELEMENT,
|
||||
'div',
|
||||
['a', 'b'],
|
||||
[null, 'click', 'window', 'scroll'],
|
||||
['someVar', null],
|
||||
[],
|
||||
true,
|
||||
null
|
||||
],
|
||||
[END_ELEMENT]
|
||||
]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should create element commands with directives',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
var rootComp =
|
||||
createComp({type: RootCompTypeMeta, template: '<div a #some-var="someExport">'});
|
||||
var dir = CompileDirectiveMetadata.create({
|
||||
selector: '[a]',
|
||||
exportAs: 'someExport',
|
||||
isComponent: false,
|
||||
type: SomeDirTypeMeta,
|
||||
host: {'(click)': 'doIt()', '(window:scroll)': 'doIt()', 'role': 'button'}
|
||||
});
|
||||
run(rootComp, [dir])
|
||||
.then((data) => {
|
||||
expect(data).toEqual([
|
||||
[
|
||||
BEGIN_ELEMENT,
|
||||
'div',
|
||||
['a', '', 'role', 'button'],
|
||||
[null, 'click', 'window', 'scroll'],
|
||||
['someVar', 0],
|
||||
['SomeDirType'],
|
||||
true,
|
||||
null
|
||||
],
|
||||
[END_ELEMENT]
|
||||
]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should emulate style encapsulation', inject([AsyncTestCompleter], (async) => {
|
||||
var rootComp = createComp({
|
||||
type: RootCompTypeMeta,
|
||||
template: '<div>',
|
||||
encapsulation: ViewEncapsulation.Emulated
|
||||
});
|
||||
run(rootComp, [])
|
||||
.then((data) => {
|
||||
expect(data).toEqual([
|
||||
[BEGIN_ELEMENT, 'div', ['_ngcontent-app1-1', ''], [], [], [], false, null],
|
||||
[END_ELEMENT]
|
||||
]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should create nested nodes', inject([AsyncTestCompleter], (async) => {
|
||||
var rootComp = createComp({type: RootCompTypeMeta, template: '<div>a</div>'});
|
||||
run(rootComp, [])
|
||||
.then((data) => {
|
||||
expect(data).toEqual([
|
||||
[BEGIN_ELEMENT, 'div', [], [], [], [], false, null],
|
||||
[TEXT, 'a', false, null],
|
||||
[END_ELEMENT]
|
||||
]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
describe('components', () => {
|
||||
|
||||
it('should create component commands', inject([AsyncTestCompleter], (async) => {
|
||||
var rootComp = createComp(
|
||||
{type: RootCompTypeMeta, template: '<a a="b" #some-var (click)="someHandler">'});
|
||||
var comp = createComp({type: ACompTypeMeta, selector: 'a'});
|
||||
run(rootComp, [comp])
|
||||
.then((data) => {
|
||||
expect(data).toEqual([
|
||||
[
|
||||
BEGIN_COMPONENT,
|
||||
'a',
|
||||
['a', 'b'],
|
||||
[null, 'click'],
|
||||
['someVar', 0],
|
||||
['ACompType'],
|
||||
false,
|
||||
null,
|
||||
3
|
||||
],
|
||||
[END_COMPONENT]
|
||||
]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should emulate style encapsulation on host elements',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
var rootComp = createComp({
|
||||
type: RootCompTypeMeta,
|
||||
template: '<a></a>',
|
||||
encapsulation: ViewEncapsulation.Emulated
|
||||
});
|
||||
var comp = createComp(
|
||||
{type: ACompTypeMeta, selector: 'a', encapsulation: ViewEncapsulation.Emulated});
|
||||
run(rootComp, [comp])
|
||||
.then((data) => {
|
||||
expect(data).toEqual([
|
||||
[
|
||||
BEGIN_COMPONENT,
|
||||
'a',
|
||||
['_nghost-app1-3', '', '_ngcontent-app1-1', ''],
|
||||
[],
|
||||
[],
|
||||
['ACompType'],
|
||||
false,
|
||||
null,
|
||||
3
|
||||
],
|
||||
[END_COMPONENT]
|
||||
]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should set nativeShadow flag', inject([AsyncTestCompleter], (async) => {
|
||||
var rootComp = createComp({type: RootCompTypeMeta, template: '<a></a>'});
|
||||
var comp = createComp(
|
||||
{type: ACompTypeMeta, selector: 'a', encapsulation: ViewEncapsulation.Native});
|
||||
run(rootComp, [comp])
|
||||
.then((data) => {
|
||||
expect(data).toEqual([
|
||||
[BEGIN_COMPONENT, 'a', [], [], [], ['ACompType'], true, null, 3],
|
||||
[END_COMPONENT]
|
||||
]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should create nested nodes and set ngContentIndex',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
var rootComp = createComp({type: RootCompTypeMeta, template: '<a>t</a>'});
|
||||
var comp = createComp({type: ACompTypeMeta, selector: 'a', ngContentSelectors: ['*']});
|
||||
run(rootComp, [comp])
|
||||
.then((data) => {
|
||||
expect(data).toEqual([
|
||||
[BEGIN_COMPONENT, 'a', [], [], [], ['ACompType'], false, null, 3],
|
||||
[TEXT, 't', false, 0],
|
||||
[END_COMPONENT]
|
||||
]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
describe('embedded templates', () => {
|
||||
it('should create embedded template commands', inject([AsyncTestCompleter], (async) => {
|
||||
var rootComp =
|
||||
createComp({type: RootCompTypeMeta, template: '<template a="b"></template>'});
|
||||
var dir = createDirective(SomeDirTypeMeta, '[a]');
|
||||
run(rootComp, [dir], 1)
|
||||
.then((data) => {
|
||||
expect(data).toEqual([
|
||||
[EMBEDDED_TEMPLATE, ['a', 'b'], [], ['SomeDirType'], false, null, 'cd1', []]
|
||||
]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should keep variable name and value for <template> elements',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
var rootComp = createComp({
|
||||
type: RootCompTypeMeta,
|
||||
template: '<template #some-var="someValue" #some-empty-var></template>'
|
||||
});
|
||||
var dir = createDirective(SomeDirTypeMeta, '[a]');
|
||||
run(rootComp, [dir], 1)
|
||||
.then((data) => {
|
||||
expect(data[0][2])
|
||||
.toEqual(['someEmptyVar', '$implicit', 'someVar', 'someValue']);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should keep variable name and value for template attributes',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
var rootComp = createComp({
|
||||
type: RootCompTypeMeta,
|
||||
template: '<div template="var someVar=someValue; var someEmptyVar"></div>'
|
||||
});
|
||||
var dir = createDirective(SomeDirTypeMeta, '[a]');
|
||||
run(rootComp, [dir], 1)
|
||||
.then((data) => {
|
||||
expect(data[0][2])
|
||||
.toEqual(['someVar', 'someValue', 'someEmptyVar', '$implicit']);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should created nested nodes', inject([AsyncTestCompleter], (async) => {
|
||||
var rootComp =
|
||||
createComp({type: RootCompTypeMeta, template: '<template>t</template>'});
|
||||
run(rootComp, [], 1)
|
||||
.then((data) => {
|
||||
expect(data).toEqual([
|
||||
[
|
||||
EMBEDDED_TEMPLATE,
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
false,
|
||||
null,
|
||||
'cd1',
|
||||
[[TEXT, 't', false, null]]
|
||||
]
|
||||
]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should calculate wether the template is merged based on nested ng-content elements',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
var rootComp = createComp({
|
||||
type: RootCompTypeMeta,
|
||||
template: '<template><ng-content></ng-content></template>'
|
||||
});
|
||||
run(rootComp, [], 1)
|
||||
.then((data) => {
|
||||
expect(data).toEqual(
|
||||
[[EMBEDDED_TEMPLATE, [], [], [], true, null, 'cd1', [[NG_CONTENT, null]]]]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
describe('ngContent', () => {
|
||||
it('should create ng-content commands', inject([AsyncTestCompleter], (async) => {
|
||||
var rootComp =
|
||||
createComp({type: RootCompTypeMeta, template: '<ng-content></ng-content>'});
|
||||
run(rootComp, [])
|
||||
.then((data) => {
|
||||
expect(data).toEqual([[NG_CONTENT, null]]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
describe('compileComponentRuntime', () => {
|
||||
beforeEach(() => {
|
||||
componentTemplateFactory = (directive: CompileDirectiveMetadata) => {
|
||||
return new CompiledTemplate(compTypeTemplateId.get(directive.type), () => []);
|
||||
};
|
||||
});
|
||||
|
||||
function run(component: CompileDirectiveMetadata, directives: CompileDirectiveMetadata[],
|
||||
embeddedTemplateCount: number = 0): Promise<any[][]> {
|
||||
var changeDetectorFactories = [];
|
||||
for (var i = 0; i < embeddedTemplateCount + 1; i++) {
|
||||
(function(i) { changeDetectorFactories.push((_) => `cd${i}`); })(i);
|
||||
}
|
||||
var parsedTemplate =
|
||||
parser.parse(component.template.template, directives, component.type.name);
|
||||
var commands = commandCompiler.compileComponentRuntime(
|
||||
component, APP_ID, compTypeTemplateId.get(component.type), parsedTemplate,
|
||||
changeDetectorFactories, componentTemplateFactory);
|
||||
return PromiseWrapper.resolve(humanize(commands));
|
||||
}
|
||||
|
||||
createTests(run);
|
||||
});
|
||||
|
||||
|
||||
describe('compileComponentCodeGen', () => {
|
||||
beforeEach(() => {
|
||||
componentTemplateFactory = (directive: CompileDirectiveMetadata) => {
|
||||
return `new ${TEMPLATE_COMMANDS_MODULE_REF}CompiledTemplate(${compTypeTemplateId.get(directive.type)}, ${codeGenValueFn([], '{}')})`;
|
||||
};
|
||||
});
|
||||
|
||||
function run(component: CompileDirectiveMetadata, directives: CompileDirectiveMetadata[],
|
||||
embeddedTemplateCount: number = 0): Promise<any[][]> {
|
||||
var changeDetectorFactoryExpressions = [];
|
||||
for (var i = 0; i < embeddedTemplateCount + 1; i++) {
|
||||
changeDetectorFactoryExpressions.push(codeGenValueFn(['_'], `'cd${i}'`));
|
||||
}
|
||||
var parsedTemplate =
|
||||
parser.parse(component.template.template, directives, component.type.name);
|
||||
var sourceModule = commandCompiler.compileComponentCodeGen(
|
||||
component, `'${APP_ID}'`, `${compTypeTemplateId.get(component.type)}`, parsedTemplate,
|
||||
changeDetectorFactoryExpressions, componentTemplateFactory);
|
||||
var testableModule = createTestableModule(sourceModule).getSourceWithImports();
|
||||
return evalModule(testableModule.source, testableModule.imports, null);
|
||||
}
|
||||
|
||||
createTests(run);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
// Attention: read by eval!
|
||||
export function humanize(cmds: TemplateCmd[]): any[][] {
|
||||
var visitor = new CommandHumanizer();
|
||||
visitAllCommands(visitor, cmds);
|
||||
return visitor.result;
|
||||
}
|
||||
|
||||
function checkAndStringifyType(type: Type): string {
|
||||
expect(isType(type)).toBe(true);
|
||||
return `${stringify(type)}Type`;
|
||||
}
|
||||
|
||||
class CommandHumanizer implements CommandVisitor {
|
||||
result: any[][] = [];
|
||||
visitText(cmd: TextCmd, context: any): any {
|
||||
this.result.push([TEXT, cmd.value, cmd.isBound, cmd.ngContentIndex]);
|
||||
return null;
|
||||
}
|
||||
visitNgContent(cmd: NgContentCmd, context: any): any {
|
||||
this.result.push([NG_CONTENT, cmd.ngContentIndex]);
|
||||
return null;
|
||||
}
|
||||
visitBeginElement(cmd: BeginElementCmd, context: any): any {
|
||||
this.result.push([
|
||||
BEGIN_ELEMENT,
|
||||
cmd.name,
|
||||
cmd.attrNameAndValues,
|
||||
cmd.eventTargetAndNames,
|
||||
cmd.variableNameAndValues,
|
||||
cmd.directives.map(checkAndStringifyType),
|
||||
cmd.isBound,
|
||||
cmd.ngContentIndex
|
||||
]);
|
||||
return null;
|
||||
}
|
||||
visitEndElement(context: any): any {
|
||||
this.result.push([END_ELEMENT]);
|
||||
return null;
|
||||
}
|
||||
visitBeginComponent(cmd: BeginComponentCmd, context: any): any {
|
||||
this.result.push([
|
||||
BEGIN_COMPONENT,
|
||||
cmd.name,
|
||||
cmd.attrNameAndValues,
|
||||
cmd.eventTargetAndNames,
|
||||
cmd.variableNameAndValues,
|
||||
cmd.directives.map(checkAndStringifyType),
|
||||
cmd.nativeShadow,
|
||||
cmd.ngContentIndex,
|
||||
cmd.template.id
|
||||
]);
|
||||
return null;
|
||||
}
|
||||
visitEndComponent(context: any): any {
|
||||
this.result.push([END_COMPONENT]);
|
||||
return null;
|
||||
}
|
||||
visitEmbeddedTemplate(cmd: EmbeddedTemplateCmd, context: any): any {
|
||||
this.result.push([
|
||||
EMBEDDED_TEMPLATE,
|
||||
cmd.attrNameAndValues,
|
||||
cmd.variableNameAndValues,
|
||||
cmd.directives.map(checkAndStringifyType),
|
||||
cmd.isMerged,
|
||||
cmd.ngContentIndex,
|
||||
cmd.changeDetectorFactory(null),
|
||||
humanize(cmd.children)
|
||||
]);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function createTestableModule(source: SourceExpression): SourceModule {
|
||||
var resultExpression = `${THIS_MODULE_REF}humanize(${source.expression})`;
|
||||
var testableSource = `${source.declarations.join('\n')}
|
||||
${codeGenExportVariable('run')}${codeGenValueFn(['_'], resultExpression)};`;
|
||||
return new SourceModule(null, testableSource);
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
import {
|
||||
AsyncTestCompleter,
|
||||
beforeEach,
|
||||
ddescribe,
|
||||
describe,
|
||||
el,
|
||||
expect,
|
||||
iit,
|
||||
inject,
|
||||
it,
|
||||
xit,
|
||||
TestComponentBuilder
|
||||
} from 'angular2/test_lib';
|
||||
|
||||
import {
|
||||
CompileDirectiveMetadata,
|
||||
CompileTypeMetadata,
|
||||
CompileTemplateMetadata
|
||||
} from 'angular2/src/compiler/directive_metadata';
|
||||
import {ViewEncapsulation} from 'angular2/src/core/render/api';
|
||||
import {ChangeDetectionStrategy} from 'angular2/src/core/change_detection';
|
||||
import {LifecycleHooks} from 'angular2/src/core/linker/interfaces';
|
||||
|
||||
export function main() {
|
||||
describe('DirectiveMetadata', () => {
|
||||
var fullTypeMeta: CompileTypeMetadata;
|
||||
var fullTemplateMeta: CompileTemplateMetadata;
|
||||
var fullDirectiveMeta: CompileDirectiveMetadata;
|
||||
|
||||
beforeEach(() => {
|
||||
fullTypeMeta =
|
||||
new CompileTypeMetadata({name: 'SomeType', moduleUrl: 'someUrl', isHost: true});
|
||||
fullTemplateMeta = new CompileTemplateMetadata({
|
||||
encapsulation: ViewEncapsulation.Emulated,
|
||||
template: '<a></a>',
|
||||
templateUrl: 'someTemplateUrl',
|
||||
styles: ['someStyle'],
|
||||
styleUrls: ['someStyleUrl'],
|
||||
ngContentSelectors: ['*']
|
||||
});
|
||||
fullDirectiveMeta = CompileDirectiveMetadata.create({
|
||||
selector: 'someSelector',
|
||||
isComponent: true,
|
||||
dynamicLoadable: true,
|
||||
type: fullTypeMeta, template: fullTemplateMeta,
|
||||
changeDetection: ChangeDetectionStrategy.Default,
|
||||
inputs: ['someProp'],
|
||||
outputs: ['someEvent'],
|
||||
host: {'(event1)': 'handler1', '[prop1]': 'expr1', 'attr1': 'attrValue2'},
|
||||
lifecycleHooks: [LifecycleHooks.OnChanges]
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('DirectiveMetadata', () => {
|
||||
it('should serialize with full data', () => {
|
||||
expect(CompileDirectiveMetadata.fromJson(fullDirectiveMeta.toJson()))
|
||||
.toEqual(fullDirectiveMeta);
|
||||
});
|
||||
|
||||
it('should serialize with no data', () => {
|
||||
var empty = CompileDirectiveMetadata.create();
|
||||
expect(CompileDirectiveMetadata.fromJson(empty.toJson())).toEqual(empty);
|
||||
});
|
||||
});
|
||||
|
||||
describe('TypeMetadata', () => {
|
||||
it('should serialize with full data', () => {
|
||||
expect(CompileTypeMetadata.fromJson(fullTypeMeta.toJson())).toEqual(fullTypeMeta);
|
||||
});
|
||||
|
||||
it('should serialize with no data', () => {
|
||||
var empty = new CompileTypeMetadata();
|
||||
expect(CompileTypeMetadata.fromJson(empty.toJson())).toEqual(empty);
|
||||
});
|
||||
});
|
||||
|
||||
describe('TemplateMetadata', () => {
|
||||
it('should serialize with full data', () => {
|
||||
expect(CompileTemplateMetadata.fromJson(fullTemplateMeta.toJson()))
|
||||
.toEqual(fullTemplateMeta);
|
||||
});
|
||||
|
||||
it('should serialize with no data', () => {
|
||||
var empty = new CompileTemplateMetadata();
|
||||
expect(CompileTemplateMetadata.fromJson(empty.toJson())).toEqual(empty);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
import "dart:isolate";
|
||||
import "dart:async";
|
||||
|
||||
Uri toDartDataUri(String source) {
|
||||
return Uri.parse("data:application/dart;charset=utf-8,"
|
||||
"${Uri.encodeComponent(source)}");
|
||||
}
|
||||
|
||||
createIsolateSource(String moduleSource, List<List<String>> moduleImports) {
|
||||
var moduleSourceParts = ['import "dart:isolate";'];
|
||||
moduleImports.forEach((sourceImport) {
|
||||
String modName = sourceImport[0];
|
||||
String modAlias = sourceImport[1];
|
||||
moduleSourceParts.add("import '${modName}' as ${modAlias};");
|
||||
});
|
||||
moduleSourceParts.add(moduleSource);
|
||||
moduleSourceParts.add("""
|
||||
main(List args, SendPort replyPort) {
|
||||
replyPort.send(run(args));
|
||||
}
|
||||
""");
|
||||
return moduleSourceParts.join('\n');
|
||||
}
|
||||
|
||||
var timeStamp = new DateTime.now().millisecondsSinceEpoch;
|
||||
|
||||
dynamic callModule(dynamic data) { return data.map( (a) => a+1); }
|
||||
|
||||
evalModule(String moduleSource, List<List<String>> imports, List args) {
|
||||
String source = createIsolateSource(moduleSource, imports);
|
||||
Completer completer = new Completer();
|
||||
RawReceivePort receivePort;
|
||||
receivePort = new RawReceivePort( (message) {
|
||||
receivePort.close();
|
||||
completer.complete(message);
|
||||
});
|
||||
// Note: we have a special karma plugin that sends files under
|
||||
// urls like /package_1234 as permanently cached.
|
||||
// With this, spawning multiple isolates gets faster as Darts does not
|
||||
// reload the files from the server.
|
||||
var packageRoot = Uri.parse('/packages_${timeStamp}');
|
||||
return Isolate.spawnUri(toDartDataUri(source), args, receivePort.sendPort, packageRoot: packageRoot).then( (isolate) {
|
||||
RawReceivePort errorPort;
|
||||
errorPort = new RawReceivePort( (message) {
|
||||
completer.completeError(message);
|
||||
});
|
||||
isolate.addErrorListener(errorPort.sendPort);
|
||||
return completer.future;
|
||||
});
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
import {Promise, PromiseWrapper} from 'angular2/src/core/facade/async';
|
||||
import {isPresent, global, StringWrapper} from 'angular2/src/core/facade/lang';
|
||||
|
||||
var evalCounter = 0;
|
||||
var MODULE_URL_REGEX = /^package:(.*)\.js/;
|
||||
|
||||
function nextModuleId() {
|
||||
return `evalScript${evalCounter++}`;
|
||||
}
|
||||
|
||||
export function evalModule(moduleSource: string, imports: string[][], args: any[]): Promise<any> {
|
||||
var moduleId = nextModuleId();
|
||||
var moduleSourceWithImports = [];
|
||||
var importModuleIds = [];
|
||||
imports.forEach(sourceImport => {
|
||||
var modUrl = sourceImport[0];
|
||||
var modMatch = MODULE_URL_REGEX.exec(modUrl);
|
||||
if (!modMatch) {
|
||||
throw new Error(`Module url ${modUrl} does not match the pattern ${MODULE_URL_REGEX}`);
|
||||
}
|
||||
var modId = modMatch[1];
|
||||
|
||||
var modAlias = sourceImport[1];
|
||||
importModuleIds.push(modId);
|
||||
// Note: After transpilation to commonJS and loading this file in a browser
|
||||
// using SystemJS, the loader might get confused by the presence of require,
|
||||
// and attempt to load "+ modName +.js" !?!
|
||||
// A simple string concat manages to prevent that, but that is one compiler
|
||||
// optimaztion away from breaking again. Proceed with caution!
|
||||
moduleSourceWithImports.push(`var ${modAlias} = require` + `('${modId}');`);
|
||||
});
|
||||
moduleSourceWithImports.push(moduleSource);
|
||||
|
||||
var moduleBody = new Function('require', 'exports', 'module', moduleSourceWithImports.join('\n'));
|
||||
var System = global['System'];
|
||||
if (isPresent(System) && isPresent(System.registerDynamic)) {
|
||||
System.registerDynamic(moduleId, importModuleIds, false, moduleBody);
|
||||
return <Promise<any>>System.import(moduleId).then((module) => module.run(args));
|
||||
} else {
|
||||
var exports = {};
|
||||
moduleBody(require, exports, {});
|
||||
return PromiseWrapper.resolve(exports['run'](args));
|
||||
}
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
import {
|
||||
ddescribe,
|
||||
describe,
|
||||
xdescribe,
|
||||
it,
|
||||
iit,
|
||||
xit,
|
||||
expect,
|
||||
beforeEach,
|
||||
afterEach,
|
||||
AsyncTestCompleter,
|
||||
inject
|
||||
} from 'angular2/test_lib';
|
||||
import {IS_DART} from '../platform';
|
||||
|
||||
import {evalModule} from './eval_module';
|
||||
|
||||
// This export is used by this test code
|
||||
// when evaling the test module!
|
||||
export var TEST_VALUE = 23;
|
||||
|
||||
const THIS_MODULE_URL = `package:angular2/test/compiler/eval_module_spec${IS_DART?'.dart':'.js'}`;
|
||||
|
||||
export function main() {
|
||||
describe('evalModule', () => {
|
||||
it('should call the "run" function and allow to use imports',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
var moduleSource = IS_DART ? testDartModule : testJsModule;
|
||||
evalModule(moduleSource, [[THIS_MODULE_URL, 'tst']], [1])
|
||||
.then((value) => {
|
||||
expect(value).toEqual([1, 23]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
var testDartModule = `
|
||||
run(data) {
|
||||
data.add(tst.TEST_VALUE);
|
||||
return data;
|
||||
}
|
||||
`;
|
||||
|
||||
var testJsModule = `
|
||||
exports.run = function(data) {
|
||||
data.push(tst.TEST_VALUE);
|
||||
return data;
|
||||
}
|
||||
`;
|
@ -1,131 +0,0 @@
|
||||
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/test_lib';
|
||||
|
||||
import {HtmlParser} from 'angular2/src/compiler/html_parser';
|
||||
import {
|
||||
HtmlAst,
|
||||
HtmlAstVisitor,
|
||||
HtmlElementAst,
|
||||
HtmlAttrAst,
|
||||
HtmlTextAst,
|
||||
htmlVisitAll
|
||||
} from 'angular2/src/compiler/html_ast';
|
||||
|
||||
export function main() {
|
||||
describe('DomParser', () => {
|
||||
var parser: HtmlParser;
|
||||
beforeEach(() => { parser = new HtmlParser(); });
|
||||
|
||||
describe('parse', () => {
|
||||
|
||||
describe('text nodes', () => {
|
||||
it('should parse root level text nodes', () => {
|
||||
expect(humanizeDom(parser.parse('a', 'TestComp')))
|
||||
.toEqual([[HtmlTextAst, 'a', 'TestComp > #text(a):nth-child(0)']]);
|
||||
});
|
||||
|
||||
it('should parse text nodes inside regular elements', () => {
|
||||
expect(humanizeDom(parser.parse('<div>a</div>', 'TestComp')))
|
||||
.toEqual([
|
||||
[HtmlElementAst, 'div', 'TestComp > div:nth-child(0)'],
|
||||
[HtmlTextAst, 'a', 'TestComp > div:nth-child(0) > #text(a):nth-child(0)']
|
||||
]);
|
||||
});
|
||||
|
||||
it('should parse text nodes inside template elements', () => {
|
||||
expect(humanizeDom(parser.parse('<template>a</template>', 'TestComp')))
|
||||
.toEqual([
|
||||
[HtmlElementAst, 'template', 'TestComp > template:nth-child(0)'],
|
||||
[HtmlTextAst, 'a', 'TestComp > template:nth-child(0) > #text(a):nth-child(0)']
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('elements', () => {
|
||||
it('should parse root level elements', () => {
|
||||
expect(humanizeDom(parser.parse('<div></div>', 'TestComp')))
|
||||
.toEqual([[HtmlElementAst, 'div', 'TestComp > div:nth-child(0)']]);
|
||||
});
|
||||
|
||||
it('should parse elements inside of regular elements', () => {
|
||||
expect(humanizeDom(parser.parse('<div><span></span></div>', 'TestComp')))
|
||||
.toEqual([
|
||||
[HtmlElementAst, 'div', 'TestComp > div:nth-child(0)'],
|
||||
[HtmlElementAst, 'span', 'TestComp > div:nth-child(0) > span:nth-child(0)']
|
||||
]);
|
||||
});
|
||||
|
||||
it('should parse elements inside of template elements', () => {
|
||||
expect(humanizeDom(parser.parse('<template><span></span></template>', 'TestComp')))
|
||||
.toEqual([
|
||||
[HtmlElementAst, 'template', 'TestComp > template:nth-child(0)'],
|
||||
[HtmlElementAst, 'span', 'TestComp > template:nth-child(0) > span:nth-child(0)']
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('attributes', () => {
|
||||
it('should parse attributes on regular elements', () => {
|
||||
expect(humanizeDom(parser.parse('<div k="v"></div>', 'TestComp')))
|
||||
.toEqual([
|
||||
[HtmlElementAst, 'div', 'TestComp > div:nth-child(0)'],
|
||||
[HtmlAttrAst, 'k', 'v', 'TestComp > div:nth-child(0)[k=v]']
|
||||
]);
|
||||
});
|
||||
|
||||
it('should parse attributes on template elements', () => {
|
||||
expect(humanizeDom(parser.parse('<template k="v"></template>', 'TestComp')))
|
||||
.toEqual([
|
||||
[HtmlElementAst, 'template', 'TestComp > template:nth-child(0)'],
|
||||
[HtmlAttrAst, 'k', 'v', 'TestComp > template:nth-child(0)[k=v]']
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('unparse', () => {
|
||||
it('should unparse text nodes',
|
||||
() => { expect(parser.unparse(parser.parse('a', null))).toEqual('a'); });
|
||||
|
||||
it('should unparse elements',
|
||||
() => { expect(parser.unparse(parser.parse('<a></a>', null))).toEqual('<a></a>'); });
|
||||
|
||||
it('should unparse attributes', () => {
|
||||
expect(parser.unparse(parser.parse('<div a b="c"></div>', null)))
|
||||
.toEqual('<div a="" b="c"></div>');
|
||||
});
|
||||
|
||||
it('should unparse nested elements', () => {
|
||||
expect(parser.unparse(parser.parse('<div><a></a></div>', null)))
|
||||
.toEqual('<div><a></a></div>');
|
||||
});
|
||||
|
||||
it('should unparse nested text nodes', () => {
|
||||
expect(parser.unparse(parser.parse('<div>a</div>', null))).toEqual('<div>a</div>');
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function humanizeDom(asts: HtmlAst[]): any[] {
|
||||
var humanizer = new Humanizer();
|
||||
htmlVisitAll(humanizer, asts);
|
||||
return humanizer.result;
|
||||
}
|
||||
|
||||
class Humanizer implements HtmlAstVisitor {
|
||||
result: any[] = [];
|
||||
visitElement(ast: HtmlElementAst, context: any): any {
|
||||
this.result.push([HtmlElementAst, ast.name, ast.sourceInfo]);
|
||||
htmlVisitAll(this, ast.attrs);
|
||||
htmlVisitAll(this, ast.children);
|
||||
return null;
|
||||
}
|
||||
visitAttr(ast: HtmlAttrAst, context: any): any {
|
||||
this.result.push([HtmlAttrAst, ast.name, ast.value, ast.sourceInfo]);
|
||||
return null;
|
||||
}
|
||||
visitText(ast: HtmlTextAst, context: any): any {
|
||||
this.result.push([HtmlTextAst, ast.value, ast.sourceInfo]);
|
||||
return null;
|
||||
}
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
import {
|
||||
ddescribe,
|
||||
describe,
|
||||
xdescribe,
|
||||
it,
|
||||
iit,
|
||||
xit,
|
||||
expect,
|
||||
beforeEach,
|
||||
afterEach,
|
||||
AsyncTestCompleter,
|
||||
inject,
|
||||
beforeEachBindings
|
||||
} from 'angular2/test_lib';
|
||||
|
||||
import {Component, View, bind} from 'angular2/core';
|
||||
import {PromiseWrapper} from 'angular2/src/core/facade/async';
|
||||
import {SpyProtoViewFactory} from '../core/spies';
|
||||
import {
|
||||
CompiledHostTemplate,
|
||||
CompiledTemplate,
|
||||
BeginComponentCmd
|
||||
} from 'angular2/src/core/linker/template_commands';
|
||||
import {RuntimeCompiler} from 'angular2/src/compiler/runtime_compiler';
|
||||
import {ProtoViewFactory} from 'angular2/src/core/linker/proto_view_factory';
|
||||
import {AppProtoView} from 'angular2/src/core/linker/view';
|
||||
|
||||
export function main() {
|
||||
describe('RuntimeCompiler', () => {
|
||||
var compiler: RuntimeCompiler;
|
||||
|
||||
beforeEach(inject([RuntimeCompiler], (_compiler) => { compiler = _compiler; }));
|
||||
|
||||
describe('compileInHost', () => {
|
||||
var protoViewFactorySpy;
|
||||
var someProtoView;
|
||||
|
||||
beforeEachBindings(() => {
|
||||
protoViewFactorySpy = new SpyProtoViewFactory();
|
||||
someProtoView = new AppProtoView(null, null, null, null, null, null);
|
||||
protoViewFactorySpy.spy('createHost').andReturn(someProtoView);
|
||||
return [bind(ProtoViewFactory).toValue(protoViewFactorySpy)];
|
||||
});
|
||||
|
||||
it('should compile the template via TemplateCompiler',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
var cht: CompiledHostTemplate;
|
||||
protoViewFactorySpy.spy('createHost')
|
||||
.andCallFake((_cht) => {
|
||||
cht = _cht;
|
||||
return someProtoView;
|
||||
});
|
||||
compiler.compileInHost(SomeComponent)
|
||||
.then((_) => {
|
||||
var beginComponentCmd =
|
||||
<BeginComponentCmd>cht.getTemplate().getData('app1').commands[0];
|
||||
expect(beginComponentCmd.name).toEqual('some-comp');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
|
||||
it('should cache the result', inject([AsyncTestCompleter], (async) => {
|
||||
PromiseWrapper
|
||||
.all([compiler.compileInHost(SomeComponent), compiler.compileInHost(SomeComponent)])
|
||||
.then((protoViewRefs) => {
|
||||
expect(protoViewRefs[0]).toBe(protoViewRefs[1]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should clear the cache',
|
||||
inject([AsyncTestCompleter], (async) => {compiler.compileInHost(SomeComponent)
|
||||
.then((protoViewRef1) => {
|
||||
compiler.clearCache();
|
||||
compiler.compileInHost(SomeComponent)
|
||||
.then((protoViewRef2) => {
|
||||
expect(protoViewRef1)
|
||||
.not.toBe(protoViewRef2);
|
||||
async.done();
|
||||
});
|
||||
})}));
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@Component({selector: 'some-comp'})
|
||||
@View({template: ''})
|
||||
class SomeComponent {
|
||||
}
|
@ -1,127 +0,0 @@
|
||||
import {
|
||||
ddescribe,
|
||||
describe,
|
||||
xdescribe,
|
||||
it,
|
||||
iit,
|
||||
xit,
|
||||
expect,
|
||||
beforeEach,
|
||||
afterEach,
|
||||
AsyncTestCompleter,
|
||||
inject,
|
||||
beforeEachBindings
|
||||
} from 'angular2/test_lib';
|
||||
|
||||
import {stringify} from 'angular2/src/core/facade/lang';
|
||||
import {RuntimeMetadataResolver} from 'angular2/src/compiler/runtime_metadata';
|
||||
import {LifecycleHooks, LIFECYCLE_HOOKS_VALUES} from 'angular2/src/core/linker/interfaces';
|
||||
import {
|
||||
Component,
|
||||
View,
|
||||
Directive,
|
||||
ViewEncapsulation,
|
||||
ChangeDetectionStrategy,
|
||||
OnChanges,
|
||||
OnInit,
|
||||
DoCheck,
|
||||
OnDestroy,
|
||||
AfterContentInit,
|
||||
AfterContentChecked,
|
||||
AfterViewInit,
|
||||
AfterViewChecked,
|
||||
SimpleChange
|
||||
} from 'angular2/core';
|
||||
|
||||
import {TEST_BINDINGS} from './test_bindings';
|
||||
import {MODULE_SUFFIX, IS_DART} from 'angular2/src/compiler/util';
|
||||
|
||||
export function main() {
|
||||
describe('RuntimeMetadataResolver', () => {
|
||||
beforeEachBindings(() => TEST_BINDINGS);
|
||||
|
||||
describe('getMetadata', () => {
|
||||
it('should read metadata',
|
||||
inject([RuntimeMetadataResolver], (resolver: RuntimeMetadataResolver) => {
|
||||
var meta = resolver.getMetadata(ComponentWithEverything);
|
||||
expect(meta.selector).toEqual('someSelector');
|
||||
expect(meta.exportAs).toEqual('someExportAs');
|
||||
expect(meta.isComponent).toBe(true);
|
||||
expect(meta.dynamicLoadable).toBe(true);
|
||||
expect(meta.type.runtime).toBe(ComponentWithEverything);
|
||||
expect(meta.type.name).toEqual(stringify(ComponentWithEverything));
|
||||
expect(meta.type.moduleUrl).toEqual(`package:someModuleId${MODULE_SUFFIX}`);
|
||||
expect(meta.lifecycleHooks).toEqual(LIFECYCLE_HOOKS_VALUES);
|
||||
expect(meta.changeDetection).toBe(ChangeDetectionStrategy.CheckAlways);
|
||||
expect(meta.inputs).toEqual({'someProp': 'someProp'});
|
||||
expect(meta.outputs).toEqual({'someEvent': 'someEvent'});
|
||||
expect(meta.hostListeners).toEqual({'someHostListener': 'someHostListenerExpr'});
|
||||
expect(meta.hostProperties).toEqual({'someHostProp': 'someHostPropExpr'});
|
||||
expect(meta.hostAttributes).toEqual({'someHostAttr': 'someHostAttrValue'});
|
||||
expect(meta.template.encapsulation).toBe(ViewEncapsulation.Emulated);
|
||||
expect(meta.template.styles).toEqual(['someStyle']);
|
||||
expect(meta.template.styleUrls).toEqual(['someStyleUrl']);
|
||||
expect(meta.template.template).toEqual('someTemplate');
|
||||
expect(meta.template.templateUrl).toEqual('someTemplateUrl');
|
||||
}));
|
||||
|
||||
it('should use the moduleUrl from the reflector if none is given',
|
||||
inject([RuntimeMetadataResolver], (resolver: RuntimeMetadataResolver) => {
|
||||
var value: string = resolver.getMetadata(DirectiveWithoutModuleId).type.moduleUrl;
|
||||
var expectedEndValue =
|
||||
IS_DART ? 'base/dist/dart/angular2/test/compiler/runtime_metadata_spec.dart' : './';
|
||||
expect((<any>value).endsWith(expectedEndValue)).toBe(true);
|
||||
}));
|
||||
});
|
||||
|
||||
describe('getViewDirectivesMetadata', () => {
|
||||
|
||||
it('should return the directive metadatas',
|
||||
inject([RuntimeMetadataResolver], (resolver: RuntimeMetadataResolver) => {
|
||||
expect(resolver.getViewDirectivesMetadata(ComponentWithEverything))
|
||||
.toEqual([resolver.getMetadata(DirectiveWithoutModuleId)]);
|
||||
}));
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Directive({selector: 'someSelector'})
|
||||
class DirectiveWithoutModuleId {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'someSelector',
|
||||
inputs: ['someProp'],
|
||||
outputs: ['someEvent'],
|
||||
host: {
|
||||
'[someHostProp]': 'someHostPropExpr',
|
||||
'(someHostListener)': 'someHostListenerExpr',
|
||||
'someHostAttr': 'someHostAttrValue'
|
||||
},
|
||||
exportAs: 'someExportAs',
|
||||
moduleId: 'someModuleId',
|
||||
changeDetection: ChangeDetectionStrategy.CheckAlways
|
||||
})
|
||||
@View({
|
||||
template: 'someTemplate',
|
||||
templateUrl: 'someTemplateUrl',
|
||||
encapsulation: ViewEncapsulation.Emulated,
|
||||
styles: ['someStyle'],
|
||||
styleUrls: ['someStyleUrl'],
|
||||
directives: [DirectiveWithoutModuleId]
|
||||
})
|
||||
class ComponentWithEverything implements OnChanges,
|
||||
OnInit, DoCheck, OnDestroy, AfterContentInit, AfterContentChecked, AfterViewInit,
|
||||
AfterViewChecked {
|
||||
onChanges(changes: StringMap<string, SimpleChange>): void {}
|
||||
onInit(): void {}
|
||||
doCheck(): void {}
|
||||
onDestroy(): void {}
|
||||
afterContentInit(): void {}
|
||||
afterContentChecked(): void {}
|
||||
afterViewInit(): void {}
|
||||
afterViewChecked(): void {}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
import {ElementSchemaRegistry} from 'angular2/src/core/render/dom/schema/element_schema_registry';
|
||||
import {StringMap} from 'angular2/src/core/facade/collection';
|
||||
import {isPresent} from 'angular2/src/core/facade/lang';
|
||||
|
||||
export class MockSchemaRegistry implements ElementSchemaRegistry {
|
||||
constructor(public existingProperties: StringMap<string, boolean>,
|
||||
public attrPropMapping: StringMap<string, string>) {}
|
||||
hasProperty(tagName: string, property: string): boolean {
|
||||
var result = this.existingProperties[property];
|
||||
return isPresent(result) ? result : true;
|
||||
}
|
||||
|
||||
getMappedPropName(attrName: string): string {
|
||||
var result = this.attrPropMapping[attrName];
|
||||
return isPresent(result) ? result : attrName;
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
import {
|
||||
AsyncTestCompleter,
|
||||
beforeEach,
|
||||
ddescribe,
|
||||
describe,
|
||||
el,
|
||||
expect,
|
||||
iit,
|
||||
inject,
|
||||
it,
|
||||
xit,
|
||||
TestComponentBuilder
|
||||
} from 'angular2/test_lib';
|
||||
|
||||
import {SourceModule, moduleRef} from 'angular2/src/compiler/source_module';
|
||||
|
||||
export function main() {
|
||||
describe('SourceModule', () => {
|
||||
describe('getSourceWithImports', () => {
|
||||
it('should generate named imports for modules', () => {
|
||||
var sourceWithImports =
|
||||
new SourceModule('package:some/moda', `${moduleRef('package:some/modb')}A`)
|
||||
.getSourceWithImports();
|
||||
expect(sourceWithImports.source).toEqual('import0.A');
|
||||
expect(sourceWithImports.imports).toEqual([['package:some/modb', 'import0']]);
|
||||
});
|
||||
|
||||
it('should dedupe imports', () => {
|
||||
var sourceWithImports =
|
||||
new SourceModule(
|
||||
'package:some/moda',
|
||||
`${moduleRef('package:some/modb')}A + ${moduleRef('package:some/modb')}B`)
|
||||
.getSourceWithImports();
|
||||
expect(sourceWithImports.source).toEqual('import0.A + import0.B');
|
||||
expect(sourceWithImports.imports).toEqual([['package:some/modb', 'import0']]);
|
||||
});
|
||||
|
||||
it('should not use an import for the moduleUrl of the SourceModule', () => {
|
||||
var sourceWithImports =
|
||||
new SourceModule('package:some/moda', `${moduleRef('package:some/moda')}A`)
|
||||
.getSourceWithImports();
|
||||
expect(sourceWithImports.source).toEqual('A');
|
||||
expect(sourceWithImports.imports).toEqual([]);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
// used by style_compiler_spec.ts
|
||||
export var STYLES = ['span[_ngcontent-%COMP%] {\ncolor: blue;\n}'];
|
@ -1,2 +0,0 @@
|
||||
// used by style_compiler_spec.ts
|
||||
export var STYLES = ['span {color: blue}'];
|
@ -1,327 +0,0 @@
|
||||
import {
|
||||
ddescribe,
|
||||
describe,
|
||||
xdescribe,
|
||||
it,
|
||||
iit,
|
||||
xit,
|
||||
expect,
|
||||
beforeEach,
|
||||
afterEach,
|
||||
AsyncTestCompleter,
|
||||
inject,
|
||||
beforeEachBindings
|
||||
} from 'angular2/test_lib';
|
||||
import {bind} from 'angular2/src/core/di';
|
||||
import {SpyXHR} from '../core/spies';
|
||||
import {XHR} from 'angular2/src/core/render/xhr';
|
||||
import {BaseException, WrappedException} from 'angular2/src/core/facade/exceptions';
|
||||
|
||||
import {CONST_EXPR, isPresent, isBlank, StringWrapper} from 'angular2/src/core/facade/lang';
|
||||
import {PromiseWrapper, Promise} from 'angular2/src/core/facade/async';
|
||||
import {evalModule} from './eval_module';
|
||||
import {StyleCompiler} from 'angular2/src/compiler/style_compiler';
|
||||
import {
|
||||
CompileDirectiveMetadata,
|
||||
CompileTemplateMetadata,
|
||||
CompileTypeMetadata
|
||||
} from 'angular2/src/compiler/directive_metadata';
|
||||
import {SourceExpression, SourceModule} from 'angular2/src/compiler/source_module';
|
||||
import {ViewEncapsulation} from 'angular2/src/core/render/api';
|
||||
import {TEST_BINDINGS} from './test_bindings';
|
||||
import {codeGenValueFn, codeGenExportVariable, MODULE_SUFFIX} from 'angular2/src/compiler/util';
|
||||
|
||||
// Attention: These module names have to correspond to real modules!
|
||||
var MODULE_URL = `package:angular2/test/compiler/style_compiler_spec${MODULE_SUFFIX}`;
|
||||
var IMPORT_ABS_STYLESHEET_URL = `package:angular2/test/compiler/style_compiler_import.css`;
|
||||
var IMPORT_REL_STYLESHEET_URL = './style_compiler_import.css';
|
||||
// Note: Not a real module, only used via mocks.
|
||||
var IMPORT_ABS_STYLESHEET_URL_WITH_IMPORT =
|
||||
`package:angular2/test/compiler/style_compiler_transitive_import.css`;
|
||||
|
||||
export function main() {
|
||||
describe('StyleCompiler', () => {
|
||||
var xhr: SpyXHR;
|
||||
var templateId;
|
||||
var appId;
|
||||
|
||||
beforeEachBindings(() => {
|
||||
xhr = <any>new SpyXHR();
|
||||
return [TEST_BINDINGS, bind(XHR).toValue(xhr)];
|
||||
});
|
||||
|
||||
var compiler: StyleCompiler;
|
||||
|
||||
beforeEach(inject([StyleCompiler], (_compiler) => {
|
||||
templateId = 23;
|
||||
appId = 'app1';
|
||||
compiler = _compiler;
|
||||
}));
|
||||
|
||||
describe('compileComponentRuntime', () => {
|
||||
var xhrUrlResults;
|
||||
var xhrCount;
|
||||
|
||||
beforeEach(() => {
|
||||
xhrCount = 0;
|
||||
xhrUrlResults = {};
|
||||
xhrUrlResults[IMPORT_ABS_STYLESHEET_URL] = 'span {color: blue}';
|
||||
xhrUrlResults[IMPORT_ABS_STYLESHEET_URL_WITH_IMPORT] =
|
||||
`a {color: green}@import ${IMPORT_REL_STYLESHEET_URL};`;
|
||||
});
|
||||
|
||||
function compile(styles: string[], styleAbsUrls: string[], encapsulation: ViewEncapsulation):
|
||||
Promise<string[]> {
|
||||
// Note: Can't use MockXHR as the xhr is called recursively,
|
||||
// so we can't trigger flush.
|
||||
xhr.spy('get').andCallFake((url) => {
|
||||
var response = xhrUrlResults[url];
|
||||
xhrCount++;
|
||||
if (isBlank(response)) {
|
||||
throw new BaseException(`Unexpected url ${url}`);
|
||||
}
|
||||
return PromiseWrapper.resolve(response);
|
||||
});
|
||||
return compiler.compileComponentRuntime(
|
||||
appId, templateId,
|
||||
new CompileTemplateMetadata(
|
||||
{styles: styles, styleUrls: styleAbsUrls, encapsulation: encapsulation}));
|
||||
}
|
||||
|
||||
describe('no shim', () => {
|
||||
var encapsulation = ViewEncapsulation.None;
|
||||
|
||||
it('should compile plain css rules', inject([AsyncTestCompleter], (async) => {
|
||||
compile(['div {color: red}', 'span {color: blue}'], [], encapsulation)
|
||||
.then(styles => {
|
||||
expect(styles).toEqual(['div {color: red}', 'span {color: blue}']);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should allow to import rules', inject([AsyncTestCompleter], (async) => {
|
||||
compile(['div {color: red}'], [IMPORT_ABS_STYLESHEET_URL], encapsulation)
|
||||
.then(styles => {
|
||||
expect(styles).toEqual(['div {color: red}', 'span {color: blue}']);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should allow to import rules transitively', inject([AsyncTestCompleter], (async) => {
|
||||
compile(['div {color: red}'], [IMPORT_ABS_STYLESHEET_URL_WITH_IMPORT], encapsulation)
|
||||
.then(styles => {
|
||||
expect(styles)
|
||||
.toEqual(['div {color: red}', 'a {color: green}', 'span {color: blue}']);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
describe('with shim', () => {
|
||||
var encapsulation = ViewEncapsulation.Emulated;
|
||||
|
||||
it('should compile plain css rules', inject([AsyncTestCompleter], (async) => {
|
||||
compile(['div {\ncolor: red;\n}', 'span {\ncolor: blue;\n}'], [], encapsulation)
|
||||
.then(styles => {
|
||||
compareStyles(styles, [
|
||||
'div[_ngcontent-app1-23] {\ncolor: red;\n}',
|
||||
'span[_ngcontent-app1-23] {\ncolor: blue;\n}'
|
||||
]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should allow to import rules', inject([AsyncTestCompleter], (async) => {
|
||||
compile(['div {\ncolor: red;\n}'], [IMPORT_ABS_STYLESHEET_URL], encapsulation)
|
||||
.then(styles => {
|
||||
compareStyles(styles, [
|
||||
'div[_ngcontent-app1-23] {\ncolor: red;\n}',
|
||||
'span[_ngcontent-app1-23] {\ncolor: blue;\n}'
|
||||
]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should allow to import rules transitively', inject([AsyncTestCompleter], (async) => {
|
||||
compile(['div {\ncolor: red;\n}'], [IMPORT_ABS_STYLESHEET_URL_WITH_IMPORT],
|
||||
encapsulation)
|
||||
.then(styles => {
|
||||
compareStyles(styles, [
|
||||
'div[_ngcontent-app1-23] {\ncolor: red;\n}',
|
||||
'a[_ngcontent-app1-23] {\ncolor: green;\n}',
|
||||
'span[_ngcontent-app1-23] {\ncolor: blue;\n}'
|
||||
]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('should cache stylesheets for parallel requests', inject([AsyncTestCompleter], (async) => {
|
||||
PromiseWrapper.all([
|
||||
compile([], [IMPORT_ABS_STYLESHEET_URL], ViewEncapsulation.None),
|
||||
compile([], [IMPORT_ABS_STYLESHEET_URL], ViewEncapsulation.None)
|
||||
])
|
||||
.then((styleArrays) => {
|
||||
expect(styleArrays[0]).toEqual(['span {color: blue}']);
|
||||
expect(styleArrays[1]).toEqual(['span {color: blue}']);
|
||||
expect(xhrCount).toBe(1);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should cache stylesheets for serial requests', inject([AsyncTestCompleter], (async) => {
|
||||
compile([], [IMPORT_ABS_STYLESHEET_URL], ViewEncapsulation.None)
|
||||
.then((styles0) => {
|
||||
xhrUrlResults[IMPORT_ABS_STYLESHEET_URL] = 'span {color: black}';
|
||||
return compile([], [IMPORT_ABS_STYLESHEET_URL], ViewEncapsulation.None)
|
||||
.then((styles1) => {
|
||||
expect(styles0).toEqual(['span {color: blue}']);
|
||||
expect(styles1).toEqual(['span {color: blue}']);
|
||||
expect(xhrCount).toBe(1);
|
||||
async.done();
|
||||
});
|
||||
});
|
||||
}));
|
||||
|
||||
it('should allow to clear the cache', inject([AsyncTestCompleter], (async) => {
|
||||
compile([], [IMPORT_ABS_STYLESHEET_URL], ViewEncapsulation.None)
|
||||
.then((_) => {
|
||||
compiler.clearCache();
|
||||
xhrUrlResults[IMPORT_ABS_STYLESHEET_URL] = 'span {color: black}';
|
||||
return compile([], [IMPORT_ABS_STYLESHEET_URL], ViewEncapsulation.None);
|
||||
})
|
||||
.then((styles) => {
|
||||
expect(xhrCount).toBe(2);
|
||||
expect(styles).toEqual(['span {color: black}']);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
describe('compileComponentCodeGen', () => {
|
||||
function compile(styles: string[], styleAbsUrls: string[], encapsulation: ViewEncapsulation):
|
||||
Promise<string[]> {
|
||||
var sourceExpression = compiler.compileComponentCodeGen(
|
||||
`'${appId}'`, `${templateId}`,
|
||||
new CompileTemplateMetadata(
|
||||
{styles: styles, styleUrls: styleAbsUrls, encapsulation: encapsulation}));
|
||||
var sourceWithImports = testableExpression(sourceExpression).getSourceWithImports();
|
||||
return evalModule(sourceWithImports.source, sourceWithImports.imports, null);
|
||||
};
|
||||
|
||||
describe('no shim', () => {
|
||||
var encapsulation = ViewEncapsulation.None;
|
||||
|
||||
it('should compile plain css rules', inject([AsyncTestCompleter], (async) => {
|
||||
compile(['div {color: red}', 'span {color: blue}'], [], encapsulation)
|
||||
.then(styles => {
|
||||
expect(styles).toEqual(['div {color: red}', 'span {color: blue}']);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should compile css rules with newlines and quotes',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
compile(['div\n{"color": \'red\'}'], [], encapsulation)
|
||||
.then(styles => {
|
||||
expect(styles).toEqual(['div\n{"color": \'red\'}']);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should allow to import rules', inject([AsyncTestCompleter], (async) => {
|
||||
compile(['div {color: red}'], [IMPORT_ABS_STYLESHEET_URL], encapsulation)
|
||||
.then(styles => {
|
||||
expect(styles).toEqual(['div {color: red}', 'span {color: blue}']);
|
||||
async.done();
|
||||
});
|
||||
}), 1000);
|
||||
});
|
||||
|
||||
describe('with shim', () => {
|
||||
var encapsulation = ViewEncapsulation.Emulated;
|
||||
|
||||
it('should compile plain css ruless', inject([AsyncTestCompleter], (async) => {
|
||||
compile(['div {\ncolor: red;\n}', 'span {\ncolor: blue;\n}'], [], encapsulation)
|
||||
.then(styles => {
|
||||
compareStyles(styles, [
|
||||
'div[_ngcontent-app1-23] {\ncolor: red;\n}',
|
||||
'span[_ngcontent-app1-23] {\ncolor: blue;\n}'
|
||||
]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should allow to import rules', inject([AsyncTestCompleter], (async) => {
|
||||
compile(['div {color: red}'], [IMPORT_ABS_STYLESHEET_URL], encapsulation)
|
||||
.then(styles => {
|
||||
compareStyles(styles, [
|
||||
'div[_ngcontent-app1-23] {\ncolor: red;\n}',
|
||||
'span[_ngcontent-app1-23] {\ncolor: blue;\n}'
|
||||
]);
|
||||
async.done();
|
||||
});
|
||||
}), 1000);
|
||||
});
|
||||
});
|
||||
|
||||
describe('compileStylesheetCodeGen', () => {
|
||||
function compile(style: string): Promise<string[][]> {
|
||||
var sourceModules = compiler.compileStylesheetCodeGen(MODULE_URL, style);
|
||||
return PromiseWrapper.all(sourceModules.map(sourceModule => {
|
||||
var sourceWithImports = testableModule(sourceModule).getSourceWithImports();
|
||||
return evalModule(sourceWithImports.source, sourceWithImports.imports, null);
|
||||
}));
|
||||
}
|
||||
|
||||
it('should compile plain css rules', inject([AsyncTestCompleter], (async) => {
|
||||
compile('div {color: red;}')
|
||||
.then(stylesAndShimStyles => {
|
||||
var expected =
|
||||
[['div {color: red;}'], ['div[_ngcontent-%COMP%] {\ncolor: red;\n}']];
|
||||
compareStyles(stylesAndShimStyles[0], expected[0]);
|
||||
compareStyles(stylesAndShimStyles[1], expected[1]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should allow to import rules with relative paths',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
compile(`div {color: red}@import ${IMPORT_REL_STYLESHEET_URL};`)
|
||||
.then(stylesAndShimStyles => {
|
||||
var expected = [
|
||||
['div {color: red}', 'span {color: blue}'],
|
||||
[
|
||||
'div[_ngcontent-%COMP%] {\ncolor: red;\n}',
|
||||
'span[_ngcontent-%COMP%] {\ncolor: blue;\n}'
|
||||
]
|
||||
];
|
||||
compareStyles(stylesAndShimStyles[0], expected[0]);
|
||||
compareStyles(stylesAndShimStyles[1], expected[1]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function testableExpression(source: SourceExpression): SourceModule {
|
||||
var testableSource = `${source.declarations.join('\n')}
|
||||
${codeGenExportVariable('run')}${codeGenValueFn(['_'], source.expression)};`;
|
||||
return new SourceModule(null, testableSource);
|
||||
}
|
||||
|
||||
function testableModule(sourceModule: SourceModule): SourceModule {
|
||||
var testableSource = `${sourceModule.sourceWithModuleRefs}
|
||||
${codeGenExportVariable('run')}${codeGenValueFn(['_'], 'STYLES')};`;
|
||||
return new SourceModule(sourceModule.moduleUrl, testableSource);
|
||||
}
|
||||
|
||||
// Needed for Android browsers which add an extra space at the end of some lines
|
||||
function compareStyles(styles: string[], expectedStyles: string[]) {
|
||||
expect(styles.length).toEqual(expectedStyles.length);
|
||||
for (var i = 0; i < styles.length; i++) {
|
||||
expect(StringWrapper.replaceAll(styles[i], /\s+\n/g, '\n')).toEqual(expectedStyles[i]);
|
||||
}
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
import {describe, it, expect, beforeEach, ddescribe, iit, xit, el} from 'angular2/test_lib';
|
||||
import {resolveStyleUrls} from 'angular2/src/compiler/style_url_resolver';
|
||||
|
||||
import {UrlResolver} from 'angular2/src/core/services/url_resolver';
|
||||
|
||||
export function main() {
|
||||
describe('StyleUrlResolver', () => {
|
||||
var urlResolver;
|
||||
|
||||
beforeEach(() => { urlResolver = new UrlResolver(); });
|
||||
|
||||
it('should resolve "url()" urls', () => {
|
||||
var css = `
|
||||
.foo {
|
||||
background-image: url("double.jpg");
|
||||
background-image: url('simple.jpg');
|
||||
background-image: url(noquote.jpg);
|
||||
}`;
|
||||
var expectedCss = `
|
||||
.foo {
|
||||
background-image: url('http://ng.io/double.jpg');
|
||||
background-image: url('http://ng.io/simple.jpg');
|
||||
background-image: url('http://ng.io/noquote.jpg');
|
||||
}`;
|
||||
|
||||
var resolvedCss = resolveStyleUrls(urlResolver, 'http://ng.io', css).style;
|
||||
expect(resolvedCss).toEqual(expectedCss);
|
||||
});
|
||||
|
||||
it('should not strip quotes from inlined SVG styles', () => {
|
||||
var css = `
|
||||
.selector {
|
||||
background:rgb(55,71,79) url('data:image/svg+xml;utf8,<?xml version="1.0"?>');
|
||||
background:rgb(55,71,79) url("data:image/svg+xml;utf8,<?xml version='1.0'?>");
|
||||
background:rgb(55,71,79) url("/some/data:image");
|
||||
}
|
||||
`;
|
||||
|
||||
var expectedCss = `
|
||||
.selector {
|
||||
background:rgb(55,71,79) url('data:image/svg+xml;utf8,<?xml version="1.0"?>');
|
||||
background:rgb(55,71,79) url("data:image/svg+xml;utf8,<?xml version='1.0'?>");
|
||||
background:rgb(55,71,79) url('http://ng.io/some/data:image');
|
||||
}
|
||||
`;
|
||||
|
||||
var resolvedCss = resolveStyleUrls(urlResolver, 'http://ng.io', css).style;
|
||||
expect(resolvedCss).toEqual(expectedCss);
|
||||
});
|
||||
|
||||
it('should extract "@import" urls', () => {
|
||||
var css = `
|
||||
@import '1.css';
|
||||
@import "2.css";
|
||||
`;
|
||||
var styleWithImports = resolveStyleUrls(urlResolver, 'http://ng.io', css);
|
||||
expect(styleWithImports.style.trim()).toEqual('');
|
||||
expect(styleWithImports.styleUrls).toEqual(['http://ng.io/1.css', 'http://ng.io/2.css']);
|
||||
});
|
||||
|
||||
it('should extract "@import url()" urls', () => {
|
||||
var css = `
|
||||
@import url('3.css');
|
||||
@import url("4.css");
|
||||
@import url(5.css);
|
||||
`;
|
||||
var styleWithImports = resolveStyleUrls(urlResolver, 'http://ng.io', css);
|
||||
expect(styleWithImports.style.trim()).toEqual('');
|
||||
expect(styleWithImports.styleUrls)
|
||||
.toEqual(['http://ng.io/3.css', 'http://ng.io/4.css', 'http://ng.io/5.css']);
|
||||
});
|
||||
|
||||
it('should extract "@import urls and keep rules in the same line', () => {
|
||||
var css = `@import url('some.css');div {color: red};`;
|
||||
var styleWithImports = resolveStyleUrls(urlResolver, 'http://ng.io', css);
|
||||
expect(styleWithImports.style.trim()).toEqual('div {color: red};');
|
||||
expect(styleWithImports.styleUrls).toEqual(['http://ng.io/some.css']);
|
||||
});
|
||||
|
||||
it('should extract media query in "@import"', () => {
|
||||
var css = `
|
||||
@import 'print1.css' print;
|
||||
@import url(print2.css) print;
|
||||
`;
|
||||
var styleWithImports = resolveStyleUrls(urlResolver, 'http://ng.io', css);
|
||||
expect(styleWithImports.style.trim()).toEqual('');
|
||||
expect(styleWithImports.styleUrls)
|
||||
.toEqual(['http://ng.io/print1.css', 'http://ng.io/print2.css']);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
@ -1,394 +0,0 @@
|
||||
import {
|
||||
ddescribe,
|
||||
describe,
|
||||
xdescribe,
|
||||
it,
|
||||
iit,
|
||||
xit,
|
||||
expect,
|
||||
beforeEach,
|
||||
afterEach,
|
||||
AsyncTestCompleter,
|
||||
inject,
|
||||
beforeEachBindings
|
||||
} from 'angular2/test_lib';
|
||||
|
||||
import {Promise, PromiseWrapper} from 'angular2/src/core/facade/async';
|
||||
import {Type, isPresent, isBlank, stringify, isString} from 'angular2/src/core/facade/lang';
|
||||
import {MapWrapper, SetWrapper, ListWrapper} from 'angular2/src/core/facade/collection';
|
||||
import {RuntimeMetadataResolver} from 'angular2/src/compiler/runtime_metadata';
|
||||
import {
|
||||
TemplateCompiler,
|
||||
NormalizedComponentWithViewDirectives
|
||||
} from 'angular2/src/compiler/template_compiler';
|
||||
import {CompileDirectiveMetadata} from 'angular2/src/compiler/directive_metadata';
|
||||
import {evalModule} from './eval_module';
|
||||
import {SourceModule, moduleRef} from 'angular2/src/compiler/source_module';
|
||||
import {XHR} from 'angular2/src/core/render/xhr';
|
||||
import {MockXHR} from 'angular2/src/core/render/xhr_mock';
|
||||
|
||||
import {Locals} from 'angular2/src/core/change_detection/change_detection';
|
||||
|
||||
import {
|
||||
CommandVisitor,
|
||||
TextCmd,
|
||||
NgContentCmd,
|
||||
BeginElementCmd,
|
||||
BeginComponentCmd,
|
||||
EmbeddedTemplateCmd,
|
||||
TemplateCmd,
|
||||
visitAllCommands,
|
||||
CompiledTemplate
|
||||
} from 'angular2/src/core/linker/template_commands';
|
||||
|
||||
import {Component, View, Directive, bind} from 'angular2/core';
|
||||
|
||||
import {TEST_BINDINGS} from './test_bindings';
|
||||
import {TestDispatcher, TestPipes} from './change_detector_mocks';
|
||||
import {codeGenValueFn, codeGenExportVariable, MODULE_SUFFIX} from 'angular2/src/compiler/util';
|
||||
import {APP_ID} from 'angular2/src/core/render/dom/dom_tokens';
|
||||
|
||||
// Attention: This path has to point to this test file!
|
||||
const THIS_MODULE_ID = 'angular2/test/compiler/template_compiler_spec';
|
||||
var THIS_MODULE_REF = moduleRef(`package:${THIS_MODULE_ID}${MODULE_SUFFIX}`);
|
||||
|
||||
const APP_ID_VALUE = 'app1';
|
||||
|
||||
export function main() {
|
||||
describe('TemplateCompiler', () => {
|
||||
var compiler: TemplateCompiler;
|
||||
var runtimeMetadataResolver: RuntimeMetadataResolver;
|
||||
|
||||
beforeEachBindings(() => [bind(APP_ID).toValue(APP_ID_VALUE), TEST_BINDINGS]);
|
||||
beforeEach(inject([TemplateCompiler, RuntimeMetadataResolver],
|
||||
(_compiler, _runtimeMetadataResolver) => {
|
||||
compiler = _compiler;
|
||||
runtimeMetadataResolver = _runtimeMetadataResolver;
|
||||
}));
|
||||
|
||||
describe('compile templates', () => {
|
||||
|
||||
function runTests(compile) {
|
||||
it('should throw for non components', inject([AsyncTestCompleter], (async) => {
|
||||
PromiseWrapper.catchError(PromiseWrapper.wrap(() => compile([NonComponent])), (error) => {
|
||||
expect(error.message)
|
||||
.toEqual(
|
||||
`Could not compile '${stringify(NonComponent)}' because it is not a component.`);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should compile host components', inject([AsyncTestCompleter], (async) => {
|
||||
compile([CompWithBindingsAndStyles])
|
||||
.then((humanizedTemplate) => {
|
||||
expect(humanizedTemplate['styles']).toEqual([]);
|
||||
expect(humanizedTemplate['commands'][0]).toEqual('<comp-a>');
|
||||
expect(humanizedTemplate['cd']).toEqual(['elementProperty(title)=someDirValue']);
|
||||
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should compile nested components', inject([AsyncTestCompleter], (async) => {
|
||||
compile([CompWithBindingsAndStyles])
|
||||
.then((humanizedTemplate) => {
|
||||
var nestedTemplate = humanizedTemplate['commands'][1];
|
||||
expect(nestedTemplate['styles']).toEqual(['div {color: red}']);
|
||||
expect(nestedTemplate['commands'][0]).toEqual('<a>');
|
||||
expect(nestedTemplate['cd']).toEqual(['elementProperty(href)=someCtxValue']);
|
||||
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should compile recursive components', inject([AsyncTestCompleter], (async) => {
|
||||
compile([TreeComp])
|
||||
.then((humanizedTemplate) => {
|
||||
expect(humanizedTemplate['commands'][0]).toEqual('<tree>');
|
||||
expect(humanizedTemplate['commands'][1]['commands'][0]).toEqual('<tree>');
|
||||
expect(humanizedTemplate['commands'][1]['commands'][1]['commands'][0])
|
||||
.toEqual('<tree>');
|
||||
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should pass the right change detector to embedded templates',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
compile([CompWithEmbeddedTemplate])
|
||||
.then((humanizedTemplate) => {
|
||||
expect(humanizedTemplate['commands'][1]['commands'][0]).toEqual('<template>');
|
||||
expect(humanizedTemplate['commands'][1]['commands'][1]['cd'])
|
||||
.toEqual(['elementProperty(href)=someCtxValue']);
|
||||
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
describe('compileHostComponentRuntime', () => {
|
||||
function compile(components: Type[]): Promise<any[]> {
|
||||
return compiler.compileHostComponentRuntime(components[0])
|
||||
.then((compiledHostTemplate) => humanizeTemplate(compiledHostTemplate.getTemplate()));
|
||||
}
|
||||
|
||||
runTests(compile);
|
||||
|
||||
it('should cache components for parallel requests',
|
||||
inject([AsyncTestCompleter, XHR], (async, xhr: MockXHR) => {
|
||||
xhr.expect('package:angular2/test/compiler/compUrl.html', 'a');
|
||||
PromiseWrapper.all([compile([CompWithTemplateUrl]), compile([CompWithTemplateUrl])])
|
||||
.then((humanizedTemplates) => {
|
||||
expect(humanizedTemplates[0]['commands'][1]['commands']).toEqual(['#text(a)']);
|
||||
expect(humanizedTemplates[1]['commands'][1]['commands']).toEqual(['#text(a)']);
|
||||
|
||||
async.done();
|
||||
});
|
||||
xhr.flush();
|
||||
}));
|
||||
|
||||
it('should cache components for sequential requests',
|
||||
inject([AsyncTestCompleter, XHR], (async, xhr: MockXHR) => {
|
||||
xhr.expect('package:angular2/test/compiler/compUrl.html', 'a');
|
||||
compile([CompWithTemplateUrl])
|
||||
.then((humanizedTemplate0) => {
|
||||
return compile([CompWithTemplateUrl])
|
||||
.then((humanizedTemplate1) => {
|
||||
expect(humanizedTemplate0['commands'][1]['commands'])
|
||||
.toEqual(['#text(a)']);
|
||||
expect(humanizedTemplate1['commands'][1]['commands'])
|
||||
.toEqual(['#text(a)']);
|
||||
async.done();
|
||||
});
|
||||
});
|
||||
xhr.flush();
|
||||
}));
|
||||
|
||||
it('should allow to clear the cache',
|
||||
inject([AsyncTestCompleter, XHR], (async, xhr: MockXHR) => {
|
||||
xhr.expect('package:angular2/test/compiler/compUrl.html', 'a');
|
||||
compile([CompWithTemplateUrl])
|
||||
.then((humanizedTemplate) => {
|
||||
compiler.clearCache();
|
||||
xhr.expect('package:angular2/test/compiler/compUrl.html', 'b');
|
||||
var result = compile([CompWithTemplateUrl]);
|
||||
xhr.flush();
|
||||
return result;
|
||||
})
|
||||
.then((humanizedTemplate) => {
|
||||
expect(humanizedTemplate['commands'][1]['commands']).toEqual(['#text(b)']);
|
||||
async.done();
|
||||
});
|
||||
xhr.flush();
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
describe('compileTemplatesCodeGen', () => {
|
||||
function normalizeComponent(component: Type):
|
||||
Promise<NormalizedComponentWithViewDirectives> {
|
||||
var compAndViewDirMetas = [runtimeMetadataResolver.getMetadata(component)].concat(
|
||||
runtimeMetadataResolver.getViewDirectivesMetadata(component));
|
||||
return PromiseWrapper.all(compAndViewDirMetas.map(
|
||||
meta => compiler.normalizeDirectiveMetadata(meta)))
|
||||
.then((normalizedCompAndViewDirMetas: CompileDirectiveMetadata[]) =>
|
||||
new NormalizedComponentWithViewDirectives(
|
||||
normalizedCompAndViewDirMetas[0],
|
||||
normalizedCompAndViewDirMetas.slice(1)));
|
||||
}
|
||||
|
||||
function compile(components: Type[]): Promise<any[]> {
|
||||
return PromiseWrapper.all(components.map(normalizeComponent))
|
||||
.then((normalizedCompWithViewDirMetas: NormalizedComponentWithViewDirectives[]) => {
|
||||
var sourceModule = compiler.compileTemplatesCodeGen(normalizedCompWithViewDirMetas);
|
||||
var sourceWithImports =
|
||||
testableTemplateModule(sourceModule,
|
||||
normalizedCompWithViewDirMetas[0].component)
|
||||
.getSourceWithImports();
|
||||
return evalModule(sourceWithImports.source, sourceWithImports.imports, null);
|
||||
});
|
||||
}
|
||||
|
||||
runTests(compile);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('normalizeDirectiveMetadata', () => {
|
||||
it('should return the given DirectiveMetadata for non components',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
var meta = runtimeMetadataResolver.getMetadata(NonComponent);
|
||||
compiler.normalizeDirectiveMetadata(meta).then(normMeta => {
|
||||
expect(normMeta).toBe(meta);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should normalize the template',
|
||||
inject([AsyncTestCompleter, XHR], (async, xhr: MockXHR) => {
|
||||
xhr.expect('package:angular2/test/compiler/compUrl.html', 'loadedTemplate');
|
||||
compiler.normalizeDirectiveMetadata(
|
||||
runtimeMetadataResolver.getMetadata(CompWithTemplateUrl))
|
||||
.then((meta: CompileDirectiveMetadata) => {
|
||||
expect(meta.template.template).toEqual('loadedTemplate');
|
||||
async.done();
|
||||
});
|
||||
xhr.flush();
|
||||
}));
|
||||
|
||||
it('should copy all the other fields', inject([AsyncTestCompleter], (async) => {
|
||||
var meta = runtimeMetadataResolver.getMetadata(CompWithBindingsAndStyles);
|
||||
compiler.normalizeDirectiveMetadata(meta).then((normMeta: CompileDirectiveMetadata) => {
|
||||
expect(normMeta.type).toEqual(meta.type);
|
||||
expect(normMeta.isComponent).toEqual(meta.isComponent);
|
||||
expect(normMeta.dynamicLoadable).toEqual(meta.dynamicLoadable);
|
||||
expect(normMeta.selector).toEqual(meta.selector);
|
||||
expect(normMeta.exportAs).toEqual(meta.exportAs);
|
||||
expect(normMeta.changeDetection).toEqual(meta.changeDetection);
|
||||
expect(normMeta.inputs).toEqual(meta.inputs);
|
||||
expect(normMeta.outputs).toEqual(meta.outputs);
|
||||
expect(normMeta.hostListeners).toEqual(meta.hostListeners);
|
||||
expect(normMeta.hostProperties).toEqual(meta.hostProperties);
|
||||
expect(normMeta.hostAttributes).toEqual(meta.hostAttributes);
|
||||
expect(normMeta.lifecycleHooks).toEqual(meta.lifecycleHooks);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
describe('compileStylesheetCodeGen', () => {
|
||||
it('should compile stylesheets into code', inject([AsyncTestCompleter], (async) => {
|
||||
var cssText = 'div {color: red}';
|
||||
var sourceModule =
|
||||
compiler.compileStylesheetCodeGen('package:someModuleUrl', cssText)[0];
|
||||
var sourceWithImports = testableStylesModule(sourceModule).getSourceWithImports();
|
||||
evalModule(sourceWithImports.source, sourceWithImports.imports, null)
|
||||
.then(loadedCssText => {
|
||||
expect(loadedCssText).toEqual([cssText]);
|
||||
async.done();
|
||||
});
|
||||
|
||||
}));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'comp-a',
|
||||
host: {'[title]': 'someProp'},
|
||||
moduleId: THIS_MODULE_ID,
|
||||
exportAs: 'someExportAs'
|
||||
})
|
||||
@View({template: '<a [href]="someProp"></a>', styles: ['div {color: red}']})
|
||||
class CompWithBindingsAndStyles {
|
||||
}
|
||||
|
||||
@Component({selector: 'tree', moduleId: THIS_MODULE_ID})
|
||||
@View({template: '<tree></tree>', directives: [TreeComp]})
|
||||
class TreeComp {
|
||||
}
|
||||
|
||||
@Component({selector: 'comp-url', moduleId: THIS_MODULE_ID})
|
||||
@View({templateUrl: 'compUrl.html'})
|
||||
class CompWithTemplateUrl {
|
||||
}
|
||||
|
||||
@Component({selector: 'comp-tpl', moduleId: THIS_MODULE_ID})
|
||||
@View({template: '<template><a [href]="someProp"></a></template>'})
|
||||
class CompWithEmbeddedTemplate {
|
||||
}
|
||||
|
||||
|
||||
@Directive({selector: 'plain', moduleId: THIS_MODULE_ID})
|
||||
@View({template: ''})
|
||||
class NonComponent {
|
||||
}
|
||||
|
||||
function testableTemplateModule(sourceModule: SourceModule, normComp: CompileDirectiveMetadata):
|
||||
SourceModule {
|
||||
var resultExpression =
|
||||
`${THIS_MODULE_REF}humanizeTemplate(Host${normComp.type.name}Template.getTemplate())`;
|
||||
var testableSource = `${sourceModule.sourceWithModuleRefs}
|
||||
${codeGenExportVariable('run')}${codeGenValueFn(['_'], resultExpression)};`;
|
||||
return new SourceModule(sourceModule.moduleUrl, testableSource);
|
||||
}
|
||||
|
||||
function testableStylesModule(sourceModule: SourceModule): SourceModule {
|
||||
var testableSource = `${sourceModule.sourceWithModuleRefs}
|
||||
${codeGenExportVariable('run')}${codeGenValueFn(['_'], 'STYLES')};`;
|
||||
return new SourceModule(sourceModule.moduleUrl, testableSource);
|
||||
}
|
||||
|
||||
// Attention: read by eval!
|
||||
export function humanizeTemplate(template: CompiledTemplate,
|
||||
humanizedTemplates: Map<number, StringMap<string, any>> = null):
|
||||
StringMap<string, any> {
|
||||
if (isBlank(humanizedTemplates)) {
|
||||
humanizedTemplates = new Map<number, StringMap<string, any>>();
|
||||
}
|
||||
var result = humanizedTemplates.get(template.id);
|
||||
if (isPresent(result)) {
|
||||
return result;
|
||||
}
|
||||
var templateData = template.getData(APP_ID_VALUE);
|
||||
var commands = [];
|
||||
result = {
|
||||
'styles': templateData.styles,
|
||||
'commands': commands,
|
||||
'cd': testChangeDetector(templateData.changeDetectorFactory)
|
||||
};
|
||||
humanizedTemplates.set(template.id, result);
|
||||
visitAllCommands(new CommandHumanizer(commands, humanizedTemplates), templateData.commands);
|
||||
return result;
|
||||
}
|
||||
|
||||
class TestContext implements CompWithBindingsAndStyles, TreeComp, CompWithTemplateUrl,
|
||||
CompWithEmbeddedTemplate {
|
||||
someProp: string;
|
||||
}
|
||||
|
||||
|
||||
function testChangeDetector(changeDetectorFactory: Function): string[] {
|
||||
var ctx = new TestContext();
|
||||
ctx.someProp = 'someCtxValue';
|
||||
var dir1 = new TestContext();
|
||||
dir1.someProp = 'someDirValue';
|
||||
|
||||
var dispatcher = new TestDispatcher([dir1], []);
|
||||
var cd = changeDetectorFactory(dispatcher);
|
||||
var locals = new Locals(null, MapWrapper.createFromStringMap({'someVar': null}));
|
||||
cd.hydrate(ctx, locals, dispatcher, new TestPipes());
|
||||
cd.detectChanges();
|
||||
return dispatcher.log;
|
||||
}
|
||||
|
||||
|
||||
class CommandHumanizer implements CommandVisitor {
|
||||
constructor(private result: any[],
|
||||
private humanizedTemplates: Map<number, StringMap<string, any>>) {}
|
||||
visitText(cmd: TextCmd, context: any): any {
|
||||
this.result.push(`#text(${cmd.value})`);
|
||||
return null;
|
||||
}
|
||||
visitNgContent(cmd: NgContentCmd, context: any): any { return null; }
|
||||
visitBeginElement(cmd: BeginElementCmd, context: any): any {
|
||||
this.result.push(`<${cmd.name}>`);
|
||||
return null;
|
||||
}
|
||||
visitEndElement(context: any): any {
|
||||
this.result.push('</>');
|
||||
return null;
|
||||
}
|
||||
visitBeginComponent(cmd: BeginComponentCmd, context: any): any {
|
||||
this.result.push(`<${cmd.name}>`);
|
||||
this.result.push(humanizeTemplate(cmd.template, this.humanizedTemplates));
|
||||
return null;
|
||||
}
|
||||
visitEndComponent(context: any): any { return this.visitEndElement(context); }
|
||||
visitEmbeddedTemplate(cmd: EmbeddedTemplateCmd, context: any): any {
|
||||
this.result.push(`<template>`);
|
||||
this.result.push({'cd': testChangeDetector(cmd.changeDetectorFactory)});
|
||||
this.result.push(`</template>`);
|
||||
return null;
|
||||
}
|
||||
}
|
@ -1,307 +0,0 @@
|
||||
import {
|
||||
AsyncTestCompleter,
|
||||
beforeEach,
|
||||
ddescribe,
|
||||
describe,
|
||||
el,
|
||||
expect,
|
||||
iit,
|
||||
inject,
|
||||
it,
|
||||
xit,
|
||||
TestComponentBuilder,
|
||||
beforeEachBindings
|
||||
} from 'angular2/test_lib';
|
||||
|
||||
import {
|
||||
CompileTypeMetadata,
|
||||
CompileTemplateMetadata
|
||||
} from 'angular2/src/compiler/directive_metadata';
|
||||
import {ViewEncapsulation} from 'angular2/src/core/render/api';
|
||||
|
||||
import {TemplateNormalizer} from 'angular2/src/compiler/template_normalizer';
|
||||
import {XHR} from 'angular2/src/core/render/xhr';
|
||||
import {MockXHR} from 'angular2/src/core/render/xhr_mock';
|
||||
import {TEST_BINDINGS} from './test_bindings';
|
||||
|
||||
export function main() {
|
||||
describe('TemplateNormalizer', () => {
|
||||
var dirType: CompileTypeMetadata;
|
||||
|
||||
beforeEachBindings(() => TEST_BINDINGS);
|
||||
|
||||
beforeEach(() => {
|
||||
dirType = new CompileTypeMetadata({moduleUrl: 'package:some/module/a.js', name: 'SomeComp'});
|
||||
});
|
||||
|
||||
describe('loadTemplate', () => {
|
||||
describe('inline template', () => {
|
||||
it('should store the template',
|
||||
inject([AsyncTestCompleter, TemplateNormalizer],
|
||||
(async, normalizer: TemplateNormalizer) => {
|
||||
normalizer.normalizeTemplate(dirType, new CompileTemplateMetadata({
|
||||
encapsulation: null,
|
||||
template: 'a',
|
||||
templateUrl: null,
|
||||
styles: [],
|
||||
styleUrls: ['test.css']
|
||||
}))
|
||||
.then((template: CompileTemplateMetadata) => {
|
||||
expect(template.template).toEqual('a');
|
||||
expect(template.templateUrl).toEqual('package:some/module/a.js');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should resolve styles on the annotation against the moduleUrl',
|
||||
inject([AsyncTestCompleter, TemplateNormalizer],
|
||||
(async, normalizer: TemplateNormalizer) => {
|
||||
normalizer.normalizeTemplate(dirType, new CompileTemplateMetadata({
|
||||
encapsulation: null,
|
||||
template: '',
|
||||
templateUrl: null,
|
||||
styles: [],
|
||||
styleUrls: ['test.css']
|
||||
}))
|
||||
.then((template: CompileTemplateMetadata) => {
|
||||
expect(template.styleUrls).toEqual(['package:some/module/test.css']);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should resolve styles in the template against the moduleUrl',
|
||||
inject([AsyncTestCompleter, TemplateNormalizer],
|
||||
(async, normalizer: TemplateNormalizer) => {
|
||||
normalizer.normalizeTemplate(dirType, new CompileTemplateMetadata({
|
||||
encapsulation: null,
|
||||
template: '<style>@import test.css</style>',
|
||||
templateUrl: null,
|
||||
styles: [],
|
||||
styleUrls: []
|
||||
}))
|
||||
.then((template: CompileTemplateMetadata) => {
|
||||
expect(template.styleUrls).toEqual(['package:some/module/test.css']);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
describe('templateUrl', () => {
|
||||
|
||||
it('should load a template from a url that is resolved against moduleUrl',
|
||||
inject([AsyncTestCompleter, TemplateNormalizer, XHR],
|
||||
(async, normalizer: TemplateNormalizer, xhr: MockXHR) => {
|
||||
xhr.expect('package:some/module/sometplurl.html', 'a');
|
||||
normalizer.normalizeTemplate(dirType, new CompileTemplateMetadata({
|
||||
encapsulation: null,
|
||||
template: null,
|
||||
templateUrl: 'sometplurl.html',
|
||||
styles: [],
|
||||
styleUrls: ['test.css']
|
||||
}))
|
||||
.then((template: CompileTemplateMetadata) => {
|
||||
expect(template.template).toEqual('a');
|
||||
expect(template.templateUrl)
|
||||
.toEqual('package:some/module/sometplurl.html');
|
||||
async.done();
|
||||
});
|
||||
xhr.flush();
|
||||
}));
|
||||
|
||||
it('should resolve styles on the annotation against the moduleUrl',
|
||||
inject([AsyncTestCompleter, TemplateNormalizer, XHR],
|
||||
(async, normalizer: TemplateNormalizer, xhr: MockXHR) => {
|
||||
xhr.expect('package:some/module/tpl/sometplurl.html', '');
|
||||
normalizer.normalizeTemplate(dirType, new CompileTemplateMetadata({
|
||||
encapsulation: null,
|
||||
template: null,
|
||||
templateUrl: 'tpl/sometplurl.html',
|
||||
styles: [],
|
||||
styleUrls: ['test.css']
|
||||
}))
|
||||
.then((template: CompileTemplateMetadata) => {
|
||||
expect(template.styleUrls).toEqual(['package:some/module/test.css']);
|
||||
async.done();
|
||||
});
|
||||
xhr.flush();
|
||||
}));
|
||||
|
||||
it('should resolve styles in the template against the templateUrl',
|
||||
inject([AsyncTestCompleter, TemplateNormalizer, XHR],
|
||||
(async, normalizer: TemplateNormalizer, xhr: MockXHR) => {
|
||||
xhr.expect('package:some/module/tpl/sometplurl.html',
|
||||
'<style>@import test.css</style>');
|
||||
normalizer.normalizeTemplate(dirType, new CompileTemplateMetadata({
|
||||
encapsulation: null,
|
||||
template: null,
|
||||
templateUrl: 'tpl/sometplurl.html',
|
||||
styles: [],
|
||||
styleUrls: []
|
||||
}))
|
||||
.then((template: CompileTemplateMetadata) => {
|
||||
expect(template.styleUrls).toEqual(['package:some/module/tpl/test.css']);
|
||||
async.done();
|
||||
});
|
||||
xhr.flush();
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
it('should throw if no template was specified',
|
||||
inject([TemplateNormalizer], (normalizer: TemplateNormalizer) => {
|
||||
expect(() => normalizer.normalizeTemplate(
|
||||
dirType, new CompileTemplateMetadata(
|
||||
{encapsulation: null, styles: [], styleUrls: []})))
|
||||
.toThrowError('No template specified for component SomeComp');
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
describe('normalizeLoadedTemplate', () => {
|
||||
it('should store the viewEncapsulationin the result',
|
||||
inject([TemplateNormalizer], (normalizer: TemplateNormalizer) => {
|
||||
|
||||
var viewEncapsulation = ViewEncapsulation.Native;
|
||||
var template = normalizer.normalizeLoadedTemplate(
|
||||
dirType, new CompileTemplateMetadata(
|
||||
{encapsulation: viewEncapsulation, styles: [], styleUrls: []}),
|
||||
'', 'package:some/module/');
|
||||
expect(template.encapsulation).toBe(viewEncapsulation);
|
||||
}));
|
||||
|
||||
it('should keep the template as html',
|
||||
inject([TemplateNormalizer], (normalizer: TemplateNormalizer) => {
|
||||
var template = normalizer.normalizeLoadedTemplate(
|
||||
dirType,
|
||||
new CompileTemplateMetadata({encapsulation: null, styles: [], styleUrls: []}), 'a',
|
||||
'package:some/module/');
|
||||
expect(template.template).toEqual('a')
|
||||
}));
|
||||
|
||||
it('should collect ngContent',
|
||||
inject([TemplateNormalizer], (normalizer: TemplateNormalizer) => {
|
||||
var template = normalizer.normalizeLoadedTemplate(
|
||||
dirType,
|
||||
new CompileTemplateMetadata({encapsulation: null, styles: [], styleUrls: []}),
|
||||
'<ng-content select="a"></ng-content>', 'package:some/module/');
|
||||
expect(template.ngContentSelectors).toEqual(['a']);
|
||||
}));
|
||||
|
||||
it('should normalize ngContent wildcard selector',
|
||||
inject([TemplateNormalizer], (normalizer: TemplateNormalizer) => {
|
||||
var template = normalizer.normalizeLoadedTemplate(
|
||||
dirType,
|
||||
new CompileTemplateMetadata({encapsulation: null, styles: [], styleUrls: []}),
|
||||
'<ng-content></ng-content><ng-content select></ng-content><ng-content select="*"></ng-content>',
|
||||
'package:some/module/');
|
||||
expect(template.ngContentSelectors).toEqual(['*', '*', '*']);
|
||||
}));
|
||||
|
||||
it('should collect top level styles in the template',
|
||||
inject([TemplateNormalizer], (normalizer: TemplateNormalizer) => {
|
||||
var template = normalizer.normalizeLoadedTemplate(
|
||||
dirType,
|
||||
new CompileTemplateMetadata({encapsulation: null, styles: [], styleUrls: []}),
|
||||
'<style>a</style>', 'package:some/module/');
|
||||
expect(template.styles).toEqual(['a']);
|
||||
}));
|
||||
|
||||
it('should collect styles inside in elements',
|
||||
inject([TemplateNormalizer], (normalizer: TemplateNormalizer) => {
|
||||
var template = normalizer.normalizeLoadedTemplate(
|
||||
dirType,
|
||||
new CompileTemplateMetadata({encapsulation: null, styles: [], styleUrls: []}),
|
||||
'<div><style>a</style></div>', 'package:some/module/');
|
||||
expect(template.styles).toEqual(['a']);
|
||||
}));
|
||||
|
||||
it('should collect styleUrls in the template',
|
||||
inject([TemplateNormalizer], (normalizer: TemplateNormalizer) => {
|
||||
var template = normalizer.normalizeLoadedTemplate(
|
||||
dirType,
|
||||
new CompileTemplateMetadata({encapsulation: null, styles: [], styleUrls: []}),
|
||||
'<link rel="stylesheet" href="aUrl">', 'package:some/module/');
|
||||
expect(template.styleUrls).toEqual(['package:some/module/aUrl']);
|
||||
}));
|
||||
|
||||
it('should collect styleUrls in elements',
|
||||
inject([TemplateNormalizer], (normalizer: TemplateNormalizer) => {
|
||||
var template = normalizer.normalizeLoadedTemplate(
|
||||
dirType,
|
||||
new CompileTemplateMetadata({encapsulation: null, styles: [], styleUrls: []}),
|
||||
'<div><link rel="stylesheet" href="aUrl"></div>', 'package:some/module/');
|
||||
expect(template.styleUrls).toEqual(['package:some/module/aUrl']);
|
||||
}));
|
||||
|
||||
it('should ignore link elements with non stylesheet rel attribute',
|
||||
inject([TemplateNormalizer], (normalizer: TemplateNormalizer) => {
|
||||
var template = normalizer.normalizeLoadedTemplate(
|
||||
dirType,
|
||||
new CompileTemplateMetadata({encapsulation: null, styles: [], styleUrls: []}),
|
||||
'<link href="b" rel="a"></link>', 'package:some/module/');
|
||||
expect(template.styleUrls).toEqual([]);
|
||||
}));
|
||||
|
||||
it('should extract @import style urls into styleAbsUrl',
|
||||
inject([TemplateNormalizer], (normalizer: TemplateNormalizer) => {
|
||||
var template = normalizer.normalizeLoadedTemplate(
|
||||
dirType, new CompileTemplateMetadata(
|
||||
{encapsulation: null, styles: ['@import "test.css";'], styleUrls: []}),
|
||||
'', 'package:some/module/id');
|
||||
expect(template.styles).toEqual(['']);
|
||||
expect(template.styleUrls).toEqual(['package:some/module/test.css']);
|
||||
}));
|
||||
|
||||
it('should resolve relative urls in inline styles',
|
||||
inject([TemplateNormalizer], (normalizer: TemplateNormalizer) => {
|
||||
var template = normalizer.normalizeLoadedTemplate(
|
||||
dirType, new CompileTemplateMetadata({
|
||||
encapsulation: null,
|
||||
styles: ['.foo{background-image: url(\'double.jpg\');'],
|
||||
styleUrls: []
|
||||
}),
|
||||
'', 'package:some/module/id');
|
||||
expect(template.styles)
|
||||
.toEqual(['.foo{background-image: url(\'package:some/module/double.jpg\');']);
|
||||
}));
|
||||
|
||||
it('should resolve relative style urls in styleUrls',
|
||||
inject([TemplateNormalizer], (normalizer: TemplateNormalizer) => {
|
||||
var template = normalizer.normalizeLoadedTemplate(
|
||||
dirType, new CompileTemplateMetadata(
|
||||
{encapsulation: null, styles: [], styleUrls: ['test.css']}),
|
||||
'', 'package:some/module/id');
|
||||
expect(template.styles).toEqual([]);
|
||||
expect(template.styleUrls).toEqual(['package:some/module/test.css']);
|
||||
}));
|
||||
|
||||
it('should normalize ViewEncapsulation.Emulated to ViewEncapsulation.None if there are no stlyes nor stylesheets',
|
||||
inject([TemplateNormalizer], (normalizer: TemplateNormalizer) => {
|
||||
var template = normalizer.normalizeLoadedTemplate(
|
||||
dirType, new CompileTemplateMetadata(
|
||||
{encapsulation: ViewEncapsulation.Emulated, styles: [], styleUrls: []}),
|
||||
'', 'package:some/module/id');
|
||||
expect(template.encapsulation).toEqual(ViewEncapsulation.None);
|
||||
}));
|
||||
|
||||
it('should ignore ng-content in elements with ng-non-bindable',
|
||||
inject([TemplateNormalizer], (normalizer: TemplateNormalizer) => {
|
||||
var template = normalizer.normalizeLoadedTemplate(
|
||||
dirType,
|
||||
new CompileTemplateMetadata({encapsulation: null, styles: [], styleUrls: []}),
|
||||
'<div ng-non-bindable><ng-content select="a"></ng-content></div>',
|
||||
'package:some/module/');
|
||||
expect(template.ngContentSelectors).toEqual([]);
|
||||
}));
|
||||
|
||||
it('should still collect <style> in elements with ng-non-bindable',
|
||||
inject([TemplateNormalizer], (normalizer: TemplateNormalizer) => {
|
||||
var template = normalizer.normalizeLoadedTemplate(
|
||||
dirType,
|
||||
new CompileTemplateMetadata({encapsulation: null, styles: [], styleUrls: []}),
|
||||
'<div ng-non-bindable><style>div {color:red}</style></div>', 'package:some/module/');
|
||||
expect(template.styles).toEqual(['div {color:red}']);
|
||||
}));
|
||||
});
|
||||
});
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,58 +0,0 @@
|
||||
import {
|
||||
ddescribe,
|
||||
describe,
|
||||
xdescribe,
|
||||
it,
|
||||
iit,
|
||||
xit,
|
||||
expect,
|
||||
beforeEach,
|
||||
afterEach,
|
||||
AsyncTestCompleter,
|
||||
inject,
|
||||
beforeEachBindings
|
||||
} from 'angular2/test_lib';
|
||||
|
||||
import {HtmlParser} from 'angular2/src/compiler/html_parser';
|
||||
import {
|
||||
preparseElement,
|
||||
PreparsedElementType,
|
||||
PreparsedElement
|
||||
} from 'angular2/src/compiler/template_preparser';
|
||||
|
||||
export function main() {
|
||||
describe('preparseElement', () => {
|
||||
var htmlParser;
|
||||
beforeEach(inject([HtmlParser], (_htmlParser: HtmlParser) => { htmlParser = _htmlParser; }));
|
||||
|
||||
function preparse(html: string): PreparsedElement {
|
||||
return preparseElement(htmlParser.parse(html, '')[0]);
|
||||
}
|
||||
|
||||
it('should detect script elements', inject([HtmlParser], (htmlParser: HtmlParser) => {
|
||||
expect(preparse('<script>').type).toBe(PreparsedElementType.SCRIPT);
|
||||
}));
|
||||
|
||||
it('should detect style elements', inject([HtmlParser], (htmlParser: HtmlParser) => {
|
||||
expect(preparse('<style>').type).toBe(PreparsedElementType.STYLE);
|
||||
}));
|
||||
|
||||
it('should detect stylesheet elements', inject([HtmlParser], (htmlParser: HtmlParser) => {
|
||||
expect(preparse('<link rel="stylesheet">').type).toBe(PreparsedElementType.STYLESHEET);
|
||||
expect(preparse('<link rel="stylesheet" href="someUrl">').hrefAttr).toEqual('someUrl');
|
||||
expect(preparse('<link rel="someRel">').type).toBe(PreparsedElementType.OTHER);
|
||||
}));
|
||||
|
||||
it('should detect ng-content elements', inject([HtmlParser], (htmlParser: HtmlParser) => {
|
||||
expect(preparse('<ng-content>').type).toBe(PreparsedElementType.NG_CONTENT);
|
||||
}));
|
||||
|
||||
it('should normalize ng-content.select attribute',
|
||||
inject([HtmlParser], (htmlParser: HtmlParser) => {
|
||||
expect(preparse('<ng-content>').selectAttr).toEqual('*');
|
||||
expect(preparse('<ng-content select>').selectAttr).toEqual('*');
|
||||
expect(preparse('<ng-content select="*">').selectAttr).toEqual('*');
|
||||
}));
|
||||
|
||||
});
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
import {bind, Binding} from 'angular2/src/core/di';
|
||||
import {MockSchemaRegistry} from './schema_registry_mock';
|
||||
import {ElementSchemaRegistry} from 'angular2/src/core/render/dom/schema/element_schema_registry';
|
||||
|
||||
export var TEST_BINDINGS = [bind(ElementSchemaRegistry).toValue(new MockSchemaRegistry({}, {}))];
|
@ -1,55 +0,0 @@
|
||||
import {
|
||||
AsyncTestCompleter,
|
||||
beforeEach,
|
||||
ddescribe,
|
||||
describe,
|
||||
el,
|
||||
expect,
|
||||
iit,
|
||||
inject,
|
||||
it,
|
||||
xit,
|
||||
TestComponentBuilder
|
||||
} from 'angular2/test_lib';
|
||||
|
||||
import {IS_DART} from '../platform';
|
||||
import {escapeSingleQuoteString, escapeDoubleQuoteString} from 'angular2/src/compiler/util';
|
||||
|
||||
export function main() {
|
||||
describe('util', () => {
|
||||
describe('escapeSingleQuoteString', () => {
|
||||
it('should escape single quotes',
|
||||
() => { expect(escapeSingleQuoteString(`'`)).toEqual(`'\\''`); });
|
||||
|
||||
it('should escape backslash',
|
||||
() => { expect(escapeSingleQuoteString('\\')).toEqual(`'\\\\'`); });
|
||||
|
||||
it('should escape newlines',
|
||||
() => { expect(escapeSingleQuoteString('\n')).toEqual(`'\\n'`); });
|
||||
|
||||
if (IS_DART) {
|
||||
it('should escape $', () => { expect(escapeSingleQuoteString('$')).toEqual(`'\\$'`); });
|
||||
} else {
|
||||
it('should not escape $', () => { expect(escapeSingleQuoteString('$')).toEqual(`'$'`); });
|
||||
}
|
||||
});
|
||||
|
||||
describe('escapeDoubleQuoteString', () => {
|
||||
it('should escape double quotes',
|
||||
() => { expect(escapeDoubleQuoteString(`"`)).toEqual(`"\\""`); });
|
||||
|
||||
it('should escape backslash',
|
||||
() => { expect(escapeDoubleQuoteString('\\')).toEqual(`"\\\\"`); });
|
||||
|
||||
it('should escape newlines',
|
||||
() => { expect(escapeDoubleQuoteString('\n')).toEqual(`"\\n"`); });
|
||||
|
||||
if (IS_DART) {
|
||||
it('should escape $', () => { expect(escapeDoubleQuoteString('$')).toEqual(`"\\$"`); });
|
||||
} else {
|
||||
it('should not escape $', () => { expect(escapeDoubleQuoteString('$')).toEqual(`"$"`); });
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
}
|
Reference in New Issue
Block a user