fabric.js/test/unit/canvas_static.js
Jeremy Shipman 0c936ed6bc Fix testem runner, and further improvements (#4593)
* Switched qunit dependency to npm

* Fixed testem not working

* Switched test.js build to use node-qunit.
As stated in the QUnit docs: The qunit package prior to 2.4.1 is an alternative CLI that is now published as node-qunit.

* Introduced qunit 2.4.1, with an npm script for running node tests

* Switched testem page fixture to use qunit package instead of qunitjs

* Configured testem to run in headless mode, and use new npm node test script for "Node" launcher configuration.
This means that individual tests will show up in testem output via the the `tap` test protocol.

* Made canvas_static 'toDataURL cropping' test asynchronous.

* Configured QUnit testTimeout and enabled 'noglobals' config

* Updated .travis.yml config to do cross-browser/env testing via Testem

* Specify qunit binary directly to fix confict with binary from node-qunit

* Avoid test hanging by aborting the animated cursor

* Firefox test fix, and enabled in Testem config
2017-12-31 09:51:07 +01:00

1624 lines
67 KiB
JavaScript

(function() {
// var emptyImageCanvasData = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAfQAAAH0CAYAAADL1t+KAAAH7ElEQVR4nO3VMQ0AMAzAsPInvYHoMS2yEeTLHADge/M6AADYM3QACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIuMjH4b7osLFBAAAAAElFTkSuQmCC";
var CANVAS_SVG = '<?xml version="1.0" encoding="UTF-8" standalone="no" ?>\n<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n' +
'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="600" viewBox="0 0 600 600" xml:space="preserve">\n<desc>Created with Fabric.js ' + fabric.version + '</desc>\n<defs>\n</defs>\n</svg>';
var CANVAS_SVG_VIEWBOX = '<?xml version="1.0" encoding="UTF-8" standalone="no" ?>\n<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n' +
'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="600" viewBox="100 100 300 300" xml:space="preserve">\n<desc>Created with Fabric.js ' + fabric.version + '</desc>\n<defs>\n</defs>\n</svg>';
var PATH_JSON = '{"version":"' + fabric.version + '","objects": [{"type": "path", "version":"' + fabric.version + '", "originX": "left", "originY": "top", "left": 268, "top": 266, "width": 51, "height": 49,' +
' "fill": "rgb(0,0,0)", "stroke": null, "strokeWidth": 1, "scaleX": 1, "scaleY": 1, ' +
'"angle": 0, "flipX": false, "flipY": false, "opacity": 1, "path": [["M", 18.511, 13.99],' +
' ["c", 0, 0, -2.269, -4.487, -12.643, 4.411], ["c", 0, 0, 4.824, -14.161, 19.222, -9.059],' +
' ["l", 0.379, -2.1], ["c", -0.759, -0.405, -1.375, -1.139, -1.645, -2.117], ["c", -0.531, ' +
'-1.864, 0.371, -3.854, 1.999, -4.453], ["c", 0.312, -0.118, 0.633, -0.169, 0.953, -0.169], ' +
'["c", 1.299, 0, 2.514, 0.953, 2.936, 2.455], ["c", 0.522, 1.864, -0.372, 3.854, -1.999, ' +
'4.453], ["c", -0.229, 0.084, -0.464, 0.127, -0.692, 0.152], ["l", -0.379, 2.37], ["c", ' +
'1.146, 0.625, 2.024, 1.569, 2.674, 2.758], ["c", 3.213, 2.514, 8.561, 4.184, 11.774, -8.232],' +
' ["c", 0, 0, 0.86, 16.059, -12.424, 14.533], ["c", 0.008, 2.859, 0.615, 5.364, -0.076, 8.224],' +
' ["c", 8.679, 3.146, 15.376, 14.389, 17.897, 18.168], ["l", 2.497, -2.151], ["l", 1.206, 1.839],' +
' ["l", -3.889, 3.458], ["C", 46.286, 48.503, 31.036, 32.225, 22.72, 35.81], ["c", -1.307, 2.851,' +
' -3.56, 6.891, -7.481, 8.848], ["c", -4.689, 2.336, -9.084, -0.802, -11.277, -2.868], ["l",' +
' -1.948, 3.104], ["l", -1.628, -1.333], ["l", 3.138, -4.689], ["c", 0.025, 0, 9, 1.932, 9, 1.932], ' +
'["c", 0.877, -9.979, 2.893, -12.905, 4.942, -15.621], ["C", 17.878, 21.775, 18.713, 17.397, 18.511, ' +
'13.99], ["z", null]]}], "background": "#ff5555", "overlay":"rgba(0,0,0,0.2)"}';
var PATH_WITHOUT_DEFAULTS_JSON = '{"version":"' + fabric.version + '","objects": [{"type": "path", "version":"' + fabric.version + '", "left": 268, "top": 266, "width": 51, "height": 49, "path": [["M", 18.511, 13.99],' +
' ["c", 0, 0, -2.269, -4.487, -12.643, 4.411], ["c", 0, 0, 4.824, -14.161, 19.222, -9.059],' +
' ["l", 0.379, -2.1], ["c", -0.759, -0.405, -1.375, -1.139, -1.645, -2.117], ["c", -0.531, ' +
'-1.864, 0.371, -3.854, 1.999, -4.453], ["c", 0.312, -0.118, 0.633, -0.169, 0.953, -0.169], ' +
'["c", 1.299, 0, 2.514, 0.953, 2.936, 2.455], ["c", 0.522, 1.864, -0.372, 3.854, -1.999, ' +
'4.453], ["c", -0.229, 0.084, -0.464, 0.127, -0.692, 0.152], ["l", -0.379, 2.37], ["c", ' +
'1.146, 0.625, 2.024, 1.569, 2.674, 2.758], ["c", 3.213, 2.514, 8.561, 4.184, 11.774, -8.232],' +
' ["c", 0, 0, 0.86, 16.059, -12.424, 14.533], ["c", 0.008, 2.859, 0.615, 5.364, -0.076, 8.224],' +
' ["c", 8.679, 3.146, 15.376, 14.389, 17.897, 18.168], ["l", 2.497, -2.151], ["l", 1.206, 1.839],' +
' ["l", -3.889, 3.458], ["C", 46.286, 48.503, 31.036, 32.225, 22.72, 35.81], ["c", -1.307, 2.851,' +
' -3.56, 6.891, -7.481, 8.848], ["c", -4.689, 2.336, -9.084, -0.802, -11.277, -2.868], ["l",' +
' -1.948, 3.104], ["l", -1.628, -1.333], ["l", 3.138, -4.689], ["c", 0.025, 0, 9, 1.932, 9, 1.932], ' +
'["c", 0.877, -9.979, 2.893, -12.905, 4.942, -15.621], ["C", 17.878, 21.775, 18.713, 17.397, 18.511, ' +
'13.99], ["z", null]]}], "background": "#ff5555","overlay": "rgba(0,0,0,0.2)"}';
var PATH_DATALESS_JSON = '{"version":"' + fabric.version + '","objects":[{"type":"path","version":"' + fabric.version + '","originX":"left","originY":"top","left":100,"top":100,"width":200,"height":200,"fill":"rgb(0,0,0)",' +
'"stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeLineJoin":"miter","strokeMiterLimit":10,' +
'"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,' +
'"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"sourcePath":"http://example.com/"}]}';
var RECT_JSON = '{"version":"' + fabric.version + '","objects":[{"type":"rect","version":"' + fabric.version + '","originX":"left","originY":"top","left":0,"top":0,"width":10,"height":10,"fill":"rgb(0,0,0)",' +
'"stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeLineJoin":"miter","strokeMiterLimit":10,' +
'"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,' +
'"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"rx":0,"ry":0}],"background":"#ff5555","overlay":"rgba(0,0,0,0.2)"}';
var RECT_JSON_WITH_PADDING = '{"version":"' + fabric.version + '","objects":[{"type":"rect","version":"' + fabric.version + '","originX":"left","originY":"top","left":0,"top":0,"width":10,"height":20,"fill":"rgb(0,0,0)",' +
'"stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeLineJoin":"miter","strokeMiterLimit":10,' +
'"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,' +
'"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"rx":0,"ry":0,"padding":123,"foo":"bar"}]}';
function getAbsolutePath(path) {
var isAbsolute = /^https?:/.test(path);
if (isAbsolute) { return path; };
var imgEl = _createImageElement();
imgEl.src = path;
var src = imgEl.src;
imgEl = null;
return src;
}
var IMG_SRC = fabric.isLikelyNode ? (__dirname + '/../fixtures/test_image.gif') : getAbsolutePath('../fixtures/test_image.gif'),
IMG_WIDTH = 276,
IMG_HEIGHT = 110;
var REFERENCE_IMG_OBJECT = {
'version': fabric.version,
'type': 'image',
'originX': 'left',
'originY': 'top',
'left': 0,
'top': 0,
'width': IMG_WIDTH, // node-canvas doesn't seem to allow setting width/height on image objects
'height': IMG_HEIGHT, // or does it now?
'fill': 'rgb(0,0,0)',
'stroke': null,
'strokeWidth': 0,
'strokeDashArray': null,
'strokeLineCap': 'butt',
'strokeLineJoin': 'miter',
'strokeMiterLimit': 10,
'scaleX': 1,
'scaleY': 1,
'angle': 0,
'flipX': false,
'flipY': false,
'opacity': 1,
'src': IMG_SRC,
'shadow': null,
'visible': true,
'backgroundColor': '',
'clipTo': null,
'filters': [],
'fillRule': 'nonzero',
'paintFirst': 'fill',
'globalCompositeOperation': 'source-over',
'transformMatrix': null,
'crossOrigin': '',
'skewX': 0,
'skewY': 0,
'cropX': 0,
'cropY': 0
};
function _createImageElement() {
return fabric.document.createElement('img');
}
function _createImageObject(width, height, callback) {
var elImage = _createImageElement();
elImage.width = width;
elImage.height = height;
setSrc(elImage, IMG_SRC, function() {
callback(new fabric.Image(elImage));
});
}
function createImageObject(callback) {
return _createImageObject(IMG_WIDTH, IMG_HEIGHT, callback);
}
function setSrc(img, src, callback) {
img.onload = callback;
img.src = src;
}
function fixImageDimension(imgObj) {
// workaround for node-canvas sometimes producing images with width/height and sometimes not
if (imgObj.width === 0) {
imgObj.width = IMG_WIDTH;
}
if (imgObj.height === 0) {
imgObj.height = IMG_HEIGHT;
}
}
// force creation of static canvas
// TODO: fix this
var canvas = this.canvas = new fabric.StaticCanvas(null, {enableRetinaScaling: false, width: 600, height: 600});
var canvas2 = this.canvas2 = new fabric.StaticCanvas(null, {enableRetinaScaling: false, width: 600, height: 600});
var lowerCanvasEl = canvas.lowerCanvasEl;
function makeRect(options) {
var defaultOptions = { width: 10, height: 10 };
return new fabric.Rect(fabric.util.object.extend(defaultOptions, options || { }));
}
QUnit.module('fabric.StaticCanvas', {
beforeEach: function() {
canvas.clear();
canvas.backgroundColor = fabric.StaticCanvas.prototype.backgroundColor;
canvas.backgroundImage = fabric.StaticCanvas.prototype.backgroundImage;
canvas.overlayColor = fabric.StaticCanvas.prototype.overlayColor;
canvas.viewportTransform = [1, 0, 0, 1, 0, 0];
canvas.calcOffset();
}
});
QUnit.test('initialProperties', function(assert) {
assert.ok('backgroundColor' in canvas);
assert.ok('overlayColor' in canvas);
assert.ok('backgroundImage' in canvas);
assert.ok('overlayImage' in canvas);
assert.ok('clipTo' in canvas);
assert.ok('includeDefaultValues' in canvas);
assert.ok('stateful' in canvas);
assert.ok('renderOnAddRemove' in canvas);
assert.ok('controlsAboveOverlay' in canvas);
assert.ok('allowTouchScrolling' in canvas);
assert.ok('imageSmoothingEnabled' in canvas);
assert.ok('backgroundVpt' in canvas);
assert.ok('overlayVpt' in canvas);
assert.equal(canvas.includeDefaultValues, true);
assert.equal(canvas.stateful, false);
assert.equal(canvas.renderOnAddRemove, true);
assert.equal(canvas.controlsAboveOverlay, false);
assert.equal(canvas.allowTouchScrolling, false);
assert.equal(canvas.imageSmoothingEnabled, true);
assert.equal(canvas.backgroundVpt, true);
assert.equal(canvas.overlayVpt, true);
assert.notStrictEqual(canvas.viewportTransform, canvas2.viewportTransform);
});
QUnit.test('getObjects', function(assert) {
assert.ok(typeof canvas.getObjects === 'function', 'should respond to `getObjects` method');
assert.deepEqual([], canvas.getObjects(), 'should return empty array for `getObjects` when empty');
assert.equal(canvas.getObjects().length, 0, 'should have a 0 length when empty');
});
QUnit.test('getObjects with type', function(assert) {
var rect = new fabric.Rect({ width: 10, height: 20 });
var circle = new fabric.Circle({ radius: 30 });
canvas.add(rect, circle);
assert.equal(canvas.getObjects().length, 2, 'should have length=2 initially');
assert.deepEqual(canvas.getObjects('rect'), [rect], 'should return rect only');
assert.deepEqual(canvas.getObjects('circle'), [circle], 'should return circle only');
});
QUnit.test('getElement', function(assert) {
assert.ok(typeof canvas.getElement === 'function', 'should respond to `getElement` method');
assert.equal(canvas.getElement(), lowerCanvasEl, 'should return a proper element');
});
QUnit.test('item', function(assert) {
var rect = makeRect();
assert.ok(typeof canvas.item === 'function', 'should respond to item');
canvas.add(rect);
assert.equal(canvas.item(0), rect, 'should return proper item');
});
QUnit.test('calcOffset', function(assert) {
assert.ok(typeof canvas.calcOffset === 'function', 'should respond to `calcOffset`');
assert.equal(canvas.calcOffset(), canvas, 'should be chainable');
});
QUnit.test('add', function(assert) {
var rect1 = makeRect(),
rect2 = makeRect(),
rect3 = makeRect(),
rect4 = makeRect();
assert.ok(typeof canvas.add === 'function');
assert.equal(canvas.add(rect1), canvas, 'should be chainable');
assert.strictEqual(canvas.item(0), rect1);
canvas.add(rect2, rect3, rect4);
assert.equal(canvas.getObjects().length, 4, 'should support multiple arguments');
assert.strictEqual(canvas.item(1), rect2);
assert.strictEqual(canvas.item(2), rect3);
assert.strictEqual(canvas.item(3), rect4);
});
QUnit.test('add renderOnAddRemove disabled', function(assert) {
var rect = makeRect(),
originalRenderOnAddition,
renderAllCount = 0;
function countRenderAll() {
renderAllCount++;
}
originalRenderOnAddition = canvas.renderOnAddRemove;
canvas.renderOnAddRemove = false;
canvas.on('after:render', countRenderAll);
assert.equal(canvas.add(rect), canvas, 'should be chainable');
assert.equal(renderAllCount, 0);
assert.equal(canvas.item(0), rect);
canvas.add(makeRect(), makeRect(), makeRect());
assert.equal(canvas.getObjects().length, 4, 'should support multiple arguments');
assert.equal(renderAllCount, 0);
canvas.renderAll();
assert.equal(renderAllCount, 1);
canvas.off('after:render', countRenderAll);
canvas.renderOnAddRemove = originalRenderOnAddition;
});
QUnit.test('object:added', function(assert) {
var objectsAdded = [];
canvas.on('object:added', function(e) {
objectsAdded.push(e.target);
});
var rect = new fabric.Rect({ width: 10, height: 20 });
canvas.add(rect);
assert.deepEqual(objectsAdded[0], rect);
var circle1 = new fabric.Circle(),
circle2 = new fabric.Circle();
canvas.add(circle1, circle2);
assert.strictEqual(objectsAdded[1], circle1);
assert.strictEqual(objectsAdded[2], circle2);
var circle3 = new fabric.Circle();
canvas.insertAt(circle3, 2);
assert.strictEqual(objectsAdded[3], circle3);
});
QUnit.test('insertAt', function(assert) {
var rect1 = makeRect(),
rect2 = makeRect();
canvas.add(rect1, rect2);
assert.ok(typeof canvas.insertAt === 'function', 'should respond to `insertAt` method');
var rect = makeRect();
canvas.insertAt(rect, 1);
assert.strictEqual(canvas.item(1), rect);
canvas.insertAt(rect, 2);
assert.strictEqual(canvas.item(2), rect);
assert.equal(canvas.insertAt(rect, 2), canvas, 'should be chainable');
});
QUnit.test('insertAt renderOnAddRemove disabled', function(assert) {
var rect1 = makeRect(),
rect2 = makeRect(),
originalRenderOnAddition,
renderAllCount = 0;
function countRenderAll() {
renderAllCount++;
}
originalRenderOnAddition = canvas.renderOnAddRemove;
canvas.renderOnAddRemove = false;
canvas.on('after:render', countRenderAll);
canvas.add(rect1, rect2);
assert.equal(renderAllCount, 0);
var rect = makeRect();
canvas.insertAt(rect, 1);
assert.equal(renderAllCount, 0);
assert.strictEqual(canvas.item(1), rect);
canvas.insertAt(rect, 2);
assert.equal(renderAllCount, 0);
canvas.renderAll();
assert.equal(renderAllCount, 1);
canvas.off('after:render', countRenderAll);
canvas.renderOnAddRemove = originalRenderOnAddition;
});
QUnit.test('remove', function(assert) {
var rect1 = makeRect(),
rect2 = makeRect(),
rect3 = makeRect(),
rect4 = makeRect();
canvas.add(rect1, rect2, rect3, rect4);
assert.ok(typeof canvas.remove === 'function');
assert.equal(canvas.remove(rect1), canvas, 'should be chainable');
assert.strictEqual(canvas.item(0), rect2, 'should be second object');
canvas.remove(rect2, rect3);
assert.strictEqual(canvas.item(0), rect4);
canvas.remove(rect4);
assert.equal(canvas.isEmpty(), true, 'canvas should be empty');
});
QUnit.test('remove renderOnAddRemove disabled', function(assert) {
var rect1 = makeRect(),
rect2 = makeRect(),
originalRenderOnAddition,
renderAllCount = 0;
function countRenderAll() {
renderAllCount++;
}
originalRenderOnAddition = canvas.renderOnAddRemove;
canvas.renderOnAddRemove = false;
canvas.on('after:render', countRenderAll);
canvas.add(rect1, rect2);
assert.equal(renderAllCount, 0);
assert.equal(canvas.remove(rect1), canvas, 'should be chainable');
assert.equal(renderAllCount, 0);
assert.strictEqual(canvas.item(0), rect2, 'only second object should be left');
canvas.renderAll();
assert.equal(renderAllCount, 1);
canvas.off('after:render', countRenderAll);
canvas.renderOnAddRemove = originalRenderOnAddition;
});
QUnit.test('object:removed', function(assert) {
var objectsRemoved = [];
canvas.on('object:removed', function(e) {
objectsRemoved.push(e.target);
});
var rect = new fabric.Rect({ width: 10, height: 20 }),
circle1 = new fabric.Circle(),
circle2 = new fabric.Circle();
canvas.add(rect, circle1, circle2);
assert.strictEqual(canvas.item(0), rect);
assert.strictEqual(canvas.item(1), circle1);
assert.strictEqual(canvas.item(2), circle2);
canvas.remove(rect);
assert.strictEqual(objectsRemoved[0], rect);
canvas.remove(circle1, circle2);
assert.strictEqual(objectsRemoved[1], circle1);
assert.strictEqual(objectsRemoved[2], circle2);
assert.equal(canvas.isEmpty(), true, 'canvas should be empty');
});
QUnit.test('clearContext', function(assert) {
assert.ok(typeof canvas.clearContext === 'function');
assert.equal(canvas.clearContext(canvas.contextContainer), canvas, 'should be chainable');
});
QUnit.test('clear', function(assert) {
assert.ok(typeof canvas.clear === 'function');
var bg = new fabric.Rect({ width: 10, height: 20 });
canvas.backgroundColor = '#FF0000';
canvas.overlayColor = '#FF0000';
canvas.backgroundImage = bg;
canvas.overlayImage = bg;
assert.equal(canvas.clear(), canvas, 'should be chainable');
assert.equal(canvas.getObjects().length, 0, 'clear remove all objects');
assert.equal(canvas.backgroundColor, '', 'clear remove background color');
assert.equal(canvas.overlayColor, '', 'clear remove overlay color');
assert.equal(canvas.backgroundImage, null, 'clear remove bg image');
assert.equal(canvas.overlayImage, null, 'clear remove overlay image');
});
QUnit.test('renderAll', function(assert) {
assert.ok(typeof canvas.renderAll === 'function');
assert.equal(canvas, canvas.renderAll());
});
QUnit.test('toDataURL', function(assert) {
assert.ok(typeof canvas.toDataURL === 'function');
if (!fabric.Canvas.supports('toDataURL')) {
window.alert('toDataURL is not supported by this environment. Some of the tests can not be run.');
}
else {
var rect = new fabric.Rect({width: 100, height: 100, fill: 'red', top: 0, left: 0});
canvas.add(rect);
var dataURL = canvas.toDataURL();
// don't compare actual data url, as it is often browser-dependent
// this.assertIdentical(emptyImageCanvasData, canvas.toDataURL('png'));
assert.equal(typeof dataURL, 'string');
assert.equal(dataURL.substring(0, 21), 'data:image/png;base64');
//we can just compare that the dataUrl generated differs from the dataURl of an empty canvas.
assert.equal(dataURL.substring(200, 210) != 'AAAAAAAAAA', true);
}
});
QUnit.test('toDataURL jpg', function(assert) {
if (!fabric.Canvas.supports('toDataURL')) {
window.alert('toDataURL is not supported by this environment. Some of the tests can not be run.');
}
else {
try {
var dataURL = canvas.toDataURL({ format: 'jpg' });
assert.equal(dataURL.substring(0, 22), 'data:image/jpeg;base64');
}
// node-canvas does not support jpeg data urls
catch (err) {
assert.ok(true);
}
}
});
QUnit.test('toDataURL cropping', function(assert) {
var done = assert.async();
assert.ok(typeof canvas.toDataURL === 'function');
if (!fabric.Canvas.supports('toDataURL')) {
window.alert('toDataURL is not supported by this environment. Some of the tests can not be run.');
done();
}
else {
var croppingWidth = 75,
croppingHeight = 50,
dataURL = canvas.toDataURL({width: croppingWidth, height: croppingHeight});
fabric.Image.fromURL(dataURL, function (img) {
assert.equal(img.width, croppingWidth, 'Width of exported image should correspond to cropping width');
assert.equal(img.height, croppingHeight, 'Height of exported image should correspond to cropping height');
done();
});
}
});
QUnit.test('centerObjectH', function(assert) {
assert.ok(typeof canvas.centerObjectH === 'function');
var rect = makeRect({ left: 102, top: 202 });
canvas.add(rect);
assert.equal(canvas.centerObjectH(rect), canvas, 'should be chainable');
assert.equal(rect.getCenterPoint().x, canvas.width / 2, 'object\'s "center.y" property should correspond to canvas element\'s center');
canvas.setZoom(4);
assert.equal(rect.getCenterPoint().x, canvas.height / 2, 'object\'s "center.x" property should correspond to canvas element\'s center when canvas is transformed');
canvas.setZoom(1);
});
QUnit.test('centerObjectV', function(assert) {
assert.ok(typeof canvas.centerObjectV === 'function');
var rect = makeRect({ left: 102, top: 202 });
canvas.add(rect);
assert.equal(canvas.centerObjectV(rect), canvas, 'should be chainable');
assert.equal(rect.getCenterPoint().y, canvas.height / 2, 'object\'s "center.y" property should correspond to canvas element\'s center');
canvas.setZoom(2);
assert.equal(rect.getCenterPoint().y, canvas.height / 2, 'object\'s "center.y" property should correspond to canvas element\'s center when canvas is transformed');
});
QUnit.test('centerObject', function(assert) {
assert.ok(typeof canvas.centerObject === 'function');
var rect = makeRect({ left: 102, top: 202 });
canvas.add(rect);
assert.equal(canvas.centerObject(rect), canvas, 'should be chainable');
assert.equal(rect.getCenterPoint().y, canvas.height / 2, 'object\'s "center.y" property should correspond to canvas element\'s center');
assert.equal(rect.getCenterPoint().x, canvas.height / 2, 'object\'s "center.x" property should correspond to canvas element\'s center');
canvas.setZoom(4);
assert.equal(rect.getCenterPoint().y, canvas.height / 2, 'object\'s "center.y" property should correspond to canvas element\'s center when canvas is transformed');
assert.equal(rect.getCenterPoint().x, canvas.height / 2, 'object\'s "center.x" property should correspond to canvas element\'s center when canvas is transformed');
canvas.setZoom(1);
});
QUnit.test('viewportCenterObjectH', function(assert) {
assert.ok(typeof canvas.viewportCenterObjectH === 'function');
var rect = makeRect({ left: 102, top: 202 }), pan = 10;
canvas.viewportTransform = [1, 0, 0, 1, 0, 0];
canvas.add(rect);
var oldY = rect.top;
assert.equal(canvas.viewportCenterObjectH(rect), canvas, 'should be chainable');
assert.equal(rect.getCenterPoint().x, canvas.width / 2, 'object\'s "center.x" property should correspond to canvas element\'s center when canvas is not transformed');
assert.equal(rect.top, oldY, 'object\'s "top" should not change');
canvas.setZoom(2);
canvas.viewportCenterObjectH(rect);
assert.equal(rect.getCenterPoint().x, canvas.width / (2 * canvas.getZoom()), 'object\'s "center.x" property should correspond to viewport center');
assert.equal(rect.top, oldY, 'object\'s "top" should not change');
canvas.absolutePan({x: pan, y: pan});
canvas.viewportCenterObjectH(rect);
assert.equal(rect.getCenterPoint().x, (canvas.width / 2 + pan) / canvas.getZoom(), 'object\'s "center.x" property should correspond to viewport center');
assert.equal(rect.top, oldY, 'object\'s "top" should not change');
});
QUnit.test('viewportCenterObjectV', function(assert) {
assert.ok(typeof canvas.viewportCenterObjectV === 'function');
var rect = makeRect({ left: 102, top: 202 }), pan = 10;
canvas.viewportTransform = [1, 0, 0, 1, 0, 0];
canvas.add(rect);
var oldX = rect.left;
assert.equal(canvas.viewportCenterObjectV(rect), canvas, 'should be chainable');
assert.equal(rect.getCenterPoint().y, canvas.height / 2, 'object\'s "center.y" property should correspond to canvas element\'s center when canvas is not transformed');
assert.equal(rect.left, oldX, 'x position did not change');
canvas.setZoom(2);
canvas.viewportCenterObjectV(rect);
assert.equal(rect.getCenterPoint().y, canvas.height / (2 * canvas.getZoom()), 'object\'s "center.y" property should correspond to viewport center');
assert.equal(rect.left, oldX, 'x position did not change');
canvas.absolutePan({x: pan, y: pan});
canvas.viewportCenterObjectV(rect);
assert.equal(rect.getCenterPoint().y, (canvas.height / 2 + pan) / canvas.getZoom(), 'object\'s "top" property should correspond to viewport center');
assert.equal(rect.left, oldX, 'x position did not change');
});
QUnit.test('viewportCenterObject', function(assert) {
assert.ok(typeof canvas.viewportCenterObject === 'function');
var rect = makeRect({ left: 102, top: 202 }), pan = 10;
canvas.viewportTransform = [1, 0, 0, 1, 0, 0];
canvas.add(rect);
assert.equal(canvas.viewportCenterObject(rect), canvas, 'should be chainable');
assert.equal(rect.getCenterPoint().y, canvas.height / 2, 'object\'s "center.y" property should correspond to canvas element\'s center when canvas is not transformed');
assert.equal(rect.getCenterPoint().x, canvas.width / 2, 'object\'s "center.x" property should correspond to canvas element\'s center when canvas is not transformed');
canvas.setZoom(2);
canvas.viewportCenterObject(rect);
assert.equal(rect.getCenterPoint().y, canvas.height / (2 * canvas.getZoom()), 'object\'s "center.y" property should correspond to viewport center');
assert.equal(rect.getCenterPoint().x, canvas.width / (2 * canvas.getZoom()), 'object\'s "center.x" property should correspond to viewport center');
canvas.absolutePan({x: pan, y: pan});
canvas.viewportCenterObject(rect);
assert.equal(rect.getCenterPoint().y, (canvas.height / 2 + pan) / canvas.getZoom(), 'object\'s "center.y" property should correspond to viewport center');
assert.equal(rect.getCenterPoint().x, (canvas.width / 2 + pan) / canvas.getZoom(), 'object\'s "center.x" property should correspond to viewport center');
canvas.viewportTransform = [1, 0, 0, 1, 0, 0];
});
QUnit.test('straightenObject', function(assert) {
assert.ok(typeof canvas.straightenObject === 'function');
var rect = makeRect({ angle: 10 });
canvas.add(rect);
assert.equal(canvas.straightenObject(rect), canvas, 'should be chainable');
assert.equal(rect.get('angle'), 0, 'angle should be coerced to 0 (from 10)');
rect.rotate('60');
canvas.straightenObject(rect);
assert.equal(rect.get('angle'), 90, 'angle should be coerced to 90 (from 60)');
rect.rotate('100');
canvas.straightenObject(rect);
assert.equal(rect.get('angle'), 90, 'angle should be coerced to 90 (from 100)');
});
QUnit.test('toSVG', function(assert) {
assert.ok(typeof canvas.toSVG === 'function');
canvas.clear();
canvas.viewportTransform = [1, 0, 0, 1, 0, 0];
var svg = canvas.toSVG();
assert.equal(svg, CANVAS_SVG);
});
QUnit.test('toSVG with different encoding (ISO-8859-1)', function(assert) {
assert.ok(typeof canvas.toSVG === 'function');
canvas.clear();
canvas.viewportTransform = [1, 0, 0, 1, 0, 0];
var svg = canvas.toSVG({encoding: 'ISO-8859-1'});
var svgDefaultEncoding = canvas.toSVG();
assert.ok(svg != svgDefaultEncoding);
assert.equal(svg, CANVAS_SVG.replace('encoding="UTF-8"', 'encoding="ISO-8859-1"'));
});
QUnit.test('toSVG without preamble', function(assert) {
assert.ok(typeof canvas.toSVG === 'function');
var withPreamble = canvas.toSVG();
var withoutPreamble = canvas.toSVG({suppressPreamble: true});
assert.ok(withPreamble != withoutPreamble);
assert.equal(withoutPreamble.slice(0, 4), '<svg', 'svg should start with root node when premable is suppressed');
});
QUnit.test('toSVG with viewBox', function(assert) {
assert.ok(typeof canvas.toSVG === 'function');
canvas.clear();
var svg = canvas.toSVG({viewBox: {x: 100, y: 100, width: 300, height: 300}});
assert.equal(svg, CANVAS_SVG_VIEWBOX);
});
QUnit.test('toSVG with reviver', function(assert) {
assert.ok(typeof canvas.toSVG === 'function');
canvas.clear();
var circle = new fabric.Circle(),
rect = new fabric.Rect(),
path1 = new fabric.Path('M 100 100 L 300 100 L 200 300 z'),
tria = new fabric.Triangle(),
polygon = new fabric.Polygon([{x: 10, y: 12},{x: 20, y: 22}]),
polyline = new fabric.Polyline([{x: 10, y: 12},{x: 20, y: 22}]),
line = new fabric.Line(),
text = new fabric.Text('Text'),
group = new fabric.Group([text, line]),
ellipse = new fabric.Ellipse(),
image = new fabric.Image({width: 0, height: 0}),
path2 = new fabric.Path('M 0 0 L 200 100 L 200 300 z'),
path3 = new fabric.Path('M 50 50 L 100 300 L 400 400 z'),
pathGroup = new fabric.Group([path2, path3]);
canvas.renderOnAddRemove = false;
canvas.add(circle, rect, path1, tria, polygon, polyline, group, ellipse, image, pathGroup);
var reviverCount = 0,
len = canvas.size() + group.size() + pathGroup.size();
function reviver(svg) {
reviverCount++;
return svg;
}
canvas.toSVG(null, reviver);
assert.equal(reviverCount, len);
canvas.renderOnAddRemove = true;
});
QUnit.test('toSVG with reviver 2', function(assert) {
assert.ok(typeof canvas.toSVG === 'function');
canvas.clear();
var circle = new fabric.Circle(),
rect = new fabric.Rect(),
path1 = new fabric.Path('M 100 100 L 300 100 L 200 300 z'),
tria = new fabric.Triangle(),
polygon = new fabric.Polygon([{x: 10, y: 12},{x: 20, y: 22}]),
polyline = new fabric.Polyline([{x: 10, y: 12},{x: 20, y: 22}]),
line = new fabric.Line(),
text = new fabric.Text('Text'),
group = new fabric.Group([text, line]),
ellipse = new fabric.Ellipse(),
image = new fabric.Image({width: 0, height: 0}),
imageBG = new fabric.Image({width: 0, height: 0}),
imageOL = new fabric.Image({width: 0, height: 0}),
path2 = new fabric.Path('M 0 0 L 200 100 L 200 300 z'),
path3 = new fabric.Path('M 50 50 L 100 300 L 400 400 z'),
pathGroup = new fabric.Group([path2, path3]);
canvas.renderOnAddRemove = false;
canvas.add(circle, rect, path1, tria, polygon, polyline, group, ellipse, image, pathGroup);
canvas.setBackgroundImage(imageBG);
canvas.setOverlayImage(imageOL);
var reviverCount = 0,
len = canvas.size() + group.size() + pathGroup.size();
function reviver(svg) {
reviverCount++;
return svg;
}
canvas.toSVG(null, reviver);
assert.equal(reviverCount, len + 2, 'reviver should include background and overlay image');
canvas.setBackgroundImage(null);
canvas.setOverlayImage(null);
canvas.renderOnAddRemove = true;
});
QUnit.test('toSVG with exclude from export', function(assert) {
assert.ok(typeof canvas.toSVG === 'function');
canvas.clear();
var circle = new fabric.Circle({excludeFromExport: true}),
rect = new fabric.Rect({excludeFromExport: true}),
path1 = new fabric.Path('M 100 100 L 300 100 L 200 300 z'),
tria = new fabric.Triangle(),
polygon = new fabric.Polygon([{x: 10, y: 12},{x: 20, y: 22}]),
polyline = new fabric.Polyline([{x: 10, y: 12},{x: 20, y: 22}]),
line = new fabric.Line(),
text = new fabric.Text('Text'),
group = new fabric.Group([text, line]),
ellipse = new fabric.Ellipse(),
image = new fabric.Image({width: 0, height: 0}),
path2 = new fabric.Path('M 0 0 L 200 100 L 200 300 z'),
path3 = new fabric.Path('M 50 50 L 100 300 L 400 400 z'),
pathGroup = new fabric.Group([path2, path3]);
canvas.renderOnAddRemove = false;
canvas.add(circle, rect, path1, tria, polygon, polyline, group, ellipse, image, pathGroup);
var reviverCount = 0,
len = canvas.size() + group.size() + pathGroup.size();
function reviver(svg) {
reviverCount++;
return svg;
}
canvas.toSVG(null, reviver);
assert.equal(reviverCount, len - 2, 'reviver should not include objects with excludeFromExport');
canvas.renderOnAddRemove = true;
});
QUnit.test('toJSON', function(assert) {
assert.ok(typeof canvas.toJSON === 'function');
assert.equal(JSON.stringify(canvas.toJSON()), '{"version":"' + fabric.version + '","objects":[]}');
canvas.backgroundColor = '#ff5555';
canvas.overlayColor = 'rgba(0,0,0,0.2)';
assert.equal(JSON.stringify(canvas.toJSON()), '{"version":"' + fabric.version + '","objects":[],"background":"#ff5555","overlay":"rgba(0,0,0,0.2)"}', '`background` and `overlay` value should be reflected in json');
canvas.add(makeRect());
assert.deepEqual(JSON.stringify(canvas.toJSON()), RECT_JSON);
});
QUnit.test('toJSON custom properties non-existence check', function(assert) {
var rect = new fabric.Rect({ width: 10, height: 20 });
rect.padding = 123;
canvas.add(rect);
rect.foo = 'bar';
canvas.bar = 456;
var data = canvas.toJSON(['padding', 'foo', 'bar', 'baz']);
assert.ok('padding' in data.objects[0]);
assert.ok('foo' in data.objects[0], 'foo shouldn\'t be included if it\'s not in an object');
assert.ok(!('bar' in data.objects[0]), 'bar shouldn\'t be included if it\'s not in an object');
assert.ok(!('baz' in data.objects[0]), 'bar shouldn\'t be included if it\'s not in an object');
assert.ok(!('foo' in data));
assert.ok(!('baz' in data));
assert.ok('bar' in data);
});
QUnit.test('toJSON backgroundImage', function(assert) {
var done = assert.async();
createImageObject(function(image) {
canvas.backgroundImage = image;
var json = canvas.toJSON();
fixImageDimension(json.backgroundImage);
assert.deepEqual(json.backgroundImage, REFERENCE_IMG_OBJECT);
canvas.backgroundImage = null;
done();
});
});
QUnit.test('toJSON backgroundImage with custom props', function(assert) {
var done = assert.async();
createImageObject(function(image) {
canvas.backgroundImage = image;
image.custom = 'yes';
var json = canvas.toJSON(['custom']);
assert.equal(json.backgroundImage.custom, 'yes');
canvas.backgroundImage = null;
done();
});
});
QUnit.test('toJSON overlayImage', function(assert) {
var done = assert.async();
createImageObject(function(image) {
canvas.overlayImage = image;
var json = canvas.toJSON();
fixImageDimension(json.overlayImage);
assert.deepEqual(json.overlayImage, REFERENCE_IMG_OBJECT);
canvas.overlayImage = null;
done();
});
});
QUnit.test('toJSON overlayImage with custom props', function(assert) {
var done = assert.async();
createImageObject(function(image) {
canvas.overlayImage = image;
image.custom = 'yes';
var json = canvas.toJSON(['custom']);
assert.equal(json.overlayImage.custom, 'yes');
canvas.overlayImage = null;
done();
});
});
QUnit.test('toDatalessJSON', function(assert) {
var path = new fabric.Path('M 100 100 L 300 100 L 200 300 z', {
sourcePath: 'http://example.com/'
});
canvas.add(path);
assert.equal(JSON.stringify(canvas.toDatalessJSON()), PATH_DATALESS_JSON);
});
QUnit.test('toObject', function(assert) {
assert.ok(typeof canvas.toObject === 'function');
var expectedObject = {
version: fabric.version,
objects: canvas.getObjects()
};
assert.deepEqual(expectedObject, canvas.toObject());
var rect = makeRect();
canvas.add(rect);
assert.equal(canvas.toObject().objects[0].type, rect.type);
});
QUnit.test('toObject non includeDefaultValues', function(assert) {
canvas.includeDefaultValues = false;
var rect = makeRect();
canvas.add(rect);
var cObject = canvas.toObject();
var expectedRect = { version: fabric.version, type: 'rect', width: 10, height: 10 };
assert.deepEqual(cObject.objects[0], expectedRect, 'Rect should be exported withoud defaults');
canvas.includeDefaultValues = true;
});
QUnit.test('toObject excludeFromExport', function(assert) {
var rect = makeRect(), rect2 = makeRect(), rect3 = makeRect();
canvas.clear();
canvas.add(rect, rect2, rect3);
assert.equal(canvas.toObject().objects.length, 3, 'all objects get exported');
rect.excludeFromExport = true;
rect2.excludeFromExport = true;
assert.equal(canvas.toObject().objects.length, 1, 'only one object gets exported');
});
QUnit.test('toObject excludeFromExport bgImage overlay', function(assert) {
var rect = makeRect(), rect2 = makeRect(), rect3 = makeRect();
canvas.clear();
canvas.backgroundImage = rect;
canvas.overlayImage = rect2;
canvas.add(rect3);
var rectToObject = rect.toObject();
var rect2ToObject = rect2.toObject();
var canvasToObject = canvas.toObject();
assert.deepEqual(canvasToObject.backgroundImage, rectToObject, 'background exported');
assert.deepEqual(canvasToObject.overlayImage, rect2ToObject, 'overlay exported');
rect.excludeFromExport = true;
rect2.excludeFromExport = true;
canvasToObject = canvas.toObject();
assert.equal(canvasToObject.backgroundImage, undefined, 'background not exported');
assert.equal(canvasToObject.overlayImage, undefined, 'overlay not exported');
});
QUnit.test('toDatalessObject', function(assert) {
assert.ok(typeof canvas.toDatalessObject === 'function');
var expectedObject = {
version: fabric.version,
objects: canvas.getObjects()
};
assert.deepEqual(expectedObject, canvas.toDatalessObject());
var rect = makeRect();
canvas.add(rect);
assert.equal(canvas.toObject().objects[0].type, rect.type);
// TODO (kangax): need to test this method with fabric.Path to ensure that path is not populated
});
QUnit.test('toObject with additional properties', function(assert) {
canvas.freeDrawingColor = 'red';
canvas.foobar = 123;
var expectedObject = {
version: fabric.version,
objects: canvas.getObjects(),
freeDrawingColor: 'red',
foobar: 123
};
assert.deepEqual(expectedObject, canvas.toObject(['freeDrawingColor', 'foobar']));
var rect = makeRect();
canvas.add(rect);
assert.ok(!('rotatingPointOffset' in canvas.toObject(['smthelse']).objects[0]));
assert.ok('rotatingPointOffset' in canvas.toObject(['rotatingPointOffset']).objects[0]);
});
QUnit.test('isEmpty', function(assert) {
assert.ok(typeof canvas.isEmpty === 'function');
assert.ok(canvas.isEmpty());
canvas.add(makeRect());
assert.ok(!canvas.isEmpty());
});
QUnit.test('loadFromJSON with json string staticCanvas', function(assert) {
var done = assert.async();
assert.ok(typeof canvas.loadFromJSON === 'function');
canvas.loadFromJSON(PATH_JSON, function(){
var obj = canvas.item(0);
assert.ok(!canvas.isEmpty(), 'canvas is not empty');
assert.equal(obj.type, 'path', 'first object is a path object');
assert.equal(canvas.backgroundColor, '#ff5555', 'backgroundColor is populated properly');
assert.equal(obj.get('left'), 268);
assert.equal(obj.get('top'), 266);
assert.equal(obj.get('width'), 49.803999999999995);
assert.equal(obj.get('height'), 48.027);
assert.equal(obj.get('fill'), 'rgb(0,0,0)');
assert.strictEqual(obj.get('stroke'), null);
assert.strictEqual(obj.get('strokeWidth'), 1);
assert.strictEqual(obj.get('scaleX'), 1);
assert.strictEqual(obj.get('scaleY'), 1);
assert.strictEqual(obj.get('angle'), 0);
assert.strictEqual(obj.get('flipX'), false);
assert.strictEqual(obj.get('flipY'), false);
assert.strictEqual(obj.get('opacity'), 1);
assert.ok(obj.get('path').length > 0);
done();
});
});
QUnit.test('loadFromJSON with json object', function(assert) {
var done = assert.async();
assert.ok(typeof canvas.loadFromJSON === 'function');
canvas.loadFromJSON(JSON.parse(PATH_JSON), function(){
var obj = canvas.item(0);
assert.ok(!canvas.isEmpty(), 'canvas is not empty');
assert.equal(obj.type, 'path', 'first object is a path object');
assert.equal(canvas.backgroundColor, '#ff5555', 'backgroundColor is populated properly');
assert.equal(canvas.overlayColor, 'rgba(0,0,0,0.2)', 'overlayColor is populated properly');
assert.equal(obj.get('left'), 268);
assert.equal(obj.get('top'), 266);
assert.equal(obj.get('width'), 49.803999999999995);
assert.equal(obj.get('height'), 48.027);
assert.equal(obj.get('fill'), 'rgb(0,0,0)');
assert.strictEqual(obj.get('stroke'), null);
assert.strictEqual(obj.get('strokeWidth'), 1);
assert.strictEqual(obj.get('scaleX'), 1);
assert.strictEqual(obj.get('scaleY'), 1);
assert.strictEqual(obj.get('angle'), 0);
assert.strictEqual(obj.get('flipX'), false);
assert.strictEqual(obj.get('flipY'), false);
assert.strictEqual(obj.get('opacity'), 1);
assert.ok(obj.get('path').length > 0);
done();
});
});
QUnit.test('loadFromJSON with json object without default values', function(assert) {
var done = assert.async();
assert.ok(typeof canvas.loadFromJSON === 'function');
canvas.loadFromJSON(JSON.parse(PATH_WITHOUT_DEFAULTS_JSON), function(){
var obj = canvas.item(0);
assert.ok(!canvas.isEmpty(), 'canvas is not empty');
assert.equal(obj.type, 'path', 'first object is a path object');
assert.equal(canvas.backgroundColor, '#ff5555', 'backgroundColor is populated properly');
assert.equal(canvas.overlayColor, 'rgba(0,0,0,0.2)', 'overlayColor is populated properly');
assert.equal(obj.get('left'), 268);
assert.equal(obj.get('top'), 266);
assert.equal(obj.get('width'), 49.803999999999995);
assert.equal(obj.get('height'), 48.027);
assert.equal(obj.get('fill'), 'rgb(0,0,0)');
assert.strictEqual(obj.get('stroke'), null);
assert.strictEqual(obj.get('strokeWidth'), 1);
assert.strictEqual(obj.get('scaleX'), 1);
assert.strictEqual(obj.get('scaleY'), 1);
assert.strictEqual(obj.get('angle'), 0);
assert.strictEqual(obj.get('flipX'), false);
assert.strictEqual(obj.get('flipY'), false);
assert.strictEqual(obj.get('opacity'), 1);
assert.ok(obj.get('path').length > 0);
done();
});
});
QUnit.test('loadFromJSON with image background and color', function(assert) {
var done = assert.async();
var serialized = JSON.parse(PATH_JSON);
serialized.background = 'green';
serialized.backgroundImage = JSON.parse('{"type":"image","originX":"left","originY":"top","left":13.6,"top":-1.4,"width":3000,"height":3351,"fill":"rgb(0,0,0)","stroke":null,"strokeWidth":0,"strokeDashArray":null,"strokeLineCap":"butt","strokeLineJoin":"miter","strokeMiterLimit":10,"scaleX":0.05,"scaleY":0.05,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"src":"' + IMG_SRC + '","filters":[],"crossOrigin":""}');
canvas.loadFromJSON(serialized, function() {
assert.ok(!canvas.isEmpty(), 'canvas is not empty');
assert.equal(canvas.backgroundColor, 'green');
assert.ok(canvas.backgroundImage instanceof fabric.Image);
done();
});
});
QUnit.test('loadFromJSON custom properties', function(assert) {
var done = assert.async();
var rect = new fabric.Rect({ width: 10, height: 20 });
rect.padding = 123;
rect.foo = 'bar';
canvas.add(rect);
var jsonWithoutFoo = JSON.stringify(canvas.toJSON(['padding']));
var jsonWithFoo = JSON.stringify(canvas.toJSON(['padding', 'foo']));
assert.equal(jsonWithFoo, RECT_JSON_WITH_PADDING);
assert.ok(jsonWithoutFoo !== RECT_JSON_WITH_PADDING);
canvas.clear();
canvas.loadFromJSON(jsonWithFoo, function() {
var obj = canvas.item(0);
assert.equal(obj.padding, 123, 'padding on object is set properly');
assert.equal(obj.foo, 'bar', '"foo" property on object is set properly');
done();
});
});
QUnit.test('loadFromJSON with text', function(assert) {
var done = assert.async();
var json = '{"objects":[{"type":"text","left":150,"top":200,"width":128,"height":64.32,"fill":"#000000","stroke":"","strokeWidth":"","scaleX":0.8,"scaleY":0.8,"angle":0,"flipX":false,"flipY":false,"opacity":1,"text":"NAME HERE","fontSize":24,"fontWeight":"","fontFamily":"Delicious_500","fontStyle":"","lineHeight":"","textDecoration":"","textAlign":"center","path":"","strokeStyle":"","backgroundColor":""}],"background":"#ffffff"}';
canvas.loadFromJSON(json, function() {
canvas.renderAll();
assert.equal('text', canvas.item(0).type);
assert.equal(150, canvas.item(0).left);
assert.equal(200, canvas.item(0).top);
assert.equal('NAME HERE', canvas.item(0).text);
done();
});
});
QUnit.test('sendToBack', function(assert) {
assert.ok(typeof canvas.sendToBack === 'function');
var rect1 = makeRect(),
rect2 = makeRect(),
rect3 = makeRect();
canvas.add(rect1, rect2, rect3);
canvas.sendToBack(rect3);
assert.equal(canvas.item(0), rect3, 'third should now be the first one');
canvas.sendToBack(rect2);
assert.equal(canvas.item(0), rect2, 'second should now be the first one');
canvas.sendToBack(rect2);
assert.equal(canvas.item(0), rect2, 'second should *still* be the first one');
});
QUnit.test('bringToFront', function(assert) {
assert.ok(typeof canvas.bringToFront === 'function');
var rect1 = makeRect(),
rect2 = makeRect(),
rect3 = makeRect();
canvas.add(rect1, rect2, rect3);
canvas.bringToFront(rect1);
assert.equal(canvas.item(2), rect1, 'first should now be the last one');
canvas.bringToFront(rect2);
assert.equal(canvas.item(2), rect2, 'second should now be the last one');
canvas.bringToFront(rect2);
assert.equal(canvas.item(2), rect2, 'second should *still* be the last one');
});
QUnit.test('sendBackwards', function(assert) {
assert.ok(typeof canvas.sendBackwards === 'function');
var rect1 = makeRect(),
rect2 = makeRect(),
rect3 = makeRect();
canvas.add(rect1, rect2, rect3);
// [ 1, 2, 3 ]
assert.equal(canvas.item(0), rect1);
assert.equal(canvas.item(1), rect2);
assert.equal(canvas.item(2), rect3);
canvas.sendBackwards(rect3);
// moved 3 one level back — [1, 3, 2]
assert.equal(canvas.item(0), rect1);
assert.equal(canvas.item(2), rect2);
assert.equal(canvas.item(1), rect3);
canvas.sendBackwards(rect3);
// moved 3 one level back — [3, 1, 2]
assert.equal(canvas.item(1), rect1);
assert.equal(canvas.item(2), rect2);
assert.equal(canvas.item(0), rect3);
canvas.sendBackwards(rect3);
// 3 stays at the deepEqual position — [2, 3, 1]
assert.equal(canvas.item(1), rect1);
assert.equal(canvas.item(2), rect2);
assert.equal(canvas.item(0), rect3);
canvas.sendBackwards(rect2);
assert.equal(canvas.item(2), rect1);
assert.equal(canvas.item(1), rect2);
assert.equal(canvas.item(0), rect3);
canvas.sendBackwards(rect2);
assert.equal(canvas.item(2), rect1);
assert.equal(canvas.item(0), rect2);
assert.equal(canvas.item(1), rect3);
});
QUnit.test('bringForward', function(assert) {
assert.ok(typeof canvas.bringForward === 'function');
var rect1 = makeRect(),
rect2 = makeRect(),
rect3 = makeRect();
canvas.add(rect1, rect2, rect3);
// initial position — [ 1, 2, 3 ]
assert.equal(canvas.item(0), rect1);
assert.equal(canvas.item(1), rect2);
assert.equal(canvas.item(2), rect3);
canvas.bringForward(rect1);
// 1 moves one way up — [ 2, 1, 3 ]
assert.equal(canvas.item(1), rect1);
assert.equal(canvas.item(0), rect2);
assert.equal(canvas.item(2), rect3);
canvas.bringForward(rect1);
// 1 moves one way up again — [ 2, 3, 1 ]
assert.equal(canvas.item(2), rect1);
assert.equal(canvas.item(0), rect2);
assert.equal(canvas.item(1), rect3);
canvas.bringForward(rect1);
// 1 is already all the way on top and so doesn't change position — [ 2, 3, 1 ]
assert.equal(canvas.item(2), rect1);
assert.equal(canvas.item(0), rect2);
assert.equal(canvas.item(1), rect3);
canvas.bringForward(rect3);
// 1 is already all the way on top and so doesn't change position — [ 2, 1, 3 ]
assert.equal(canvas.item(1), rect1);
assert.equal(canvas.item(0), rect2);
assert.equal(canvas.item(2), rect3);
});
QUnit.test('moveTo', function(assert) {
assert.ok(typeof canvas.moveTo === 'function');
var rect1 = makeRect(),
rect2 = makeRect(),
rect3 = makeRect();
canvas.add(rect1, rect2, rect3);
// [ 1, 2, 3 ]
assert.equal(canvas.item(0), rect1);
assert.equal(canvas.item(1), rect2);
assert.equal(canvas.item(2), rect3);
canvas.moveTo(rect3, 0);
// moved 3 to level 0 — [3, 1, 2]
assert.equal(canvas.item(1), rect1);
assert.equal(canvas.item(2), rect2);
assert.equal(canvas.item(0), rect3);
canvas.moveTo(rect3, 1);
// moved 3 to level 1 — [1, 3, 2]
assert.equal(canvas.item(0), rect1);
assert.equal(canvas.item(2), rect2);
assert.equal(canvas.item(1), rect3);
canvas.moveTo(rect3, 2);
// moved 3 to level 2 — [1, 2, 3]
assert.equal(canvas.item(0), rect1);
assert.equal(canvas.item(1), rect2);
assert.equal(canvas.item(2), rect3);
canvas.moveTo(rect3, 2);
// moved 3 to same level 2 and so doesn't change position — [1, 2, 3]
assert.equal(canvas.item(0), rect1);
assert.equal(canvas.item(1), rect2);
assert.equal(canvas.item(2), rect3);
canvas.moveTo(rect2, 0);
// moved 2 to level 0 — [2, 1, 3]
assert.equal(canvas.item(1), rect1);
assert.equal(canvas.item(0), rect2);
assert.equal(canvas.item(2), rect3);
canvas.moveTo(rect2, 2);
// moved 2 to level 2 — [1, 3, 2]
assert.equal(canvas.item(0), rect1);
assert.equal(canvas.item(2), rect2);
assert.equal(canvas.item(1), rect3);
});
QUnit.test('item', function(assert) {
assert.ok(typeof canvas.item === 'function');
var rect1 = makeRect(),
rect2 = makeRect();
canvas.add(rect1, rect2);
assert.equal(canvas.item(0), rect1);
assert.equal(canvas.item(1), rect2);
canvas.remove(canvas.item(0));
assert.equal(canvas.item(0), rect2);
});
QUnit.test('complexity', function(assert) {
assert.ok(typeof canvas.complexity === 'function');
assert.equal(canvas.complexity(), 0);
canvas.add(makeRect());
assert.equal(canvas.complexity(), 1);
canvas.add(makeRect(), makeRect());
assert.equal(canvas.complexity(), 3);
});
QUnit.test('toString', function(assert) {
assert.ok(typeof canvas.toString === 'function');
assert.equal(canvas.toString(), '#<fabric.Canvas (0): { objects: 0 }>');
canvas.add(makeRect());
assert.equal(canvas.toString(), '#<fabric.Canvas (1): { objects: 1 }>');
});
QUnit.test('dispose clear references', function(assert) {
var canvas2 = new fabric.Canvas();
assert.ok(typeof canvas2.dispose === 'function');
canvas2.add(makeRect(), makeRect(), makeRect());
canvas2.dispose();
assert.equal(canvas2.getObjects().length, 0, 'dispose should clear canvas');
assert.equal(canvas2.lowerCanvasEl, null, 'dispose should clear lowerCanvasEl');
});
QUnit.test('clone', function(assert) {
assert.ok(typeof canvas.clone === 'function');
// TODO (kangax): test clone
});
QUnit.test('getSetWidth', function(assert) {
assert.ok(typeof canvas.getWidth === 'function');
assert.equal(canvas.getWidth(), 600);
assert.equal(canvas.setWidth(444), canvas, 'should be chainable');
assert.equal(canvas.getWidth(), 444);
assert.equal(canvas.lowerCanvasEl.style.width, 444 + 'px');
});
QUnit.test('getSetHeight', function(assert) {
assert.ok(typeof canvas.getHeight === 'function');
assert.equal(canvas.getHeight(), 600);
assert.equal(canvas.setHeight(765), canvas, 'should be chainable');
assert.equal(canvas.getHeight(), 765);
assert.equal(canvas.lowerCanvasEl.style.height, 765 + 'px');
});
QUnit.test('setWidth css only', function(assert) {
canvas.setWidth(123);
canvas.setWidth('100%', { cssOnly: true });
assert.equal(canvas.lowerCanvasEl.style.width, '100%', 'Should be as the css only value');
assert.equal(canvas.getWidth(), 123, 'Should be as the none css only value');
});
QUnit.test('setHeight css only', function(assert) {
canvas.setHeight(123);
canvas.setHeight('100%', { cssOnly: true });
assert.equal(canvas.lowerCanvasEl.style.height, '100%', 'Should be as the css only value');
assert.equal(canvas.getWidth(), 123, 'Should be as the none css only value');
});
QUnit.test('setWidth backstore only', function(assert) {
canvas.setWidth(123);
canvas.setWidth(500, { backstoreOnly: true });
assert.equal(canvas.lowerCanvasEl.style.width, 123 + 'px', 'Should be as none backstore only value + "px"');
assert.equal(canvas.getWidth(), 500, 'Should be as the backstore only value');
});
QUnit.test('setHeight backstore only', function(assert) {
canvas.setHeight(123);
canvas.setHeight(500, { backstoreOnly: true });
assert.equal(canvas.lowerCanvasEl.style.height, 123 + 'px', 'Should be as none backstore only value + "px"');
assert.equal(canvas.getHeight(), 500, 'Should be as the backstore only value');
});
QUnit.test('fxRemove', function(assert) {
var done = assert.async();
assert.ok(typeof canvas.fxRemove === 'function');
var rect = new fabric.Rect();
canvas.add(rect);
var callbackFired = false;
function onComplete(){
callbackFired = true;
}
assert.ok(canvas.item(0) === rect);
assert.equal(canvas.fxRemove(rect, { onComplete: onComplete }), canvas, 'should be chainable');
setTimeout(function() {
assert.equal(canvas.item(0), undefined);
assert.ok(callbackFired);
done();
}, 1000);
});
QUnit.test('options in setBackgroundImage from URL', function(assert) {
var done = assert.async();
canvas.setBackgroundImage(IMG_SRC, function() {
assert.equal(canvas.backgroundImage.left, 50);
assert.equal(canvas.backgroundImage.originX, 'right');
done();
}, {
left: 50,
originX: 'right'
});
});
QUnit.test('setViewportTransform', function(assert) {
assert.ok(typeof canvas.setViewportTransform === 'function');
var vpt = [2, 0, 0, 2, 50, 50];
canvas.viewportTransform = fabric.StaticCanvas.prototype.viewportTransform;
assert.deepEqual(canvas.viewportTransform, [1, 0, 0, 1, 0, 0], 'initial viewport is identity matrix');
canvas.setViewportTransform(vpt);
assert.deepEqual(canvas.viewportTransform, vpt, 'viewport now is the set one');
canvas.viewportTransform = fabric.StaticCanvas.prototype.viewportTransform;
});
QUnit.test('getZoom', function(assert) {
assert.ok(typeof canvas.getZoom === 'function');
var vpt = [2, 0, 0, 2, 50, 50];
canvas.viewportTransform = fabric.StaticCanvas.prototype.viewportTransform;
assert.deepEqual(canvas.getZoom(), 1, 'initial zoom is 1');
canvas.setViewportTransform(vpt);
assert.deepEqual(canvas.getZoom(), 2, 'zoom is set to 2');
canvas.viewportTransform = fabric.StaticCanvas.prototype.viewportTransform;
});
QUnit.test('setZoom', function(assert) {
assert.ok(typeof canvas.setZoom === 'function');
assert.deepEqual(canvas.getZoom(), 1, 'initial zoom is 1');
canvas.setZoom(2);
assert.deepEqual(canvas.getZoom(), 2, 'zoom is set to 2');
canvas.viewportTransform = fabric.StaticCanvas.prototype.viewportTransform;
});
QUnit.test('zoomToPoint', function(assert) {
assert.ok(typeof canvas.zoomToPoint === 'function');
assert.deepEqual(canvas.viewportTransform, [1, 0, 0, 1, 0, 0], 'initial viewport is identity matrix');
var point = new fabric.Point(50, 50);
canvas.zoomToPoint(point, 1);
assert.deepEqual(canvas.viewportTransform, [1, 0, 0, 1, 0, 0], 'viewport has no changes if not moving with zoom level');
canvas.zoomToPoint(point, 2);
assert.deepEqual(canvas.viewportTransform, [2, 0, 0, 2, -50, -50], 'viewport has a translation effect and zoom');
canvas.zoomToPoint(point, 3);
assert.deepEqual(canvas.viewportTransform, [3, 0, 0, 3, -100, -100], 'viewport has a translation effect and zoom');
canvas.viewportTransform = fabric.StaticCanvas.prototype.viewportTransform;
});
QUnit.test('absolutePan', function(assert) {
assert.ok(typeof canvas.absolutePan === 'function');
assert.deepEqual(canvas.viewportTransform, [1, 0, 0, 1, 0, 0], 'initial viewport is identity matrix');
var point = new fabric.Point(50, 50);
canvas.absolutePan(point);
assert.deepEqual(canvas.viewportTransform, [1, 0, 0, 1, -point.x, -point.y], 'viewport has translation effect applied');
canvas.absolutePan(point);
assert.deepEqual(canvas.viewportTransform, [1, 0, 0, 1, -point.x, -point.y], 'viewport has same translation effect applied');
canvas.viewportTransform = fabric.StaticCanvas.prototype.viewportTransform;
});
QUnit.test('relativePan', function(assert) {
assert.ok(typeof canvas.relativePan === 'function');
assert.deepEqual(canvas.viewportTransform, [1, 0, 0, 1, 0, 0], 'initial viewport is identity matrix');
var point = new fabric.Point(-50, -50);
canvas.relativePan(point);
assert.deepEqual(canvas.viewportTransform, [1, 0, 0, 1, -50, -50], 'viewport has translation effect applied');
canvas.relativePan(point);
assert.deepEqual(canvas.viewportTransform, [1, 0, 0, 1, -100, -100], 'viewport has translation effect applied on top of old one');
canvas.viewportTransform = fabric.StaticCanvas.prototype.viewportTransform;
});
QUnit.test('getContext', function(assert) {
assert.ok(typeof canvas.getContext === 'function');
var context = canvas.getContext();
assert.equal(context, canvas.contextContainer, 'should return the context container');
});
QUnit.test('calcViewportBoundaries', function(assert) {
assert.ok(typeof canvas.calcViewportBoundaries === 'function');
canvas.calcViewportBoundaries();
assert.deepEqual(canvas.vptCoords.tl, new fabric.Point(0, 0), 'tl is 0,0');
assert.deepEqual(canvas.vptCoords.tr, new fabric.Point(canvas.getWidth(), 0), 'tr is width, 0');
assert.deepEqual(canvas.vptCoords.bl, new fabric.Point(0, canvas.getHeight()), 'bl is 0, height');
assert.deepEqual(canvas.vptCoords.br, new fabric.Point(canvas.getWidth(), canvas.getHeight()), 'tl is width, height');
});
QUnit.test('calcViewportBoundaries with zoom', function(assert) {
assert.ok(typeof canvas.calcViewportBoundaries === 'function');
canvas.setViewportTransform([2, 0, 0, 2, 0, 0]);
assert.deepEqual(canvas.vptCoords.tl, new fabric.Point(0, 0), 'tl is 0,0');
assert.deepEqual(canvas.vptCoords.tr, new fabric.Point(canvas.getWidth() / 2, 0), 'tl is 0,0');
assert.deepEqual(canvas.vptCoords.bl, new fabric.Point(0, canvas.getHeight() / 2), 'tl is 0,0');
assert.deepEqual(canvas.vptCoords.br, new fabric.Point(canvas.getWidth() / 2, canvas.getHeight() / 2), 'tl is 0,0');
});
QUnit.test('calcViewportBoundaries with zoom and translation', function(assert) {
assert.ok(typeof canvas.calcViewportBoundaries === 'function');
canvas.setViewportTransform([2, 0, 0, 2, -60, 60]);
assert.deepEqual(canvas.vptCoords.tl, new fabric.Point(30, -30), 'tl is 0,0');
assert.deepEqual(canvas.vptCoords.tr, new fabric.Point(30 + canvas.getWidth() / 2, -30), 'tl is 0,0');
assert.deepEqual(canvas.vptCoords.bl, new fabric.Point(30, canvas.getHeight() / 2 - 30), 'tl is 0,0');
assert.deepEqual(canvas.vptCoords.br, new fabric.Point(30 + canvas.getWidth() / 2, canvas.getHeight() / 2 - 30), 'tl is 0,0');
});
QUnit.test('_isRetinaScaling', function(assert) {
canvas.enableRetinaScaling = true;
fabric.devicePixelRatio = 2;
var isScaling = canvas._isRetinaScaling();
assert.equal(isScaling, true, 'retina > 1 and enabled');
canvas.enableRetinaScaling = false;
fabric.devicePixelRatio = 2;
var isScaling = canvas._isRetinaScaling();
assert.equal(isScaling, false, 'retina > 1 and disabled');
canvas.enableRetinaScaling = false;
fabric.devicePixelRatio = 1;
var isScaling = canvas._isRetinaScaling();
assert.equal(isScaling, false, 'retina = 1 and disabled');
canvas.enableRetinaScaling = true;
fabric.devicePixelRatio = 1;
var isScaling = canvas._isRetinaScaling();
assert.equal(isScaling, false, 'retina = 1 and enabled');
});
QUnit.test('getRetinaScaling', function(assert) {
canvas.enableRetinaScaling = true;
fabric.devicePixelRatio = 1;
var scaling = canvas.getRetinaScaling();
assert.equal(scaling, 1, 'retina is devicePixelRatio');
fabric.devicePixelRatio = 2;
var scaling = canvas.getRetinaScaling();
assert.equal(scaling, 2, 'retina is devicePixelRatio');
fabric.devicePixelRatio = 2;
canvas.enableRetinaScaling = false;
var scaling = canvas.getRetinaScaling();
assert.equal(scaling, 1, 'retina is disabled, 1');
});
//how to test with an exception?
/*QUnit.test('options in setBackgroundImage from invalid URL', function(assert) {
var done = assert.async();
canvas.backgroundImage = null;
canvas.setBackgroundImage(IMG_SRC + '_not_exist', function( ) {
assert.equal(canvas.backgroundImage, null);
done();
}, {
left: 50,
originX: 'right'
});
});*/
QUnit.test('options in setBackgroundImage from image instance', function(assert) {
var done = assert.async();
createImageObject(function(imageInstance) {
canvas.setBackgroundImage(imageInstance, function() {
assert.equal(canvas.backgroundImage.left, 100);
assert.equal(canvas.backgroundImage.originX, 'center');
done();
}, {
left: 100,
originX: 'center'
});
});
});
QUnit.test('createPNGStream', function(assert) {
if (!fabric.isLikelyNode) {
assert.ok(true, 'not supposed to run outside node');
}
else {
assert.ok(typeof canvas.createPNGStream === 'function', 'there is a createPNGStream method');
}
});
QUnit.test('createJPEGStream', function(assert) {
if (!fabric.isLikelyNode) {
assert.ok(true, 'not supposed to run outside node');
}
else {
assert.ok(typeof canvas.createJPEGStream === 'function', 'there is a createJPEGStream method');
}
});
// QUnit.test('backgroundImage', function(assert) {
// var done = assert.async();
// assert.deepEqual('', canvas.backgroundImage);
// canvas.setBackgroundImage('../../assets/pug.jpg');
// setTimeout(function() {
// assert.ok(typeof canvas.backgroundImage == 'object');
// assert.ok(/pug\.jpg$/.test(canvas.backgroundImage.src));
// done();
// }, 1000);
// });
// QUnit.test('setOverlayImage', function(assert) {
// var done = assert.async();
// assert.deepEqual(canvas.overlayImage, undefined);
// canvas.setOverlayImage('../../assets/pug.jpg');
// setTimeout(function() {
// assert.ok(typeof canvas.overlayImage == 'object');
// assert.ok(/pug\.jpg$/.test(canvas.overlayImage.src));
// done();
// }, 1000);
// });
})();