204 lines
8.0 KiB
TypeScript
204 lines
8.0 KiB
TypeScript
import {
|
|
AsyncTestCompleter,
|
|
beforeEach,
|
|
beforeEachBindings,
|
|
ddescribe,
|
|
describe,
|
|
el,
|
|
expect,
|
|
iit,
|
|
inject,
|
|
it,
|
|
xit,
|
|
} from 'angular2/test_lib';
|
|
import {StyleInliner} from 'angular2/src/render/dom/compiler/style_inliner';
|
|
|
|
import {isBlank} from 'angular2/src/facade/lang';
|
|
import {Promise, PromiseWrapper} from 'angular2/src/facade/async';
|
|
import {Map, MapWrapper} from 'angular2/src/facade/collection';
|
|
|
|
import {XHR} from 'angular2/src/render/xhr';
|
|
|
|
import {bind} from 'angular2/di';
|
|
|
|
export function main() {
|
|
describe('StyleInliner', () => {
|
|
beforeEachBindings(() => [
|
|
bind(XHR)
|
|
.toClass(FakeXHR),
|
|
]);
|
|
|
|
describe('loading', () => {
|
|
|
|
it('should return a string when there is no import statement',
|
|
inject([StyleInliner], (inliner) => {
|
|
var css = '.main {}';
|
|
var loadedCss = inliner.inlineImports(css, 'http://base');
|
|
expect(loadedCss).toEqual(css);
|
|
}));
|
|
|
|
it('should inline @import rules',
|
|
inject([XHR, StyleInliner, AsyncTestCompleter], (xhr, inliner, async) => {
|
|
xhr.reply('http://base/one.css', '.one {}');
|
|
var css = '@import url("one.css");.main {}';
|
|
var loadedCss = inliner.inlineImports(css, 'http://base');
|
|
expect(loadedCss).toBePromise();
|
|
PromiseWrapper.then(loadedCss,
|
|
function(css) {
|
|
expect(css).toEqual('.one {}\n.main {}');
|
|
async.done();
|
|
},
|
|
function(e) { throw 'fail;' });
|
|
}));
|
|
|
|
it('should support url([unquoted url]) in @import rules',
|
|
inject([XHR, StyleInliner, AsyncTestCompleter], (xhr, inliner, async) => {
|
|
xhr.reply('http://base/one.css', '.one {}');
|
|
var css = '@import url(one.css);.main {}';
|
|
var loadedCss = inliner.inlineImports(css, 'http://base');
|
|
expect(loadedCss).toBePromise();
|
|
PromiseWrapper.then(loadedCss,
|
|
function(css) {
|
|
expect(css).toEqual('.one {}\n.main {}');
|
|
async.done();
|
|
},
|
|
function(e) { throw 'fail;' });
|
|
}));
|
|
|
|
it('should handle @import error gracefuly',
|
|
inject([StyleInliner, AsyncTestCompleter], (inliner, async) => {
|
|
var css = '@import "one.css";.main {}';
|
|
var loadedCss = inliner.inlineImports(css, 'http://base');
|
|
expect(loadedCss).toBePromise();
|
|
PromiseWrapper.then(
|
|
loadedCss,
|
|
function(css) {
|
|
expect(css).toEqual('/* failed to import http://base/one.css */\n.main {}');
|
|
async.done();
|
|
},
|
|
function(e) { throw 'fail;' });
|
|
}));
|
|
|
|
it('should inline multiple @import rules',
|
|
inject([XHR, StyleInliner, AsyncTestCompleter], (xhr, inliner, async) => {
|
|
xhr.reply('http://base/one.css', '.one {}');
|
|
xhr.reply('http://base/two.css', '.two {}');
|
|
var css = '@import "one.css";@import "two.css";.main {}';
|
|
var loadedCss = inliner.inlineImports(css, 'http://base');
|
|
expect(loadedCss).toBePromise();
|
|
PromiseWrapper.then(loadedCss,
|
|
function(css) {
|
|
expect(css).toEqual('.one {}\n.two {}\n.main {}');
|
|
async.done();
|
|
},
|
|
function(e) { throw 'fail;' });
|
|
}));
|
|
|
|
it('should inline nested @import rules',
|
|
inject([XHR, StyleInliner, AsyncTestCompleter], (xhr, inliner, async) => {
|
|
xhr.reply('http://base/one.css', '@import "two.css";.one {}');
|
|
xhr.reply('http://base/two.css', '.two {}');
|
|
var css = '@import "one.css";.main {}';
|
|
var loadedCss = inliner.inlineImports(css, 'http://base/');
|
|
expect(loadedCss).toBePromise();
|
|
PromiseWrapper.then(loadedCss,
|
|
function(css) {
|
|
expect(css).toEqual('.two {}\n.one {}\n.main {}');
|
|
async.done();
|
|
},
|
|
function(e) { throw 'fail;' });
|
|
}));
|
|
|
|
it('should handle circular dependencies gracefuly',
|
|
inject([XHR, StyleInliner, AsyncTestCompleter], (xhr, inliner, async) => {
|
|
xhr.reply('http://base/one.css', '@import "two.css";.one {}');
|
|
xhr.reply('http://base/two.css', '@import "one.css";.two {}');
|
|
var css = '@import "one.css";.main {}';
|
|
var loadedCss = inliner.inlineImports(css, 'http://base/');
|
|
expect(loadedCss).toBePromise();
|
|
PromiseWrapper.then(loadedCss,
|
|
function(css) {
|
|
expect(css).toEqual('.two {}\n.one {}\n.main {}');
|
|
async.done();
|
|
},
|
|
function(e) { throw 'fail;' });
|
|
}));
|
|
|
|
it('should handle invalid @import fracefuly',
|
|
inject([StyleInliner, AsyncTestCompleter], (inliner, async) => {
|
|
// Invalid rule: the url is not quoted
|
|
var css = '@import one.css;.main {}';
|
|
var loadedCss = inliner.inlineImports(css, 'http://base/');
|
|
expect(loadedCss).toBePromise();
|
|
PromiseWrapper.then(
|
|
loadedCss,
|
|
function(css) {
|
|
expect(css).toEqual('/* Invalid import rule: "@import one.css;" */.main {}');
|
|
async.done();
|
|
},
|
|
function(e) { throw 'fail;' });
|
|
}));
|
|
});
|
|
|
|
describe('media query', () => {
|
|
it('should wrap inlined content in media query',
|
|
inject([XHR, StyleInliner, AsyncTestCompleter], (xhr, inliner, async) => {
|
|
xhr.reply('http://base/one.css', '.one {}');
|
|
var css = '@import "one.css" (min-width: 700px) and (orientation: landscape);';
|
|
var loadedCss = inliner.inlineImports(css, 'http://base/');
|
|
expect(loadedCss).toBePromise();
|
|
PromiseWrapper.then(
|
|
loadedCss,
|
|
function(css) {
|
|
expect(css).toEqual(
|
|
'@media (min-width: 700px) and (orientation: landscape) {\n.one {}\n}\n');
|
|
async.done();
|
|
},
|
|
function(e) { throw 'fail;' });
|
|
}));
|
|
});
|
|
|
|
describe('url rewritting', () => {
|
|
it('should rewrite url in inlined content',
|
|
inject([XHR, StyleInliner, AsyncTestCompleter], (xhr, inliner, async) => {
|
|
// it should rewrite both '@import' and 'url()'
|
|
xhr.reply('http://base/one.css',
|
|
'@import "./nested/two.css";.one {background-image: url("one.jpg");}');
|
|
xhr.reply('http://base/nested/two.css',
|
|
'.two {background-image: url("../img/two.jpg");}');
|
|
var css = '@import "one.css";';
|
|
var loadedCss = inliner.inlineImports(css, 'http://base/');
|
|
expect(loadedCss).toBePromise();
|
|
PromiseWrapper.then(
|
|
loadedCss,
|
|
function(css) {
|
|
expect(css).toEqual(".two {background-image: url('http://base/img/two.jpg');}\n" +
|
|
".one {background-image: url('http://base/one.jpg');}\n");
|
|
async.done();
|
|
},
|
|
function(e) { throw 'fail;' });
|
|
}));
|
|
});
|
|
});
|
|
}
|
|
|
|
class FakeXHR extends XHR {
|
|
_responses: Map<string, string>;
|
|
|
|
constructor() {
|
|
super();
|
|
this._responses = new Map();
|
|
}
|
|
|
|
get(url: string): Promise<string> {
|
|
var response = this._responses.get(url);
|
|
if (isBlank(response)) {
|
|
return PromiseWrapper.reject('xhr error', null);
|
|
}
|
|
|
|
return PromiseWrapper.resolve(response);
|
|
}
|
|
|
|
reply(url: string, response: string) { this._responses.set(url, response); }
|
|
}
|