From 5813c4b94c41c0fd2a3f113aa883c85ee34ed88a Mon Sep 17 00:00:00 2001 From: "zhernovkova.anna" Date: Tue, 13 Mar 2018 16:49:58 +0300 Subject: [PATCH 01/10] Prevent option change event firing when changes occur in component --- src/core/component.ts | 2 ++ src/core/events-strategy.ts | 9 ++++++--- tests/src/core/component.spec.ts | 17 +++++++++++++++++ 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/core/component.ts b/src/core/component.ts index f8092a117..5be07c3b7 100644 --- a/src/core/component.ts +++ b/src/core/component.ts @@ -101,7 +101,9 @@ export abstract class DxComponent implements OnChanges, OnInit, DoCheck, AfterCo } if (this.instance) { + this.eventHelper.lockEventFire = true; this.instance.option(name, value); + this.eventHelper.lockEventFire = false; } else { this._initialOptions[name] = value; } diff --git a/src/core/events-strategy.ts b/src/core/events-strategy.ts index 23e7d89a1..d84d1d4a9 100644 --- a/src/core/events-strategy.ts +++ b/src/core/events-strategy.ts @@ -67,14 +67,17 @@ export class NgEventsStrategy { export class EmitterHelper { strategy: NgEventsStrategy; + lockEventFire = false; constructor(ngZone: NgZone, public component: DxComponent) { this.strategy = new NgEventsStrategy(component, ngZone); } fireNgEvent(eventName: string, eventArgs: any) { - let emitter = this.component[eventName]; - if (emitter) { - emitter.next(eventArgs && eventArgs[0]); + if (!this.lockEventFire) { + let emitter = this.component[eventName]; + if (emitter) { + emitter.next(eventArgs && eventArgs[0]); + } } } createEmitter(ngEventName: string, dxEventName: string) { diff --git a/tests/src/core/component.spec.ts b/tests/src/core/component.spec.ts index b8565dd3a..25ae7a88a 100644 --- a/tests/src/core/component.spec.ts +++ b/tests/src/core/component.spec.ts @@ -194,6 +194,23 @@ describe('DevExtreme Angular widget', () => { expect(testSpy).toHaveBeenCalledTimes(1); })); + it('should not emit testOptionChange event when changes happen in component (T614207)', async(() => { + TestBed.overrideComponent(TestContainerComponent, { + set: { + template: '' + } + }); + let fixture = TestBed.createComponent(TestContainerComponent); + fixture.detectChanges(); + + let component = fixture.componentInstance, + testSpy = spyOn(component, 'testMethod'); + + component.testOption = 'new value'; + fixture.detectChanges(); + expect(testSpy).toHaveBeenCalledTimes(0); + })); + it('should change component option value', async(() => { let fixture = TestBed.createComponent(DxTestWidgetComponent); fixture.detectChanges(); From 3a2ab2e596d4c6ac49ae93be61867af99d3066ec Mon Sep 17 00:00:00 2001 From: "zhernovkova.anna" Date: Wed, 14 Mar 2018 10:35:13 +0300 Subject: [PATCH 02/10] Update event lockers --- src/core/component.ts | 13 +++++++++++-- src/core/events-strategy.ts | 4 ++-- tests/src/core/component.spec.ts | 2 +- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/core/component.ts b/src/core/component.ts index 5be07c3b7..791e73eff 100644 --- a/src/core/component.ts +++ b/src/core/component.ts @@ -93,6 +93,15 @@ export abstract class DxComponent implements OnChanges, OnInit, DoCheck, AfterCo this.instance.endUpdate(); } } + lockEventFire(name: string) { + this.eventHelper.lockEventFire.push(name + 'Change'); + } + unlockEventFire(name: string) { + let index = this.eventHelper.lockEventFire.indexOf(name + 'Change'); + if (index > -1) { + this.eventHelper.lockEventFire.splice(index, 1); + } + } protected _setOption(name: string, value: any) { this.lockWidgetUpdate(); @@ -101,9 +110,9 @@ export abstract class DxComponent implements OnChanges, OnInit, DoCheck, AfterCo } if (this.instance) { - this.eventHelper.lockEventFire = true; + this.lockEventFire(name); this.instance.option(name, value); - this.eventHelper.lockEventFire = false; + this.unlockEventFire(name); } else { this._initialOptions[name] = value; } diff --git a/src/core/events-strategy.ts b/src/core/events-strategy.ts index d84d1d4a9..d057644f2 100644 --- a/src/core/events-strategy.ts +++ b/src/core/events-strategy.ts @@ -67,13 +67,13 @@ export class NgEventsStrategy { export class EmitterHelper { strategy: NgEventsStrategy; - lockEventFire = false; + lockEventFire: Array = []; constructor(ngZone: NgZone, public component: DxComponent) { this.strategy = new NgEventsStrategy(component, ngZone); } fireNgEvent(eventName: string, eventArgs: any) { - if (!this.lockEventFire) { + if (this.lockEventFire.indexOf(eventName) === -1) { let emitter = this.component[eventName]; if (emitter) { emitter.next(eventArgs && eventArgs[0]); diff --git a/tests/src/core/component.spec.ts b/tests/src/core/component.spec.ts index 25ae7a88a..29d879afa 100644 --- a/tests/src/core/component.spec.ts +++ b/tests/src/core/component.spec.ts @@ -194,7 +194,7 @@ describe('DevExtreme Angular widget', () => { expect(testSpy).toHaveBeenCalledTimes(1); })); - it('should not emit testOptionChange event when changes happen in component (T614207)', async(() => { + it('should not emit testOptionChange event when changes occur in component (T614207)', () => { TestBed.overrideComponent(TestContainerComponent, { set: { template: '' From 4d6026a0f9c8021849342ff44a55ce47b28903ea Mon Sep 17 00:00:00 2001 From: "zhernovkova.anna" Date: Wed, 14 Mar 2018 10:56:25 +0300 Subject: [PATCH 03/10] Fix typo --- tests/src/core/component.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/core/component.spec.ts b/tests/src/core/component.spec.ts index 29d879afa..eca0169a9 100644 --- a/tests/src/core/component.spec.ts +++ b/tests/src/core/component.spec.ts @@ -209,7 +209,7 @@ describe('DevExtreme Angular widget', () => { component.testOption = 'new value'; fixture.detectChanges(); expect(testSpy).toHaveBeenCalledTimes(0); - })); + }); it('should change component option value', async(() => { let fixture = TestBed.createComponent(DxTestWidgetComponent); From 85aad2425e53e8cfc9af61f13bb359c8d4aa1832 Mon Sep 17 00:00:00 2001 From: "zhernovkova.anna" Date: Wed, 14 Mar 2018 11:22:23 +0300 Subject: [PATCH 04/10] Add test for bound options --- tests/src/ui/accordion.spec.ts | 74 ++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 tests/src/ui/accordion.spec.ts diff --git a/tests/src/ui/accordion.spec.ts b/tests/src/ui/accordion.spec.ts new file mode 100644 index 000000000..58a6f0ab5 --- /dev/null +++ b/tests/src/ui/accordion.spec.ts @@ -0,0 +1,74 @@ +/* tslint:disable:component-selector */ + +import { + Component, + ViewChildren, + QueryList +} from '@angular/core'; + +import { TestBed } from '@angular/core/testing'; + +import DxAccordion from 'devextreme/ui/accordion'; + +import { + DxAccordionModule, + DxAccordionComponent +} from '../../../dist'; + +@Component({ + selector: 'test-container-component', + template: '' +}) +class TestContainerComponent { + items = [{ id: 1, name: 'name1' }, { id: 2, name: 'name2' }]; + selectedItem = this.items[0]; + selectedIndex = 0; + + @ViewChildren(DxAccordionComponent) innerWidgets: QueryList; +} + +describe('DxAccordion', () => { + + beforeEach(() => { + TestBed.configureTestingModule( + { + declarations: [TestContainerComponent], + imports: [DxAccordionModule] + }); + }); + + function getWidget(fixture) { + let widgetElement = fixture.nativeElement.querySelector('.dx-accordion') || fixture.nativeElement; + return DxAccordion['getInstance'](widgetElement) as any; + } + + it('should change bound options', () => { + TestBed.overrideComponent(TestContainerComponent, { + set: { + template: ` + + + ` + } + }); + + let fixture = TestBed.createComponent(TestContainerComponent); + fixture.detectChanges(); + + let accordion = fixture.componentInstance; + let instance = getWidget(fixture); + + expect(instance.option('selectedIndex')).toBe(0); + expect(instance.option('selectedItem')).toBe(accordion.items[0]); + expect(accordion.selectedIndex).toBe(0); + expect(accordion.selectedItem).toBe(accordion.items[0]); + + accordion.selectedIndex = 1; + fixture.detectChanges(); + + expect(instance.option('selectedIndex')).toBe(1); + expect(instance.option('selectedItem')).toBe(accordion.items[1]); + expect(accordion.selectedIndex).toBe(1); + expect(accordion.selectedItem).toBe(accordion.items[1]); + }); +}); From 57a08c6cbacc2f2e2fd5602907e2e965dc34d246 Mon Sep 17 00:00:00 2001 From: "zhernovkova.anna" Date: Wed, 14 Mar 2018 14:15:39 +0300 Subject: [PATCH 05/10] Simplify lockers --- src/core/component.ts | 13 ++----------- src/core/events-strategy.ts | 4 ++-- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/src/core/component.ts b/src/core/component.ts index 791e73eff..4a8f0754f 100644 --- a/src/core/component.ts +++ b/src/core/component.ts @@ -93,15 +93,6 @@ export abstract class DxComponent implements OnChanges, OnInit, DoCheck, AfterCo this.instance.endUpdate(); } } - lockEventFire(name: string) { - this.eventHelper.lockEventFire.push(name + 'Change'); - } - unlockEventFire(name: string) { - let index = this.eventHelper.lockEventFire.indexOf(name + 'Change'); - if (index > -1) { - this.eventHelper.lockEventFire.splice(index, 1); - } - } protected _setOption(name: string, value: any) { this.lockWidgetUpdate(); @@ -110,9 +101,9 @@ export abstract class DxComponent implements OnChanges, OnInit, DoCheck, AfterCo } if (this.instance) { - this.lockEventFire(name); + this.eventHelper.lockEventFire = name + 'Change'; this.instance.option(name, value); - this.unlockEventFire(name); + this.eventHelper.lockEventFire = ''; } else { this._initialOptions[name] = value; } diff --git a/src/core/events-strategy.ts b/src/core/events-strategy.ts index d057644f2..4d39fc4f7 100644 --- a/src/core/events-strategy.ts +++ b/src/core/events-strategy.ts @@ -67,13 +67,13 @@ export class NgEventsStrategy { export class EmitterHelper { strategy: NgEventsStrategy; - lockEventFire: Array = []; + lockEventFire = ''; constructor(ngZone: NgZone, public component: DxComponent) { this.strategy = new NgEventsStrategy(component, ngZone); } fireNgEvent(eventName: string, eventArgs: any) { - if (this.lockEventFire.indexOf(eventName) === -1) { + if (this.lockEventFire !== eventName) { let emitter = this.component[eventName]; if (emitter) { emitter.next(eventArgs && eventArgs[0]); From ed8f2ed366b3991c70bb2f06aeb8675fa823b873 Mon Sep 17 00:00:00 2001 From: "zhernovkova.anna" Date: Wed, 14 Mar 2018 15:43:36 +0300 Subject: [PATCH 06/10] Refactor test --- tests/src/ui/accordion.spec.ts | 54 ++++++++++++++-------------------- 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/tests/src/ui/accordion.spec.ts b/tests/src/ui/accordion.spec.ts index 58a6f0ab5..33f6464b6 100644 --- a/tests/src/ui/accordion.spec.ts +++ b/tests/src/ui/accordion.spec.ts @@ -2,13 +2,12 @@ import { Component, - ViewChildren, - QueryList + ViewChild } from '@angular/core'; -import { TestBed } from '@angular/core/testing'; - -import DxAccordion from 'devextreme/ui/accordion'; +import { + TestBed +} from '@angular/core/testing'; import { DxAccordionModule, @@ -17,18 +16,23 @@ import { @Component({ selector: 'test-container-component', - template: '' + template: ` + + ` }) class TestContainerComponent { + @ViewChild(DxAccordionComponent) accordion: DxAccordionComponent; + items = [{ id: 1, name: 'name1' }, { id: 2, name: 'name2' }]; selectedItem = this.items[0]; selectedIndex = 0; - - @ViewChildren(DxAccordionComponent) innerWidgets: QueryList; } describe('DxAccordion', () => { - beforeEach(() => { TestBed.configureTestingModule( { @@ -37,38 +41,24 @@ describe('DxAccordion', () => { }); }); - function getWidget(fixture) { - let widgetElement = fixture.nativeElement.querySelector('.dx-accordion') || fixture.nativeElement; - return DxAccordion['getInstance'](widgetElement) as any; - } - it('should change bound options', () => { - TestBed.overrideComponent(TestContainerComponent, { - set: { - template: ` - - - ` - } - }); - let fixture = TestBed.createComponent(TestContainerComponent); fixture.detectChanges(); - let accordion = fixture.componentInstance; - let instance = getWidget(fixture); + let component: TestContainerComponent = fixture.componentInstance; + let instance: any = component.accordion.instance; expect(instance.option('selectedIndex')).toBe(0); - expect(instance.option('selectedItem')).toBe(accordion.items[0]); - expect(accordion.selectedIndex).toBe(0); - expect(accordion.selectedItem).toBe(accordion.items[0]); + expect(instance.option('selectedItem')).toBe(component.items[0]); + expect(component.selectedIndex).toBe(0); + expect(component.selectedItem).toBe(component.items[0]); - accordion.selectedIndex = 1; + component.selectedIndex = 1; fixture.detectChanges(); expect(instance.option('selectedIndex')).toBe(1); - expect(instance.option('selectedItem')).toBe(accordion.items[1]); - expect(accordion.selectedIndex).toBe(1); - expect(accordion.selectedItem).toBe(accordion.items[1]); + expect(instance.option('selectedItem')).toBe(component.items[1]); + expect(component.selectedIndex).toBe(1); + expect(component.selectedItem).toBe(component.items[1]); }); }); From 5220137ca3de3fd6179e627b12a4c77e7ccdaec0 Mon Sep 17 00:00:00 2001 From: "zhernovkova.anna" Date: Thu, 15 Mar 2018 13:49:57 +0300 Subject: [PATCH 07/10] Prevent option change event firing when nested option was changed --- src/core/component.ts | 4 ++-- src/core/events-strategy.ts | 13 +++++++------ src/core/nested-option.ts | 19 ++++++++++++++++++- tests/src/core/nested-option.spec.ts | 23 +++++++++++++++++++++++ 4 files changed, 50 insertions(+), 9 deletions(-) diff --git a/src/core/component.ts b/src/core/component.ts index 4a8f0754f..b5b56ba3b 100644 --- a/src/core/component.ts +++ b/src/core/component.ts @@ -101,9 +101,9 @@ export abstract class DxComponent implements OnChanges, OnInit, DoCheck, AfterCo } if (this.instance) { - this.eventHelper.lockEventFire = name + 'Change'; + this.eventHelper.lockedEventName = name + 'Change'; this.instance.option(name, value); - this.eventHelper.lockEventFire = ''; + this.eventHelper.lockedEventName = ''; } else { this._initialOptions[name] = value; } diff --git a/src/core/events-strategy.ts b/src/core/events-strategy.ts index 4d39fc4f7..49ee70fb1 100644 --- a/src/core/events-strategy.ts +++ b/src/core/events-strategy.ts @@ -67,17 +67,18 @@ export class NgEventsStrategy { export class EmitterHelper { strategy: NgEventsStrategy; - lockEventFire = ''; + lockedEventName = ''; constructor(ngZone: NgZone, public component: DxComponent) { this.strategy = new NgEventsStrategy(component, ngZone); } fireNgEvent(eventName: string, eventArgs: any) { - if (this.lockEventFire !== eventName) { - let emitter = this.component[eventName]; - if (emitter) { - emitter.next(eventArgs && eventArgs[0]); - } + if (this.lockedEventName === eventName) { + return; + } + let emitter = this.component[eventName]; + if (emitter) { + emitter.next(eventArgs && eventArgs[0]); } } createEmitter(ngEventName: string, dxEventName: string) { diff --git a/src/core/nested-option.ts b/src/core/nested-option.ts index c550dd6f2..0dbeb546b 100644 --- a/src/core/nested-option.ts +++ b/src/core/nested-option.ts @@ -38,7 +38,12 @@ export abstract class BaseNestedOption implements INestedOptionContainer, IColle protected _setOption(name: string, value: any) { if (this.isLinked) { - this.instance.option(this._fullOptionPath() + name, value); + let optionPath = this._fullOptionPath(), + parent = this.getParentComponent(); + + parent.eventHelper.lockedEventName = optionPath.split('.')[0] + 'Change'; + this.instance.option(optionPath + name, value); + parent.eventHelper.lockedEventName = ''; } else { this._initialOptions[name] = value; } @@ -49,6 +54,18 @@ export abstract class BaseNestedOption implements INestedOptionContainer, IColle this._hostOptionPath = optionPath; } + getHost() { + return this._host; + } + + getParentComponent() { + let parent: any = this.getHost(); + while (parent.getHost) { + parent = parent.getHost(); + } + return parent; + } + setChildren(propertyName: string, items: QueryList) { return this._collectionContainerImpl.setChildren(propertyName, items); } diff --git a/tests/src/core/nested-option.spec.ts b/tests/src/core/nested-option.spec.ts index 0aeb78a43..3afe7db38 100644 --- a/tests/src/core/nested-option.spec.ts +++ b/tests/src/core/nested-option.spec.ts @@ -225,6 +225,8 @@ export class DxTestWidgetComponent extends DxComponent { export class TestContainerComponent { testOption: string; @ViewChildren(DxTestWidgetComponent) innerWidgets: QueryList; + + testMethod() {} } @@ -329,4 +331,25 @@ describe('DevExtreme Angular widget', () => { expect(nestedOption.shownEventFired).toBe(true); })); + it('nested option setting should not emit testOptionChange event (T614207)', () => { + TestBed.overrideComponent(TestContainerComponent, { + set: { + template: ` + + + + ` + } + }); + let fixture = TestBed.createComponent(TestContainerComponent); + fixture.detectChanges(); + + let component = fixture.componentInstance, + testSpy = spyOn(component, 'testMethod'); + + component.testOption = 'new value'; + fixture.detectChanges(); + expect(testSpy).toHaveBeenCalledTimes(0); + }); + }); From 8747f65508198aeab0f1ded8210847696c94ec7a Mon Sep 17 00:00:00 2001 From: "zhernovkova.anna" Date: Tue, 20 Mar 2018 14:56:16 +0300 Subject: [PATCH 08/10] Move event locker to writeValue method --- src/core/component.ts | 2 - src/core/events-strategy.ts | 4 +- src/core/nested-option.ts | 19 +----- templates/component.tst | 2 + tests/src/core/component.spec.ts | 17 ----- tests/src/core/nested-option.spec.ts | 23 ------- tests/src/ui/accordion.spec.ts | 64 ------------------- ...stom-value-accessor-implementation.spec.ts | 18 +++++- 8 files changed, 22 insertions(+), 127 deletions(-) delete mode 100644 tests/src/ui/accordion.spec.ts diff --git a/src/core/component.ts b/src/core/component.ts index b5b56ba3b..f8092a117 100644 --- a/src/core/component.ts +++ b/src/core/component.ts @@ -101,9 +101,7 @@ export abstract class DxComponent implements OnChanges, OnInit, DoCheck, AfterCo } if (this.instance) { - this.eventHelper.lockedEventName = name + 'Change'; this.instance.option(name, value); - this.eventHelper.lockedEventName = ''; } else { this._initialOptions[name] = value; } diff --git a/src/core/events-strategy.ts b/src/core/events-strategy.ts index 49ee70fb1..d891406fc 100644 --- a/src/core/events-strategy.ts +++ b/src/core/events-strategy.ts @@ -67,13 +67,13 @@ export class NgEventsStrategy { export class EmitterHelper { strategy: NgEventsStrategy; - lockedEventName = ''; + lockedValueChangeEvent = false; constructor(ngZone: NgZone, public component: DxComponent) { this.strategy = new NgEventsStrategy(component, ngZone); } fireNgEvent(eventName: string, eventArgs: any) { - if (this.lockedEventName === eventName) { + if (this.lockedValueChangeEvent && eventName === 'valueChange') { return; } let emitter = this.component[eventName]; diff --git a/src/core/nested-option.ts b/src/core/nested-option.ts index 0dbeb546b..c550dd6f2 100644 --- a/src/core/nested-option.ts +++ b/src/core/nested-option.ts @@ -38,12 +38,7 @@ export abstract class BaseNestedOption implements INestedOptionContainer, IColle protected _setOption(name: string, value: any) { if (this.isLinked) { - let optionPath = this._fullOptionPath(), - parent = this.getParentComponent(); - - parent.eventHelper.lockedEventName = optionPath.split('.')[0] + 'Change'; - this.instance.option(optionPath + name, value); - parent.eventHelper.lockedEventName = ''; + this.instance.option(this._fullOptionPath() + name, value); } else { this._initialOptions[name] = value; } @@ -54,18 +49,6 @@ export abstract class BaseNestedOption implements INestedOptionContainer, IColle this._hostOptionPath = optionPath; } - getHost() { - return this._host; - } - - getParentComponent() { - let parent: any = this.getHost(); - while (parent.getHost) { - parent = parent.getHost(); - } - return parent; - } - setChildren(propertyName: string, items: QueryList) { return this._collectionContainerImpl.setChildren(propertyName, items); } diff --git a/templates/component.tst b/templates/component.tst index 2d08882fd..b836e8f48 100644 --- a/templates/component.tst +++ b/templates/component.tst @@ -147,7 +147,9 @@ export class <#= it.className #>Component extends <#= baseClass #> <#? implement } <#? it.isEditor #> writeValue(value: any): void { + this.eventHelper.lockedValueChangeEvent = true; this.value = value; + this.eventHelper.lockedValueChangeEvent = false; } <#? it.widgetName !== "dxRangeSelector" #> setDisabledState(isDisabled: boolean): void { diff --git a/tests/src/core/component.spec.ts b/tests/src/core/component.spec.ts index eca0169a9..b8565dd3a 100644 --- a/tests/src/core/component.spec.ts +++ b/tests/src/core/component.spec.ts @@ -194,23 +194,6 @@ describe('DevExtreme Angular widget', () => { expect(testSpy).toHaveBeenCalledTimes(1); })); - it('should not emit testOptionChange event when changes occur in component (T614207)', () => { - TestBed.overrideComponent(TestContainerComponent, { - set: { - template: '' - } - }); - let fixture = TestBed.createComponent(TestContainerComponent); - fixture.detectChanges(); - - let component = fixture.componentInstance, - testSpy = spyOn(component, 'testMethod'); - - component.testOption = 'new value'; - fixture.detectChanges(); - expect(testSpy).toHaveBeenCalledTimes(0); - }); - it('should change component option value', async(() => { let fixture = TestBed.createComponent(DxTestWidgetComponent); fixture.detectChanges(); diff --git a/tests/src/core/nested-option.spec.ts b/tests/src/core/nested-option.spec.ts index 3afe7db38..0aeb78a43 100644 --- a/tests/src/core/nested-option.spec.ts +++ b/tests/src/core/nested-option.spec.ts @@ -225,8 +225,6 @@ export class DxTestWidgetComponent extends DxComponent { export class TestContainerComponent { testOption: string; @ViewChildren(DxTestWidgetComponent) innerWidgets: QueryList; - - testMethod() {} } @@ -331,25 +329,4 @@ describe('DevExtreme Angular widget', () => { expect(nestedOption.shownEventFired).toBe(true); })); - it('nested option setting should not emit testOptionChange event (T614207)', () => { - TestBed.overrideComponent(TestContainerComponent, { - set: { - template: ` - - - - ` - } - }); - let fixture = TestBed.createComponent(TestContainerComponent); - fixture.detectChanges(); - - let component = fixture.componentInstance, - testSpy = spyOn(component, 'testMethod'); - - component.testOption = 'new value'; - fixture.detectChanges(); - expect(testSpy).toHaveBeenCalledTimes(0); - }); - }); diff --git a/tests/src/ui/accordion.spec.ts b/tests/src/ui/accordion.spec.ts deleted file mode 100644 index 33f6464b6..000000000 --- a/tests/src/ui/accordion.spec.ts +++ /dev/null @@ -1,64 +0,0 @@ -/* tslint:disable:component-selector */ - -import { - Component, - ViewChild -} from '@angular/core'; - -import { - TestBed -} from '@angular/core/testing'; - -import { - DxAccordionModule, - DxAccordionComponent -} from '../../../dist'; - -@Component({ - selector: 'test-container-component', - template: ` - - ` -}) -class TestContainerComponent { - @ViewChild(DxAccordionComponent) accordion: DxAccordionComponent; - - items = [{ id: 1, name: 'name1' }, { id: 2, name: 'name2' }]; - selectedItem = this.items[0]; - selectedIndex = 0; -} - -describe('DxAccordion', () => { - beforeEach(() => { - TestBed.configureTestingModule( - { - declarations: [TestContainerComponent], - imports: [DxAccordionModule] - }); - }); - - it('should change bound options', () => { - let fixture = TestBed.createComponent(TestContainerComponent); - fixture.detectChanges(); - - let component: TestContainerComponent = fixture.componentInstance; - let instance: any = component.accordion.instance; - - expect(instance.option('selectedIndex')).toBe(0); - expect(instance.option('selectedItem')).toBe(component.items[0]); - expect(component.selectedIndex).toBe(0); - expect(component.selectedItem).toBe(component.items[0]); - - component.selectedIndex = 1; - fixture.detectChanges(); - - expect(instance.option('selectedIndex')).toBe(1); - expect(instance.option('selectedItem')).toBe(component.items[1]); - expect(component.selectedIndex).toBe(1); - expect(component.selectedItem).toBe(component.items[1]); - }); -}); diff --git a/tests/src/ui/custom-value-accessor-implementation.spec.ts b/tests/src/ui/custom-value-accessor-implementation.spec.ts index b02981ee5..c7527757d 100644 --- a/tests/src/ui/custom-value-accessor-implementation.spec.ts +++ b/tests/src/ui/custom-value-accessor-implementation.spec.ts @@ -28,7 +28,7 @@ import { template: `
- +
` @@ -44,6 +44,7 @@ class TestContainerComponent implements OnInit { }); this.formControl = this.form.controls['formControl']; } + testMethod() { } } describe('DxTextBox value accessor', () => { @@ -78,6 +79,7 @@ describe('DxTextBox value accessor', () => { expect(instance.option('disabled')).toBe(false); })); + it('should change the value', async(() => { let fixture = TestBed.createComponent(TestContainerComponent); fixture.detectChanges(); @@ -89,6 +91,7 @@ describe('DxTextBox value accessor', () => { expect(instance.option('value')).toBe('text'); })); + it('should change touched option', async(() => { let fixture = TestBed.createComponent(TestContainerComponent); fixture.detectChanges(); @@ -102,4 +105,17 @@ describe('DxTextBox value accessor', () => { expect(fixture.componentInstance.formControl.touched).toBe(true); })); + + it('should not fire valueChange event after value changing (T614207)', () => { + let fixture = TestBed.createComponent(TestContainerComponent); + fixture.detectChanges(); + + let component = fixture.componentInstance, + testSpy = spyOn(component, 'testMethod'); + + component.value = 'text'; + fixture.detectChanges(); + + expect(testSpy).toHaveBeenCalledTimes(0); + }); }); From 8bca0b94a0faf5ad31d8c5e3a0bfbfc58ee13ddc Mon Sep 17 00:00:00 2001 From: "zhernovkova.anna" Date: Tue, 20 Mar 2018 16:01:18 +0300 Subject: [PATCH 09/10] Rework test --- ...custom-value-accessor-implementation.spec.ts | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/tests/src/ui/custom-value-accessor-implementation.spec.ts b/tests/src/ui/custom-value-accessor-implementation.spec.ts index c7527757d..c9d249b93 100644 --- a/tests/src/ui/custom-value-accessor-implementation.spec.ts +++ b/tests/src/ui/custom-value-accessor-implementation.spec.ts @@ -28,7 +28,7 @@ import { template: `
- +
` @@ -44,7 +44,6 @@ class TestContainerComponent implements OnInit { }); this.formControl = this.form.controls['formControl']; } - testMethod() { } } describe('DxTextBox value accessor', () => { @@ -106,16 +105,22 @@ describe('DxTextBox value accessor', () => { expect(fixture.componentInstance.formControl.touched).toBe(true); })); - it('should not fire valueChange event after value changing (T614207)', () => { + it('should not fire valueChanges event when patchValue method is used with emitEvent=false (T614207)', () => { let fixture = TestBed.createComponent(TestContainerComponent); fixture.detectChanges(); let component = fixture.componentInstance, - testSpy = spyOn(component, 'testMethod'); + form = component.form, + testSpy = jasmine.createSpy('testSpy'); - component.value = 'text'; - fixture.detectChanges(); + form.valueChanges.subscribe(testSpy); + form.controls['formControl'].patchValue('text', { emitEvent: false }); + fixture.detectChanges(); expect(testSpy).toHaveBeenCalledTimes(0); + + form.controls['formControl'].patchValue('text'); + fixture.detectChanges(); + expect(testSpy).toHaveBeenCalledTimes(1); }); }); From 9cae97f8ab5f1a4c4508bf6bc6d513cd921d5aa7 Mon Sep 17 00:00:00 2001 From: "zhernovkova.anna" Date: Tue, 20 Mar 2018 16:04:05 +0300 Subject: [PATCH 10/10] Fix typo --- tests/src/ui/custom-value-accessor-implementation.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/ui/custom-value-accessor-implementation.spec.ts b/tests/src/ui/custom-value-accessor-implementation.spec.ts index c9d249b93..ad9bfd8f0 100644 --- a/tests/src/ui/custom-value-accessor-implementation.spec.ts +++ b/tests/src/ui/custom-value-accessor-implementation.spec.ts @@ -119,7 +119,7 @@ describe('DxTextBox value accessor', () => { fixture.detectChanges(); expect(testSpy).toHaveBeenCalledTimes(0); - form.controls['formControl'].patchValue('text'); + form.controls['formControl'].patchValue('text2'); fixture.detectChanges(); expect(testSpy).toHaveBeenCalledTimes(1); });