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.
 
 
 

164 lines
4.7 KiB

/**
* Set up mock 2D context, for usage in unit tests.
*
* Adapted from: https://github.com/Cristy94/canvas-mock
*/
var jsdom = require('jsdom');
var jsdom_global = require('jsdom-global');
var canvasMock; // Use one canvas instance for all calls to createElement('canvas');
function replaceCanvasContext (el) {
el.getContext = function() {
return {
fillRect: function() {},
clearRect: function(){},
getImageData: function(x, y, w, h) {
return {
data: new Array(w*h*4)
};
},
putImageData: function() {},
createImageData: function(){ return []},
setTransform: function(){},
drawImage: function(){},
save: function(){},
text: function(){},
fillText: function(){},
restore: function(){},
beginPath: function(){},
moveTo: function(){},
lineTo: function(){},
closePath: function(){},
stroke: function(){},
translate: function(){},
scale: function(){},
rotate: function(){},
circle: function(){},
arc: function(){},
fill: function(){},
//
// Following added for vis.js unit tests
//
measureText: function(text) {
return {
width: 12*text.length,
height: 14
};
}
};
}
}
/**
* Overrides document.createElement(), in order to supply a custom canvas element.
*
* In the canvas element, getContext() is overridden in order to supply a simple
* mock object for the 2D context. For all other elements, the call functions unchanged.
*
* The override is only done if there is no 2D context already present.
* This allows for normal running in a browser, and for node.js the usage of 'canvas'.
*
* @param {object} window - current global window object. This can possibly come from module 'jsdom',
* when running under node.js.
* @private
*/
function overrideCreateElement(window) {
var d = window.document;
var f = window.document.createElement;
// Check if 2D context already present. That happens either when running in a browser,
// or this is node.js with 'canvas' installed.
var ctx = d.createElement('canvas').getContext('2d');
if (ctx !== null && ctx !== undefined) {
//console.log('2D context is present, no need to override');
return;
}
window.document.createElement = function(param) {
if (param === 'canvas') {
if (canvasMock === undefined) {
canvasMock = f.call(d, 'canvas');
replaceCanvasContext(canvasMock);
}
return canvasMock;
} else {
return f.call(d, param);
}
};
}
/**
* The override is only done if there is no 2D context already present.
* This allows for normal running in a browser, and for node.js the usage of 'style'
* property on a newly created svg element.
*
* @param {object} window - current global window object. This can possibly come from module 'jsdom',
* when running under node.js.
* @private
*/
function overrideCreateElementNS(window) {
var d = window.document;
var f = window.document.createElementNS;
window.document.createElementNS = function(namespaceURI, qualifiedName) {
if (namespaceURI === 'http://www.w3.org/2000/svg') {
var result = f.call(d, namespaceURI, qualifiedName);
if (result.style == undefined) {
result.style = {};
return result;
}
}
};
}
/**
* Initialize the mock, jsdom and jsdom_global for unit test usage.
*
* Suppresses a warning from `jsdom` on usage of `getContext()`. A mock definition is added for
* it, so the message is not relevant.
*
* @param {string} [html=''] html definitions which should be added to the jsdom definition
* @returns {function} function to call in after(), to clean up for `jsdom_global`
*/
function mockify(html = '') {
// Start of message that we want to suppress.
let msg = 'Error: Not implemented: HTMLCanvasElement.prototype.getContext'
+ ' (without installing the canvas npm package)';
// Override default virtual console of jsdom
const virtualConsole = new jsdom.VirtualConsole();
// Set up a simple 'mock' console output. Only 'error' needs to be overridden
let myConsole = {
error: (msg) => {
if (msg.indexOf(msg) === 0) {
//console.error('all is well');
} else {
// All other messages pass through
console.error(msg);
}
}
};
// Using the global catch instead of specific event handler, because I couldn't get them to work
virtualConsole.sendTo(myConsole);
let cleanupFunction = jsdom_global(
html,
{ skipWindowCheck: true, virtualConsole: virtualConsole}
);
overrideCreateElement(window); // The actual initialization of canvas-mock
overrideCreateElementNS(window);
return cleanupFunction;
}
module.exports = mockify;