jest-canvas-mock icon indicating copy to clipboard operation
jest-canvas-mock copied to clipboard

putImageData not updating the underlying data set

Open andy-polhill opened this issue 4 years ago • 7 comments

I've been experimenting with getImageData and putImageData, it's relatively new to me so apologies if I've missed a trick with this one. There are a few quirks some of which are outlined here notably that the data property is read only.

In the below test case when you attempt to get the imageData after it has been updated, the returned value is in fact the old data set. The same test when run in Chrome returns the newer data set. Is this a bug or misuse?

  const canvas = document.getElementById('game');
  canvas.width = 1;
  canvas.height = 1;

  const ctx = canvas.getContext('2d');

  const imageData = ctx.getImageData(0, 0, 1, 1);
  imageData.data[0] = 0;
  imageData.data[1] = 0;
  imageData.data[2] = 0;
  imageData.data[3] = 255;
  ctx.putImageData(imageData, 0, 0);
  console.log(ctx.getImageData(0, 0, 1, 1).data);
  expect(ctx.getImageData(0, 0, 1, 1).data).toEqual([0, 0, 0, 255]);

andy-polhill avatar Nov 29 '19 09:11 andy-polhill

Right. These functions are very difficult to account for. We would need to use some kind of cpu bound to keep track of image data. At the moment, this is a "misuse" of jest-canvas-mock.

Did I mention we accept pull requests? 😅

In all seriousness, this is a great feature to have, but very difficult to implement. At that point it might be better to use cairo or node-canvas.

jtenner avatar Nov 29 '19 14:11 jtenner

Hey @jtenner thanks for the response I wondered if it might be a misuse. I'll try and find some time to have a look.

andy-polhill avatar Dec 02 '19 09:12 andy-polhill

See now that I think about it, it looks like node-canvas is very accessible. I am going to do some investigation to see if we can physically replace a lot of the guts this library provides with node-canvas. It might also be worth leaving this library as it is and publish a package called jest-node-canvas-mock that uses node-canvas under the hood.

jtenner avatar Dec 02 '19 16:12 jtenner

I have run into this same using xterm.js since it uses canvas to verify setting of theme values and this canvas implementation only every returns [0, 0, 0, 0] from a context's getImageData call.

Nokel81 avatar Jan 19 '21 19:01 Nokel81

Yes. You need to manually mock that function. Do you know how to the jest mock api to force different return values?

jtenner avatar Jan 22 '21 15:01 jtenner

I do, however, I thought the point of this library was to act as a poly-fill for canvas with reasonable values.

Nokel81 avatar Jan 22 '21 15:01 Nokel81

I believe this library was initially created to do almost zero validation of user input. When I refactored and created the second version, emulating the save stack, I did not intend to perform actual draw calls to buffers. This felt like it was out of the scope of my expertise.

This particular library covers the 99% use case for most users attempting to run their tests when they cannot decouple their tests from a canvas implementation. Your use case requires pixel verification, and it's likely you just need to use node-canvas and bootstrap the tests yourself, or mock the function returns manually.

jtenner avatar Jan 22 '21 15:01 jtenner