Skip to content

Commit 257c17c

Browse files
authored
Merge pull request #5702 from kh-ub-ayb/test/add-trash-extended-tests
test: add extended unit tests for Trash class
2 parents e227461 + a8105a0 commit 257c17c

File tree

1 file changed

+242
-0
lines changed

1 file changed

+242
-0
lines changed

js/__tests__/trash.test.js

Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,3 +160,245 @@ describe("Trashcan Class", () => {
160160
expect(trashcan.overTrashcan(300, 300)).toBe(false);
161161
});
162162
});
163+
164+
describe("overTrashcan edge cases", () => {
165+
let trashcan;
166+
167+
beforeEach(() => {
168+
jest.clearAllMocks();
169+
trashcan = new Trashcan(mockActivity);
170+
trashcan._container.x = 100;
171+
trashcan._container.y = 200;
172+
});
173+
174+
it("should return true for a point exactly at the top-left corner", () => {
175+
expect(trashcan.overTrashcan(100, 200)).toBe(true);
176+
});
177+
178+
it("should return true for a point exactly at the top-right corner", () => {
179+
// TRASHWIDTH is 120, so top-right is (100 + 120, 200)
180+
expect(trashcan.overTrashcan(220, 200)).toBe(true);
181+
});
182+
183+
it("should return false for a point just left of the left edge", () => {
184+
expect(trashcan.overTrashcan(99, 200)).toBe(false);
185+
});
186+
187+
it("should return false for a point just above the top edge", () => {
188+
expect(trashcan.overTrashcan(150, 199)).toBe(false);
189+
});
190+
191+
it("should return false for a point just right of the right edge", () => {
192+
// x > tx + TRASHWIDTH (100 + 120 = 220), so 221 is out
193+
expect(trashcan.overTrashcan(221, 200)).toBe(false);
194+
});
195+
196+
it("should return true for a point far below the trashcan (no lower y bound)", () => {
197+
// overTrashcan has no lower y bound check
198+
expect(trashcan.overTrashcan(150, 10000)).toBe(true);
199+
});
200+
201+
it("should return true for a point exactly on the left edge", () => {
202+
expect(trashcan.overTrashcan(100, 250)).toBe(true);
203+
});
204+
205+
it("should return true for a point exactly on the right edge", () => {
206+
expect(trashcan.overTrashcan(220, 250)).toBe(true);
207+
});
208+
209+
it("should return false for negative x coordinates", () => {
210+
expect(trashcan.overTrashcan(-50, 250)).toBe(false);
211+
});
212+
213+
it("should return false for negative y coordinates", () => {
214+
expect(trashcan.overTrashcan(150, -50)).toBe(false);
215+
});
216+
217+
it("should return true for the center of the trashcan area", () => {
218+
// center x = 100 + 60 = 160, y = 200 + 60 = 260
219+
expect(trashcan.overTrashcan(160, 260)).toBe(true);
220+
});
221+
222+
it("should return false when x is at left boundary but y is above", () => {
223+
expect(trashcan.overTrashcan(100, 199)).toBe(false);
224+
});
225+
});
226+
227+
describe("shouldResize edge cases", () => {
228+
let trashcan;
229+
230+
beforeEach(() => {
231+
jest.clearAllMocks();
232+
trashcan = new Trashcan(mockActivity);
233+
});
234+
235+
it("should return false when both dimensions match container position", () => {
236+
trashcan._container.x = 500;
237+
trashcan._container.y = 400;
238+
expect(trashcan.shouldResize(500, 400)).toBe(false);
239+
});
240+
241+
it("should return true when only x differs", () => {
242+
trashcan._container.x = 500;
243+
trashcan._container.y = 400;
244+
expect(trashcan.shouldResize(600, 400)).toBe(true);
245+
});
246+
247+
it("should return true when only y differs", () => {
248+
trashcan._container.x = 500;
249+
trashcan._container.y = 400;
250+
expect(trashcan.shouldResize(500, 300)).toBe(true);
251+
});
252+
253+
it("should return true when both dimensions differ", () => {
254+
trashcan._container.x = 500;
255+
trashcan._container.y = 400;
256+
expect(trashcan.shouldResize(600, 300)).toBe(true);
257+
});
258+
259+
it("should return false with zero positions matching", () => {
260+
trashcan._container.x = 0;
261+
trashcan._container.y = 0;
262+
expect(trashcan.shouldResize(0, 0)).toBe(false);
263+
});
264+
265+
it("should return true with zero vs non-zero", () => {
266+
trashcan._container.x = 0;
267+
trashcan._container.y = 0;
268+
expect(trashcan.shouldResize(100, 0)).toBe(true);
269+
});
270+
});
271+
272+
describe("stopHighlightAnimation", () => {
273+
let trashcan;
274+
275+
beforeEach(() => {
276+
jest.clearAllMocks();
277+
trashcan = new Trashcan(mockActivity);
278+
});
279+
280+
it("should do nothing if not in animation", () => {
281+
trashcan._inAnimation = false;
282+
const clearSpy = jest.spyOn(global, "clearInterval");
283+
284+
trashcan.stopHighlightAnimation();
285+
286+
expect(clearSpy).not.toHaveBeenCalled();
287+
clearSpy.mockRestore();
288+
});
289+
290+
it("should clear interval and reset state when in animation", () => {
291+
trashcan._inAnimation = true;
292+
trashcan._animationInterval = 42;
293+
trashcan._animationLevel = 100;
294+
trashcan._highlightPower = 128;
295+
trashcan.isVisible = true;
296+
const clearSpy = jest.spyOn(global, "clearInterval");
297+
298+
trashcan.stopHighlightAnimation();
299+
300+
expect(clearSpy).toHaveBeenCalledWith(42);
301+
expect(trashcan._inAnimation).toBe(false);
302+
expect(trashcan.isVisible).toBe(false);
303+
expect(trashcan._animationLevel).toBe(0);
304+
expect(trashcan._highlightPower).toBe(255);
305+
clearSpy.mockRestore();
306+
});
307+
308+
it("should be safe to call multiple times", () => {
309+
trashcan._inAnimation = true;
310+
trashcan._animationInterval = 42;
311+
312+
trashcan.stopHighlightAnimation();
313+
expect(trashcan._inAnimation).toBe(false);
314+
315+
// Second call should be a no-op since _inAnimation is now false
316+
trashcan.stopHighlightAnimation();
317+
expect(trashcan._inAnimation).toBe(false);
318+
});
319+
320+
it("should reset animation level and highlight power to defaults", () => {
321+
trashcan._inAnimation = true;
322+
trashcan._animationLevel = 500;
323+
trashcan._highlightPower = 0;
324+
325+
trashcan.stopHighlightAnimation();
326+
327+
expect(trashcan._animationLevel).toBe(0);
328+
expect(trashcan._highlightPower).toBe(255);
329+
});
330+
});
331+
332+
describe("scale and container positioning", () => {
333+
let trashcan;
334+
335+
beforeEach(() => {
336+
jest.clearAllMocks();
337+
trashcan = new Trashcan(mockActivity);
338+
});
339+
340+
it("should have default scale of 1", () => {
341+
expect(trashcan._scale).toBe(1);
342+
});
343+
344+
it("should update scale via resizeEvent", () => {
345+
trashcan.resizeEvent(2);
346+
expect(trashcan._scale).toBe(2);
347+
});
348+
349+
it("should update container position based on scale", () => {
350+
// window.innerWidth = 1024, window.innerHeight = 768 (jsdom defaults)
351+
trashcan._scale = 1;
352+
trashcan.updateContainerPosition();
353+
354+
const expectedX =
355+
window.innerWidth / trashcan._scale - Trashcan.TRASHWIDTH - 2 * trashcan._iconsize;
356+
const expectedY =
357+
window.innerHeight / trashcan._scale -
358+
Trashcan.TRASHHEIGHT -
359+
(5 / 4) * trashcan._iconsize;
360+
361+
expect(trashcan._container.x).toBe(expectedX);
362+
expect(trashcan._container.y).toBe(expectedY);
363+
});
364+
365+
it("should compute different positions at different scales", () => {
366+
trashcan._scale = 1;
367+
trashcan.updateContainerPosition();
368+
const x1 = trashcan._container.x;
369+
const y1 = trashcan._container.y;
370+
371+
trashcan._scale = 2;
372+
trashcan.updateContainerPosition();
373+
const x2 = trashcan._container.x;
374+
const y2 = trashcan._container.y;
375+
376+
// At scale 2, window dimensions are halved, so positions should be different
377+
expect(x2).not.toBe(x1);
378+
expect(y2).not.toBe(y1);
379+
});
380+
381+
it("should have static TRASHWIDTH and TRASHHEIGHT constants", () => {
382+
expect(Trashcan.TRASHWIDTH).toBe(120);
383+
expect(Trashcan.TRASHHEIGHT).toBe(120);
384+
});
385+
386+
it("should set iconsize based on trash bitmap bounds", () => {
387+
// _makeTrash sets _iconsize from bitmap getBounds().width (mocked as 100)
388+
expect(trashcan._iconsize).toBe(100);
389+
});
390+
391+
it("should initialize _borderHighlightBitmap during construction", () => {
392+
// resizeEvent(1) in constructor triggers _makeBorderHighlight
393+
expect(trashcan._borderHighlightBitmap).not.toBeNull();
394+
});
395+
396+
it("should have _isHighlightInitialized set after construction", () => {
397+
// resizeEvent(1) in constructor triggers _makeBorderHighlight which sets this
398+
expect(trashcan._isHighlightInitialized).toBe(true);
399+
});
400+
401+
it("should initialize animationTime as 500", () => {
402+
expect(trashcan.animationTime).toBe(500);
403+
});
404+
});

0 commit comments

Comments
 (0)