From 0d66844ad6e9fdaff6be1d515e9dc6c386c3f2a8 Mon Sep 17 00:00:00 2001 From: cexbrayat Date: Wed, 13 Mar 2019 15:31:57 +0100 Subject: [PATCH] refactor(ivy): move di tests for Attribute to acceptance (#29299) PR Close #29299 --- packages/core/test/acceptance/di_spec.ts | 107 ++++++++++++++++++- packages/core/test/render3/di_spec.ts | 124 +---------------------- 2 files changed, 107 insertions(+), 124 deletions(-) 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;