Skip to content

Commit f7f7ba3

Browse files
authored
Merge pull request #17116 from IgniteUI/coverage-extras
test(extras): adding more coverage
2 parents 9f5fee3 + 9be0448 commit f7f7ba3

File tree

11 files changed

+801
-188
lines changed

11 files changed

+801
-188
lines changed

package-lock.json

Lines changed: 162 additions & 179 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"start:elements": "ng serve --project igniteui-angular-elements",
88
"start:performance": "ng serve --project igniteui-angular-performance",
99
"build": "npm run build:lib && npm run build:elements && npm run build:extras && npm run build:schematics && npm run build:migrations && npm run build:i18n",
10-
"test": "ng test igniteui-angular",
10+
"test": "npm run test:lib && npm run test:styles && npm run test:schematics && npm run test:i18n && npm run test:extras && npm run test:elements",
1111
"lint": "ng lint",
1212
"e2e": "ng e2e",
1313
"test:lib": "ng test igniteui-angular --watch=false --no-progress --code-coverage",
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# See http://help.github.com/ignore-files/ for more about ignoring files.
2+
3+
4+
# compiled output
5+
/dist
6+
/tmp
7+
/out-tsc
8+
9+
.angular/*
10+
11+
# dependencies
12+
/node_modules
13+
14+
# IDEs and editors
15+
/.idea
16+
.project
17+
.classpath
18+
.c9/
19+
*.launch
20+
.settings/
21+
*.sublime-workspace
22+
23+
# IDE - VSCode/VS
24+
.vscode/*
25+
.vs/*
26+
!.vscode/settings.json
27+
!.vscode/tasks.json
28+
!.vscode/launch.json
29+
!.vscode/extensions.json
30+
31+
# misc
32+
/.angular/cache
33+
/.sass-cache
34+
/connect.lock
35+
/coverage
36+
/libpeerconnection.log
37+
npm-debug.log
38+
yarn-error.log
39+
testem.log
40+
/typings
41+
TESTS-**.xml
42+
43+
# System Files
44+
.DS_Store
45+
Thumbs.db
46+
47+
src/**/*.js
48+
src/**/*.js.map
49+
src/**/*.css.map
50+
51+
# Typedoc and SassDoc Themes
52+
extras/sassdoc/**/*
53+
extras/docs/themes/typedoc/bin
54+
extras/docs/themes/sassdoc/node_modules
55+
extras/docs/themes/sassdoc/sassdoc/*
56+
57+
# Localization sources
58+
i18nRepo

projects/igniteui-angular-extras/src/lib/context-menu/chart-dialog/chart-dialog.component.spec.ts

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,4 +140,96 @@ describe('IgxChartMenuComponent', () => {
140140
expect(component.isConfigAreaExpanded).toBeFalse();
141141
});
142142
});
143+
144+
describe('ngAfterViewInit', () => {
145+
it('should create a ResizeObserver and call createChart when currentChartType and chartDirective are set', () => {
146+
const factorySpy = jasmine.createSpy('chartFactory');
147+
component.chartDirective = { chartFactory: factorySpy };
148+
component.chartArea = { clear: () => {} } as any;
149+
component.currentChartType = 'Pie';
150+
151+
component.ngAfterViewInit();
152+
153+
expect(factorySpy).toHaveBeenCalledWith('Pie', component.chartArea);
154+
});
155+
156+
it('should not call createChart when currentChartType is not set', () => {
157+
const factorySpy = jasmine.createSpy('chartFactory');
158+
component.chartDirective = { chartFactory: factorySpy };
159+
component.chartArea = { clear: () => {} } as any;
160+
component.currentChartType = undefined;
161+
162+
component.ngAfterViewInit();
163+
164+
expect(factorySpy).not.toHaveBeenCalled();
165+
});
166+
167+
it('should not call createChart when chartDirective is not set', () => {
168+
component.chartDirective = undefined;
169+
component.currentChartType = 'Pie';
170+
171+
expect(() => component.ngAfterViewInit()).not.toThrow();
172+
});
173+
});
174+
175+
describe('ngOnDestroy', () => {
176+
it('should disconnect the contentObserver if it exists', () => {
177+
component.ngAfterViewInit();
178+
const observer = (component as any).contentObserver;
179+
const disconnectSpy = spyOn(observer, 'disconnect');
180+
181+
component.ngOnDestroy();
182+
183+
expect(disconnectSpy).toHaveBeenCalled();
184+
});
185+
186+
it('should complete the chartDialogResizeNotify subject', () => {
187+
const completeSpy = spyOn(component.chartDialogResizeNotify, 'complete');
188+
189+
component.ngOnDestroy();
190+
191+
expect(completeSpy).toHaveBeenCalled();
192+
});
193+
194+
it('should not throw when contentObserver is not set', () => {
195+
(component as any).contentObserver = undefined;
196+
197+
expect(() => component.ngOnDestroy()).not.toThrow();
198+
});
199+
});
200+
201+
describe('createChart title formatting', () => {
202+
beforeEach(() => {
203+
component.chartDirective = { chartFactory: () => {} };
204+
component.chartArea = { clear: () => {} } as any;
205+
});
206+
207+
it('should replace only the first comma with a space for two-word types', () => {
208+
component.createChart('ColumnGrouped');
209+
expect(component.title).toBe('Column Grouped');
210+
});
211+
212+
it('should handle chart types with numbers like Column100Stacked', () => {
213+
component.createChart('Column100Stacked');
214+
// split on uppercase: 'Column100','Stacked' → 'Column100 Stacked'
215+
expect(component.title).toBe('Column100 Stacked');
216+
});
217+
218+
it('should handle single-word chart types', () => {
219+
component.createChart('Pie');
220+
expect(component.title).toBe('Pie');
221+
});
222+
223+
it('should handle three-word chart types like ScatterBubbleChart', () => {
224+
component.createChart('ScatterBubbleChart');
225+
// 'Scatter,Bubble,Chart'.replace(',', ' ') → 'Scatter Bubble,Chart'
226+
expect(component.title).toBe('Scatter Bubble,Chart');
227+
});
228+
});
229+
230+
describe('images', () => {
231+
it('should initialize images from charts module', () => {
232+
expect(component.images).toBeDefined();
233+
});
234+
});
143235
});

projects/igniteui-angular-extras/src/lib/context-menu/context-menu.component.spec.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Subject } from 'rxjs';
44
import { IgxOverlayService } from 'igniteui-angular/core';
55
import { IgxContextMenuComponent } from './context-menu.component';
66
import { CHART_TYPE } from '../directives/chart-integration/chart-types';
7+
import { IgxChartMenuComponent } from 'igniteui-angular-extras';
78

89
describe('IgxContextMenuComponent', () => {
910
let component: IgxContextMenuComponent;
@@ -265,4 +266,68 @@ describe('IgxContextMenuComponent', () => {
265266
expect(component.displayCreationTab).toBeFalse();
266267
});
267268
});
269+
270+
describe('ngOnDestroy', () => {
271+
it('should complete destroy$ and not throw on subsequent event emissions', () => {
272+
component.ngOnDestroy();
273+
274+
// After destroy, emitting on subscribed observables should not cause errors
275+
expect(() => mockContextDirective.chartsDirective.chartTypesDetermined.emit({ chartsForCreation: [] })).not.toThrow();
276+
expect(() => mockContextDirective.textFormatter.formattersReady.emit([])).not.toThrow();
277+
expect(() => mockContextDirective.buttonClose.emit()).not.toThrow();
278+
});
279+
});
280+
281+
describe('overlayService.closing subscription', () => {
282+
it('should not reopen tabsMenu when closing a dialog that is not IgxChartMenuComponent', () => {
283+
// Simulate having an open dialog
284+
(component as any)._dialogId = 'dialog-id';
285+
const mockInstance = new (class { })();
286+
Object.setPrototypeOf(mockInstance, { constructor: { name: 'IgxChartMenuComponent' } });
287+
288+
// The closing event checks instanceof IgxChartMenuComponent — we mock at the overlay level
289+
(mockOverlay.closing as Subject<any>).next({
290+
componentRef: { instance: TestBed.createComponent(IgxChartMenuComponent).componentInstance }
291+
});
292+
293+
// When the closed component looks like an IgxChartMenuComponent and _dialogId is set, tabsMenu.open should be called
294+
expect(mockTabsMenu.open).toHaveBeenCalled();
295+
});
296+
297+
it('should not open tabsMenu when closing event has no componentRef', () => {
298+
(component as any)._dialogId = 'dialog-id';
299+
300+
(mockOverlay.closing as Subject<any>).next({ componentRef: undefined });
301+
302+
expect(mockTabsMenu.open).not.toHaveBeenCalled();
303+
});
304+
});
305+
306+
describe('overlayService.opening with chartDialogResizeNotify', () => {
307+
it('should not throw when opening event has no componentRef', () => {
308+
expect(() => {
309+
(mockOverlay.opening as Subject<any>).next({ componentRef: undefined });
310+
}).not.toThrow();
311+
});
312+
});
313+
314+
describe('constructor', () => {
315+
it('should initialize chartImages and conditionImages', () => {
316+
expect(component.chartImages).toBeDefined();
317+
expect(component.conditionImages).toBeDefined();
318+
});
319+
});
320+
321+
describe('toggleTabMenu with target setting', () => {
322+
it('should set the overlay target to the button nativeElement', () => {
323+
component.toggleTabMenu();
324+
expect((component as any)._tabsMenuOverlaySettings.target).toBe(component.button.nativeElement);
325+
});
326+
327+
it('should preserve currentChartType if already set', () => {
328+
component.currentChartType = CHART_TYPE.Pie;
329+
component.toggleTabMenu();
330+
expect(component.currentChartType).toBe(CHART_TYPE.Pie);
331+
});
332+
});
268333
});

0 commit comments

Comments
 (0)