Esempio n. 1
0
 it('should be able to get metadata for a class with nested method calls', () => {
   const annotations = reflector.annotations(
       reflector.getStaticSymbol('/tmp/src/static-method-call.ts', 'MyFactoryComponent'));
   expect(annotations.length).toBe(1);
   expect(annotations[0].providers).toEqual({
     provide: 'c',
     useFactory:
         reflector.getStaticSymbol('/tmp/src/static-method.ts', 'AnotherModule', ['someFactory'])
   });
 });
Esempio n. 2
0
 it('should simplify values initialized with a function call', () => {
   expect(simplify(
              reflector.getStaticSymbol('/tmp/src/function-reference.ts', ''),
              reflector.getStaticSymbol('/tmp/src/function-reference.ts', 'one')))
       .toEqual(['some-value']);
   expect(simplify(
              reflector.getStaticSymbol('/tmp/src/function-reference.ts', ''),
              reflector.getStaticSymbol('/tmp/src/function-reference.ts', 'three')))
       .toEqual(3);
 });
Esempio n. 3
0
 function init(
     testData: {[key: string]: any} = DEFAULT_TEST_DATA,
     decorators: {name: string, filePath: string, ctor: any}[] = [],
     errorRecorder?: (error: any, fileName: string) => void, collectorOptions?: CollectorOptions) {
   const symbolCache = new StaticSymbolCache();
   host = new MockStaticSymbolResolverHost(testData, collectorOptions);
   symbolResolver =
       new StaticSymbolResolver(host, symbolCache, new MockSummaryResolver([]), errorRecorder);
   reflector = new StaticReflector(symbolResolver, decorators, [], errorRecorder);
   noContext = reflector.getStaticSymbol('', '');
 }
  it('should quote identifiers quoted in the source', () => {
    const sourceText = `
      import {Component} from '@angular/core';

      @Component({
        providers: [{ provide: 'SomeToken', useValue: {a: 1, 'b': 2, c: 3, 'd': 4}}]
      })
      export class MyComponent {}
    `;
    const source = ts.createSourceFile('test.ts', sourceText, ts.ScriptTarget.Latest);
    const collector = new MetadataCollector({quotedNames: true});
    const stubHost = new StubReflectorHost();
    const symbolCache = new StaticSymbolCache();
    const symbolResolver =
        new StaticSymbolResolver(stubHost, symbolCache, new MockSummaryResolver());
    const reflector = new StaticReflector(symbolResolver);

    // Get the metadata from the above source
    const metadata = collector.getMetadata(source);
    const componentMetadata = metadata.metadata['MyComponent'];

    // Get the first argument of the decorator call which is passed to @Component
    expect(isClassMetadata(componentMetadata)).toBeTruthy();
    if (!isClassMetadata(componentMetadata)) return;
    const decorators = componentMetadata.decorators;
    const firstDecorator = decorators[0];
    expect(isMetadataSymbolicCallExpression(firstDecorator)).toBeTruthy();
    if (!isMetadataSymbolicCallExpression(firstDecorator)) return;
    const firstArgument = firstDecorator.arguments[0];

    // Simplify this value using the StaticReflector
    const context = reflector.getStaticSymbol('none', 'none');
    const argumentValue = reflector.simplify(context, firstArgument);

    // Convert the value to an output AST
    const outputAst = convertValueToOutputAst(argumentValue);
    const statement = outputAst.toStmt();

    // Convert the value to text using the typescript emitter
    const emitter = new TypeScriptEmitter(new StubImportResolver());
    const text = emitter.emitStatements('module', [statement], []);

    // Expect the keys for 'b' and 'd' to be quoted but 'a' and 'c' not to be.
    expect(text).toContain('\'b\': 2');
    expect(text).toContain('\'d\': 4');
    expect(text).not.toContain('\'a\'');
    expect(text).not.toContain('\'c\'');
  });
Esempio n. 5
0
  it('should not throw on unknown decorators', () => {
    const data = Object.create(DEFAULT_TEST_DATA);
    const file = '/tmp/src/app.component.ts';
    data[file] = `
      import { Component } from '@angular/core';

      export const enum TypeEnum {
        type
      }

      export function MyValidationDecorator(p1: any, p2: any): any {
        return null;
      }

      export function ValidationFunction(a1: any): any {
        return null;
      }

      @Component({
        selector: 'my-app',
        template: "<h1>Hello {{name}}</h1>",
      })
      export class AppComponent  {
        name = 'Angular';

        @MyValidationDecorator( TypeEnum.type, ValidationFunction({option: 'value'}))
        myClassProp: number;
    }`;
    init(data);
    const appComponent = reflector.getStaticSymbol(file, 'AppComponent');
    expect(() => reflector.propMetadata(appComponent)).not.toThrow();
  });
