diff --git a/packages/core/test/acceptance/di_spec.ts b/packages/core/test/acceptance/di_spec.ts
index f39ba35412..195f3964c1 100644
--- a/packages/core/test/acceptance/di_spec.ts
+++ b/packages/core/test/acceptance/di_spec.ts
@@ -7,7 +7,7 @@
*/
import {CommonModule} from '@angular/common';
-import {Attribute, ChangeDetectorRef, Component, Directive, Inject, LOCALE_ID, Optional, Pipe, PipeTransform, SkipSelf, ViewChild} from '@angular/core';
+import {Attribute, ChangeDetectorRef, Component, Directive, EventEmitter, Inject, Input, LOCALE_ID, Optional, Output, Pipe, PipeTransform, SkipSelf, ViewChild} from '@angular/core';
import {ViewRef} from '@angular/core/src/render3/view_ref';
import {TestBed} from '@angular/core/testing';
@@ -155,6 +155,78 @@ describe('di', () => {
describe('@Attribute', () => {
+ it('should inject attributes', () => {
+ @Directive({selector: '[dir]'})
+ class MyDir {
+ constructor(
+ @Attribute('exist') public exist: string,
+ @Attribute('nonExist') public nonExist: string) {}
+ }
+
+ @Component({template: '
'})
+ class MyComp {
+ @ViewChild(MyDir) directiveInstance !: MyDir;
+ }
+
+ TestBed.configureTestingModule({declarations: [MyDir, MyComp]});
+ const fixture = TestBed.createComponent(MyComp);
+ fixture.detectChanges();
+
+ const directive = fixture.componentInstance.directiveInstance;
+
+ expect(directive.exist).toBe('existValue');
+ expect(directive.nonExist).toBeNull();
+ });
+
+ it('should inject attributes on ', () => {
+ @Directive({selector: '[dir]'})
+ class MyDir {
+ constructor(
+ @Attribute('exist') public exist: string,
+ @Attribute('dir') public myDirectiveAttrValue: string) {}
+ }
+
+ @Component(
+ {template: ''})
+ class MyComp {
+ @ViewChild(MyDir) directiveInstance !: MyDir;
+ }
+
+ TestBed.configureTestingModule({declarations: [MyDir, MyComp]});
+ const fixture = TestBed.createComponent(MyComp);
+ fixture.detectChanges();
+
+ const directive = fixture.componentInstance.directiveInstance;
+
+ expect(directive.exist).toBe('existValue');
+ expect(directive.myDirectiveAttrValue).toBe('initial');
+ });
+
+ it('should inject attributes on ', () => {
+ @Directive({selector: '[dir]'})
+ class MyDir {
+ constructor(
+ @Attribute('exist') public exist: string,
+ @Attribute('dir') public myDirectiveAttrValue: string) {}
+ }
+
+ @Component({
+ template: ''
+ })
+ class MyComp {
+ @ViewChild(MyDir) directiveInstance !: MyDir;
+ }
+
+ TestBed.configureTestingModule({declarations: [MyDir, MyComp]});
+ const fixture = TestBed.createComponent(MyComp);
+ fixture.detectChanges();
+
+ const directive = fixture.componentInstance.directiveInstance;
+
+ expect(directive.exist).toBe('existValue');
+ expect(directive.myDirectiveAttrValue).toBe('initial');
+ });
+
it('should be able to inject different kinds of attributes', () => {
@Directive({selector: '[dir]'})
class MyDir {
@@ -181,7 +253,6 @@ describe('di', () => {
expect(directive.otherAttr).toBe('value');
expect(directive.className).toBe('hello there');
expect(directive.inlineStyles).toBe('margin: 1px; color: red;');
-
});
it('should not inject attributes with namespace', () => {
@@ -210,5 +281,37 @@ describe('di', () => {
expect(directive.namespacedExist).toBeNull();
expect(directive.other).toBe('otherValue');
});
+
+ it('should not inject attributes representing bindings and outputs', () => {
+ @Directive({selector: '[dir]'})
+ class MyDir {
+ @Input() binding !: string;
+ @Output() output = new EventEmitter();
+ constructor(
+ @Attribute('exist') public exist: string,
+ @Attribute('binding') public bindingAttr: string,
+ @Attribute('output') public outputAttr: string,
+ @Attribute('other') public other: string) {}
+ }
+
+ @Component({
+ template:
+ ''
+ })
+ class MyComp {
+ @ViewChild(MyDir) directiveInstance !: MyDir;
+ }
+
+ TestBed.configureTestingModule({declarations: [MyDir, MyComp]});
+ const fixture = TestBed.createComponent(MyComp);
+ fixture.detectChanges();
+
+ const directive = fixture.componentInstance.directiveInstance;
+
+ expect(directive.exist).toBe('existValue');
+ expect(directive.bindingAttr).toBeNull();
+ expect(directive.outputAttr).toBeNull();
+ expect(directive.other).toBe('otherValue');
+ });
});
});
diff --git a/packages/core/test/render3/di_spec.ts b/packages/core/test/render3/di_spec.ts
index 07082bb508..78c91a54ee 100644
--- a/packages/core/test/render3/di_spec.ts
+++ b/packages/core/test/render3/di_spec.ts
@@ -6,14 +6,14 @@
* found in the LICENSE file at https://angular.io/license
*/
-import {Attribute, ChangeDetectorRef, ElementRef, Host, INJECTOR, Inject, InjectFlags, Injector, Optional, Renderer2, Self, SkipSelf, TemplateRef, ViewContainerRef, ɵɵdefineInjectable, ɵɵdefineInjector} from '@angular/core';
+import {ChangeDetectorRef, ElementRef, Host, INJECTOR, Inject, InjectFlags, Injector, Optional, Renderer2, Self, SkipSelf, TemplateRef, ViewContainerRef, ɵɵdefineInjectable, ɵɵdefineInjector} from '@angular/core';
import {createLView, createNodeAtIndex, createTView} from '@angular/core/src/render3/instructions/shared';
import {ComponentType, RenderFlags} from '@angular/core/src/render3/interfaces/definition';
import {createInjector} from '../../src/di/r3_injector';
import {ɵɵdefineComponent} from '../../src/render3/definition';
import {bloomAdd, bloomHasToken, bloomHashBitOrFactory as bloomHash, getOrCreateNodeInjectorForNode} from '../../src/render3/di';
-import {ɵɵProvidersFeature, ɵɵallocHostVars, ɵɵbind, ɵɵcontainer, ɵɵcontainerRefreshEnd, ɵɵcontainerRefreshStart, ɵɵdefineDirective, ɵɵdirectiveInject, ɵɵelement, ɵɵelementContainerEnd, ɵɵelementContainerStart, ɵɵelementEnd, ɵɵelementProperty, ɵɵelementStart, ɵɵembeddedViewEnd, ɵɵembeddedViewStart, ɵɵinjectAttribute, ɵɵinterpolation2, ɵɵload, ɵɵprojection, ɵɵprojectionDef, ɵɵreference, ɵɵtemplate, ɵɵtemplateRefExtractor, ɵɵtext, ɵɵtextBinding} from '../../src/render3/index';
+import {ɵɵProvidersFeature, ɵɵallocHostVars, ɵɵbind, ɵɵcontainer, ɵɵcontainerRefreshEnd, ɵɵcontainerRefreshStart, ɵɵdefineDirective, ɵɵdirectiveInject, ɵɵelement, ɵɵelementContainerEnd, ɵɵelementContainerStart, ɵɵelementEnd, ɵɵelementProperty, ɵɵelementStart, ɵɵembeddedViewEnd, ɵɵembeddedViewStart, ɵɵinterpolation2, ɵɵload, ɵɵprojection, ɵɵprojectionDef, ɵɵreference, ɵɵtemplate, ɵɵtemplateRefExtractor, ɵɵtext, ɵɵtextBinding} from '../../src/render3/index';
import {LContainer, NATIVE} from '../../src/render3/interfaces/container';
import {TNODE} from '../../src/render3/interfaces/injector';
import {AttributeMarker, TNodeType} from '../../src/render3/interfaces/node';
@@ -2054,126 +2054,6 @@ describe('di', () => {
() => { expect(() => new ComponentFixture(MyComp)).toThrow(); });
});
- describe('@Attribute', () => {
- let myDirectiveInstance !: MyDirective | null;
-
- class MyDirective {
- exists = 'wrong' as string | null;
- myDirective = 'wrong' as string | null;
- constructor(
- @Attribute('exist') existAttrValue: string|null,
- @Attribute('myDirective') myDirectiveAttrValue: string|null) {
- this.exists = existAttrValue;
- this.myDirective = myDirectiveAttrValue;
- }
-
- static ngDirectiveDef = ɵɵdefineDirective({
- type: MyDirective,
- selectors: [['', 'myDirective', '']],
- factory: () => myDirectiveInstance =
- new MyDirective(ɵɵinjectAttribute('exist'), ɵɵinjectAttribute('myDirective'))
- });
- }
-
- beforeEach(() => myDirectiveInstance = null);
-
- it('should inject attribute', () => {
- let exist = 'wrong' as string | null;
- let nonExist = 'wrong' as string | null;
-
- const MyApp = createComponent('my-app', function(rf: RenderFlags, ctx: any) {
- if (rf & RenderFlags.Create) {
- ɵɵelementStart(0, 'div', ['exist', 'existValue', 'other', 'ignore']);
- exist = ɵɵinjectAttribute('exist');
- nonExist = ɵɵinjectAttribute('nonExist');
- }
- }, 1);
-
- new ComponentFixture(MyApp);
- expect(exist).toEqual('existValue');
- expect(nonExist).toBeNull();
- });
-
- // https://stackblitz.com/edit/angular-scawyi?file=src%2Fapp%2Fapp.component.ts
- it('should inject attributes on ', () => {
- let myDirectiveInstance: MyDirective;
-
- /* */
- const MyApp = createComponent('my-app', function(rf: RenderFlags, ctx: any) {
- if (rf & RenderFlags.Create) {
- ɵɵtemplate(
- 0, null, 0, 0, 'ng-template',
- ['myDirective', 'initial', 'exist', 'existValue', 'other', 'ignore']);
- }
- if (rf & RenderFlags.Update) {
- myDirectiveInstance = getDirectiveOnNode(0);
- }
- }, 1, 0, [MyDirective]);
-
- new ComponentFixture(MyApp);
- expect(myDirectiveInstance !.exists).toEqual('existValue');
- expect(myDirectiveInstance !.myDirective).toEqual('initial');
- });
-
- // https://stackblitz.com/edit/angular-scawyi?file=src%2Fapp%2Fapp.component.ts
- it('should inject attributes on ', () => {
- let myDirectiveInstance: MyDirective;
-
- /* */
- const MyApp = createComponent('my-app', function(rf: RenderFlags, ctx: any) {
- if (rf & RenderFlags.Create) {
- ɵɵelementContainerStart(
- 0, ['myDirective', 'initial', 'exist', 'existValue', 'other', 'ignore']);
- ɵɵelementContainerEnd();
- }
- if (rf & RenderFlags.Update) {
- myDirectiveInstance = getDirectiveOnNode(0);
- }
- }, 1, 0, [MyDirective]);
-
- new ComponentFixture(MyApp);
- expect(myDirectiveInstance !.exists).toEqual('existValue');
- expect(myDirectiveInstance !.myDirective).toEqual('initial');
- });
-
- // https://stackblitz.com/edit/angular-8ytqkp?file=src%2Fapp%2Fapp.component.ts
- it('should not inject attributes representing bindings and outputs', () => {
- let exist = 'wrong' as string | null;
- let nonExist = 'wrong' as string | null;
-
- const MyApp = createComponent('my-app', function(rf: RenderFlags, ctx: any) {
- if (rf & RenderFlags.Create) {
- ɵɵelementStart(0, 'div', ['exist', 'existValue', AttributeMarker.Bindings, 'nonExist']);
- exist = ɵɵinjectAttribute('exist');
- nonExist = ɵɵinjectAttribute('nonExist');
- }
- }, 1);
-
- new ComponentFixture(MyApp);
- expect(exist).toEqual('existValue');
- expect(nonExist).toBeNull();
- });
-
- it('should not accidentally inject attributes representing bindings and outputs', () => {
- let exist = 'wrong' as string | null;
- let nonExist = 'wrong' as string | null;
-
- const MyApp = createComponent('my-app', function(rf: RenderFlags, ctx: any) {
- if (rf & RenderFlags.Create) {
- ɵɵelementStart(0, 'div', [
- 'exist', 'existValue', AttributeMarker.Bindings, 'binding1', 'nonExist', 'binding2'
- ]);
- exist = ɵɵinjectAttribute('exist');
- nonExist = ɵɵinjectAttribute('nonExist');
- }
- }, 1);
-
- new ComponentFixture(MyApp);
- expect(exist).toEqual('existValue');
- expect(nonExist).toBeNull();
- });
- });
-
describe('ɵɵinject', () => {
describe('bloom filter', () => {
let mockTView: any;