@ -11,11 +11,9 @@ import {
|
||||
AsyncTestCompleter,
|
||||
inject
|
||||
} from 'angular2/test_lib';
|
||||
import {PromiseWrapper} from 'angular2/src/core/facade/async';
|
||||
import {IS_DART} from '../platform';
|
||||
|
||||
import {evalModule} from './eval_module';
|
||||
import {SourceModule} from 'angular2/src/compiler/api';
|
||||
|
||||
// This export is used by this test code
|
||||
// when evaling the test module!
|
||||
@ -23,14 +21,16 @@ export var TEST_VALUE = 23;
|
||||
|
||||
export function main() {
|
||||
describe('evalModule', () => {
|
||||
it('should call the "run" function and allow to use imports', inject([AsyncTestCompleter], (async) => {
|
||||
it('should call the "run" function and allow to use imports',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
var moduleSource = IS_DART ? testDartModule : testJsModule;
|
||||
var imports = [['angular2/test/compiler/eval_module_spec', 'testMod']];
|
||||
|
||||
evalModule(moduleSource, imports, [1]).then( (value) => {
|
||||
expect(value).toEqual([1, 23]);
|
||||
async.done();
|
||||
});
|
||||
|
||||
evalModule(moduleSource, imports, [1])
|
||||
.then((value) => {
|
||||
expect(value).toEqual([1, 23]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
@ -0,0 +1,2 @@
|
||||
// used by style_compiler_spec.ts
|
||||
export var STYLES = ['span[_ngcontent-%COMP%] {\ncolor: blue;\n}'];
|
2
modules/angular2/test/compiler/style_compiler_import.ts
Normal file
2
modules/angular2/test/compiler/style_compiler_import.ts
Normal file
@ -0,0 +1,2 @@
|
||||
// used by style_compiler_spec.ts
|
||||
export var STYLES = ['span {color: blue}'];
|
201
modules/angular2/test/compiler/style_compiler_spec.ts
Normal file
201
modules/angular2/test/compiler/style_compiler_spec.ts
Normal file
@ -0,0 +1,201 @@
|
||||
import {
|
||||
ddescribe,
|
||||
describe,
|
||||
xdescribe,
|
||||
it,
|
||||
iit,
|
||||
xit,
|
||||
expect,
|
||||
beforeEach,
|
||||
afterEach,
|
||||
AsyncTestCompleter,
|
||||
inject
|
||||
} from 'angular2/test_lib';
|
||||
import {IS_DART} from '../platform';
|
||||
import {SpyXHR} from '../core/spies';
|
||||
|
||||
import {CONST_EXPR, isPresent, BaseException} 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 {UrlResolver} from 'angular2/src/core/services/url_resolver';
|
||||
import {
|
||||
DirectiveMetadata,
|
||||
TemplateMetadata,
|
||||
TypeMetadata,
|
||||
ViewEncapsulation
|
||||
} from 'angular2/src/compiler/api';
|
||||
|
||||
// Attention: These module names have to correspond to real modules!
|
||||
const MODULE_NAME = 'angular2/test/compiler/style_compiler_spec';
|
||||
const IMPORT_ABS_MODULE_NAME = 'angular2/test/compiler/style_compiler_import';
|
||||
const IMPORT_REL_MODULE_NAME = './style_compiler_import';
|
||||
// Note: Not a real module, only used via mocks.
|
||||
const IMPORT_ABS_MODULE_NAME_WITH_IMPORT =
|
||||
'angular2/test/compiler/style_compiler_transitive_import';
|
||||
|
||||
export function main() {
|
||||
describe('StyleCompiler', () => {
|
||||
var compiler: StyleCompiler;
|
||||
var xhr;
|
||||
|
||||
beforeEach(() => {
|
||||
xhr = <any>new SpyXHR();
|
||||
compiler = new StyleCompiler(xhr, new UrlResolver());
|
||||
});
|
||||
|
||||
function comp(styles: string[], styleAbsUrls: string[], encapsulation: ViewEncapsulation):
|
||||
DirectiveMetadata {
|
||||
return new DirectiveMetadata({
|
||||
type: new TypeMetadata({id: 23, typeUrl: 'someUrl'}),
|
||||
template: new TemplateMetadata(
|
||||
{styles: styles, styleAbsUrls: styleAbsUrls, encapsulation: encapsulation})
|
||||
});
|
||||
}
|
||||
|
||||
describe('compileComponentRuntime', () => {
|
||||
function runTest(styles: string[], styleAbsUrls: string[], encapsulation: ViewEncapsulation,
|
||||
expectedStyles: string[]) {
|
||||
return inject([AsyncTestCompleter], (async) => {
|
||||
// Note: Can't use MockXHR as the xhr is called recursively,
|
||||
// so we can't trigger flush.
|
||||
xhr.spy('get').andCallFake((url) => {
|
||||
var response;
|
||||
if (url == IMPORT_ABS_MODULE_NAME) {
|
||||
response = 'span {color: blue}';
|
||||
} else if (url == IMPORT_ABS_MODULE_NAME_WITH_IMPORT) {
|
||||
response = `a {color: green}@import ${IMPORT_REL_MODULE_NAME};`;
|
||||
} else {
|
||||
throw new BaseException(`Unexpected url ${url}`);
|
||||
}
|
||||
return PromiseWrapper.resolve(response);
|
||||
});
|
||||
compiler.compileComponentRuntime(comp(styles, styleAbsUrls, encapsulation))
|
||||
.then((value) => {
|
||||
expect(value).toEqual(expectedStyles);
|
||||
async.done();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
describe('no shim', () => {
|
||||
var encapsulation = ViewEncapsulation.None;
|
||||
|
||||
it('should compile plain css rules',
|
||||
runTest(['div {color: red}', 'span {color: blue}'], [], encapsulation,
|
||||
['div {color: red}', 'span {color: blue}']));
|
||||
|
||||
it('should allow to import rules',
|
||||
runTest(['div {color: red}'], [IMPORT_ABS_MODULE_NAME], encapsulation,
|
||||
['div {color: red}', 'span {color: blue}']));
|
||||
|
||||
it('should allow to import rules transitively',
|
||||
runTest(['div {color: red}'], [IMPORT_ABS_MODULE_NAME_WITH_IMPORT], encapsulation,
|
||||
['div {color: red}', 'a {color: green}', 'span {color: blue}']));
|
||||
});
|
||||
|
||||
describe('with shim', () => {
|
||||
var encapsulation = ViewEncapsulation.Emulated;
|
||||
|
||||
it('should compile plain css rules',
|
||||
runTest(
|
||||
['div {\ncolor: red;\n}', 'span {\ncolor: blue;\n}'], [], encapsulation,
|
||||
['div[_ngcontent-23] {\ncolor: red;\n}', 'span[_ngcontent-23] {\ncolor: blue;\n}']));
|
||||
|
||||
it('should allow to import rules',
|
||||
runTest(
|
||||
['div {\ncolor: red;\n}'], [IMPORT_ABS_MODULE_NAME], encapsulation,
|
||||
['div[_ngcontent-23] {\ncolor: red;\n}', 'span[_ngcontent-23] {\ncolor: blue;\n}']));
|
||||
|
||||
it('should allow to import rules transitively',
|
||||
runTest(['div {\ncolor: red;\n}'], [IMPORT_ABS_MODULE_NAME_WITH_IMPORT], encapsulation, [
|
||||
'div[_ngcontent-23] {\ncolor: red;\n}',
|
||||
'a[_ngcontent-23] {\ncolor: green;\n}',
|
||||
'span[_ngcontent-23] {\ncolor: blue;\n}'
|
||||
]));
|
||||
});
|
||||
});
|
||||
|
||||
describe('compileComponentCodeGen', () => {
|
||||
function runTest(styles: string[], styleAbsUrls: string[], encapsulation: ViewEncapsulation,
|
||||
expectedStyles: string[]) {
|
||||
return inject([AsyncTestCompleter], (async) => {
|
||||
var sourceModule =
|
||||
compiler.compileComponentCodeGen(comp(styles, styleAbsUrls, encapsulation));
|
||||
evalModule(testableModule(sourceModule.source), sourceModule.imports, null)
|
||||
.then((value) => {
|
||||
expect(value).toEqual(expectedStyles);
|
||||
async.done();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
describe('no shim', () => {
|
||||
var encapsulation = ViewEncapsulation.None;
|
||||
|
||||
it('should compile plain css ruless',
|
||||
runTest(['div {color: red}', 'span {color: blue}'], [], encapsulation,
|
||||
['div {color: red}', 'span {color: blue}']));
|
||||
|
||||
it('should compile css rules with newlines and quotes',
|
||||
runTest(['div\n{"color": \'red\'}'], [], encapsulation, ['div\n{"color": \'red\'}']));
|
||||
|
||||
it('should allow to import rules',
|
||||
runTest(['div {color: red}'], [IMPORT_ABS_MODULE_NAME], encapsulation,
|
||||
['div {color: red}', 'span {color: blue}']));
|
||||
});
|
||||
|
||||
describe('with shim', () => {
|
||||
var encapsulation = ViewEncapsulation.Emulated;
|
||||
|
||||
it('should compile plain css ruless',
|
||||
runTest(
|
||||
['div {\ncolor: red;\n}', 'span {\ncolor: blue;\n}'], [], encapsulation,
|
||||
['div[_ngcontent-23] {\ncolor: red;\n}', 'span[_ngcontent-23] {\ncolor: blue;\n}']));
|
||||
|
||||
it('should allow to import rules',
|
||||
runTest(
|
||||
['div {color: red}'], [IMPORT_ABS_MODULE_NAME], encapsulation,
|
||||
['div[_ngcontent-23] {\ncolor: red;\n}', 'span[_ngcontent-23] {\ncolor: blue;\n}']));
|
||||
});
|
||||
});
|
||||
|
||||
describe('compileStylesheetCodeGen', () => {
|
||||
function runTest(style: string, expectedStyles: string[], expectedShimStyles: string[]) {
|
||||
return inject([AsyncTestCompleter], (async) => {
|
||||
var sourceModules = compiler.compileStylesheetCodeGen(MODULE_NAME, style);
|
||||
PromiseWrapper.all(sourceModules.map(sourceModule =>
|
||||
evalModule(testableModule(sourceModule.source),
|
||||
sourceModule.imports, null)))
|
||||
.then((values) => {
|
||||
expect(values[0]).toEqual(expectedStyles);
|
||||
expect(values[1]).toEqual(expectedShimStyles);
|
||||
async.done();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
it('should compile plain css rules', runTest('div {color: red;}', ['div {color: red;}'],
|
||||
['div[_ngcontent-%COMP%] {\ncolor: red;\n}']));
|
||||
|
||||
it('should allow to import rules with relative paths',
|
||||
runTest(`div {color: red}@import ${IMPORT_REL_MODULE_NAME};`,
|
||||
['div {color: red}', 'span {color: blue}'], [
|
||||
'div[_ngcontent-%COMP%] {\ncolor: red;\n}',
|
||||
'span[_ngcontent-%COMP%] {\ncolor: blue;\n}'
|
||||
]));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testableModule(sourceModule: string) {
|
||||
if (IS_DART) {
|
||||
return `${sourceModule}
|
||||
run(_) { return STYLES; }
|
||||
`;
|
||||
} else {
|
||||
return `${sourceModule}
|
||||
exports.run = function(_) { return STYLES; };
|
||||
`;
|
||||
}
|
||||
}
|
@ -1,87 +1,91 @@
|
||||
import {describe, it, expect, beforeEach, ddescribe, iit, xit, el} from 'angular2/test_lib';
|
||||
import {StyleUrlResolver} from 'angular2/src/compiler/style_url_resolver';
|
||||
import {resolveStyleUrls} from 'angular2/src/compiler/style_url_resolver';
|
||||
|
||||
import {UrlResolver} from 'angular2/src/core/services/url_resolver';
|
||||
|
||||
export function main() {
|
||||
describe('StyleUrlResolver', () => {
|
||||
let styleUrlResolver: StyleUrlResolver;
|
||||
var urlResolver;
|
||||
|
||||
beforeEach(() => { styleUrlResolver = new StyleUrlResolver(new UrlResolver()); });
|
||||
beforeEach(() => { urlResolver = new UrlResolver(); });
|
||||
|
||||
describe('resolveUrls', () => {
|
||||
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');
|
||||
}`;
|
||||
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 = styleUrlResolver.resolveUrls(css, 'http://ng.io');
|
||||
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 = styleUrlResolver.resolveUrls(css, 'http://ng.io');
|
||||
expect(resolvedCss).toEqual(expectedCss);
|
||||
});
|
||||
var resolvedCss = resolveStyleUrls(urlResolver, 'http://ng.io', css).style;
|
||||
expect(resolvedCss).toEqual(expectedCss);
|
||||
});
|
||||
|
||||
describe('extractUrls', () => {
|
||||
it('should extract "@import" urls', () => {
|
||||
var css = `
|
||||
@import '1.css';
|
||||
@import "2.css";
|
||||
`;
|
||||
var styleWithImports = styleUrlResolver.extractImports(css);
|
||||
expect(styleWithImports.style.trim()).toEqual('');
|
||||
expect(styleWithImports.styleUrls).toEqual(['1.css', '2.css']);
|
||||
});
|
||||
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");
|
||||
}
|
||||
`;
|
||||
|
||||
it('should extract "@import url()" urls', () => {
|
||||
var css = `
|
||||
@import url('3.css');
|
||||
@import url("4.css");
|
||||
@import url(5.css);
|
||||
`;
|
||||
var styleWithImports = styleUrlResolver.extractImports(css);
|
||||
expect(styleWithImports.style.trim()).toEqual('');
|
||||
expect(styleWithImports.styleUrls).toEqual(['3.css', '4.css', '5.css']);
|
||||
});
|
||||
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');
|
||||
}
|
||||
`;
|
||||
|
||||
it('should extract media query in "@import"', () => {
|
||||
var css = `
|
||||
@import 'print.css' print;
|
||||
@import url(print2.css) print;
|
||||
`;
|
||||
var styleWithImports = styleUrlResolver.extractImports(css);
|
||||
expect(styleWithImports.style.trim()).toEqual('');
|
||||
expect(styleWithImports.styleUrls).toEqual(['print.css', 'print2.css']);
|
||||
});
|
||||
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']);
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -19,7 +19,6 @@ import {TypeMetadata, ViewEncapsulation, TemplateMetadata} from 'angular2/src/co
|
||||
|
||||
import {TemplateLoader} from 'angular2/src/compiler/template_loader';
|
||||
import {UrlResolver} from 'angular2/src/core/services/url_resolver';
|
||||
import {StyleUrlResolver} from 'angular2/src/compiler/style_url_resolver';
|
||||
import {humanizeDom} from './html_parser_spec';
|
||||
import {HtmlTextAst, HtmlElementAst, HtmlAttrAst} from 'angular2/src/compiler/html_ast';
|
||||
import {XHR} from 'angular2/src/core/render/xhr';
|
||||
@ -33,8 +32,7 @@ export function main() {
|
||||
beforeEach(inject([XHR], (mockXhr) => {
|
||||
xhr = mockXhr;
|
||||
var urlResolver = new UrlResolver();
|
||||
loader =
|
||||
new TemplateLoader(xhr, urlResolver, new StyleUrlResolver(urlResolver), new HtmlParser());
|
||||
loader = new TemplateLoader(xhr, urlResolver, new HtmlParser());
|
||||
dirType = new TypeMetadata({typeUrl: 'http://sometypeurl', typeName: 'SomeComp'});
|
||||
}));
|
||||
|
||||
|
Reference in New Issue
Block a user