vis.js is a dynamic, browser-based visualization library
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

137 lines
3.9 KiB

  1. /**
  2. * Set up mock 2D context, for usage in unit tests.
  3. *
  4. * Adapted from: https://github.com/Cristy94/canvas-mock
  5. */
  6. var jsdom = require('jsdom');
  7. var jsdom_global = require('jsdom-global');
  8. var canvasMock; // Use one canvas instance for all calls to createElement('canvas');
  9. function replaceCanvasContext (el) {
  10. el.getContext = function() {
  11. return {
  12. fillRect: function() {},
  13. clearRect: function(){},
  14. getImageData: function(x, y, w, h) {
  15. return {
  16. data: new Array(w*h*4)
  17. };
  18. },
  19. putImageData: function() {},
  20. createImageData: function(){ return []},
  21. setTransform: function(){},
  22. drawImage: function(){},
  23. save: function(){},
  24. fillText: function(){},
  25. restore: function(){},
  26. beginPath: function(){},
  27. moveTo: function(){},
  28. lineTo: function(){},
  29. closePath: function(){},
  30. stroke: function(){},
  31. translate: function(){},
  32. scale: function(){},
  33. rotate: function(){},
  34. arc: function(){},
  35. fill: function(){},
  36. //
  37. // Following added for vis.js unit tests
  38. //
  39. measureText: function(text) {
  40. return {
  41. width: 12*text.length,
  42. height: 14
  43. };
  44. },
  45. };
  46. }
  47. };
  48. /**
  49. * Overrides document.createElement(), in order to supply a custom canvas element.
  50. *
  51. * In the canvas element, getContext() is overridden in order to supply a simple
  52. * mock object for the 2D context. For all other elements, the call functions unchanged.
  53. *
  54. * The override is only done if there is no 2D context already present.
  55. * This allows for normal running in a browser, and for node.js the usage of 'canvas'.
  56. *
  57. * @param {object} the current global window object. This can possibly come from module 'jsdom',
  58. * when running under node.js.
  59. * @private
  60. */
  61. function overrideCreateElement(window) {
  62. var d = window.document;
  63. var f = window.document.createElement;
  64. // Check if 2D context already present. That happens either when running in a browser,
  65. // or this is node.js with 'canvas' installed.
  66. var ctx = d.createElement('canvas').getContext('2d');
  67. if (ctx !== null && ctx !== undefined) {
  68. //console.log('2D context is present, no need to override');
  69. return;
  70. }
  71. window.document.createElement = function(param) {
  72. if (param === 'canvas') {
  73. if (canvasMock === undefined) {
  74. canvasMock = f.call(d, 'canvas');
  75. replaceCanvasContext(canvasMock);
  76. }
  77. return canvasMock;
  78. } else {
  79. return f.call(d, param);
  80. }
  81. };
  82. }
  83. /**
  84. * Initialize the mock, jsdom and jsdom_global for unit test usage.
  85. *
  86. * Suppresses a warning from `jsdom` on usage of `getContext()`. A mock definition is added for
  87. * it, so the message is not relevant.
  88. *
  89. * @param {string} [html=''] html definitions which should be added to the jsdom definition
  90. * @returns {function} function to call in after(), to clean up for `jsdom_global`
  91. */
  92. function mockify(html = '') {
  93. // Start of message that we want to suppress.
  94. let msg = 'Error: Not implemented: HTMLCanvasElement.prototype.getContext'
  95. + ' (without installing the canvas npm package)';
  96. // Override default virtual console of jsdom
  97. const virtualConsole = new jsdom.VirtualConsole();
  98. // Set up a simple 'mock' console output. Only 'error' needs to be overridden
  99. let myConsole = {
  100. error: (msg) => {
  101. if (msg.indexOf(msg) === 0) {
  102. //console.error('all is well');
  103. } else {
  104. // All other messages pass through
  105. console.error(msg);
  106. }
  107. }
  108. };
  109. // Using the global catch instead of specific event handler, because I couldn't get them to work
  110. virtualConsole.sendTo(myConsole);
  111. let cleanupFunction = jsdom_global(
  112. html,
  113. { skipWindowCheck: true, virtualConsole: virtualConsole}
  114. );
  115. overrideCreateElement(window); // The actual initialization of canvas-mock
  116. return cleanupFunction;
  117. }
  118. module.exports = mockify;