-
Notifications
You must be signed in to change notification settings - Fork 308
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
211 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,209 @@ | ||
import ImageWindowLoaderImpl from "../src/common/image-window-loader"; | ||
|
||
describe("ImageWindowLoaderImpl", () => { | ||
let loader: ImageWindowLoaderImpl; | ||
|
||
beforeEach(() => { | ||
loader = new ImageWindowLoaderImpl(); | ||
}); | ||
|
||
describe("setWindow()", () => { | ||
it("should set the new visible window and freezeCols", () => { | ||
const newWindow = { | ||
x: 10, | ||
y: 10, | ||
width: 100, | ||
height: 100, | ||
}; | ||
const freezeCols = 5; | ||
|
||
loader.setWindow(newWindow, freezeCols); | ||
|
||
// Assuming you modify your class to expose `visibleWindow` and `freezeCols` for testing | ||
expect(loader.visibleWindow).toEqual(newWindow); | ||
expect(loader.freezeCols).toBe(freezeCols); | ||
}); | ||
|
||
it("should call clearOutOfWindow() if the window or freezeCols changes", () => { | ||
const spyClearOutOfWindow = jest.spyOn(loader, "clearOutOfWindow" as any); // Private method, so using 'as any' | ||
|
||
const window1 = { | ||
x: 10, | ||
y: 10, | ||
width: 100, | ||
height: 100, | ||
}; | ||
const window2 = { | ||
x: 15, | ||
y: 15, | ||
width: 100, | ||
height: 100, | ||
}; | ||
const freezeCols1 = 5; | ||
const freezeCols2 = 10; | ||
|
||
loader.setWindow(window1, freezeCols1); | ||
expect(spyClearOutOfWindow).toHaveBeenCalledTimes(1); | ||
|
||
loader.setWindow(window2, freezeCols1); | ||
expect(spyClearOutOfWindow).toHaveBeenCalledTimes(2); | ||
|
||
loader.setWindow(window2, freezeCols2); | ||
expect(spyClearOutOfWindow).toHaveBeenCalledTimes(3); | ||
|
||
// Cleanup | ||
spyClearOutOfWindow.mockRestore(); | ||
}); | ||
|
||
it("should not call clearOutOfWindow() if the window and freezeCols stay the same", () => { | ||
const spyClearOutOfWindow = jest.spyOn(loader, "clearOutOfWindow" as any); | ||
|
||
const newWindow = { | ||
x: 10, | ||
y: 10, | ||
width: 100, | ||
height: 100, | ||
}; | ||
const freezeCols = 5; | ||
|
||
loader.setWindow(newWindow, freezeCols); | ||
loader.setWindow(newWindow, freezeCols); | ||
|
||
expect(spyClearOutOfWindow).toHaveBeenCalledTimes(1); | ||
|
||
// Cleanup | ||
spyClearOutOfWindow.mockRestore(); | ||
}); | ||
}); | ||
|
||
describe("loadOrGetImage()", () => { | ||
// Define image data that might be used across tests | ||
const url = "http://example.com/image.png"; | ||
const col = 1; | ||
const row = 1; | ||
|
||
it("should return the image if it is in the cache", () => { | ||
// Setup: Mock the cache to contain the image | ||
const img = new Image(); | ||
const key = url; | ||
(loader as any).cache[key] = { | ||
img, | ||
url, | ||
cells: [], | ||
cancel: jest.fn(), | ||
}; | ||
|
||
// Act: Retrieve the image | ||
const result = loader.loadOrGetImage(url, col, row); | ||
|
||
// Assert: Ensure the returned image is what we expect | ||
expect(result).toBe(img); | ||
}); | ||
|
||
it("should trigger image loading if the image is not in the cache", () => { | ||
// Setup: Spy on `loadImage` method and clear the cache | ||
const spyLoadImage = jest.spyOn(loader, "loadImage" as any); | ||
(loader as any).cache = {}; | ||
|
||
// Act: Try to retrieve an image that's not in the cache | ||
loader.loadOrGetImage(url, col, row); | ||
|
||
// Assert: Ensure `loadImage` was called to fetch the image | ||
expect(spyLoadImage).toHaveBeenCalledWith(url, col, row, url); | ||
|
||
// Cleanup: Restore the spy | ||
spyLoadImage.mockRestore(); | ||
}); | ||
|
||
it("should not trigger image loading if the image is in the cache but not yet loaded", () => { | ||
// Setup: Mock the cache with a non-loaded image and spy on `loadImage` method | ||
const key = url; | ||
(loader as any).cache[key] = { | ||
img: undefined, | ||
url, | ||
cells: [], | ||
cancel: jest.fn(), | ||
}; | ||
const spyLoadImage = jest.spyOn(loader, "loadImage" as any); | ||
|
||
// Act: Try to retrieve an image that's in the cache but not loaded | ||
const result = loader.loadOrGetImage(url, col, row); | ||
|
||
// Assert: Ensure the image isn't returned and `loadImage` wasn't called | ||
expect(result).toBeUndefined(); | ||
expect(spyLoadImage).not.toHaveBeenCalled(); | ||
|
||
// Cleanup: Restore the spy | ||
spyLoadImage.mockRestore(); | ||
}); | ||
}); | ||
|
||
describe("loadImage()", () => { | ||
// Define image data that might be used across tests | ||
const url = "http://example.com/image.png"; | ||
const col = 1; | ||
const row = 1; | ||
const key = url; | ||
|
||
it("should add a loading image to the cache", () => { | ||
// Act: Load an image | ||
(loader as any).loadImage(url, col, row, key); | ||
|
||
// Assert: Ensure the cache was updated with an entry for the loading image | ||
expect((loader as any).cache[key]).toBeDefined(); | ||
expect((loader as any).cache[key].url).toBe(url); | ||
expect((loader as any).cache[key].img).toBeUndefined(); | ||
expect((loader as any).cache[key].cells).toEqual([row * (1 << 16) + col]); | ||
}); | ||
|
||
it("should handle image loading and decoding successfully", async () => { | ||
// Setup: Spy on `Image` constructor and `decode` method | ||
const img = new Image(); | ||
img.addEventListener = jest.fn((_kind: string, cb: any) => cb()); | ||
jest.useFakeTimers(); | ||
|
||
const spyConstructor = jest.spyOn(window, "Image").mockImplementation(() => img); | ||
img.decode = jest.fn().mockResolvedValue(undefined); | ||
|
||
// Act: Load an image and simulate its successful loading | ||
(loader as any).loadImage(url, col, row, key); | ||
|
||
jest.runAllTimers(); | ||
|
||
jest.useRealTimers(); | ||
await new Promise(r => setTimeout(r, 100)); | ||
|
||
// Assert: Ensure `decode` was called and the image data is updated in the cache | ||
expect(img.decode).toHaveBeenCalled(); | ||
expect((loader as any).cache[key].img).toBe(img); | ||
|
||
// Cleanup: Restore the spies | ||
spyConstructor.mockRestore(); | ||
}); | ||
|
||
it("should handle image loading failure gracefully", async () => { | ||
// Setup: Spy on `Image` constructor and `decode` method | ||
const img = new Image(); | ||
img.addEventListener = jest.fn((_kind: string, cb: any) => cb()); | ||
jest.useFakeTimers(); | ||
|
||
const spyConstructor = jest.spyOn(window, "Image").mockImplementation(() => img); | ||
img.decode = jest.fn().mockRejectedValue(new Error("Decoding failed")); | ||
|
||
// Act: Load an image and simulate its successful loading but decoding failure | ||
(loader as any).loadImage(url, col, row, key); | ||
|
||
jest.runAllTimers(); | ||
|
||
jest.useRealTimers(); | ||
await new Promise(r => setTimeout(r, 100)); | ||
|
||
// Assert: Ensure `decode` was called and the image data remains undefined in the cache | ||
expect(img.decode).toHaveBeenCalled(); | ||
expect((loader as any).cache[key].img).toBeUndefined(); | ||
|
||
// Cleanup: Restore the spies | ||
spyConstructor.mockRestore(); | ||
}); | ||
}); | ||
}); |