Skip to content
This repository was archived by the owner on Jan 13, 2025. It is now read-only.

Commit ba9e310

Browse files
Shi Shucopybara-github
authored andcommitted
test(tooltip): Splits unit tests for destroy into multiple methods to ensure cancellation of all potential timeouts and removal of all potential event handlers. Smaller methods also make code more readable and easier to maintain.
PiperOrigin-RevId: 346363503
1 parent fd88d40 commit ba9e310

File tree

1 file changed

+107
-17
lines changed

1 file changed

+107
-17
lines changed

packages/mdc-tooltip/test/foundation.test.ts

Lines changed: 107 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ const ESC_EVENTS = [
3333
{type: 'keydown', keyCode: 27, target: {}},
3434
];
3535

36+
// Constant for the animationFrame mock found in setUpMdcTestEnvironment
37+
const ANIMATION_FRAME = 1;
38+
3639
// This function assumes that the foundation has already been initialized for
3740
// rich tooltips. If isRich and isPersistent have not been initialized, the
3841
// checks for rich tooltip and persistent rich tooltips will not be called. This
@@ -1229,27 +1232,93 @@ describe('MDCTooltipFoundation', () => {
12291232
.toHaveBeenCalledWith('top', `${expectedTooltipTop}px`);
12301233
});
12311234

