From 8552d01d2c593bd981c52d1672fa7b8643ee70ac Mon Sep 17 00:00:00 2001 From: Ghislain Beaulac Date: Tue, 7 May 2019 18:12:57 -0400 Subject: [PATCH 1/6] feat(resizer): add calculateAvailableSizeBy container option - bring an extra option to calculate available grid size by their container size --- .../components/angular-slickgrid.component.ts | 2 +- .../angular-slickgrid/global-grid-options.ts | 1 + .../models/autoResizeOption.interface.ts | 3 + .../services/resizer.service.spec.ts | 55 +++++++++++++++++++ .../services/resizer.service.ts | 23 ++++++-- 5 files changed, 77 insertions(+), 7 deletions(-) create mode 100644 src/app/modules/angular-slickgrid/services/resizer.service.spec.ts diff --git a/src/app/modules/angular-slickgrid/components/angular-slickgrid.component.ts b/src/app/modules/angular-slickgrid/components/angular-slickgrid.component.ts index dbeb45110..831574828 100644 --- a/src/app/modules/angular-slickgrid/components/angular-slickgrid.component.ts +++ b/src/app/modules/angular-slickgrid/components/angular-slickgrid.component.ts @@ -589,7 +589,7 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy, OnIn this.resizer.init(grid); } if (options.enableAutoResize) { - this.resizer.attachAutoResizeDataGrid(); + this.resizer.bindAutoResizeDataGrid(); if (grid && options.autoFitColumnsOnFirstLoad && options.enableAutoSizeColumns) { grid.autosizeColumns(); } diff --git a/src/app/modules/angular-slickgrid/global-grid-options.ts b/src/app/modules/angular-slickgrid/global-grid-options.ts index 478891ddd..b30c469f1 100644 --- a/src/app/modules/angular-slickgrid/global-grid-options.ts +++ b/src/app/modules/angular-slickgrid/global-grid-options.ts @@ -10,6 +10,7 @@ export const GlobalGridOptions: GridOption = { asyncEditorLoading: false, autoFitColumnsOnFirstLoad: true, autoResize: { + calculateAvailableSizeBy: 'window', bottomPadding: 20, minHeight: 180, minWidth: 300, diff --git a/src/app/modules/angular-slickgrid/models/autoResizeOption.interface.ts b/src/app/modules/angular-slickgrid/models/autoResizeOption.interface.ts index 235e14e4a..183b72ec1 100644 --- a/src/app/modules/angular-slickgrid/models/autoResizeOption.interface.ts +++ b/src/app/modules/angular-slickgrid/models/autoResizeOption.interface.ts @@ -1,4 +1,7 @@ export interface AutoResizeOption { + /** Defaults to 'window', which DOM element are we using to calculate the available size for the grid? */ + calculateAvailableSizeBy?: 'container' | 'window'; + /** bottom padding of the grid in pixels */ bottomPadding?: number; diff --git a/src/app/modules/angular-slickgrid/services/resizer.service.spec.ts b/src/app/modules/angular-slickgrid/services/resizer.service.spec.ts new file mode 100644 index 000000000..04b4acee6 --- /dev/null +++ b/src/app/modules/angular-slickgrid/services/resizer.service.spec.ts @@ -0,0 +1,55 @@ +import { GridOption } from './../models/gridOption.interface'; +import { TestBed, async } from '@angular/core/testing'; +import { ResizerService } from './resizer.service'; +import { Component } from '@angular/core'; + +const gridOptionMock = { + gridId: 'grid1', + autoResize: { containerId: 'demo-container' }, + enableAutoResize: true +} as GridOption; + +const gridStub = { + getOptions: () => gridOptionMock, + getUID: () => 'abc123', +}; + +// define a
container to simulate the grid container +@Component({ + template: `
` +}) +class TestComponent { } + +describe('Resizer Service', () => { + let service: ResizerService; + + beforeEach(() => { + const fixture = TestBed.configureTestingModule({ + declarations: [TestComponent] + }) + .createComponent(TestComponent); + + service = new ResizerService(); + service.init(gridStub); + }); + + it('should create the service', () => { + expect(service).toBeTruthy(); + }); + + it('should trigger a grid resize on a window resize', () => { + // arrange + const gridSpy = jest.spyOn(gridStub, 'getOptions'); + const serviceSpy = jest.spyOn(service, 'resizeGrid'); + + // act + // bind window resize & call a viewport resize + service.bindAutoResizeDataGrid(); + Object.defineProperty(window, 'innerHeight', { writable: true, configurable: true, value: 500 }); + window.dispatchEvent(new Event('resize')); + + // assert + expect(gridSpy).toHaveBeenCalled(); + expect(serviceSpy).toHaveBeenCalled(); + }); +}); diff --git a/src/app/modules/angular-slickgrid/services/resizer.service.ts b/src/app/modules/angular-slickgrid/services/resizer.service.ts index 0483b7ce5..fe3424d8e 100644 --- a/src/app/modules/angular-slickgrid/services/resizer.service.ts +++ b/src/app/modules/angular-slickgrid/services/resizer.service.ts @@ -45,7 +45,7 @@ export class ResizerService { /** Attach an auto resize trigger on the datagrid, if that is enable then it will resize itself to the available space * Options: we could also provide a % factor to resize on each height/width independently */ - attachAutoResizeDataGrid(newSizes?: GridDimension) { + bindAutoResizeDataGrid(newSizes?: GridDimension) { // if we can't find the grid to resize, return without attaching anything const gridDomElm = $(`#${this._gridOptions && this._gridOptions.gridId ? this._gridOptions.gridId : 'grid1'}`); if (gridDomElm === undefined || gridDomElm.offset() === undefined) { @@ -70,7 +70,7 @@ export class ResizerService { */ calculateGridNewDimensions(gridOptions: GridOption): GridDimension | null { const gridDomElm = $(`#${gridOptions.gridId}`); - const autoResizeOptions = gridOptions && gridOptions.autoResize; + const autoResizeOptions = gridOptions && gridOptions.autoResize || {}; const containerElm = (autoResizeOptions && autoResizeOptions.containerId) ? $(`#${autoResizeOptions.containerId}`) : $(`#${gridOptions.gridContainerId}`); const windowElm = $(window); if (windowElm === undefined || containerElm === undefined || gridDomElm === undefined) { @@ -84,9 +84,20 @@ export class ResizerService { bottomPadding += DATAGRID_PAGINATION_HEIGHT; } - const gridHeight = windowElm.height() || 0; - const coordOffsetTop = gridDomElm.offset(); - const gridOffsetTop = (coordOffsetTop !== undefined) ? coordOffsetTop.top : 0; + let gridHeight = 0; + let gridOffsetTop = 0; + + // which DOM element are we using to calculate the available size for the grid? + if (autoResizeOptions.calculateAvailableSizeBy === 'container') { + // uses the container's height to calculate grid height without any top offset + gridHeight = containerElm.height() || 0; + } else { + // uses the browser's window height with its top offset to calculate grid height + gridHeight = windowElm.height() || 0; + const coordOffsetTop = gridDomElm.offset(); + gridOffsetTop = (coordOffsetTop !== undefined) ? coordOffsetTop.top : 0; + } + const availableHeight = gridHeight - gridOffsetTop - bottomPadding; const availableWidth = containerElm.width() || 0; const maxHeight = autoResizeOptions && autoResizeOptions.maxHeight || undefined; @@ -158,7 +169,7 @@ export class ResizerService { if (!this._grid || !this._gridOptions) { throw new Error(` Angular-Slickgrid resizer requires a valid Grid object and Grid Options defined. - You can fix this by setting your gridOption to use "enableAutoResize" or create an instance of the ResizerService by calling attachAutoResizeDataGrid()`); + You can fix this by setting your gridOption to use "enableAutoResize" or create an instance of the ResizerService by calling bindAutoResizeDataGrid()`); } return new Promise((resolve) => { From 998257fa6c8947b258f7839868ad9cf06598f804 Mon Sep 17 00:00:00 2001 From: Ghislain Beaulac Date: Wed, 8 May 2019 19:53:51 -0400 Subject: [PATCH 2/6] feat(tests): add full test suite to Resizer Service - also tweak some small issues found in the service & use window.innerHeight instead of jQuery(window) which comes to the same --- .../services/resizer.service.spec.ts | 164 ++++++++++++++++-- .../services/resizer.service.ts | 9 +- 2 files changed, 151 insertions(+), 22 deletions(-) diff --git a/src/app/modules/angular-slickgrid/services/resizer.service.spec.ts b/src/app/modules/angular-slickgrid/services/resizer.service.spec.ts index 04b4acee6..3e2ebe708 100644 --- a/src/app/modules/angular-slickgrid/services/resizer.service.spec.ts +++ b/src/app/modules/angular-slickgrid/services/resizer.service.spec.ts @@ -1,55 +1,185 @@ import { GridOption } from './../models/gridOption.interface'; -import { TestBed, async } from '@angular/core/testing'; import { ResizerService } from './resizer.service'; -import { Component } from '@angular/core'; + +const DATAGRID_MIN_HEIGHT = 180; +const DATAGRID_MIN_WIDTH = 300; +const DATAGRID_BOTTOM_PADDING = 20; +const DATAGRID_PAGINATION_HEIGHT = 35; +const gridId = 'grid1'; +const gridUid = 'abc123'; +const containerId = 'demo-container'; const gridOptionMock = { - gridId: 'grid1', - autoResize: { containerId: 'demo-container' }, + gridId, + gridContainerId: `slickGridContainer-${gridId}`, + autoResize: { containerId }, enableAutoResize: true } as GridOption; const gridStub = { + autosizeColumns: jest.fn(), + getScrollbarDimensions: jest.fn(), getOptions: () => gridOptionMock, - getUID: () => 'abc123', + getUID: () => gridUid, }; // define a
container to simulate the grid container -@Component({ - template: `
` -}) -class TestComponent { } +const template = + `
+
+
+
+
`; + +// --- NOTE --- +// with JSDOM our container or element height/width will always be 0 (JSDOM does not render like a real browser) +// we can only mock the window height/width, we cannot mock an element height/width +// I tried various hack but nothing worked, this one for example https://github.com/jsdom/jsdom/issues/135#issuecomment-68191941 describe('Resizer Service', () => { let service: ResizerService; beforeEach(() => { - const fixture = TestBed.configureTestingModule({ - declarations: [TestComponent] - }) - .createComponent(TestComponent); + const div = document.createElement('div'); + div.innerHTML = template; + document.body.appendChild(div); service = new ResizerService(); service.init(gridStub); }); + afterEach(() => { + service.dispose(); + }); + it('should create the service', () => { expect(service).toBeTruthy(); }); - it('should trigger a grid resize on a window resize', () => { + it('should throw an error when there is no grid object defined', () => { + service = new ResizerService(); + service.init(null); + expect(() => service.resizeGrid()).toThrowError('Angular-Slickgrid resizer requires a valid Grid object and Grid Options defined'); + }); + + it('should throw an error when there is no grid options defined', () => { + service = new ResizerService(); + service.init({ getOptions: () => null }); + expect(() => service.resizeGrid()).toThrowError('Angular-Slickgrid resizer requires a valid Grid object and Grid Options defined'); + }); + + it('should trigger a grid resize when a window resize event occurs', () => { // arrange + const newHeight = 500; + const previousHeight = window.innerHeight; const gridSpy = jest.spyOn(gridStub, 'getOptions'); - const serviceSpy = jest.spyOn(service, 'resizeGrid'); + const serviceCalculateSpy = jest.spyOn(service, 'calculateGridNewDimensions'); + const serviceResizeSpy = jest.spyOn(service, 'resizeGrid'); // act // bind window resize & call a viewport resize service.bindAutoResizeDataGrid(); - Object.defineProperty(window, 'innerHeight', { writable: true, configurable: true, value: 500 }); + Object.defineProperty(window, 'innerHeight', { writable: true, configurable: true, value: newHeight }); window.dispatchEvent(new Event('resize')); + const lastDimensions = service.getLastResizeDimensions(); + + // so the height dimension will work because calculateGridNewDimensions() uses "window.innerHeight" while the width it uses the container width + // for that reason, we can only verify the height, while the width should be set as the minimum width from the constant because 0 is override by the constant + const dimensionResult = { height: newHeight - DATAGRID_BOTTOM_PADDING, width: DATAGRID_MIN_WIDTH }; // assert expect(gridSpy).toHaveBeenCalled(); - expect(serviceSpy).toHaveBeenCalled(); + expect(serviceResizeSpy).toHaveBeenCalled(); + expect(window.innerHeight).not.toEqual(previousHeight); + expect(serviceCalculateSpy).toReturnWith(dimensionResult); + expect(lastDimensions).toEqual(dimensionResult); + service.onGridBeforeResize.subscribe((result) => expect(result).toBe(true)); + }); + + it('should resize grid to a defined height and width when fixed dimensions are provided to the init method', () => { + const fixedHeight = 330; + const fixedWidth = 412; + const windowHeight = 840; + service.init(gridStub, { height: fixedHeight, width: fixedWidth }); + const serviceCalculateSpy = jest.spyOn(service, 'calculateGridNewDimensions'); + + Object.defineProperty(window, 'innerHeight', { writable: true, configurable: true, value: windowHeight }); + window.dispatchEvent(new Event('resize')); + service.calculateGridNewDimensions(gridOptionMock); + + // same comment as previous test, the height dimension will work because calculateGridNewDimensions() uses "window.innerHeight" + expect(serviceCalculateSpy).toReturnWith({ height: fixedHeight, width: fixedWidth }); + }); + + it('should calculate new dimensions when calculateGridNewDimensions is called', () => { + const newHeight = 440; + const serviceCalculateSpy = jest.spyOn(service, 'calculateGridNewDimensions'); + + Object.defineProperty(window, 'innerHeight', { writable: true, configurable: true, value: newHeight }); + window.dispatchEvent(new Event('resize')); + service.calculateGridNewDimensions(gridOptionMock); + + // same comment as previous test, the height dimension will work because calculateGridNewDimensions() uses "window.innerHeight" + expect(serviceCalculateSpy).toReturnWith({ height: (newHeight - DATAGRID_BOTTOM_PADDING), width: DATAGRID_MIN_WIDTH }); + }); + + it('should calculate new dimensions minus a padding when "bottomPadding" is defined in "autoResize" and calculateGridNewDimensions is called', () => { + const newHeight = 422; + const inputBottomPadding = 13; + const serviceCalculateSpy = jest.spyOn(service, 'calculateGridNewDimensions'); + + Object.defineProperty(window, 'innerHeight', { writable: true, configurable: true, value: newHeight }); + window.dispatchEvent(new Event('resize')); + service.calculateGridNewDimensions({ ...gridOptionMock, autoResize: { bottomPadding: inputBottomPadding } }); + + // same comment as previous test, the height dimension will work because calculateGridNewDimensions() uses "window.innerHeight" + expect(serviceCalculateSpy).toReturnWith({ height: (newHeight - inputBottomPadding), width: DATAGRID_MIN_WIDTH }); + }); + + it('should calculate new dimensions minus the pagination height when pagination is enabled and resizeGrid is called with a delay', (done) => { + const newHeight = 440; + const newOptions = { ...gridOptionMock, enablePagination: true }; + const newGridStub = { ...gridStub, getOptions: () => newOptions }; + service.init(newGridStub); + const serviceCalculateSpy = jest.spyOn(service, 'calculateGridNewDimensions'); + + Object.defineProperty(window, 'innerHeight', { writable: true, configurable: true, value: newHeight }); + window.dispatchEvent(new Event('resize')); + service.resizeGrid(100).then((newGridDimensions) => { + // same comment as previous test, the height dimension will work because calculateGridNewDimensions() uses "window.innerHeight" + const calculatedDimensions = { height: (newHeight - DATAGRID_BOTTOM_PADDING - DATAGRID_PAGINATION_HEIGHT), width: DATAGRID_MIN_WIDTH }; + expect(serviceCalculateSpy).toReturnWith(calculatedDimensions); + expect(newGridDimensions).toEqual({ ...calculatedDimensions, heightWithPagination: (calculatedDimensions.height + DATAGRID_PAGINATION_HEIGHT) }); + done(); + }); + }); + + it('should calculate new dimensions by using the container dimensions (instead of the window dimensions) when calculateAvailableSizeBy is set to container', () => { + const newHeight = 500; + const spy = jest.spyOn(service, 'calculateGridNewDimensions'); + + Object.defineProperty(window, 'innerHeight', { writable: true, configurable: true, value: newHeight }); + window.dispatchEvent(new Event('resize')); + service.calculateGridNewDimensions({ ...gridOptionMock, autoResize: { calculateAvailableSizeBy: 'container' } }); + + // with JSDOM the height is always 0 so we can assume that the height will be the minimum height (without the padding) + expect(spy).toReturnWith({ height: DATAGRID_MIN_HEIGHT, width: DATAGRID_MIN_WIDTH }); + }); + + it('should call the autosizeColumns from the core lib when "enableAutoSizeColumns" is set and the new width is wider than prior width', () => { + const newHeight = 500; + const newOptions = { ...gridOptionMock, enableAutoSizeColumns: true }; + const newGridStub = { ...gridStub, getOptions: () => newOptions }; + service.init(newGridStub); + const serviceCalculateSpy = jest.spyOn(service, 'calculateGridNewDimensions'); + const gridAutosizeSpy = jest.spyOn(newGridStub, 'autosizeColumns'); + + service.bindAutoResizeDataGrid(); + Object.defineProperty(window, 'innerHeight', { writable: true, configurable: true, value: newHeight }); + window.dispatchEvent(new Event('resize')); + + // with JSDOM the height is always 0 so we can assume that the height will be the minimum height (without the padding) + expect(serviceCalculateSpy).toHaveBeenCalled(); + expect(gridAutosizeSpy).toHaveBeenCalled(); }); }); diff --git a/src/app/modules/angular-slickgrid/services/resizer.service.ts b/src/app/modules/angular-slickgrid/services/resizer.service.ts index fe3424d8e..c9a5e889f 100644 --- a/src/app/modules/angular-slickgrid/services/resizer.service.ts +++ b/src/app/modules/angular-slickgrid/services/resizer.service.ts @@ -31,7 +31,7 @@ export class ResizerService { } private get _gridUid(): string { - return (this._grid && this._grid.getUID) ? this._grid.getUID() : this._gridOptions.gridId; + return (this._grid && this._grid.getUID) ? this._grid.getUID() : this._gridOptions && this._gridOptions.gridId; } init(grid: any, fixedDimensions?: GridDimension): void { @@ -72,8 +72,7 @@ export class ResizerService { const gridDomElm = $(`#${gridOptions.gridId}`); const autoResizeOptions = gridOptions && gridOptions.autoResize || {}; const containerElm = (autoResizeOptions && autoResizeOptions.containerId) ? $(`#${autoResizeOptions.containerId}`) : $(`#${gridOptions.gridContainerId}`); - const windowElm = $(window); - if (windowElm === undefined || containerElm === undefined || gridDomElm === undefined) { + if (!window || containerElm === undefined || gridDomElm === undefined) { return null; } @@ -93,7 +92,7 @@ export class ResizerService { gridHeight = containerElm.height() || 0; } else { // uses the browser's window height with its top offset to calculate grid height - gridHeight = windowElm.height() || 0; + gridHeight = window.innerHeight || 0; const coordOffsetTop = gridDomElm.offset(); gridOffsetTop = (coordOffsetTop !== undefined) ? coordOffsetTop.top : 0; } @@ -220,7 +219,7 @@ export class ResizerService { // also call the grid auto-size columns so that it takes available when going bigger if (this._gridOptions && this._gridOptions.enableAutoSizeColumns && this._grid.autosizeColumns) { // make sure that the grid still exist (by looking if the Grid UID is found in the DOM tree) to avoid SlickGrid error "missing stylesheet" - if (this._gridUid && $(`.${this._gridUid}`).length > 0) { + if (this._gridUid && $(`.slickgrid_${this._gridUid}`).length > 0) { this._grid.autosizeColumns(); } From 9ba641e8856e95f58c4ea22837f27fdcc30737bf Mon Sep 17 00:00:00 2001 From: Ghislain Beaulac Date: Wed, 8 May 2019 21:37:52 -0400 Subject: [PATCH 3/6] refactor(resizer): fix grid uid which already has the slickgrid prefix --- .../angular-slickgrid/services/resizer.service.spec.ts | 4 ++-- src/app/modules/angular-slickgrid/services/resizer.service.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/modules/angular-slickgrid/services/resizer.service.spec.ts b/src/app/modules/angular-slickgrid/services/resizer.service.spec.ts index 3e2ebe708..92fb2f184 100644 --- a/src/app/modules/angular-slickgrid/services/resizer.service.spec.ts +++ b/src/app/modules/angular-slickgrid/services/resizer.service.spec.ts @@ -6,7 +6,7 @@ const DATAGRID_MIN_WIDTH = 300; const DATAGRID_BOTTOM_PADDING = 20; const DATAGRID_PAGINATION_HEIGHT = 35; const gridId = 'grid1'; -const gridUid = 'abc123'; +const gridUid = 'slickgrid_124343'; const containerId = 'demo-container'; const gridOptionMock = { @@ -27,7 +27,7 @@ const gridStub = { const template = `
-
+
`; diff --git a/src/app/modules/angular-slickgrid/services/resizer.service.ts b/src/app/modules/angular-slickgrid/services/resizer.service.ts index c9a5e889f..c7081872d 100644 --- a/src/app/modules/angular-slickgrid/services/resizer.service.ts +++ b/src/app/modules/angular-slickgrid/services/resizer.service.ts @@ -219,7 +219,7 @@ export class ResizerService { // also call the grid auto-size columns so that it takes available when going bigger if (this._gridOptions && this._gridOptions.enableAutoSizeColumns && this._grid.autosizeColumns) { // make sure that the grid still exist (by looking if the Grid UID is found in the DOM tree) to avoid SlickGrid error "missing stylesheet" - if (this._gridUid && $(`.slickgrid_${this._gridUid}`).length > 0) { + if (this._gridUid && $(`.${this._gridUid}`).length > 0) { this._grid.autosizeColumns(); } From c3f95b843362e09b8eddf9d69db2b9d2fa5e0a87 Mon Sep 17 00:00:00 2001 From: Ghislain Beaulac Date: Thu, 9 May 2019 11:14:38 -0400 Subject: [PATCH 4/6] feat(resizer): add onGridAfterResize Subject with tests --- .../services/resizer.service.spec.ts | 5 ++++- .../angular-slickgrid/services/resizer.service.ts | 15 +++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/app/modules/angular-slickgrid/services/resizer.service.spec.ts b/src/app/modules/angular-slickgrid/services/resizer.service.spec.ts index 92fb2f184..a4c3d42ca 100644 --- a/src/app/modules/angular-slickgrid/services/resizer.service.spec.ts +++ b/src/app/modules/angular-slickgrid/services/resizer.service.spec.ts @@ -72,6 +72,8 @@ describe('Resizer Service', () => { // arrange const newHeight = 500; const previousHeight = window.innerHeight; + const subjectBeforeSpy = jest.spyOn(service.onGridBeforeResize, 'next'); + const subjectAfterSpy = jest.spyOn(service.onGridAfterResize, 'next'); const gridSpy = jest.spyOn(gridStub, 'getOptions'); const serviceCalculateSpy = jest.spyOn(service, 'calculateGridNewDimensions'); const serviceResizeSpy = jest.spyOn(service, 'resizeGrid'); @@ -93,7 +95,8 @@ describe('Resizer Service', () => { expect(window.innerHeight).not.toEqual(previousHeight); expect(serviceCalculateSpy).toReturnWith(dimensionResult); expect(lastDimensions).toEqual(dimensionResult); - service.onGridBeforeResize.subscribe((result) => expect(result).toBe(true)); + expect(subjectBeforeSpy).toHaveBeenCalledWith(true); + expect(subjectAfterSpy).toHaveBeenCalledWith(dimensionResult); }); it('should resize grid to a defined height and width when fixed dimensions are provided to the init method', () => { diff --git a/src/app/modules/angular-slickgrid/services/resizer.service.ts b/src/app/modules/angular-slickgrid/services/resizer.service.ts index c7081872d..85e5facca 100644 --- a/src/app/modules/angular-slickgrid/services/resizer.service.ts +++ b/src/app/modules/angular-slickgrid/services/resizer.service.ts @@ -23,6 +23,7 @@ export class ResizerService { private _grid: any; private _lastDimensions: GridDimension; private _timer: any; + onGridAfterResize = new Subject(); onGridBeforeResize = new Subject(); /** Getter for the Grid Options pulled through the Grid Object */ @@ -177,17 +178,19 @@ export class ResizerService { if (delay > 0) { clearTimeout(this._timer); - this._timer = setTimeout(() => { - this.resizeGridWithDimensions(newSizes); - resolve(this._lastDimensions); - }, delay); + this._timer = setTimeout(() => resolve(this.resizeGridCallback(newSizes)), delay); } else { - this.resizeGridWithDimensions(newSizes); - resolve(this._lastDimensions); + resolve(this.resizeGridCallback(newSizes)); } }); } + resizeGridCallback(newSizes: GridDimension) { + const lastDimensions = this.resizeGridWithDimensions(newSizes); + this.onGridAfterResize.next(lastDimensions); + return lastDimensions; + } + resizeGridWithDimensions(newSizes?: GridDimension): GridDimension { // calculate the available sizes with minimum height defined as a constant const availableDimensions = this.calculateGridNewDimensions(this._gridOptions); From 9a9762960fb4d246cfce3ff66e66a4be08cd06eb Mon Sep 17 00:00:00 2001 From: Ghislain Beaulac Date: Thu, 9 May 2019 11:16:25 -0400 Subject: [PATCH 5/6] feat(jest): update to latest Jest version - note that we are staying on previous version of jest-preset-angular because version 7+ has some startup time issue --- jest.config.js | 2 +- package.json | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/jest.config.js b/jest.config.js index 4986aa9a7..006e8c354 100644 --- a/jest.config.js +++ b/jest.config.js @@ -42,7 +42,7 @@ module.exports = { ], reporters: ['default', 'jest-junit'], setupFiles: ['/jest-pretest.ts'], - setupTestFrameworkScriptFile: '/setup-jest.ts', + setupFilesAfterEnv: ['/setup-jest.ts'], transform: { '^.+\\.(ts|html)$': '/node_modules/jest-preset-angular/preprocessor.js', }, diff --git a/package.json b/package.json index 40bb87ca2..b59161eeb 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,7 @@ "vinyl-paths": "^2.1.0" }, "devDependencies": { - "@angular-builders/jest": "^7.3.1", + "@angular-builders/jest": "^7.4.2", "@angular-devkit/build-angular": "~0.13.1", "@angular/animations": "^7.2.8", "@angular/cli": "^7.3.1", @@ -105,12 +105,12 @@ "@angular/router": "^7.2.8", "@ng-select/ng-select": "^2.15.3", "@types/flatpickr": "^3.1.2", - "@types/jest": "^23.3.9", + "@types/jest": "^24.0.12", "@types/jquery": "^3.3.29", "@types/moment": "^2.13.0", "@types/node": "^10.12.15", "@types/text-encoding-utf-8": "^1.0.1", - "babel-jest": "^23.6.0", + "babel-jest": "^24.8.0", "bootstrap": "3.4.1", "codecov": "^3.3.0", "codelyzer": "~4.5.0", @@ -124,15 +124,14 @@ "gulp-bump": "^3.1.3", "gulp-sass": "^4.0.2", "gulp-yuidoc": "^0.1.2", - "jest": "^23.6.0", - "jest-junit": "^6.3.0", + "jest": "^24.8.0", + "jest-junit": "^6.4.0", "jest-preset-angular": "^6.0.1", "mocha": "^5.2.0", "mochawesome": "^3.1.2", "mochawesome-merge": "^1.0.7", "mochawesome-report-generator": "^3.1.5", "ng-packagr": "^4.7.0", - "ngx-wallaby-jest": "^0.0.2", "node-sass": "^4.11.0", "npm-run-all": "^4.1.5", "postcss-cli": "^6.0.1", From ce1ea93e5b4c994350fd9c17c97459802e0dd9a4 Mon Sep 17 00:00:00 2001 From: Ghislain Beaulac Date: Fri, 10 May 2019 11:39:28 -0400 Subject: [PATCH 6/6] refactor(test): add extra test of event published in resolved promise --- .../angular-slickgrid/services/resizer.service.spec.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/app/modules/angular-slickgrid/services/resizer.service.spec.ts b/src/app/modules/angular-slickgrid/services/resizer.service.spec.ts index a4c3d42ca..4c116daa5 100644 --- a/src/app/modules/angular-slickgrid/services/resizer.service.spec.ts +++ b/src/app/modules/angular-slickgrid/services/resizer.service.spec.ts @@ -144,15 +144,17 @@ describe('Resizer Service', () => { const newOptions = { ...gridOptionMock, enablePagination: true }; const newGridStub = { ...gridStub, getOptions: () => newOptions }; service.init(newGridStub); + const subjectAfterSpy = jest.spyOn(service.onGridAfterResize, 'next'); const serviceCalculateSpy = jest.spyOn(service, 'calculateGridNewDimensions'); Object.defineProperty(window, 'innerHeight', { writable: true, configurable: true, value: newHeight }); window.dispatchEvent(new Event('resize')); - service.resizeGrid(100).then((newGridDimensions) => { + service.resizeGrid(2).then((newGridDimensions) => { // same comment as previous test, the height dimension will work because calculateGridNewDimensions() uses "window.innerHeight" const calculatedDimensions = { height: (newHeight - DATAGRID_BOTTOM_PADDING - DATAGRID_PAGINATION_HEIGHT), width: DATAGRID_MIN_WIDTH }; expect(serviceCalculateSpy).toReturnWith(calculatedDimensions); expect(newGridDimensions).toEqual({ ...calculatedDimensions, heightWithPagination: (calculatedDimensions.height + DATAGRID_PAGINATION_HEIGHT) }); + expect(subjectAfterSpy).toHaveBeenCalledWith(newGridDimensions); done(); }); });