Skip to content
This repository has been archived by the owner on Jul 29, 2019. It is now read-only.

Commit

Permalink
Use mock canvas object replacing canvas (#3518)
Browse files Browse the repository at this point in the history
* Use mock canvas object replacing `canvas`

Fixes #3515.

A mock canvas object is added to the unit tests, which makes usage of module `canvas` voluntary.

The issue with `canvas` is that it requires an external dependency to `cairo`. This complicates setting up a develop environment for `vis.js`

- Removed `canvas` from `package.json`
- Added section to README.md with instructions on how to install `canvas` instead.

* Removed debugger statements

* Updates for review

* Fixes for review
  • Loading branch information
wimrijnders authored and yotamberk committed Oct 13, 2017
1 parent f6445cd commit 06b2623
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 8 deletions.
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@ Link via cdnjs: http://cdnjs.com
Or download the library from the github project:
[https://github.com/almende/vis.git](https://github.com/almende/vis.git).


### Installing module `canvas`

Module `canvas` is only required if you need to run `vis.js` on `node.js` and require actual output. It is not required for regular usage in a browser.

Currently, the unit tests use a mock object for canvas which has limited but adequate functionality. If `canvas` is installed, that will be used silently in place of the mock object.

The issue with `canvas` is that it has an external dependency to `cairo`. This needs to be installed outside of the regular install as done by `npm`. Please consult [`node-canvas` github page](https://github.com/Automattic/node-canvas/wiki#desktop) for the correct installation procecure your platform


## Load

To use a component, include the javascript and css files of vis in your web page:
Expand Down Expand Up @@ -322,6 +332,9 @@ module: {

There is also an [demo-project](https://github.com/mojoaxel/vis-webpack-demo) showing the integration of vis.js using webpack.




## Test

To test the library, install the project dependencies once:
Expand Down
11 changes: 5 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,29 +34,28 @@
},
"dependencies": {
"emitter-component": "^1.1.1",
"moment": "^2.18.1",
"propagating-hammerjs": "^1.4.6",
"hammerjs": "^2.0.8",
"keycharm": "^0.2.0"
"keycharm": "^0.2.0",
"moment": "^2.18.1",
"propagating-hammerjs": "^1.4.6"
},
"devDependencies": {
"async": "^2.5.0",
"babel-core": "^6.25.0",
"babel-loader": "^7.1.1",
"babel-polyfill": "^6.23.0",
"babel-plugin-transform-es3-member-expression-literals": "^6.22.0",
"babel-plugin-transform-es3-property-literals": "^6.22.0",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-polyfill": "^6.23.0",
"babel-preset-es2015": "^6.24.1",
"babel-runtime": "^6.23.0",
"babelify": "^7.3.0",
"canvas": "^1.6.5",
"clean-css": "^4.1.7",
"eslint": "^4.3.0",
"gulp": "^3.9.1",
"gulp-eslint": "^4.0.0",
"gulp-clean-css": "^3.7.0",
"gulp-concat": "^2.6.1",
"gulp-eslint": "^4.0.0",
"gulp-rename": "^1.2.2",
"gulp-util": "^3.0.8",
"jsdom": "9.12.0",
Expand Down
2 changes: 2 additions & 0 deletions test/Graph3d.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ var assert = require('assert');
var vis = require('../dist/vis');
var Graph3d = vis.Graph3d;
var jsdom_global = require('jsdom-global');
var canvasMockify = require('./canvas-mock');
var stdout = require('test-console').stdout;
var Validator = require("./../lib/shared/Validator").default;
//var {printStyle} = require('./../lib/shared/Validator');
Expand All @@ -16,6 +17,7 @@ describe('Graph3d', function () {
"<div id='mygraph'></div>",
{ skipWindowCheck: true}
);
canvasMockify(window);
this.container = document.getElementById('mygraph');
});

Expand Down
2 changes: 2 additions & 0 deletions test/Label.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ var Label = require('../lib/network/modules/components/shared/Label').default;
var NodesHandler = require('../lib/network/modules/NodesHandler').default;
var util = require('../lib/util');
var jsdom_global = require('jsdom-global');
var canvasMockify = require('./canvas-mock');
var vis = require('../dist/vis');
var Network = vis.network;

Expand Down Expand Up @@ -324,6 +325,7 @@ describe('Network Label', function() {
"<div id='mynetwork'></div>",
{ skipWindowCheck: true}
);
canvasMockify(window);
this.container = document.getElementById('mynetwork');
});

Expand Down
8 changes: 6 additions & 2 deletions test/Network.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ var fs = require('fs');
var assert = require('assert');
var vis = require('../dist/vis');
var Network = vis.network;
var jsdom_global = require('jsdom-global');
var stdout = require('test-console').stdout;
var Validator = require("./../lib/shared/Validator").default;
var jsdom_global = require('jsdom-global');
var canvasMockify = require('./canvas-mock');
var {allOptions, configureOptions} = require('./../lib/network/options.js');
//var {printStyle} = require('./../lib/shared/Validator');

Expand Down Expand Up @@ -222,13 +223,16 @@ function checkFontProperties(fontItem, checkStrict = true) {





describe('Network', function () {

before(function() {
this.jsdom_global = jsdom_global(
"<div id='mynetwork'></div>",
{ skipWindowCheck: true}
);
canvasMockify(window);
this.container = document.getElementById('mynetwork');
});

Expand Down Expand Up @@ -324,6 +328,7 @@ describe('Network', function () {
* The real deterrent is eslint rule 'guard-for-in`.
*/
it('can deal with added fields in Array.prototype', function (done) {
var canvas = window.document.createElement('canvas');
Array.prototype.foo = 1; // Just add anything to the prototype
Object.prototype.bar = 2; // Let's screw up hashes as well

Expand Down Expand Up @@ -688,7 +693,6 @@ describe('Edge', function () {

describe('Clustering', function () {


it('properly handles options allowSingleNodeCluster', function() {
var [network, data, numNodes, numEdges] = createSampleNetwork();
data.edges.update({from: 1, to: 11,});
Expand Down
90 changes: 90 additions & 0 deletions test/canvas-mock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/**
* Set up mock 2D context, for usage in unit tests.
*
* Adapted from: https://github.com/Cristy94/canvas-mock
*/

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(){},
fillText: function(){},
restore: function(){},
beginPath: function(){},
moveTo: function(){},
lineTo: function(){},
closePath: function(){},
stroke: function(){},
translate: function(){},
scale: function(){},
rotate: 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} the current global window object. This can possible come from module 'jsdom',
* when running under node.js.
*/
function mockify(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);
}
};
}

module.exports = mockify;

0 comments on commit 06b2623

Please sign in to comment.