1232-
it('#destroy cancels any pending callbacks, removes global event listeners, and removes all tooltip animation classes',
1235+
it('#destroy clears showTimeout', () => {
1236+
const {foundation} = setUpFoundationTest(MDCTooltipFoundation);
1237+
1238+
foundation.handleAnchorMouseEnter();
1239+
foundation.destroy();
1240+
1241+
expect(foundation.showTimeout).toEqual(null);
1242+
});
1243+
1244+
it('#destroy clears requestAnimationFrame from show', () => {
1245+
const {foundation, mockAdapter} = setUpFoundationTest(MDCTooltipFoundation);
1246+
1247+
foundation.show();
1248+
expect(foundation['frameId']).not.toEqual(null);
1249+
foundation.destroy();
1250+
jasmine.clock().tick(ANIMATION_FRAME);
1251+
1252+
expect(foundation['frameId']).toEqual(null);
1253+
expect(mockAdapter.removeClass)
1254+
.toHaveBeenCalledWith(CssClasses.SHOWING_TRANSITION);
1255+
expect(mockAdapter.removeClass)
1256+
.toHaveBeenCalledWith(CssClasses.HIDE_TRANSITION);
1257+
// 1 call from show and 5 calls from destroy
1258+
expect(mockAdapter.removeClass).toHaveBeenCalledTimes(6);
1259+
expect(mockAdapter.addClass).not.toHaveBeenCalledWith(CssClasses.SHOWN);
1260+
expect(mockAdapter.addClass)
1261+
.not.toHaveBeenCalledWith(CssClasses.SHOWING_TRANSITION);
1262+
});
1263+
1264+
it('#destroy clears hideTimeout', () => {
1265+
const {foundation} = setUpFoundationTest(MDCTooltipFoundation);
1266+
1267+
foundation.handleAnchorMouseLeave();
1268+
foundation.destroy();
1269+
1270+
expect(foundation.hideTimeout).toEqual(null);
1271+
});
1272+
1273+
it('#destroy removes tooltip classes', () => {
1274+
const {foundation, mockAdapter} = setUpFoundationTest(MDCTooltipFoundation);
1275+
1276+
foundation.destroy();
1277+
1278+
expect(mockAdapter.removeClass).toHaveBeenCalledWith(CssClasses.SHOWN);
1279+
expect(mockAdapter.removeClass)
1280+
.toHaveBeenCalledWith(CssClasses.SHOWING_TRANSITION);
1281+
expect(mockAdapter.removeClass).toHaveBeenCalledWith(CssClasses.SHOWING);
1282+
expect(mockAdapter.removeClass).toHaveBeenCalledWith(CssClasses.HIDE);
1283+
expect(mockAdapter.removeClass)
1284+
.toHaveBeenCalledWith(CssClasses.HIDE_TRANSITION);
1285+
});
1286+
1287+
it('#destroy cancels all animation frame requests', () => {
1288+
const {foundation} = setUpFoundationTest(MDCTooltipFoundation);
1289+
1290+
foundation.handleWindowChangeEvent();
1291+
foundation.destroy();
1292+
1293+
expect(foundation['animFrame']['rafIDs'].size).toEqual(0);
1294+
});
1295+
1296+
it('#destroy removes the event listeners for plain tooltips', () => {
1297+
const {foundation, mockAdapter} = setUpFoundationTest(MDCTooltipFoundation);
1298+
1299+
foundation.destroy();
1300+
1301+
expect(mockAdapter.deregisterEventHandler)
1302+
.not.toHaveBeenCalledWith('mouseenter', jasmine.any(Function));
1303+
expect(mockAdapter.deregisterEventHandler)
1304+
.not.toHaveBeenCalledWith('mouseleave', jasmine.any(Function));
1305+
expect(mockAdapter.deregisterDocumentEventHandler)
1306+
.toHaveBeenCalledWith('click', jasmine.any(Function));
1307+
expect(mockAdapter.deregisterDocumentEventHandler)
1308+
.toHaveBeenCalledWith('keydown', jasmine.any(Function));
1309+
expect(mockAdapter.deregisterWindowEventHandler)
1310+
.toHaveBeenCalledWith('scroll', jasmine.any(Function));
1311+
expect(mockAdapter.deregisterWindowEventHandler)
1312+
.toHaveBeenCalledWith('resize', jasmine.any(Function));
1313+
});
1314+
1315+
it('#destroy removes the event listeners for default rich tooltips',
12331316
() => {
12341317
const {foundation, mockAdapter} =
1235-
setUpFoundationTest(MDCTooltipFoundation);
1236-
mockAdapter.hasClass.withArgs(CssClasses.RICH).and.returnValue(true);
1237-
foundation.init();
1238-
foundation.handleAnchorMouseEnter();
1239-
foundation.handleAnchorMouseLeave();
1240-
foundation.destroy();
1318+
setUpFoundationTestForRichTooltip(MDCTooltipFoundation);
12411319

1242-
jasmine.clock().tick(1);
1243-
expect(mockAdapter.addClass).not.toHaveBeenCalledWith(CssClasses.SHOWN);
1244-
expect(mockAdapter.addClass)
1245-
.not.toHaveBeenCalledWith(CssClasses.SHOWING_TRANSITION);
1246-
expect(foundation.hideTimeout).toEqual(null);
1320+
foundation.destroy();
12471321

1248-
expect(mockAdapter.removeClass).toHaveBeenCalledWith(CssClasses.SHOWN);
1249-
expect(mockAdapter.removeClass).toHaveBeenCalledWith(CssClasses.SHOWING);
1250-
expect(mockAdapter.removeClass).toHaveBeenCalledWith(CssClasses.HIDE);
1251-
expect(mockAdapter.removeClass)
1252-
.toHaveBeenCalledWith(CssClasses.HIDE_TRANSITION);
12531322
expect(mockAdapter.deregisterEventHandler)
12541323
.toHaveBeenCalledWith('mouseenter', jasmine.any(Function));
12551324
expect(mockAdapter.deregisterEventHandler)
@@ -1264,6 +1333,27 @@ describe('MDCTooltipFoundation', () => {
12641333
.toHaveBeenCalledWith('resize', jasmine.any(Function));
12651334
});
12661335

1336+
it('#destroy removes the event listeners for persistent rich tooltips',
1337+
() => {
1338+
const {foundation, mockAdapter} = setUpFoundationTestForRichTooltip(
1339+
MDCTooltipFoundation, {isPersistent: true});
1340+
1341+
foundation.destroy();
1342+
1343+
expect(mockAdapter.deregisterEventHandler)
1344+
.not.toHaveBeenCalledWith('mouseenter', jasmine.any(Function));
1345+
expect(mockAdapter.deregisterEventHandler)
1346+
.not.toHaveBeenCalledWith('mouseleave', jasmine.any(Function));
1347+
expect(mockAdapter.deregisterDocumentEventHandler)
1348+
.toHaveBeenCalledWith('click', jasmine.any(Function));
1349+
expect(mockAdapter.deregisterDocumentEventHandler)
1350+
.toHaveBeenCalledWith('keydown', jasmine.any(Function));
1351+
expect(mockAdapter.deregisterWindowEventHandler)
1352+
.toHaveBeenCalledWith('scroll', jasmine.any(Function));
1353+
expect(mockAdapter.deregisterWindowEventHandler)
1354+
.toHaveBeenCalledWith('resize', jasmine.any(Function));
1355+
});
1356+
12671357
it('recalculates position of tooltip if anchor position changes', () => {
12681358
const anchorBoundingRect =
12691359
{top: 0, bottom: 35, left: 0, right: 200, width: 200, height: 35};

0 commit comments

Comments
 (0)