This minor version bump now has some major snapshot support but is backwards compatible.
Changes:
static CanvasRenderingContext2D method: #.__getEvents(ctx)
CanvasRenderingContext2D state machine logs an _eventstatic CanvasRenderingContext2D method: #.__getPath(ctx)
_path item and can be accessed via __getPath(ctx)beginPath() empties the _pathstatic CanvasRenderingContext2D method: #.__getDrawCalls(ctx)
_drawCall item and can be accessed via __getDrawCall(ctx)types/index.d.ts file for tooling types (in jest environment)createLinearGradient now accepts stringscreateRadialGradient now accepts stringsglobalAlpha now accepts null per Number coercion_path and _events to Path2DJust publish a stable version.
The Version 2.0.0-beta.1 of jest-canvas-mock is a complete overhaul of the mocking strategy entirely. Originally, the canvas.getCanvas('2d') method would return a single object that contained a set of methods without any property definitions. This caused problems for people who wanted to use jest to test and verify instanceof checks.
Now the following expectation works as expected.
const ctx = document.createElement('canvas').getContext('2d');
expect(ctx).toBeInstanceOf(CanvasRenderingContext2D);
When each CanvasRenderingContext2D object is created, all the methods are properly mocked with the jest.fn() method, and bound to the instance. It's still possible to verify that a function was called on the context. The main difference now is that the methods actually perform runtime checks on the passed parameters.
The following example demonstrates that canvas methods can be called, and parameters are verified.
const PI_2 = Math.PI * 2;
// create a circle at 0,0 with radius 100
ctx.arc(0, 0, 100, 0, PI_2);
expect(ctx.arc).toBeCalledWith(0, 0, 100, 0, PI_2);
// negative radius values throw DOMException errors
expect(() => ctx.arc(0, 0, -10, 0, PI_2)).toThrow(DOMExpection);
Another really big change is that the mocking strategy now attempts to conform to the html living specification. In order to do this, two packages were added as dependencies so that css colors and fonts can be more properly parsed. This is not perfect, and any problems with the color parser or font parser should be reported in the Issues tab.
This change comes with overhauled ctx.save() and ctx.restore() functions. These function calls work almost entirely as intended. For instance, ctx.save() actually pushes all the current property values to a stack, and this operation is undone when ctx.restore() is called. Take the following snippet of code as an example.
// create a context
const ctx = document.createElement('canvas').getContext('2d');
// save the current state of the canvas
ctx.save();
// set some color and font values
ctx.fillStyle = 'blue';
ctx.font = '12pt Times New Roman';
// now the fillStyle property parses the color
expect(ctx.fillStyle).toBe('#00F');
// font parsing also works as intended
expect(ctx.font).toBe('16px "Times New Roman"');
// restore the previously saved state
ctx.restore():
// the fillStyle was restored to default
expect(ctx.fillStyle).toBe('#000');
// the font was restored too
expect(ctx.font).toBe('10px sans-serif');
For all these reasons, the jest-canvas-mock package was bumped a major version to 2.0.0.
directionfillStylefilterfontglobalAlphaglobalCompositeOperationimageSmoothingEnabledimageSmoothingQualitylineCaplineDashOffsetlineDash (via getLineDash() / setLineDash())lineJoinlineWidthmiterLimitshadowBlurshadowColorshadowOffsetXshadowOffsetYstackstrokeStyletextAligntextBaselinetransform (via setTransform etc.)constructor binds the following functions
setLineDashgetLineDashsetTransformgetTransformgetImageDatasaverestorecreatePatterncreateRadialGradientaddHitRegionarcarcTobeginPathclipclosePathscalestrokeclearHitRegionsclearRectfillRectstrokeRectrectresetTransformtranslatemoveTolineTobezierCurveTocreateLinearGradientellipsemeasureTextrotatedrawImagedrawFocusIfNeededisPointInPathisPointInStrokeputImageDatastrokeTextfillTextquadraticCurveToremoveHitRegionfilltransformscrollPathIntoViewcreateImageDataaddHitRegion
path or id parameter is set, throws DOMException otherwisefillRule if set, throws TypeError if invalidarc
TypeError if arguments.length < 5DOMException(IndexSizeError) if values are finite, but radius is negativearcTo
TypeError if arguments.length < 5DOMException(IndexSizeError) if values are finite, but radius is negativebeginPath (empty noOp stub)
bezierCurveTo
TypeError if arguments.length < 6canvas
HTMLCanvasElementclearHitRegions (empty noOp stub)clearRect
TypeError if arguments.length < 4clip
fillRule is provided, throws TypeErorr if FillRule is invalidpath is provided, throws TypeError if path is not instanceof Path2DclosePath (added noOp stub)createImageData
TypeError if arguments.length === 1 and parameter is not instanceof ImageDataTypeError if arguments.length >= 2 and width is not finiteTypeError if arguments.length >= 2 and height is not finiteImageDatacreateLinearGradient
TypeError if arguments.length < 4TypeError if x0 is not finiteTypeError if y0 is not finiteTypeError if x1 is not finiteTypeError if y1 is not finiteCanvasGradientcreatePattern
TypeError if image is not supported in jest-canvas-mockTypeError if arguments.length < 4DOMException('SyntaxError') if image is detachedCanvasPattern if image is HTMLImageElement, ImageBitmap, HTMLVideoElement, HTMLCanvasElementcreateRadialGradient
TypeError if arguments.length < 4TypeError if x0 is not finiteTypeError if y0 is not finiteTypeError if r0 is not finiteTypeError if x1 is not finiteTypeError if y1 is not finiteTypeError if r1 is not finiteDOMException('DataError') if r0 is negativeDOMException('DataError') if r1 is negativecurrentTransform
value instanceof DOMMatrixDOMMatrix with current transform valuesdirection
drawFocusIfNeeded
TypeError if arguments.length === 0TypeError if arguments.length === 2 and path is not instanceof Path2DTypeError if element is not instanceof ElementTypeError if image is not supported by jest-canvas-mockellipse
TypeError if arguments.length < 7DOMException('IndexSizeError') if radiusX is negative and all parameters are finiteDOMException('IndexSizeError') if radiusY is negative and all parameters are finitefill
TypeError if fillRule is not valid FillRuleTypeError if path is not instanceof Path2DfillRect
TypeError if arguments.length < 4fillStyle
fillStyle stack value if it's a valid css color, a CanvasGradient or a CanvasPatternfillStyle stack valuefillText
TypeError if arguments.length < 3filter
filter stack value if it's a stringfilter stack valuefont
font stack value if it's a valid fontfont stack valuegetImageData
ImageData with the same size as the parent canvasgetLineDash
lineDash stack valuesetLineDash
TypeError if lineDash value is not a valid sequencelineDash stack valuelineDash length is oddgetTransform
transform stack value in the form of a DOMMatrixglobalAlpha
globalAlpha stack value if value finite and between the inclusive range [0 .. 1]globalAlpha stack valueglobalCompositeOperation
globalCompositeOperation stack value if value is a valid GlobalCompositeOperation valueglobalCompositeOperation stack valueimageSmoothingEnabled
imageSmoothingEnabled stack value to value coerced to a booleanimageSmoothingEnabled stack valueimageSmoothingQuality
imageSmoothingQuality stack value if value is a valid ImageSmoothingQuality valueimageSmoothingQuality stack valueisPointInPath
TypeError if arguments.length < 2TypeError if provided fillRule is not a valid FillRuleisPointInPath() operationisPointInStroke
TypeError if arguments.length < 2lineCap
lineCap stack value if value is a valid LineCaplineCap stack valuelineDashOffset
lineDashOffset stack value if value is finitelineDashOffset stack valuelineJoin
lineJoin stack value if value is a valid LineJoinlineJoin stack valuelineTo
TypeError if arguments.length < 2lineWidth
lineWidth stack value if value is finite and greater than 0lineWidth stack valuemeasureText
TypeError if arguments.length < 1TextMetrics objectmiterLimit
miterLimit stack value if value is finite and greater than 0miterLimit stack valuemoveTo
TypeError if arguments.length < 2putImageData
TypeError if arguments.length is not valid arityTypeError if data is not instanceof ImageDataquadraticCurveTo
TypeError if arguments.length < 4rect
TypeError if arguments.length < 4removeHitRegion
TypeError if arguments.length < 1resetTransform
transform stack value to the 2d identity matrixrestore
rotate
TypeError if arguments.length < 1transform stack value if angle is finitesave
scale
TypeError if arguments.length < 2transform stack value if the x and y values are finitescrollPathIntoView (empty noOp stub)setTransform
arguments.length === 0 sets the current transform stack value to the 2d identity matrixarguments.length == 1TypeError if value is not instanceof DOMMatrixtransform stack value to the provided matrixTypeError if arguments.length < 6Number()transform stack value if the provided values are all finiteshadowBlur
shadowBlur stack value if value is finite and greater than 0shadowBlur stack valueshadowColor
shadowColor stack value if value is a valid css colorshadowColor stack valueshadowOffsetX
shadowOffsetX stack value if value is finiteshadowOffsetX stack valueshadowOffsetY
shadowOffsetY stack value if value is finiteshadowOffsetY stack valuestroke
TypeError if path is not instanceof Path2DstrokeRect
TypeError if arguments.length < 4strokeStyle
fillStyle stack value if it's a valid css color, a CanvasGradient or a CanvasPatternfillStyle stack valuestrokeText
TypeError if arguments.length < 3textAlign
textAlign stack value if value is a valid TextAlign valuetextAlign stack valuetextBaseline
textBaseline stack value if value is a valid TextBaseline valuetextBaseline stack valuetransform
TypeError if arguments.length < 6Number()transform stack value if every parameter is finitetranslate
TypeError if arguments.length < 2transform stack value if every parameter is finiteinstanceof checksaddColorStopaddColorStopIndexSizeError DOMException if resulting offset is not finiteSyntaxError when color cannot be parsedinstanceof checkssetTransformsetTransformTypeError if argument.length > 1 and parameter is not an objectDOMMatrix implementationinstanceof checksconstructorlength === 16length === 6matrix.isIdentitytrue if matrix is an identity matrixa-fis2Dtrue if matrix was constructed as a 2d matrixm11-m44 computed propertiesNumber() coercion in settersinstanceof checkscloseclosedrawImage function calls to failinstanceof checkswidth, height and data propertiesconstructorTypeError if width is not finiteTypeError if width is 0TypeError if height is not finiteTypeError if height is 0Uint8ClampedArray of width * height * 4 sizeinstanceof checksCanvasRenderingContext2D for convenienceclosePath implemented from CanvasRenderingContext2DmoveTo implemented from CanvasRenderingContext2DlineTo implemented from CanvasRenderingContext2DbezierCurveTo implemented from CanvasRenderingContext2DquadraticCurveTo implemented from CanvasRenderingContext2Darc implemented from CanvasRenderingContext2DarcTo implemented from CanvasRenderingContext2Dellipse implemented from CanvasRenderingContext2Drect implemented from CanvasRenderingContext2DaddPathTypeError if arguments.length < 1TypeError if provided path is not instanceof Path2Dinstanceof checkswidthactualBoundingBoxLeftactualBoundingBoxRightfontBoundingBoxAscentfontBoundingBoxDescentactualBoundingBoxAscentactualBoundingBoxDescentemHeightAscentemHeightDescenthangingBaselinealphabeticBaselineideographicBaselineconstructortext parameterwidth property to text.length