Skip to content

Commit

Permalink
fix: match latest changes in jest-canvas-mock
Browse files Browse the repository at this point in the history
  • Loading branch information
Adamfsk committed Oct 30, 2023
1 parent 0ce2974 commit a51f40e
Show file tree
Hide file tree
Showing 20 changed files with 254 additions and 72 deletions.
4 changes: 4 additions & 0 deletions __mocks__/worker.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
const { TextEncoder, TextDecoder } = require('util');
global.TextEncoder = TextEncoder;
global.TextDecoder = TextDecoder;

global.window.Worker = class {
constructor(stringUrl) {
this.url = stringUrl;
Expand Down
6 changes: 4 additions & 2 deletions __tests__/classes/CanvasGradient.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ describe('CanvasGradient', () => {

[Infinity, NaN, -Infinity].forEach((value) => {
test('CanvasGradient should throw if offset is ' + value, () => {
expect(() => {
const fn = () => {
var grd = ctx.createLinearGradient(1, 2, 3, 4);
grd.addColorStop(value, 'blue');
}).toThrow(DOMException);
};
expect(fn).toThrow(DOMException);
expect(fn).toThrow('is outside the range');
});
});

Expand Down
10 changes: 6 additions & 4 deletions __tests__/classes/CanvasRenderingContext2D.addHitRegion.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ describe('addHitRegion', () => {
});

it('should throw if called with no parameters', () => {
expect(() => ctx.addHitRegion()).toThrow(DOMException);
const fn = () => ctx.addHitRegion();
expect(fn).toThrow(DOMException);
expect(fn).toThrow('Both id and control are null');
});

it("should throw if fillRule is set and isn't 'evenodd' or 'nonzero'", () => {
expect(() =>
ctx.addHitRegion({ id: 'test', fillRule: 'wrong!' })
).toThrow();
const fn = () => ctx.addHitRegion({ id: 'test', fillRule: 'wrong!' });
expect(fn).toThrow(TypeError);
expect(fn).toThrow('is not a valid enum value of type CanvasFillRule');
});

it('should not throw if fillRule is valid', () => {
Expand Down
6 changes: 4 additions & 2 deletions __tests__/classes/CanvasRenderingContext2D.arc.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ describe('arc', () => {
expect(ctx.arc).toBeCalled();
});

it("shouldn't accept parameters less than 7", () => {
it("shouldn't accept parameters less than 5", () => {
expect(() => ctx.arc()).toThrow(TypeError);
expect(() => ctx.arc(1)).toThrow(TypeError);
expect(() => ctx.arc(1, 2)).toThrow(TypeError);
Expand All @@ -27,7 +27,9 @@ describe('arc', () => {
});

it('should throw when radius is negative', () => {
expect(() => ctx.arc(1, 2, -1, 4, 5)).toThrow(DOMException);
const fn = () => ctx.arc(1, 2, -1, 4, 5);
expect(fn).toThrow(DOMException);
expect(fn).toThrow('The radius provided (-1) is negative.');
});

it('should not throw if any value is `NaN`', () => {
Expand Down
10 changes: 8 additions & 2 deletions __tests__/classes/CanvasRenderingContext2D.arcTo.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,17 @@ describe('arcTo', () => {
});

it("shouldn't accept parameters less than 5", () => {
expect(() => ctx.arcTo(1, 2, 3)).toThrow(DOMException);
expect(() => ctx.arcTo()).toThrow(TypeError);
expect(() => ctx.arcTo(1)).toThrow(TypeError);
expect(() => ctx.arcTo(1, 2)).toThrow(TypeError);
expect(() => ctx.arcTo(1, 2, 3)).toThrow(TypeError);
expect(() => ctx.arcTo(1, 2, 3, 4)).toThrow(TypeError);
});

it('should throw when radius is negative', () => {
expect(() => ctx.arcTo(1, 2, -1, 3, -1)).toThrow(TypeError);
const fn = () => ctx.arcTo(1, 2, 3, 4, -1);
expect(fn).toThrow(DOMException);
expect(fn).toThrow('The radius provided (-1) is negative.');
});

it('should accept 5 parameters regardless of type', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ describe('createImagePattern', () => {
it('should not create a pattern if the image bitmap is closed', () => {
const bmp = new ImageBitmap(400, 300);
bmp.close();
expect(() => ctx.createPattern(bmp, 'repeat')).toThrow(DOMException);
const fn = () => ctx.createPattern(bmp, 'repeat');
expect(fn).toThrow(DOMException);
expect(fn).toThrow('The image source is detached.');
});

it('should create a valid pattern for all repeat types', () => {
Expand Down
17 changes: 10 additions & 7 deletions __tests__/classes/CanvasRenderingContext2D.createRadialGradient.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,16 @@ describe('createRadialGradient', () => {
);
});

it('should not create a radial gradient if any of the radius values are < 0', () => {
expect(() => ctx.createRadialGradient(0, 0, -1, 0, 0, 0)).toThrow(
DOMException
);
expect(() => ctx.createRadialGradient(0, 0, 0, 0, 0, -1)).toThrow(
DOMException
);
it('should not create a radial gradient if r0 value is < 0', () => {
const fn = () => ctx.createRadialGradient(0, 0, -1, 0, 0, 0);
expect(fn).toThrow(DOMException);
expect(fn).toThrow('The r0 provided is less than 0.');
});

it('should not create a radial gradient if r1 value is < 0', () => {
const fn = () => ctx.createRadialGradient(0, 0, 0, 0, 0, -1);
expect(fn).toThrow(DOMException);
expect(fn).toThrow('The r1 provided is less than 0.');
});

it('should create a radial gradient with string values', () => {
Expand Down
4 changes: 3 additions & 1 deletion __tests__/classes/CanvasRenderingContext2D.drawImage.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ describe('drawImage', () => {
it('should not draw if the image bitmap is closed', () => {
const bmp = new ImageBitmap(100, 100);
bmp.close();
expect(() => ctx.drawImage(bmp, 1, 2)).toThrow(DOMException);
const fn = () => ctx.drawImage(bmp, 1, 2);
expect(fn).toThrow(DOMException);
expect(fn).toThrow('The image source is detached.');
});

it('should accept 3, 5, and 9 parameters', () => {
Expand Down
13 changes: 10 additions & 3 deletions __tests__/classes/CanvasRenderingContext2D.ellipse.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,16 @@ describe('ellipse', () => {
expect(() => ctx.ellipse(1, 2, 3, 4, 5, 6)).toThrow(TypeError);
});

it('should throw when radius is negative', () => {
expect(() => ctx.ellipse(1, 2, -1, 4, 5, 6, 7)).toThrow(DOMException);
expect(() => ctx.ellipse(1, 2, 3, -1, 5, 6, 7)).toThrow(DOMException);
it('should throw when major axis radius is negative', () => {
const fn = () => ctx.ellipse(1, 2, -1, 4, 5, 6, 7);
expect(fn).toThrow(DOMException);
expect(fn).toThrow('The major-axis radius provided (-1) is negative.');
});

it('should throw when minor axis radius is negative', () => {
const fn = () => ctx.ellipse(1, 2, 3, -1, 5, 6, 7);
expect(fn).toThrow(DOMException);
expect(fn).toThrow('The minor-axis radius provided (-1) is negative.');
});

it('should not throw if any value is `NaN`', () => {
Expand Down
33 changes: 27 additions & 6 deletions __tests__/classes/CanvasRenderingContext2D.getImageData.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,39 @@ describe('getImageData', () => {
});

it('should be callable', () => {
ctx.getImageData();
ctx.getImageData(0, 0, 10, 20);
expect(ctx.getImageData).toBeCalled();
});

it('should throw if less than 4 parameters are given', () => {
expect(() => ctx.getImageData()).toThrow(TypeError);
expect(() => ctx.getImageData(0)).toThrow(TypeError);
expect(() => ctx.getImageData(0, 0)).toThrow(TypeError);
expect(() => ctx.getImageData(0, 0, 0)).toThrow(TypeError);
});

it('should return a image data from getImageData', () => {
expect(ctx.getImageData()).toBeInstanceOf(ImageData);
expect(ctx.getImageData(0, 0, 10, 20)).toBeInstanceOf(ImageData);
});

it('should return a image data from getImageData of proper size', () => {
const data = ctx.getImageData();
expect(data.width).toBe(400);
expect(data.height).toBe(300);
expect(data.data.length).toBe(400 * 300 * 4);
const data = ctx.getImageData(0, 0, 10, 20);
expect(data.width).toBe(10);
expect(data.height).toBe(20);
expect(data.data.length).toBe(10 * 20 * 4);
});

it('should return image data from getImageData if size is negative', () => {
const data = ctx.getImageData(0, 0, -10, -20);
expect(data.width).toBe(10);
expect(data.height).toBe(20);
expect(data.data.length).toBe(10 * 20 * 4);
});

it('should throw if width or height are zero', () => {
expect(() => ctx.getImageData(0, 0, 0, 1)).toThrow(DOMException);
expect(() => ctx.getImageData(0, 0, 0, 1)).toThrow('source width is 0');
expect(() => ctx.getImageData(0, 0, 1, 0)).toThrow('source height is 0');
expect(() => ctx.getImageData(0, 0, 0, 0)).toThrow('source width is 0');
});
});
4 changes: 2 additions & 2 deletions __tests__/classes/CanvasRenderingContext2D.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ describe('CanvasRenderingContext2D prototype', () => {
});

it('should have a getContext function', () => {
expect(canvas.getContext).toBeInstanceOf(Function);
expect(canvas.getContext).toBeCalled();
});

it('should be defined on the prototype', () => {
expect(HTMLCanvasElement.prototype.getContext).toBeInstanceOf(Function);
expect(HTMLCanvasElement.prototype.getContext).toBeCalled();
});
});
11 changes: 11 additions & 0 deletions __tests__/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,14 @@ describe('canvas', () => {
expect(ver).toBe(pkg.version);
});
});

describe('setupJestCanvasMock', () => {
it('should setup after resetAllMocks', () => {
jest.resetAllMocks();
expect(document.createElement('canvas').getContext('2d')).toBe(undefined);
setupJestCanvasMock();
expect(document.createElement('canvas').getContext('2d')).toHaveProperty(
'createImageData'
);
});
});
38 changes: 37 additions & 1 deletion __tests__/mock/prototype.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { JSDOM } from 'jsdom';
import mockPrototype from '../../src/mock/prototype';
import WebGLRenderingContext from '../../src/classes/WebGLRenderingContext';

let canvas;
Expand All @@ -14,6 +16,11 @@ describe('mock', () => {
expect(ctx).toBeInstanceOf(CanvasRenderingContext2D);
});

it('should expect getContext to be called', () => {
canvas.getContext('2d');
expect(canvas.getContext).toBeCalled();
});

it('context creation of type webgl returns WebGLRenderingContext', () => {
const ctx = canvas.getContext('webgl');
expect(ctx).toBeInstanceOf(WebGLRenderingContext);
Expand Down Expand Up @@ -113,7 +120,7 @@ describe('mock', () => {
const error = console.error;
console.error = () => void 0;
canvas.dataset.internalRequireTest = true;
canvas.getContext('random');
canvas.getContext('incorrect-value');
console.error = error;
});

Expand All @@ -123,6 +130,35 @@ describe('mock', () => {
expect(first).toBe(second);
});

it('should work in both cases where passed in window object has and does not have .HTMLCanvasElement.prototype', () => {
// arrange/act
const mockWin = new JSDOM().window;
mockPrototype();
// assert (should not have effected the mockWindow since we did not pass it in )
expect(
jest.isMockFunction(mockWin.HTMLCanvasElement.prototype.getContext)
).toBe(false);
expect(
jest.isMockFunction(mockWin.HTMLCanvasElement.prototype.toBlob)
).toBe(false);
expect(
jest.isMockFunction(mockWin.HTMLCanvasElement.prototype.toDataURL)
).toBe(false);

// act
mockPrototype(mockWin);
// assert ( should mock out expected fields in passed in window object )
expect(
jest.isMockFunction(mockWin.HTMLCanvasElement.prototype.getContext)
).toBe(true);
expect(
jest.isMockFunction(mockWin.HTMLCanvasElement.prototype.toBlob)
).toBe(true);
expect(
jest.isMockFunction(mockWin.HTMLCanvasElement.prototype.toDataURL)
).toBe(true);
});

it('should return the same context if getContext("webgl") is called twice', () => {
const first = canvas.getContext('webgl');
const second = canvas.getContext('webgl');
Expand Down
47 changes: 47 additions & 0 deletions __tests__/mock/window.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { JSDOM } from 'jsdom';
import mockWindow from '../../src/window';

describe('mockWindow', () => {
it('mocks the passed object', () => {
const win = new JSDOM().window;

mockWindow(win);

expect(win.Path2D).not.toBeNull();
expect(win.CanvasGradient).not.toBeNull();
expect(win.CanvasPattern).not.toBeNull();
expect(win.CanvasRenderingContext2D).not.toBeNull();
expect(win.DOMMatrix).not.toBeNull();
expect(win.ImageData).not.toBeNull();
expect(win.TextMetrics).not.toBeNull();
expect(win.ImageBitmap).not.toBeNull();
expect(win.createImageBitmap).not.toBeNull();

expect(
jest.isMockFunction(win.HTMLCanvasElement.prototype.getContext)
).toBe(true);
expect(jest.isMockFunction(win.HTMLCanvasElement.prototype.toBlob)).toBe(
true
);
expect(jest.isMockFunction(win.HTMLCanvasElement.prototype.toDataURL)).toBe(
true
);
});

it('mocks without a fully formed passed in window object', () => {
const win = mockWindow({ document: {} });

expect(win.Path2D).not.toBeNull();
expect(win.CanvasGradient).not.toBeNull();
expect(win.CanvasPattern).not.toBeNull();
expect(win.CanvasRenderingContext2D).not.toBeNull();
expect(win.DOMMatrix).not.toBeNull();
expect(win.ImageData).not.toBeNull();
expect(win.TextMetrics).not.toBeNull();
expect(win.ImageBitmap).not.toBeNull();
expect(win.createImageBitmap).not.toBeNull();

expect(jest.isMockFunction(win.HTMLCanvasElement)).toBe(false);
expect(win.HTMLCanvasElement).toBeUndefined();
});
});
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "jest-webgl-canvas-mock",
"version": "2.5.0",
"version": "2.5.3",
"description": "Mock both 2D and WebGL contexts in Jest.",
"main": "lib/index.js",
"types": "types/index.d.ts",
Expand All @@ -25,11 +25,14 @@
"@babel/preset-env": "^7.9.5",
"@commitlint/cli": "^17.6.1",
"@commitlint/config-angular": "^17.6.1",
"@inrupt/jest-jsdom-polyfills": "^2.5.0",
"babel-jest": "^25.3.0",
"babel-plugin-version": "^0.2.3",
"coveralls": "^3.0.11",
"husky": "^4.2.5",
"jest": "^29.5.0",
"jest-environment-jsdom": "^29.5.0",
"jsdom": "^22.1.0",
"prettier": "^2.0.4"
},
"commitlint": {
Expand All @@ -51,6 +54,7 @@
"src/mock/**/*.js"
],
"setupFiles": [
"@inrupt/jest-jsdom-polyfills",
"./src/index.js",
"./__mocks__/worker.js"
]
Expand Down
4 changes: 2 additions & 2 deletions src/classes/CanvasGradient.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ export default class CanvasGradient {
const numoffset = Number(offset);
if (!Number.isFinite(numoffset) || numoffset < 0 || numoffset > 1) {
throw new DOMException(
'IndexSizeError',
"Failed to execute 'addColorStop' on 'CanvasGradient': The provided value ('" +
numoffset +
"') is outside the range (0.0, 1.0)"
"') is outside the range (0.0, 1.0)",
'IndexSizeError'
);
}
try {
Expand Down
Loading

0 comments on commit a51f40e

Please sign in to comment.