Mock canvas when run unit test cases with jest.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Mock implementations of browser APIs related to canvas functionality. These classes provide complete implementations that match browser behavior including proper error handling, parameter validation, and type coercion. All methods are Jest mock functions with full spy capabilities.
Mock implementation of the Path2D interface for creating and manipulating 2D paths that can be used with CanvasRenderingContext2D.
/**
* Creates a new Path2D object, optionally copying from another path or SVG path string
* @param path - Optional Path2D object to copy or SVG path string to parse
*/
class Path2D {
constructor(path?: Path2D | string);
/**
* Adds the given path to the current path
* @param path - Path2D object to add to this path
* @param transform - Optional transformation matrix to apply
* @throws {TypeError} If path parameter is not a Path2D object
*/
addPath(path: Path2D, transform?: DOMMatrix2DInit): void;
/**
* Adds a straight line from current point to the start of current sub-path
*/
closePath(): void;
/**
* Moves the starting point of a new sub-path to specified coordinates
* @param x - The x-axis coordinate of the point
* @param y - The y-axis coordinate of the point
*/
moveTo(x: number, y: number): void;
/**
* Connects the last point in the sub-path to specified coordinates with a straight line
* @param x - The x-axis coordinate of the line's end point
* @param y - The y-axis coordinate of the line's end point
*/
lineTo(x: number, y: number): void;
/**
* Adds a circular arc to the current path
* @param x - The x-axis coordinate of the arc's center
* @param y - The y-axis coordinate of the arc's center
* @param radius - The arc's radius
* @param startAngle - The angle at which the arc starts in radians
* @param endAngle - The angle at which the arc ends in radians
* @param anticlockwise - If true, draws the arc counter-clockwise
*/
arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, anticlockwise?: boolean): void;
/**
* Adds an arc to the current path using control points and radius
* @param x1 - The x-axis coordinate of the first control point
* @param y1 - The y-axis coordinate of the first control point
* @param x2 - The x-axis coordinate of the second control point
* @param y2 - The y-axis coordinate of the second control point
* @param radius - The arc's radius
*/
arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void;
/**
* Adds a quadratic Bézier curve to the current path
* @param cpx - The x-axis coordinate of the control point
* @param cpy - The y-axis coordinate of the control point
* @param x - The x-axis coordinate of the end point
* @param y - The y-axis coordinate of the end point
*/
quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void;
/**
* Adds a cubic Bézier curve to the current path
* @param cp1x - The x-axis coordinate of the first control point
* @param cp1y - The y-axis coordinate of the first control point
* @param cp2x - The x-axis coordinate of the second control point
* @param cp2y - The y-axis coordinate of the second control point
* @param x - The x-axis coordinate of the end point
* @param y - The y-axis coordinate of the end point
*/
bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void;
/**
* Adds an ellipse to the current path
* @param x - The x-axis coordinate of the ellipse's center
* @param y - The y-axis coordinate of the ellipse's center
* @param radiusX - The ellipse's major-axis radius
* @param radiusY - The ellipse's minor-axis radius
* @param rotation - The rotation of the ellipse in radians
* @param startAngle - The starting angle in radians
* @param endAngle - The ending angle in radians
* @param anticlockwise - If true, draws counter-clockwise
*/
ellipse(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, anticlockwise?: boolean): void;
/**
* Adds a rectangle to the current path
* @param x - The x-axis coordinate of the rectangle's starting point
* @param y - The y-axis coordinate of the rectangle's starting point
* @param width - The rectangle's width
* @param height - The rectangle's height
*/
rect(x: number, y: number, width: number, height: number): void;
}Usage Examples:
// Create a new path
const path = new Path2D();
// Build the path
path.moveTo(10, 10);
path.lineTo(100, 100);
path.arc(50, 50, 25, 0, Math.PI * 2);
path.closePath();
// Use with canvas context
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
ctx.fill(path);
ctx.stroke(path);
// Copy another path
const path2 = new Path2D(path);
path2.addPath(path);Mock implementation of ImageData for representing pixel data with proper validation and error handling.
/**
* Creates ImageData object with specified dimensions (filled with transparent black)
* @param width - The width of the ImageData object
* @param height - The height of the ImageData object
* @throws {RangeError} If width or height is zero or not finite
*/
class ImageData {
constructor(width: number, height: number);
/**
* Creates ImageData object from existing Uint8ClampedArray data
* @param data - Uint8ClampedArray containing pixel data (RGBA format)
* @param width - The width of the ImageData object
* @param height - Optional height (calculated from data length if not provided)
* @throws {RangeError} If data length is not a multiple of 4 or dimensions are invalid
* @throws {TypeError} If data is not a Uint8ClampedArray
*/
constructor(data: Uint8ClampedArray, width: number, height?: number);
/**
* The width of the ImageData object in pixels (read-only)
*/
readonly width: number;
/**
* The height of the ImageData object in pixels (read-only)
*/
readonly height: number;
/**
* Uint8ClampedArray containing pixel data in RGBA format (read-only)
* Each pixel represented by 4 consecutive values: R, G, B, A (0-255)
*/
readonly data: Uint8ClampedArray;
}Usage Examples:
// Create empty 100x100 ImageData
const imageData1 = new ImageData(100, 100);
console.log(imageData1.width); // 100
console.log(imageData1.height); // 100
console.log(imageData1.data.length); // 40000 (100 * 100 * 4)
// Create from existing data
const pixelData = new Uint8ClampedArray([255, 0, 0, 255, 0, 255, 0, 255]); // 2 pixels
const imageData2 = new ImageData(pixelData, 2, 1);
// Error cases
expect(() => new ImageData(0, 100)).toThrow(RangeError);
expect(() => new ImageData([1, 2, 3], 1)).toThrow(TypeError);Mock implementation of TextMetrics containing text measurement information.
/**
* Contains metrics information for measured text
* @param text - The text that was measured (used to calculate basic width)
*/
class TextMetrics {
constructor(text: string);
/**
* The width of the text in CSS pixels (calculated as text length)
*/
width: number;
/**
* Distance from the alignment point to the left of the bounding box
*/
actualBoundingBoxLeft: number;
/**
* Distance from the alignment point to the right of the bounding box
*/
actualBoundingBoxRight: number;
/**
* Distance from the horizontal line to the top of the font bounding box
*/
fontBoundingBoxAscent: number;
/**
* Distance from the horizontal line to the bottom of the font bounding box
*/
fontBoundingBoxDescent: number;
/**
* Distance from the horizontal line to the top of the actual bounding box
*/
actualBoundingBoxAscent: number;
/**
* Distance from the horizontal line to the bottom of the actual bounding box
*/
actualBoundingBoxDescent: number;
/**
* Distance from the horizontal line to the top of the em square
*/
emHeightAscent: number;
/**
* Distance from the horizontal line to the bottom of the em square
*/
emHeightDescent: number;
/**
* Distance from the horizontal line to the hanging baseline
*/
hangingBaseline: number;
/**
* Distance from the horizontal line to the alphabetic baseline
*/
alphabeticBaseline: number;
/**
* Distance from the horizontal line to the ideographic baseline
*/
ideographicBaseline: number;
}Mock implementation of CanvasGradient for creating gradient fills and strokes.
/**
* Represents a gradient that can be used as fillStyle or strokeStyle
*/
class CanvasGradient {
constructor();
/**
* Adds a color stop to the gradient
* @param offset - Position of the color stop (0.0 to 1.0)
* @param color - CSS color value for the stop
* @throws {DOMException} If offset is outside the range (0.0, 1.0)
* @throws {SyntaxError} If color cannot be parsed as a valid CSS color
*/
addColorStop(offset: number, color: string): void;
}Usage Examples:
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Create linear gradient
const gradient = ctx.createLinearGradient(0, 0, 100, 0);
gradient.addColorStop(0, '#ff0000');
gradient.addColorStop(0.5, '#00ff00');
gradient.addColorStop(1, '#0000ff');
// Use gradient
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, 100, 100);
// Error cases
expect(() => gradient.addColorStop(-0.5, '#ff0000')).toThrow(DOMException);
expect(() => gradient.addColorStop(0.5, 'invalid-color')).toThrow(SyntaxError);Mock implementation of CanvasPattern for creating pattern fills and strokes.
/**
* Represents a pattern that can be used as fillStyle or strokeStyle
*/
class CanvasPattern {
constructor();
/**
* Sets the transformation matrix for the pattern
* @param transform - DOMMatrix2DInit object representing the transformation
* @throws {TypeError} If transform is provided but is not an object
*/
setTransform(transform?: DOMMatrix2DInit): void;
}Mock implementation of DOMMatrix for representing 2D and 3D transformation matrices.
/**
* Represents a 2D or 3D transformation matrix
* @param transform - Optional initial transformation as array or existing DOMMatrix
*/
class DOMMatrix {
constructor(transform?: number[] | DOMMatrix);
// Matrix elements (2D and 3D)
m11: number; m12: number; m13: number; m14: number;
m21: number; m22: number; m23: number; m24: number;
m31: number; m32: number; m33: number; m34: number;
m41: number; m42: number; m43: number; m44: number;
// 2D aliases (getters/setters)
a: number; // m11
b: number; // m12
c: number; // m21
d: number; // m22
e: number; // m41
f: number; // m42
/**
* Whether the matrix represents a 2D transformation (read-only)
*/
readonly is2D: boolean;
/**
* Whether the matrix is the identity matrix (read-only)
*/
readonly isIdentity: boolean;
/**
* Returns Float32Array representation of the matrix
* @returns 16-element Float32Array
*/
toFloat32Array(): Float32Array;
/**
* Returns Float64Array representation of the matrix
* @returns 16-element Float64Array
*/
toFloat64Array(): Float64Array;
/**
* Returns new matrix with translation applied
* @param x - Translation distance in x direction
* @param y - Translation distance in y direction
* @param z - Translation distance in z direction (optional)
* @returns New DOMMatrix with translation applied
*/
translate(x: number, y: number, z?: number): DOMMatrix;
/**
* Applies translation to this matrix (modifies in place)
* @param x - Translation distance in x direction
* @param y - Translation distance in y direction
* @param z - Translation distance in z direction (optional)
* @returns This matrix (for chaining)
*/
translateSelf(x: number, y: number, z?: number): DOMMatrix;
/**
* Returns new matrix with scaling applied
* @param scaleX - Scaling factor in x direction
* @param scaleY - Scaling factor in y direction (defaults to scaleX)
* @param scaleZ - Scaling factor in z direction (defaults to 1)
* @param originX - Origin x coordinate for scaling (defaults to 0)
* @param originY - Origin y coordinate for scaling (defaults to 0)
* @param originZ - Origin z coordinate for scaling (defaults to 0)
* @returns New DOMMatrix with scaling applied
*/
scale(scaleX: number, scaleY?: number, scaleZ?: number, originX?: number, originY?: number, originZ?: number): DOMMatrix;
/**
* Applies scaling to this matrix (modifies in place)
* @param scaleX - Scaling factor in x direction
* @param scaleY - Scaling factor in y direction (defaults to scaleX)
* @param scaleZ - Scaling factor in z direction (defaults to 1)
* @param originX - Origin x coordinate for scaling (defaults to 0)
* @param originY - Origin y coordinate for scaling (defaults to 0)
* @param originZ - Origin z coordinate for scaling (defaults to 0)
* @returns This matrix (for chaining)
*/
scaleSelf(scaleX: number, scaleY?: number, scaleZ?: number, originX?: number, originY?: number, originZ?: number): DOMMatrix;
}Mock implementation of ImageBitmap for representing bitmap images.
/**
* Represents a bitmap image that can be drawn to a canvas
* @param width - Width of the bitmap
* @param height - Height of the bitmap
*/
class ImageBitmap {
constructor(width: number, height: number);
/**
* Width of the bitmap in pixels
*/
width: number;
/**
* Height of the bitmap in pixels
*/
height: number;
/**
* Releases resources associated with the bitmap
* Sets width and height to 0 and marks as closed
*/
close(): void;
}Mock implementation of the global createImageBitmap function for creating ImageBitmap objects from various sources.
/**
* Creates an ImageBitmap from an image source
* @param image - Image source (HTMLImageElement, HTMLVideoElement, HTMLCanvasElement, Blob, ImageData, ImageBitmap)
* @param options - Optional configuration for the bitmap creation
* @returns Promise that resolves to an ImageBitmap
* @throws {TypeError} If image source is invalid or options parameter is not an object
*/
function createImageBitmap(
image: ImageBitmapSource,
options?: ImageBitmapOptions
): Promise<ImageBitmap>;
/**
* Creates an ImageBitmap from a cropped portion of an image source
* @param image - Image source
* @param sx - Source x coordinate
* @param sy - Source y coordinate
* @param sw - Source width
* @param sh - Source height
* @param options - Optional configuration for the bitmap creation
* @returns Promise that resolves to an ImageBitmap
* @throws {RangeError} If crop dimensions are zero or invalid
*/
function createImageBitmap(
image: ImageBitmapSource,
sx: number, sy: number, sw: number, sh: number,
options?: ImageBitmapOptions
): Promise<ImageBitmap>;Usage Examples:
// From canvas element
const canvas = document.createElement('canvas');
const bitmap1 = await createImageBitmap(canvas);
// From image element with cropping
const img = new Image();
const bitmap2 = await createImageBitmap(img, 10, 10, 100, 100);
// With options
const bitmap3 = await createImageBitmap(canvas, {
imageOrientation: 'flipY',
resizeWidth: 200,
resizeHeight: 200
});
// Error cases
await expect(createImageBitmap()).rejects.toThrow(TypeError);
await expect(createImageBitmap(canvas, 0, 0, 0, 100)).rejects.toThrow(RangeError);Extensions to HTMLCanvasElement.prototype for enhanced canvas testing capabilities.
/**
* Enhanced getContext method that returns mock 2D contexts
* @param contextType - The context type to create ('2d', 'webgl', etc.)
* @returns Mock CanvasRenderingContext2D for '2d', null for unsupported types
*/
HTMLCanvasElement.prototype.getContext(contextType: string): CanvasRenderingContext2D | null;
/**
* Mock implementation of toBlob that creates mock Blob objects
* @param callback - Callback function to receive the blob
* @param type - MIME type for the blob ('image/png', 'image/jpeg', 'image/webp')
* @param encoderOptions - Quality setting for lossy formats
* @throws {TypeError} If callback is not provided or not a function
*/
HTMLCanvasElement.prototype.toBlob(callback: BlobCallback, type?: string, encoderOptions?: any): void;
/**
* Mock implementation of toDataURL that returns mock data URLs
* @param type - MIME type for the data URL ('image/png', 'image/jpeg', 'image/webp')
* @param encoderOptions - Quality setting for lossy formats
* @returns Mock data URL string
*/
HTMLCanvasElement.prototype.toDataURL(type?: string, encoderOptions?: any): string;All browser API mocks are fully integrated with Jest's mocking system, providing complete spy functionality for testing and verification.