Esempio n. 6
0
 it('should get annotations for HeroDetailComponent', () => {
   const HeroDetailComponent =
       reflector.findDeclaration('src/app/hero-detail.component', 'HeroDetailComponent');
   const annotations = reflector.annotations(HeroDetailComponent);
   expect(annotations.length).toEqual(1);
   const annotation = annotations[0];
   expect(annotation.selector).toEqual('my-hero-detail');
   expect(annotation.animations).toEqual([trigger('myAnimation', [
     state('state1', style({'background': 'white'})),
     transition(
         '* => *',
         sequence([group([animate(
             '1s 0.5s',
             keyframes([style({'background': 'blue'}), style({'background': 'red'})]))])]))
   ])]);
 });
  it('should continue to aggresively evaluate enum member accessors', () => {
    const data = Object.create(DEFAULT_TEST_DATA);
    const file = '/tmp/src/my_component.ts';
    data[file] = `
      import {Component} from '@angular/core';
      import {intermediate} from './index';

      @Component({
        template: '<div></div>',
        providers: [{provide: 'foo', useValue: [...intermediate]}]
      })
      export class MyComponent { }
    `;
    data['/tmp/src/intermediate.ts'] = `
      import {MyEnum} from './indirect';
      export const intermediate = [{
        data: {
          c: [MyEnum.Value]
        }
      }];`;
    data['/tmp/src/index.ts'] = `export * from './intermediate';`;
    data['/tmp/src/indirect.ts'] = `export * from './consts';`;
    data['/tmp/src/consts.ts'] = `
      export enum MyEnum {
        Value = 3
      }
    `;
    init(data);

    expect(reflector.annotations(reflector.getStaticSymbol(file, 'MyComponent'))[0]
               .providers[0]
               .useValue)
        .toEqual([{data: {c: [3]}}]);
  });
  it('should be able to inject a ctor parameter with a @Inject and a type expression', () => {
    const data = Object.create(DEFAULT_TEST_DATA);
    const file = '/tmp/src/invalid-component.ts';
    data[file] = `
        import {Injectable, Inject} from '@angular/core';

        @Injectable()
        export class SomeClass {
          constructor (@Inject('some-token') a: {a: string, b: string}) {}
        }
      `;
    init(data);

    const someClass = reflector.getStaticSymbol(file, 'SomeClass');
    const parameters = reflector.parameters(someClass);
    expect(compilerCore.createInject.isTypeOf(parameters[0][0])).toBe(true);
  });
Esempio n. 9
0
    it('should inherit property metadata', () => {
      initWithDecorator({
        '/tmp/src/main.ts': `
            import {PropDecorator} from './decorator';

            export class A {}
            export class B {}
            export class C {}

            export class Parent {
              @PropDecorator('a')
              a: A;
              @PropDecorator('b1')
              b: B;
            }

            export class Child extends Parent {
              @PropDecorator('b2')
              b: B;
              @PropDecorator('c')
              c: C;
            }

            export class ChildInvalidParent extends a.InvalidParent {}
          `
      });

      // Check that metadata for Parent was not changed!
      expect(reflector.propMetadata(reflector.getStaticSymbol('/tmp/src/main.ts', 'Parent')))
          .toEqual({
            'a': [new PropDecorator('a')],
            'b': [new PropDecorator('b1')],
          });

      expect(reflector.propMetadata(reflector.getStaticSymbol('/tmp/src/main.ts', 'Child')))
          .toEqual({
            'a': [new PropDecorator('a')],
            'b': [new PropDecorator('b1'), new PropDecorator('b2')],
            'c': [new PropDecorator('c')]
          });

      expect(reflector.propMetadata(
                 reflector.getStaticSymbol('/tmp/src/main.ts', 'ChildInvalidParent')))
          .toEqual({});
    });
Esempio n. 10
0
 it('should get and empty annotation list for a symbol with null value', () => {
   init({
     '/tmp/test.ts': `
       export var x = null;
     `
   });
   const annotations = reflector.annotations(reflector.getStaticSymbol('/tmp/test.ts', 'x'));
   expect(annotations).toEqual([]);
 });