\]unknown="{{ctxProp}}"><\/div>"\): .*MyComp.html@0:5/);
            }
          });
      onlyInIvy('Unknown property logs an error message instead of throwing')
          .it('should throw on bindings to unknown properties', () => {
            TestBed.configureTestingModule({declarations: [MyComp]});
            const template = '
';
            TestBed.overrideComponent(MyComp, {set: {template}});
            const spy = spyOn(console, 'error');
            const fixture = TestBed.createComponent(MyComp);
            fixture.detectChanges();
            expect(spy.calls.mostRecent().args[0])
                .toMatch(/Can't bind to 'unknown' since it isn't a known property of 'div'./);
          });
      modifiedInIvy('Unknown property error thrown instead of logging it')
          .it('should throw on bindings to unknown properties', () => {
            TestBed.configureTestingModule({imports: [CommonModule], declarations: [MyComp]});
            const template = '
{{item}}
';
            TestBed.overrideComponent(MyComp, {set: {template}});
            try {
              const fixture = TestBed.createComponent(MyComp);
              fixture.detectChanges();
              throw 'Should throw';
            } catch (e) {
              expect(e.message).toMatch(
                  /Can't bind to 'ngForIn' since it isn't a known property of 'div'./);
            }
          });
      onlyInIvy('Unknown property logs an error message instead of throwing it')
          .it('should throw on bindings to unknown properties', () => {
            TestBed.configureTestingModule({imports: [CommonModule], declarations: [MyComp]});
            const template = '
{{item}}
';
            TestBed.overrideComponent(MyComp, {set: {template}});
            const spy = spyOn(console, 'error');
            const fixture = TestBed.createComponent(MyComp);
            fixture.detectChanges();
            expect(spy.calls.mostRecent().args[0])
                .toMatch(/Can't bind to 'ngForIn' since it isn't a known property of 'div'./);
          });
      it('should not throw for property binding to a non-existing property when there is a matching directive property',
         () => {
           TestBed.configureTestingModule({declarations: [MyComp, MyDir]});
           const template = '
';
           TestBed.overrideComponent(MyComp, {set: {template}});
           expect(() => TestBed.createComponent(MyComp)).not.toThrow();
         });
      it('should not be created when there is a directive with the same property', () => {
        TestBed.configureTestingModule({declarations: [MyComp, DirectiveWithTitle]});
        const template = '
';
        TestBed.overrideComponent(MyComp, {set: {template}});
        const fixture = TestBed.createComponent(MyComp);
        fixture.componentInstance.ctxProp = 'TITLE';
        fixture.detectChanges();
        const el = fixture.nativeElement.querySelector('span');
        expect(el.title).toBeFalsy();
      });
      it('should work when a directive uses hostProperty to update the DOM element', () => {
        TestBed.configureTestingModule({declarations: [MyComp, DirectiveWithTitleAndHostProperty]});
        const template = '
';
        TestBed.overrideComponent(MyComp, {set: {template}});
        const fixture = TestBed.createComponent(MyComp);
        fixture.componentInstance.ctxProp = 'TITLE';
        fixture.detectChanges();
        const el = fixture.nativeElement.querySelector('span');
        expect(getDOM().getProperty(el, 'title')).toEqual('TITLE');
      });
    });
    describe('logging property updates', () => {
      it('should reflect property values as attributes', () => {
        TestBed.configureTestingModule({declarations: [MyComp, MyDir]});
        TestBed.overrideComponent(
            MyComp, {set: {template: `
`}});
        const fixture = TestBed.createComponent(MyComp);
        fixture.componentInstance.ctxProp = 'hello';
        fixture.detectChanges();
        const html = fixture.nativeElement.innerHTML;
        expect(html).toContain('ng-reflect-dir-prop="hello"');
      });
      it('should reflect property values on unbound inputs', () => {
        TestBed.configureTestingModule({declarations: [MyComp, MyDir]});
        TestBed.overrideComponent(
            MyComp, {set: {template: `
`}});
        const fixture = TestBed.createComponent(MyComp);
        fixture.detectChanges();
        const html = fixture.nativeElement.innerHTML;
        expect(html).toContain('ng-reflect-dir-prop="hello"');
        expect(html).not.toContain('ng-reflect-title');
      });
      it(`should work with prop names containing '$'`, () => {
        TestBed.configureTestingModule({declarations: [ParentCmp, SomeCmpWithInput]});
        const fixture = TestBed.createComponent(ParentCmp);
        fixture.detectChanges();
        const html = fixture.nativeElement.innerHTML;
        expect(html).toContain('ng-reflect-test_="hello"');
      });
      it('should reflect property values on template comments', () => {
        const fixture =
            TestBed.configureTestingModule({declarations: [MyComp]})
                .overrideComponent(
                    MyComp, {set: {template: `
`}})
                .createComponent(MyComp);
        fixture.componentInstance.ctxBoolProp = true;
        fixture.detectChanges();
        const html = fixture.nativeElement.innerHTML;
        expect(html).toContain('"ng-reflect-ng-if": "true"');
      });
      it('should reflect property values on ng-containers', () => {
        const fixture =
            TestBed.configureTestingModule({declarations: [MyComp]})
                .overrideComponent(
                    MyComp,
                    {set: {template: `
content `}})
                .createComponent(MyComp);
        fixture.componentInstance.ctxBoolProp = true;
        fixture.detectChanges();
        const html = fixture.nativeElement.innerHTML;
        expect(html).toContain('"ng-reflect-ng-if": "true"');
      });
      it('should reflect property values of multiple directive bound to the same input name',
         () => {
           TestBed.configureTestingModule({declarations: [MyComp, MyDir, MyDir2]});
           TestBed.overrideComponent(
               MyComp, {set: {template: `
`}});
           const fixture = TestBed.createComponent(MyComp);
           fixture.componentInstance.ctxProp = 'hello';
           fixture.detectChanges();
           const html = fixture.nativeElement.innerHTML;
           expect(html).toContain('ng-reflect-dir-prop="hello"');
           expect(html).toContain('ng-reflect-dir-prop2="hello"');
         });
      it('should indicate when toString() throws', () => {
        TestBed.configureTestingModule({declarations: [MyComp, MyDir]});
        const template = '
';
        TestBed.overrideComponent(MyComp, {set: {template}});
        const fixture = TestBed.createComponent(MyComp);
        fixture.detectChanges();
        expect(fixture.nativeElement.innerHTML).toContain('[ERROR]');
      });
      it('should not reflect undefined values', () => {
        TestBed.configureTestingModule({declarations: [MyComp, MyDir, MyDir2]});
        TestBed.overrideComponent(
            MyComp, {set: {template: `
`}});
        const fixture = TestBed.createComponent(MyComp);
        fixture.componentInstance.ctxProp = 'hello';
        fixture.detectChanges();
        expect(fixture.nativeElement.innerHTML).toContain('ng-reflect-dir-prop="hello"');
        fixture.componentInstance.ctxProp = undefined!;
        fixture.detectChanges();
        expect(fixture.nativeElement.innerHTML).not.toContain('ng-reflect-');
      });
      it('should not reflect null values', () => {
        TestBed.configureTestingModule({declarations: [MyComp, MyDir, MyDir2]});
        TestBed.overrideComponent(
            MyComp, {set: {template: `
`}});
        const fixture = TestBed.createComponent(MyComp);
        fixture.componentInstance.ctxProp = 'hello';
        fixture.detectChanges();
        expect(fixture.nativeElement.innerHTML).toContain('ng-reflect-dir-prop="hello"');
        fixture.componentInstance.ctxProp = null!;
        fixture.detectChanges();
        expect(fixture.nativeElement.innerHTML).not.toContain('ng-reflect-');
      });
      it('should reflect empty strings', () => {
        TestBed.configureTestingModule({declarations: [MyComp, MyDir, MyDir2]});
        TestBed.overrideComponent(
            MyComp, {set: {template: `
`}});
        const fixture = TestBed.createComponent(MyComp);
        fixture.componentInstance.ctxProp = '';
        fixture.detectChanges();
        expect(fixture.nativeElement.innerHTML).toContain('ng-reflect-dir-prop=""');
      });
      it('should not reflect in comment nodes when the value changes to undefined', () => {
        const fixture =
            TestBed.configureTestingModule({declarations: [MyComp]})
                .overrideComponent(
                    MyComp, {set: {template: `
`}})
                .createComponent(MyComp);
        fixture.componentInstance.ctxBoolProp = true;
        fixture.detectChanges();
        let html = fixture.nativeElement.innerHTML;
        expect(html).toContain('bindings={');
        expect(html).toContain('"ng-reflect-ng-if": "true"');
        fixture.componentInstance.ctxBoolProp = undefined!;
        fixture.detectChanges();
        html = fixture.nativeElement.innerHTML;
        expect(html).toContain('bindings={');
        expect(html).not.toContain('ng-reflect');
      });
      it('should reflect in comment nodes when the value changes to null', () => {
        const fixture =
            TestBed.configureTestingModule({declarations: [MyComp]})
                .overrideComponent(
                    MyComp, {set: {template: `
`}})
                .createComponent(MyComp);
        fixture.componentInstance.ctxBoolProp = true;
        fixture.detectChanges();
        let html = fixture.nativeElement.innerHTML;
        expect(html).toContain('bindings={');
        expect(html).toContain('"ng-reflect-ng-if": "true"');
        fixture.componentInstance.ctxBoolProp = null!;
        fixture.detectChanges();
        html = fixture.nativeElement.innerHTML;
        expect(html).toContain('bindings={');
        expect(html).toContain('"ng-reflect-ng-if": null');
      });
    });
    describe('property decorators', () => {
      it('should support property decorators', () => {
        TestBed.configureTestingModule({
          declarations: [MyComp, DirectiveWithPropDecorators],
          schemas: [NO_ERRORS_SCHEMA],
        });
        const template = '
';
        TestBed.overrideComponent(MyComp, {set: {template}});
        const fixture = TestBed.createComponent(MyComp);
        fixture.detectChanges();
        const dir = fixture.debugElement.children[0].injector.get(DirectiveWithPropDecorators);
        expect(dir.dirProp).toEqual('aaa');
      });
      it('should support host binding decorators', () => {
        TestBed.configureTestingModule({
          declarations: [MyComp, DirectiveWithPropDecorators],
          schemas: [NO_ERRORS_SCHEMA],
        });
        const template = '
';
        TestBed.overrideComponent(MyComp, {set: {template}});
        const fixture = TestBed.createComponent(MyComp);
        fixture.detectChanges();
        const dir = fixture.debugElement.children[0].injector.get(DirectiveWithPropDecorators);
        dir.myAttr = 'aaa';
        fixture.detectChanges();
        expect(fixture.debugElement.children[0].nativeElement.outerHTML).toContain('my-attr="aaa"');
      });
      if (getDOM().supportsDOMEvents()) {
        it('should support event decorators', fakeAsync(() => {
             TestBed.configureTestingModule({
               declarations: [MyComp, DirectiveWithPropDecorators],
               schemas: [NO_ERRORS_SCHEMA],
             });
             const template = `
`;
             TestBed.overrideComponent(MyComp, {set: {template}});
             const fixture = TestBed.createComponent(MyComp);
             tick();
             const emitter =
                 fixture.debugElement.children[0].injector.get(DirectiveWithPropDecorators);
             emitter.fireEvent('fired !');
             tick();
             expect(fixture.componentInstance.ctxProp).toEqual('called');
           }));
        it('should support host listener decorators', () => {
          TestBed.configureTestingModule({
            declarations: [MyComp, DirectiveWithPropDecorators],
            schemas: [NO_ERRORS_SCHEMA],
          });
          const template = 'foo   bar ',
           })
           class MyCmp {
           }
           const f = TestBed.configureTestingModule({declarations: [MyCmp]}).createComponent(MyCmp);
           f.detectChanges();
           expect(f.nativeElement.childNodes.length).toBe(2);
         }));
      it('should not remove whitespaces when explicitly requested not to do so',
         waitForAsync(() => {
           @Component({
             selector: 'comp',
             template: 'foo   bar ',
             preserveWhitespaces: true,
           })
           class MyCmp {
           }
           const f = TestBed.configureTestingModule({declarations: [MyCmp]}).createComponent(MyCmp);
           f.detectChanges();
           expect(f.nativeElement.childNodes.length).toBe(3);
         }));
      it('should remove whitespaces when explicitly requested to do so', waitForAsync(() => {
           @Component({
             selector: 'comp',
             template: 'foo   bar ',
             preserveWhitespaces: false,
           })
           class MyCmp {
           }
           const f = TestBed.configureTestingModule({declarations: [MyCmp]}).createComponent(MyCmp);
           f.detectChanges();
           expect(f.nativeElement.childNodes.length).toBe(2);
         }));
    });
    if (getDOM().supportsDOMEvents()) {
      describe('svg', () => {
        it('should support svg elements', () => {
          TestBed.configureTestingModule({declarations: [MyComp]});
          const template = 'svg, 'namespaceURI'))
              .toEqual('http://www.w3.org/2000/svg');
          expect(getDOM().getProperty(use, 'namespaceURI'))
              .toEqual('http://www.w3.org/2000/svg');
          const firstAttribute = getDOM().getProperty(use, 'attributes')[0];
          expect(firstAttribute.name).toEqual('xlink:href');
          expect(firstAttribute.namespaceURI).toEqual('http://www.w3.org/1999/xlink');
        });
        it('should support foreignObjects with document fragments', () => {
          TestBed.configureTestingModule({declarations: [MyComp]});
          const template =
              'Test
svg, 'namespaceURI'))
              .toEqual('http://www.w3.org/2000/svg');
          expect(getDOM().getProperty(foreignObject, 'namespaceURI'))
              .toEqual('http://www.w3.org/2000/svg');
          expect(getDOM().getProperty(p, 'namespaceURI'))
              .toEqual('http://www.w3.org/1999/xhtml');
        });
      });
      describe('attributes', () => {
        it('should support attributes with namespace', () => {
          TestBed.configureTestingModule({declarations: [MyComp, SomeCmp]});
          const template = '{%text%}
`,
  interpolation: ['{%', '%}']
})
class ComponentWithCustomInterpolationA {
  text = 'Custom Interpolation A';
}
@Component({
  selector: 'cmp-with-custom-interpolation-b',
  template:
      `{**text%}
 (;
  private injector: Injector;
  constructor(private vc: ViewContainerRef, componentFactoryResolver: ComponentFactoryResolver) {
    const myService = new MyService();
    myService.greeting = 'dynamic greet';
    this.injector = Injector.create([{provide: MyService, useValue: myService}], vc.injector);
    this.componentFactory =
        componentFactoryResolver.resolveComponentFactory(ChildCompUsingService)!;
  }
  create(): ComponentRef {
    return this.vc.createComponent(this.componentFactory, this.vc.length, this.injector);
  }
  insert(viewRef: ViewRef, index?: number): ViewRef {
    return this.vc.insert(viewRef, index);
  }
  move(viewRef: ViewRef, currentIndex: number): ViewRef {
    return this.vc.move(viewRef, currentIndex);
  }
}
@Directive({selector: '[my-dir]', inputs: ['dirProp: elprop'], exportAs: 'mydir'})
class MyDir {
  dirProp: string;
  constructor() {
    this.dirProp = '';
  }
}
@Directive({selector: '[my-dir2]', inputs: ['dirProp2: elprop'], exportAs: 'mydir2'})
class MyDir2 {
  dirProp2: string;
  constructor() {
    this.dirProp2 = '';
  }
}
@Directive({selector: '[title]', inputs: ['title']})
class DirectiveWithTitle {
  // TODO(issue/24571): remove '!'.
  title!: string;
}
@Directive({selector: '[title]', inputs: ['title'], host: {'[title]': 'title'}})
class DirectiveWithTitleAndHostProperty {
  // TODO(issue/24571): remove '!'.
  title!: string;
}
@Component({selector: 'event-cmp', template: '
'})
class EventCmp {
  noop() {}
}
@Component({
  selector: 'push-cmp',
  inputs: ['prop'],
  host: {'(click)': 'true'},
  changeDetection: ChangeDetectionStrategy.OnPush,
  template:
      '{{field}}
;
  constructor() {
    this.promise = new Promise((resolve) => {
      this.resolve = resolve;
    });
  }
  get field() {
    this.numberOfChecks++;
    return this.promise;
  }
}
@Component({selector: 'my-comp', template: ''})
class MyComp {
  ctxProp: string;
  ctxNumProp: number;
  ctxBoolProp: boolean;
  ctxArrProp: number[];
  toStringThrow = {
    toString: function() {
      throw 'boom';
    }
  };
  constructor() {
    this.ctxProp = 'initial value';
    this.ctxNumProp = 0;
    this.ctxBoolProp = false;
    this.ctxArrProp = [0, 1, 2];
  }
  throwError() {
    throw 'boom';
  }
}
@Component({
  selector: 'child-cmp',
  inputs: ['dirProp'],
  viewProviders: [MyService],
  template: '{{ctxProp}}'
})
class ChildComp {
  ctxProp: string;
  dirProp: string|null;
  constructor(service: MyService) {
    this.ctxProp = service.greeting;
    this.dirProp = null;
  }
}
@Component({selector: 'child-cmp-no-template', template: ''})
class ChildCompNoTemplate {
  ctxProp: string = 'hello';
}
@Component({selector: 'child-cmp-svc', template: '{{ctxProp}}'})
class ChildCompUsingService {
  ctxProp: string;
  constructor(service: MyService) {
    this.ctxProp = service.greeting;
  }
}
@Directive({selector: 'some-directive'})
class SomeDirective {
}
class SomeDirectiveMissingAnnotation {}
@Component({
  selector: 'cmp-with-host',
  template: 'Component with an injected host
',
})
class CompWithHost {
  myHost: SomeDirective;
  constructor(@Host() someComp: SomeDirective) {
    this.myHost = someComp;
  }
}
@Component({selector: '[child-cmp2]', viewProviders: [MyService]})
class ChildComp2 {
  ctxProp: string;
  dirProp: string|null;
  constructor(service: MyService) {
    this.ctxProp = service.greeting;
    this.dirProp = null;
  }
}
class SomeViewportContext {
  constructor(public someTmpl: string) {}
}
@Directive({selector: '[some-viewport]'})
class SomeViewport {
  constructor(public container: ViewContainerRef, templateRef: TemplateRef) {
    container.createEmbeddedView(templateRef, new SomeViewportContext('hello'));
    container.createEmbeddedView(templateRef, new SomeViewportContext('again'));
  }
}
@Directive({selector: '[pollutedContext]'})
class PollutedContext {
  constructor(private tplRef: TemplateRef, private vcRef: ViewContainerRef) {
    const evRef = this.vcRef.createEmbeddedView(this.tplRef);
    evRef.context.bar = 'baz';
  }
}
@Directive({selector: '[noContext]'})
class NoContext {
  constructor(private tplRef: TemplateRef, private vcRef: ViewContainerRef) {
    this.vcRef.createEmbeddedView(this.tplRef);
  }
}
@Pipe({name: 'double'})
class DoublePipe implements PipeTransform, OnDestroy {
  ngOnDestroy() {}
  transform(value: any) {
    return `${value}${value}`;
  }
}
@Directive({selector: '[emitter]', outputs: ['event']})
class DirectiveEmittingEvent {
  msg: string;
  event: EventEmitter;
  constructor() {
    this.msg = '';
    this.event = new EventEmitter();
  }
  fireEvent(msg: string) {
    this.event.emit(msg);
  }
}
@Directive({selector: '[update-host-attributes]', host: {'role': 'button'}})
class DirectiveUpdatingHostAttributes {
}
@Directive({selector: '[update-host-properties]', host: {'[id]': 'id'}})
class DirectiveUpdatingHostProperties {
  id: string;
  constructor() {
    this.id = 'one';
  }
}
@Directive({selector: '[listener]', host: {'(event)': 'onEvent($event)'}})
class DirectiveListeningEvent {
  msg: string;
  constructor() {
    this.msg = '';
  }
  onEvent(msg: string) {
    this.msg = msg;
  }
}
@Directive({
  selector: '[listener]',
  host: {
    '(domEvent)': 'onEvent($event.type)',
    '(window:domEvent)': 'onWindowEvent($event.type)',
    '(document:domEvent)': 'onDocumentEvent($event.type)',
    '(body:domEvent)': 'onBodyEvent($event.type)'
  }
})
class DirectiveListeningDomEvent {
  eventTypes: string[] = [];
  onEvent(eventType: string) {
    this.eventTypes.push(eventType);
  }
  onWindowEvent(eventType: string) {
    this.eventTypes.push('window_' + eventType);
  }
  onDocumentEvent(eventType: string) {
    this.eventTypes.push('document_' + eventType);
  }
  onBodyEvent(eventType: string) {
    this.eventTypes.push('body_' + eventType);
  }
}
let globalCounter = 0;
@Directive({selector: '[listenerother]', host: {'(window:domEvent)': 'onEvent($event.type)'}})
class DirectiveListeningDomEventOther {
  eventType: string;
  constructor() {
    this.eventType = '';
  }
  onEvent(eventType: string) {
    globalCounter++;
    this.eventType = 'other_' + eventType;
  }
}
@Directive({selector: '[listenerprevent]', host: {'(click)': 'onEvent($event)'}})
class DirectiveListeningDomEventPrevent {
  onEvent(event: any) {
    return false;
  }
}
@Directive({selector: '[listenernoprevent]', host: {'(click)': 'onEvent($event)'}})
class DirectiveListeningDomEventNoPrevent {
  onEvent(event: any) {
    return true;
  }
}
@Directive({selector: '[id]', inputs: ['id']})
class IdDir {
  // TODO(issue/24571): remove '!'.
  id!: string;
}
@Directive({selector: '[customEvent]'})
class EventDir {
  @Output() customEvent = new EventEmitter();
  doSomething() {}
}
@Directive({selector: '[static]'})
class NeedsAttribute {
  typeAttribute: string;
  staticAttribute: string;
  fooAttribute: string;
  constructor(
      @Attribute('type') typeAttribute: string, @Attribute('static') staticAttribute: string,
      @Attribute('foo') fooAttribute: string) {
    this.typeAttribute = typeAttribute;
    this.staticAttribute = staticAttribute;
    this.fooAttribute = fooAttribute;
  }
}
@Injectable()
class PublicApi {
}
@Directive({
  selector: '[public-api]',
  providers: [{provide: PublicApi, useExisting: PrivateImpl, deps: []}]
})
class PrivateImpl extends PublicApi {
}
@Directive({selector: '[needs-public-api]'})
class NeedsPublicApi {
  constructor(@Host() api: PublicApi) {
    expect(api instanceof PrivateImpl).toBe(true);
  }
}
class ToolbarContext {
  constructor(public toolbarProp: string) {}
}
@Directive({selector: '[toolbarpart]'})
class ToolbarPart {
  templateRef: TemplateRef;
  constructor(templateRef: TemplateRef) {
    this.templateRef = templateRef;
  }
}
@Directive({selector: '[toolbarVc]', inputs: ['toolbarVc']})
class ToolbarViewContainer {
  constructor(public vc: ViewContainerRef) {}
  set toolbarVc(part: ToolbarPart) {
    this.vc.createEmbeddedView(part.templateRef, new ToolbarContext('From toolbar'), 0);
  }
}
@Component({
  selector: 'toolbar',
  template: 'TOOLBAR(
)',
})
class ToolbarComponent {
  // TODO(issue/24571): remove '!'.
  @ContentChildren(ToolbarPart) query!: QueryList;
  ctxProp: string = 'hello world';
  constructor() {}
}
@Directive({selector: '[two-way]', inputs: ['control'], outputs: ['controlChange']})
class DirectiveWithTwoWayBinding {
  controlChange = new EventEmitter();
  control: any = null;
  triggerChange(value: any) {
    this.controlChange.emit(value);
  }
}
@Injectable()
class InjectableService {
}
function createInjectableWithLogging(inj: Injector) {
  inj.get(ComponentProvidingLoggingInjectable).created = true;
  return new InjectableService();
}
@Component({
  selector: 'component-providing-logging-injectable',
  providers:
      [{provide: InjectableService, useFactory: createInjectableWithLogging, deps: [Injector]}],
  template: ''
})
class ComponentProvidingLoggingInjectable {
  created: boolean = false;
}
@Directive({selector: 'directive-providing-injectable', providers: [[InjectableService]]})
class DirectiveProvidingInjectable {
}
@Component({
  selector: 'directive-providing-injectable',
  viewProviders: [[InjectableService]],
  template: ''
})
class DirectiveProvidingInjectableInView {
}
@Component({
  selector: 'directive-providing-injectable',
  providers: [{provide: InjectableService, useValue: 'host'}],
  viewProviders: [{provide: InjectableService, useValue: 'view'}],
  template: ''
})
class DirectiveProvidingInjectableInHostAndView {
}
@Component({selector: 'directive-consuming-injectable', template: ''})
class DirectiveConsumingInjectable {
  injectable: any;
  constructor(@Host() @Inject(InjectableService) injectable: any) {
    this.injectable = injectable;
  }
}
@Component({selector: 'directive-containing-directive-consuming-an-injectable'})
class DirectiveContainingDirectiveConsumingAnInjectable {
  directive: any;
}
@Component({selector: 'directive-consuming-injectable-unbounded', template: ''})
class DirectiveConsumingInjectableUnbounded {
  injectable: any;
  constructor(
      injectable: InjectableService,
      @SkipSelf() parent: DirectiveContainingDirectiveConsumingAnInjectable) {
    this.injectable = injectable;
    parent.directive = this;
  }
}
class EventBus {
  parentEventBus: EventBus;
  name: string;
  constructor(parentEventBus: EventBus, name: string) {
    this.parentEventBus = parentEventBus;
    this.name = name;
  }
}
@Directive({
  selector: 'grand-parent-providing-event-bus',
  providers: [{provide: EventBus, useValue: new EventBus(null!, 'grandparent')}]
})
class GrandParentProvidingEventBus {
  bus: EventBus;
  constructor(bus: EventBus) {
    this.bus = bus;
  }
}
function createParentBus(peb: EventBus) {
  return new EventBus(peb, 'parent');
}
@Component({
  selector: 'parent-providing-event-bus',
  providers: [{provide: EventBus, useFactory: createParentBus, deps: [[EventBus, new SkipSelf()]]}],
  template: `|null;
  anchor: any;
  constructor(
      public vc: ViewContainerRef, public templateRef: TemplateRef,
      @Inject(ANCHOR_ELEMENT) anchor: any) {
    this.view = null;
    this.anchor = anchor;
  }
  set someImpvp(value: boolean) {
    if (this.view) {
      this.vc.clear();
      this.view = null;
    }
    if (value) {
      this.view = this.vc.createEmbeddedView(this.templateRef);
      const nodes = this.view.rootNodes;
      for (let i = 0; i < nodes.length; i++) {
        this.anchor.appendChild(nodes[i]);
      }
    }
  }
}
@Directive({selector: '[export-dir]', exportAs: 'dir'})
class ExportDir {
}
@Directive({selector: '[multiple-export-as]', exportAs: 'dirX, dirY'})
export class DirectiveWithMultipleExportAsNames {
}
@Component({selector: 'comp'})
class ComponentWithoutView {
}
@Directive({selector: '[no-duplicate]'})
class DuplicateDir {
  constructor(elRef: ElementRef) {
    elRef.nativeElement.textContent += 'noduplicate';
  }
}
@Directive({selector: '[no-duplicate]'})
class OtherDuplicateDir {
  constructor(elRef: ElementRef) {
    elRef.nativeElement.textContent += 'othernoduplicate';
  }
}
@Directive({selector: 'directive-throwing-error'})
class DirectiveThrowingAnError {
  constructor() {
    throw new Error('BOOM');
  }
}
@Component({
  selector: 'component-with-template',
  template: `No View Decorator: {{item}}
`
})
class ComponentWithTemplate {
  items = [1, 2, 3];
}
@Directive({selector: 'with-prop-decorators'})
class DirectiveWithPropDecorators {
  target: any;
  // TODO(issue/24571): remove '!'.
  @Input('elProp') dirProp!: string;
  @Output('elEvent') event = new EventEmitter();
  // TODO(issue/24571): remove '!'.
  @HostBinding('attr.my-attr') myAttr!: string;
  @HostListener('click', ['$event.target'])
  onClick(target: any) {
    this.target = target;
  }
  fireEvent(msg: any) {
    this.event.emit(msg);
  }
}
@Component({selector: 'some-cmp'})
class SomeCmp {
  value: any;
}
@Component({
  selector: 'parent-cmp',
  template: `