Skip to content

Commit

Permalink
feat(tests): add export abstract classes and add few more unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ghiscoding committed Apr 6, 2020
1 parent c588946 commit 13a1bca
Show file tree
Hide file tree
Showing 11 changed files with 256 additions and 77 deletions.
108 changes: 54 additions & 54 deletions packages/common/src/extensions/__tests__/gridMenuExtension.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Column, GridOption } from '../../interfaces/index';
import { GridMenuExtension } from '../gridMenuExtension';
import { ExtensionUtility } from '../extensionUtility';
import { SharedService } from '../../services/shared.service';
import { /*ExcelExportService, ExportService,*/ FilterService, SortService } from '../../services';
import { ExcelExportService, ExportService, FilterService, SortService } from '../../services';
import { TranslateServiceStub } from '../../../../../test/translateServiceStub';

declare const Slick: any;
Expand All @@ -13,13 +13,13 @@ const gridId = 'grid1';
const gridUid = 'slickgrid_124343';
const containerId = 'demo-container';

// const excelExportServiceStub = {
// exportToExcel: jest.fn(),
// } as unknown as ExcelExportService;
const excelExportServiceStub = {
exportToExcel: jest.fn(),
} as unknown as ExcelExportService;

// const exportServiceStub = {
// exportToFile: jest.fn(),
// } as unknown as ExportService;
const exportServiceStub = {
exportToFile: jest.fn(),
} as unknown as ExportService;

