202 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			202 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
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; };
 | 
						|
`;
 | 
						|
  }
 | 
						|
}
 |