const filterServiceStub = {
clearFilters: jest.fn(),
Expand Down Expand Up @@ -120,7 +120,7 @@ describe('gridMenuExtension', () => {
sharedService = new SharedService();
translateService = new TranslateServiceStub();
extensionUtility = new ExtensionUtility(sharedService, translateService);
extension = new GridMenuExtension(extensionUtility, filterServiceStub, sharedService, sortServiceStub, translateService);
extension = new GridMenuExtension(excelExportServiceStub, exportServiceStub, extensionUtility, filterServiceStub, sharedService, sortServiceStub, translateService);
translateService.setLocale('fr');
});

Expand Down Expand Up @@ -574,51 +574,51 @@ describe('gridMenuExtension', () => {
expect(refreshSpy).toHaveBeenCalled();
});

// it('should call "exportToExcel" set when the command triggered is "export-excel"', () => {
// const excelExportSpy = jest.spyOn(excelExportServiceStub, 'exportToExcel');
// const onCommandSpy = jest.spyOn(SharedService.prototype.gridOptions.gridMenu, 'onCommand');

// const instance = extension.register();
// instance.onCommand.notify({ grid: gridStub, command: 'export-excel' }, new Slick.EventData(), gridStub);

// expect(onCommandSpy).toHaveBeenCalled();
// expect(excelExportSpy).toHaveBeenCalledWith({
// filename: 'export',
// format: FileType.xlsx,
// });
// });

// it('should call "exportToFile" with CSV set when the command triggered is "export-csv"', () => {
// const exportSpy = jest.spyOn(exportServiceStub, 'exportToFile');
// const onCommandSpy = jest.spyOn(SharedService.prototype.gridOptions.gridMenu, 'onCommand');

// const instance = extension.register();
// instance.onCommand.notify({ grid: gridStub, command: 'export-csv' }, new Slick.EventData(), gridStub);

// expect(onCommandSpy).toHaveBeenCalled();
// expect(exportSpy).toHaveBeenCalledWith({
// delimiter: DelimiterType.comma,
// filename: 'export',
// format: FileType.csv,
// useUtf8WithBom: true
// });
// });

// it('should call "exportToFile" with CSV set when the command triggered is "export-text-delimited"', () => {
// const exportSpy = jest.spyOn(exportServiceStub, 'exportToFile');
// const onCommandSpy = jest.spyOn(SharedService.prototype.gridOptions.gridMenu, 'onCommand');

// const instance = extension.register();
// instance.onCommand.notify({ grid: gridStub, command: 'export-text-delimited' }, new Slick.EventData(), gridStub);

// expect(onCommandSpy).toHaveBeenCalled();
// expect(exportSpy).toHaveBeenCalledWith({
// delimiter: DelimiterType.tab,
// filename: 'export',
// format: FileType.txt,
// useUtf8WithBom: true
// });
// });
it('should call "exportToExcel" set when the command triggered is "export-excel"', () => {
const excelExportSpy = jest.spyOn(excelExportServiceStub, 'exportToExcel');
const onCommandSpy = jest.spyOn(SharedService.prototype.gridOptions.gridMenu, 'onCommand');

const instance = extension.register();
instance.onCommand.notify({ grid: gridStub, command: 'export-excel' }, new Slick.EventData(), gridStub);

expect(onCommandSpy).toHaveBeenCalled();
expect(excelExportSpy).toHaveBeenCalledWith({
filename: 'export',
format: FileType.xlsx,
});
});

it('should call "exportToFile" with CSV set when the command triggered is "export-csv"', () => {
const exportSpy = jest.spyOn(exportServiceStub, 'exportToFile');
const onCommandSpy = jest.spyOn(SharedService.prototype.gridOptions.gridMenu, 'onCommand');

const instance = extension.register();
instance.onCommand.notify({ grid: gridStub, command: 'export-csv' }, new Slick.EventData(), gridStub);

expect(onCommandSpy).toHaveBeenCalled();
expect(exportSpy).toHaveBeenCalledWith({
delimiter: DelimiterType.comma,
filename: 'export',
format: FileType.csv,
useUtf8WithBom: true
});
});

it('should call "exportToFile" with CSV set when the command triggered is "export-text-delimited"', () => {
const exportSpy = jest.spyOn(exportServiceStub, 'exportToFile');
const onCommandSpy = jest.spyOn(SharedService.prototype.gridOptions.gridMenu, 'onCommand');

const instance = extension.register();
instance.onCommand.notify({ grid: gridStub, command: 'export-text-delimited' }, new Slick.EventData(), gridStub);

expect(onCommandSpy).toHaveBeenCalled();
expect(exportSpy).toHaveBeenCalledWith({
delimiter: DelimiterType.tab,
filename: 'export',
format: FileType.txt,
useUtf8WithBom: true
});
});

it('should call the grid "setHeaderRowVisibility" method when the command triggered is "toggle-filter"', () => {
gridOptionsMock.showHeaderRow = false;
Expand Down Expand Up @@ -723,7 +723,7 @@ describe('gridMenuExtension', () => {
describe('without Translate Service', () => {
beforeEach(() => {
translateService = null;
extension = new GridMenuExtension({} as ExtensionUtility, filterServiceStub, { gridOptions: { enableTranslate: true } } as SharedService, {} as SortService, translateService);
extension = new GridMenuExtension(excelExportServiceStub, exportServiceStub, {} as ExtensionUtility, filterServiceStub, { gridOptions: { enableTranslate: true } } as SharedService, {} as SortService, translateService);
});

it('should throw an error if "enableTranslate" is set but the I18N Service is null', () => {
Expand Down
40 changes: 20 additions & 20 deletions packages/common/src/extensions/gridMenuExtension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import {
ExtensionName,
FileType,
} from '../enums/index';
// import { ExcelExportService } from '../services/excelExport.service';
// import { ExportService } from '../services/export.service';
import { ExcelExportService } from '../services/excelExport.service';
import { ExportService } from '../services/export.service';
import { ExtensionUtility } from './extensionUtility';
import { FilterService } from '../services/filter.service';
import { SortService } from '../services/sort.service';
Expand All @@ -35,8 +35,8 @@ export class GridMenuExtension implements Extension {
private _userOriginalGridMenu: GridMenu;

constructor(
// private excelExportService: ExcelExportService,
// private exportService: ExportService,
private excelExportService: ExcelExportService,
private exportService: ExportService,
private extensionUtility: ExtensionUtility,
private filterService: FilterService,
private sharedService: SharedService,
Expand Down Expand Up @@ -360,26 +360,26 @@ export class GridMenuExtension implements Extension {
this.sharedService.dataView.refresh();
break;
case 'export-csv':
// this.exportService.exportToFile({
// delimiter: DelimiterType.comma,
// filename: 'export',
// format: FileType.csv,
// useUtf8WithBom: true,
// });
this.exportService.exportToFile({
delimiter: DelimiterType.comma,
filename: 'export',
format: FileType.csv,
useUtf8WithBom: true,
});
break;
case 'export-excel':
// this.excelExportService.exportToExcel({
// filename: 'export',
// format: FileType.xlsx,
// });
this.excelExportService.exportToExcel({
filename: 'export',
format: FileType.xlsx,
});
break;
case 'export-text-delimited':
// this.exportService.exportToFile({
// delimiter: DelimiterType.tab,
// filename: 'export',
// format: FileType.txt,
// useUtf8WithBom: true,
// });
this.exportService.exportToFile({
delimiter: DelimiterType.tab,
filename: 'export',
format: FileType.txt,
useUtf8WithBom: true,
});
break;
case 'toggle-filter':
const showHeaderRow = this.sharedService && this.sharedService.gridOptions && this.sharedService.gridOptions.showHeaderRow || false;
Expand Down
95 changes: 95 additions & 0 deletions packages/common/src/formatters/__tests__/treeFormatter.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { Column } from '../../interfaces/index';
import { treeFormatter } from '../treeFormatter';

const dataViewStub = {
getIdxById: jest.fn(),
getItemByIdx: jest.fn(),
getIdPropertyName: jest.fn(),
};

const gridStub = {
getData: jest.fn(),
};

describe('the Uppercase Formatter', () => {
let dataset;

beforeEach(() => {
dataset = [
{ id: 0, firstName: 'John', lastName: 'Smith', email: 'john.smith@movie.com', parentId: null, indent: 0 },
{ id: 1, firstName: 'Jane', lastName: 'Doe', email: 'jane.doe@movie.com', parentId: 0, indent: 1 },
{ id: 2, firstName: 'Bob', lastName: 'Cane', email: 'bob.cane@movie.com', parentId: 1, indent: 2, __collapsed: true },
{ id: 2, firstName: 'Barbara', lastName: 'Cane', email: 'barbara.cane@movie.com', parentId: null, indent: 0, __collapsed: true },
];
});

it('should throw an error when oarams are mmissing', () => {
expect(() => treeFormatter(1, 1, 'blah', {} as Column, {}))
.toThrowError('You must provide a valid Tree Data column, it seems that there are no tree level found in this row');
});

it('should return empty string when DataView is not correctly formed', () => {
const output = treeFormatter(1, 1, '', { treeData: { levelPropName: 'indent' } } as Column, dataset[1]);
expect(output).toBe('');
});

it('should return empty string when value is null', () => {
const output = treeFormatter(1, 1, null, { treeData: { levelPropName: 'indent' } } as Column, dataset[1]);
expect(output).toBe('');
});

it('should return empty string when value is undefined', () => {
const output = treeFormatter(1, 1, undefined, { treeData: { levelPropName: 'indent' } } as Column, dataset[1]);
expect(output).toBe('');
});

it('should return empty string when item is undefined', () => {
const output = treeFormatter(1, 1, 'blah', { treeData: { levelPropName: 'indent' } } as Column, undefined);
expect(output).toBe('');
});

it('should return a span without any icon and ', () => {
jest.spyOn(gridStub, 'getData').mockReturnValue(dataViewStub);
jest.spyOn(dataViewStub, 'getIdxById').mockReturnValue(1);
jest.spyOn(dataViewStub, 'getItemByIdx').mockReturnValue(dataset[0]);

const output = treeFormatter(1, 1, dataset[0]['firstName'], { treeData: { levelPropName: 'indent' } } as Column, dataset[0], gridStub);
expect(output).toBe(`<span style="display:inline-block; width:0px;"></span><span class="slick-group-toggle"></span>&nbsp;John`);
});

it('should return a span without any icon and 15px indentation of a tree level 1', () => {
jest.spyOn(gridStub, 'getData').mockReturnValue(dataViewStub);
jest.spyOn(dataViewStub, 'getIdxById').mockReturnValue(1);
jest.spyOn(dataViewStub, 'getItemByIdx').mockReturnValue(dataset[1]);

const output = treeFormatter(1, 1, dataset[1]['firstName'], { treeData: { levelPropName: 'indent' } } as Column, dataset[1], gridStub);
expect(output).toBe(`<span style="display:inline-block; width:15px;"></span><span class="slick-group-toggle"></span>&nbsp;Jane`);
});

it('should return a span without any icon and 30px indentation of a tree level 2', () => {
jest.spyOn(gridStub, 'getData').mockReturnValue(dataViewStub);
jest.spyOn(dataViewStub, 'getIdxById').mockReturnValue(1);
jest.spyOn(dataViewStub, 'getItemByIdx').mockReturnValue(dataset[1]);

const output = treeFormatter(1, 1, dataset[2]['firstName'], { treeData: { levelPropName: 'indent' } } as Column, dataset[2], gridStub);
expect(output).toBe(`<span style="display:inline-block; width:30px;"></span><span class="slick-group-toggle"></span>&nbsp;Bob`);
});

it('should return a span with expanded icon and 15px indentation of a tree level 1 when current item is greater than next item', () => {
jest.spyOn(gridStub, 'getData').mockReturnValue(dataViewStub);
jest.spyOn(dataViewStub, 'getIdxById').mockReturnValue(1);
jest.spyOn(dataViewStub, 'getItemByIdx').mockReturnValue(dataset[2]);

const output = treeFormatter(1, 1, dataset[1]['firstName'], { treeData: { levelPropName: 'indent' } } as Column, dataset[1], gridStub);
expect(output).toBe(`<span style="display:inline-block; width:15px;"></span><span class="slick-group-toggle expanded"></span>&nbsp;Jane`);
});

it('should return a span with collapsed icon and 0px indentation of a tree level 0 when current item is lower than next item', () => {
jest.spyOn(gridStub, 'getData').mockReturnValue(dataViewStub);
jest.spyOn(dataViewStub, 'getIdxById').mockReturnValue(1);
jest.spyOn(dataViewStub, 'getItemByIdx').mockReturnValue(dataset[1]);

const output = treeFormatter(1, 1, dataset[3]['firstName'], { treeData: { levelPropName: 'indent' } } as Column, dataset[3], gridStub);
expect(output).toBe(`<span style="display:inline-block; width:0px;"></span><span class="slick-group-toggle collapsed"></span>&nbsp;Barbara`);
});
});
5 changes: 4 additions & 1 deletion packages/common/src/formatters/treeFormatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ export const treeFormatter: Formatter = (row: number, cell: number, value: any,
const indentMarginLeft = columnDef.treeData?.indentMarginLeft || 15;
const dataView = grid && grid.getData();

if (value === null || value === undefined || dataContext === undefined) {
return '';
}

if (!dataContext.hasOwnProperty(treeLevelPropName)) {
throw new Error('You must provide a valid Tree Data column, it seems that there are no tree level found in this row');
}

if (dataView && dataView.getIdxById && dataView.getItemByIdx) {
if (value === null || value === undefined || dataContext === undefined) { return ''; }
value = value.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
const identifierPropName = dataView.getIdPropertyName() || 'id';
const spacer = `<span style="display:inline-block; width:${indentMarginLeft * dataContext[treeLevelPropName]}px;"></span>`;
Expand Down
21 changes: 21 additions & 0 deletions packages/common/src/services/excelExport.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { ExcelExportOption } from '../interfaces/index';

export abstract class ExcelExportService {
/**
* Initialize the Export Service
* @param grid
* @param dataView
*/
init(grid: any, dataView: any): void {
console.log('ExcelExportService the "init" method must be implemented');
}

/**
* Method to return the current locale used by the App
* @return {string} current locale
*/
exportToExcel(options: ExcelExportOption): Promise<boolean> {
console.log('ExcelExportService the "exportToExcel" method must be implemented');
return new Promise((resolve) => resolve(true));
}
}
21 changes: 21 additions & 0 deletions packages/common/src/services/export.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { ExportOption } from '../interfaces/index';

export abstract class ExportService {
/**
* Initialize the Export Service
* @param grid
* @param dataView
*/
init(grid: any, dataView: any): void {
console.log('ExportService the "init" method must be implemented');
}

/**
* Method to return the current locale used by the App
* @return {string} current locale
*/
exportToFile(options: ExportOption): Promise<boolean> {
console.log('ExportService the "exportToFile" method must be implemented');
return new Promise((resolve) => resolve(true));
}
}
4 changes: 3 additions & 1 deletion packages/common/src/services/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export * from './collection.service';
export * from './excelExport.service';
export * from './export-utilities';
export * from './export.service';
export * from './extension.service';
export * from './filter.service';
export * from './grid.service';
Expand All @@ -8,5 +10,5 @@ export * from './groupingAndColspan.service';
export * from './pubSub.service';
export * from './shared.service';
export * from './sort.service';
export * from './utilities';
export * from './translater.service';
export * from './utilities';
11 changes: 11 additions & 0 deletions packages/vanilla-bundle/src/services/excelExport.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { ExcelExportService, ExcelExportOption } from '@slickgrid-universal/common';


export class ExcelExportServicer implements ExcelExportService {
init(grid: any, dataView: any): void {
}

exportToExcel(options: ExcelExportOption): Promise<boolean> {
return new Promise((resolve) => resolve(true));
}
}
Loading

0 comments on commit 13a1bca

Please sign in to comment.