mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-06-02 08:14:57 -04:00
Tests: Start getting QUnit tests to work on Node.js
Work in progress…
This commit is contained in:
parent
0c1b4376d3
commit
4c84c3dad5
44 changed files with 322 additions and 176 deletions
.travis.yml
gulp
package.jsonsrc
test
helpers.jsindex.htmlload.js
tests
Color.jsCompoundPath.jsCurve.jsCurveLocation.jsEmitter.jsGroup.jsHitResult.jsItem.jsItem_Bounds.jsItem_Cloning.jsItem_Getting.jsItem_Order.jsJSON.jsLayer.jsMatrix.jsPath.jsPathItem_Contains.jsPath_Boolean.jsPath_Bounds.jsPath_Curves.jsPath_Drawing_Commands.jsPath_Intersections.jsPath_Length.jsPath_Shapes.jsPlacedSymbol.jsPoint.jsProject.jsRaster.jsRectangle.jsSVGExport.jsSVGImport.jsSegment.jsShape.jsSize.jsStyle.jsTextItem.js
|
@ -18,4 +18,5 @@ addons:
|
|||
script:
|
||||
- npm run lint
|
||||
- gulp minify
|
||||
- gulp test
|
||||
- gulp test:browser
|
||||
- gulp test:node
|
||||
|
|
|
@ -11,9 +11,68 @@
|
|||
*/
|
||||
|
||||
var gulp = require('gulp'),
|
||||
qunit = require('gulp-qunit');
|
||||
gulp_qunit = require('gulp-qunit'),
|
||||
node_qunit = require('qunit'),
|
||||
gutil = require('gulp-util'),
|
||||
extend = require('extend'),
|
||||
minimist = require('minimist');
|
||||
|
||||
gulp.task('test', function() {
|
||||
return gulp.src('test/index.html')
|
||||
.pipe(qunit({ timeout: 20, noGlobals: true }));
|
||||
// Support simple command line options to pass on to test:node, to display
|
||||
// errors selectively, e.g.:
|
||||
// gulp test:node --assertions
|
||||
var options = minimist(process.argv.slice(2), {
|
||||
boolean: true
|
||||
});
|
||||
|
||||
gulp.task('test', ['test:browser']);
|
||||
|
||||
gulp.task('test:browser', ['minify:acorn'], function() {
|
||||
return gulp.src('test/index.html')
|
||||
.pipe(gulp_qunit({ timeout: 20, noGlobals: true }));
|
||||
});
|
||||
|
||||
gulp.task('test:node', ['minify:acorn'], function(callback) {
|
||||
var name = 'node-qunit';
|
||||
node_qunit.setup({
|
||||
log: extend({ errors: true }, options)
|
||||
});
|
||||
// Use the correct working directory for tests:
|
||||
process.chdir('./test');
|
||||
node_qunit.run({
|
||||
maxBlockDuration: 100 * 1000,
|
||||
deps: [
|
||||
// To dynamically load the tests files from the sources, we need to
|
||||
// require Prepro.js first. Since we need a sub-module, we have to
|
||||
// use relative addresses: require('prepro/lib/node') does not work
|
||||
// because of the way node-qunit handles relative addresses.
|
||||
'../node_modules/prepro/lib/node.js',
|
||||
// Note that loading dist/paper-full.js also works in combination
|
||||
// with `gulp load`, in which case Prepro.js is present and handles
|
||||
// the loading transparently.
|
||||
{ path: '../dist/paper-full.js', namespace: 'paper' }
|
||||
],
|
||||
// Now load the actual test files through test/load.js, using Prepro.js
|
||||
// for the loading, which was requested above.
|
||||
code: 'load.js'
|
||||
}, function(err, stats) {
|
||||
var result;
|
||||
if (err) {
|
||||
result = new gutil.PluginError(name, err);
|
||||
} else {
|
||||
// Imitate the way gulp-qunit formats results and errors.
|
||||
var color = gutil.colors[stats.failed > 0 ? 'red' : 'green'];
|
||||
gutil.log('Took ' + stats.runtime + ' ms to run ' +
|
||||
gutil.colors.blue(stats.assertions) + ' tests. ' +
|
||||
color(stats.passed + ' passed, ' + stats.failed + ' failed.'));
|
||||
if (stats.failed > 0) {
|
||||
err = 'QUnit assertions failed';
|
||||
gutil.log(name + ': ' + gutil.colors.red('✖ ') + err);
|
||||
result = new gutil.PluginError(name, err);
|
||||
} else {
|
||||
gutil.log(name + ': ' + gutil.colors.green('✔ ') +
|
||||
'QUnit assertions all passed');
|
||||
}
|
||||
}
|
||||
callback(result);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -18,7 +18,7 @@ gulp.on('error', function(err) {
|
|||
var msg = err.toString();
|
||||
if (msg === '[object Object]')
|
||||
msg = err;
|
||||
gutil.log(ERROR, err);
|
||||
gutil.log(ERROR, msg);
|
||||
if (err.stack)
|
||||
gutil.log(ERROR, err.stack);
|
||||
this.emit('end');
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
"README.md"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=0.8.0 <5.0.0"
|
||||
"node": ">=0.8.0 <6.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"jsdom": "git://github.com/lehni/jsdom.git#3d55789d0f4d55392721b1e22890837fde472375",
|
||||
|
@ -42,7 +42,7 @@
|
|||
"gulp": "^3.9.0",
|
||||
"gulp-cached": "^1.1.0",
|
||||
"gulp-jshint": "^2.0.0",
|
||||
"gulp-prepro": "^2.0.0",
|
||||
"gulp-prepro": "^2.1.0",
|
||||
"gulp-qunit": "git://github.com/lehni/gulp-qunit.git#459c5603ceac460327a40dc89df6f19c786dc61b",
|
||||
"gulp-rename": "^1.2.2",
|
||||
"gulp-rimraf": "^0.2.0",
|
||||
|
@ -56,7 +56,9 @@
|
|||
"jshint": "2.8.x",
|
||||
"jshint-summary": "^0.4.0",
|
||||
"merge-stream": "^1.0.0",
|
||||
"prepro": "^2.0.0",
|
||||
"minimist": "^1.2.0",
|
||||
"prepro": "^2.1.0",
|
||||
"qunit": "^0.7.7",
|
||||
"qunitjs": "^1.20.0",
|
||||
"require-dir": "^0.3.0",
|
||||
"resemblejs": "^2.1.0",
|
||||
|
|
|
@ -45,7 +45,7 @@ if (typeof window === 'object') {
|
|||
}
|
||||
} else {
|
||||
// Node.js based loading through Prepro.js:
|
||||
var prepro = require('prepro/lib/node.js'),
|
||||
var prepro = require('prepro/lib/node'),
|
||||
// Load the default browser-based options for further amendments.
|
||||
// Step out and back into src, in case this is loaded from
|
||||
// dist/paper-node.js
|
||||
|
|
|
@ -10,8 +10,19 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
// Until window.history.pushState() works when running locally, we need to trick
|
||||
// qunit into thinking that the feature is not present. This appears to work...
|
||||
var isNode = typeof global === 'object',
|
||||
root;
|
||||
|
||||
if (isNode) {
|
||||
root = global;
|
||||
// Resemble.js needs the Image constructor this global.
|
||||
global.Image = paper.window.Image;
|
||||
} else {
|
||||
root = window;
|
||||
// This is only required when running in the browser:
|
||||
// Until window.history.pushState() works when running locally, we need to
|
||||
// trick qunit into thinking that the feature is not present. This appears
|
||||
// to work...
|
||||
// TODO: Ideally we should fix this in QUnit instead.
|
||||
delete window.history;
|
||||
window.history = {};
|
||||
|
@ -30,6 +41,11 @@ QUnit.begin(function() {
|
|||
transparency: 1
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// The unit-tests expect the paper classes to be global.
|
||||
if (!('Base' in root))
|
||||
paper.install(root);
|
||||
|
||||
var errorHandler = console.error;
|
||||
console.error = function() {
|
||||
|
@ -37,8 +53,48 @@ console.error = function() {
|
|||
errorHandler.apply(this, arguments);
|
||||
};
|
||||
|
||||
// NOTE: In order to "export" all methods into the shared Prepro.js scope when
|
||||
// using node-qunit, we need to define global functions as:
|
||||
// `var name = function() {}`. `function name() {}` does not work!
|
||||
|
||||
var currentProject;
|
||||
|
||||
var test = function(testName, expected) {
|
||||
var parameters = expected.toString().match(/^\s*function[^\(]*\(([^\)]*)/)[1];
|
||||
// If this is running on an older version of QUnit (e.g. node-qunit is stuck
|
||||
// with v1.10 for now), emulate the new assert.async() syntax through
|
||||
// QUnit.asyncTest() and QUnit.start();
|
||||
if (!QUnit.async && parameters === 'assert') {
|
||||
return QUnit.asyncTest(testName, function() {
|
||||
// Since tests may be asynchronous, remove the old project before
|
||||
// running the next test.
|
||||
if (currentProject)
|
||||
currentProject.remove();
|
||||
currentProject = new Project();
|
||||
// Pass a fake assert object with just the functions that we need,
|
||||
// so far a async() function returning a done() function:
|
||||
expected({
|
||||
async: function() {
|
||||
return function() {
|
||||
QUnit.start();
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
return QUnit.test(testName, function(assert) {
|
||||
// Since tests may be asynchronous, remove the old project before
|
||||
// running the next test.
|
||||
if (currentProject)
|
||||
currentProject.remove();
|
||||
currentProject = new Project();
|
||||
expected(assert);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Override equals to convert functions to message and execute them as tests()
|
||||
function equals(actual, expected, message, options) {
|
||||
var equals = function(actual, expected, message, options) {
|
||||
// Allow the use of functions for actual, which will get called and their
|
||||
// source content extracted for readable reports.
|
||||
if (typeof actual === 'function') {
|
||||
|
@ -55,7 +111,7 @@ function equals(actual, expected, message, options) {
|
|||
|| type === 'boolean' && 'Boolean'
|
||||
|| type === 'undefined' && 'Undefined'
|
||||
|| Array.isArray(expected) && 'Array'
|
||||
|| expected instanceof Element && 'Element' // handle DOM Elements
|
||||
|| expected instanceof window.Element && 'Element' // handle DOM Elements
|
||||
|| (cls = expected && expected._class) // check _class 2nd last
|
||||
|| type === 'object' && 'Object'; // Object as catch-all
|
||||
var comparator = type && comparators[type];
|
||||
|
@ -76,7 +132,40 @@ function equals(actual, expected, message, options) {
|
|||
actual, identical ? expected : 'not ' + expected,
|
||||
message + ': identical after cloning');
|
||||
}
|
||||
};
|
||||
|
||||
// A list of classes that should be identical after their owners were cloned.
|
||||
var identicalAfterCloning = {
|
||||
Gradient: true,
|
||||
Symbol: true
|
||||
};
|
||||
|
||||
var getFunctionMessage = function(func) {
|
||||
var message = func.toString().match(
|
||||
/^\s*function[^\{]*\{([\s\S]*)\}\s*$/)[1]
|
||||
.replace(/ /g, '')
|
||||
.replace(/^\s+|\s+$/g, '');
|
||||
if (/^return /.test(message)) {
|
||||
message = message
|
||||
.replace(/^return /, '')
|
||||
.replace(/;$/, '');
|
||||
}
|
||||
return message;
|
||||
};
|
||||
|
||||
var createSVG = function(str, attrs) {
|
||||
if (attrs) {
|
||||
// Similar to SVGExport's createElement / setAttributes.
|
||||
var node = document.createElementNS('http://www.w3.org/2000/svg', str);
|
||||
for (var key in attrs)
|
||||
node.setAttribute(key, attrs[key]);
|
||||
return node;
|
||||
} else {
|
||||
return new window.DOMParser().parseFromString(
|
||||
'<svg xmlns="http://www.w3.org/2000/svg">' + str + '</svg>',
|
||||
'text/xml');
|
||||
}
|
||||
};
|
||||
|
||||
// Register a jsDump parser for Base.
|
||||
QUnit.jsDump.setParser('Base', function (obj, stack) {
|
||||
|
@ -95,14 +184,15 @@ QUnit.jsDump.setParser('object', function (obj, stack) {
|
|||
: objectParser).call(this, obj, stack);
|
||||
});
|
||||
|
||||
function compareProperties(actual, expected, properties, message, options) {
|
||||
var compareProperties = function(actual, expected, properties, message, options) {
|
||||
for (var i = 0, l = properties.length; i < l; i++) {
|
||||
var key = properties[i];
|
||||
equals(actual[key], expected[key], message + '.' + key, options);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function compareItem(actual, expected, message, options, properties) {
|
||||
var compareItem = function(actual, expected, message, options, properties) {
|
||||
options = options || {};
|
||||
|
||||
function rasterize(item, group, resolution) {
|
||||
var raster = null;
|
||||
|
@ -119,7 +209,7 @@ function compareItem(actual, expected, message, options, properties) {
|
|||
+ '" src="' + raster.source + '">';
|
||||
}
|
||||
|
||||
if (options && options.rasterize) {
|
||||
if (options.rasterize) {
|
||||
// In order to properly compare pixel by pixel, we need to put each item
|
||||
// into a group with a white background of the united dimensions of the
|
||||
// bounds of both items before rasterizing.
|
||||
|
@ -159,11 +249,15 @@ function compareItem(actual, expected, message, options, properties) {
|
|||
.compareTo(expected.getImageData())
|
||||
// When working with imageData, this call is synchronous:
|
||||
.onComplete(function(data) { result = data; });
|
||||
var identical = result ? 100 - result.misMatchPercentage : 0,
|
||||
ok = identical == 100,
|
||||
text = identical.toFixed(2) + '% identical';
|
||||
QUnit.push(ok, text, '100.00% identical', message);
|
||||
if (!ok && result) {
|
||||
var tolerance = (options.tolerance || 1e-4) * 100, // percentages...
|
||||
fixed = ((1 / tolerance) + '').length - 1,
|
||||
identical = result ? 100 - result.misMatchPercentage : 0,
|
||||
reached = identical.toFixed(fixed),
|
||||
hundred = (100).toFixed(fixed),
|
||||
ok = reached == hundred;
|
||||
QUnit.push(ok, reached + '% identical', hundred + '% identical',
|
||||
message);
|
||||
if (!ok && result && !isNode) {
|
||||
// Get the right entry for this unit test and assertion, and
|
||||
// replace the results with images
|
||||
var entry = document.getElementById('qunit-test-output-' + id)
|
||||
|
@ -179,14 +273,14 @@ function compareItem(actual, expected, message, options, properties) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if (options && options.cloned)
|
||||
if (options.cloned)
|
||||
QUnit.notStrictEqual(actual.id, expected.id,
|
||||
'not ' + message + '.id');
|
||||
QUnit.strictEqual(actual.constructor, expected.constructor,
|
||||
message + '.constructor');
|
||||
// When item is cloned and has a name, the name will be versioned:
|
||||
equals(actual.name,
|
||||
options && options.cloned && expected.name
|
||||
options.cloned && expected.name
|
||||
? expected.name + ' 1' : expected.name,
|
||||
message + '.name');
|
||||
compareProperties(actual, expected, ['children', 'bounds', 'position',
|
||||
|
@ -201,7 +295,7 @@ function compareItem(actual, expected, message, options, properties) {
|
|||
'dashOffset', 'miterLimit', 'fontSize', 'font', 'leading',
|
||||
'justification'], message + '.style', options);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// A list of comparator functions, based on `expected` type. See equals() for
|
||||
// an explanation of how the type is determined.
|
||||
|
@ -359,56 +453,3 @@ var comparators = {
|
|||
message, options);
|
||||
}
|
||||
};
|
||||
|
||||
// A list of classes that should be identical after their owners were cloned.
|
||||
var identicalAfterCloning = {
|
||||
Gradient: true,
|
||||
Symbol: true
|
||||
};
|
||||
|
||||
function getFunctionMessage(func) {
|
||||
var message = func.toString().match(
|
||||
/^\s*function[^\{]*\{([\s\S]*)\}\s*$/)[1]
|
||||
.replace(/ /g, '')
|
||||
.replace(/^\s+|\s+$/g, '');
|
||||
if (/^return /.test(message)) {
|
||||
message = message
|
||||
.replace(/^return /, '')
|
||||
.replace(/;$/, '');
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
function test(testName, expected) {
|
||||
return QUnit.test(testName, function() {
|
||||
var project = new Project();
|
||||
expected();
|
||||
project.remove();
|
||||
});
|
||||
}
|
||||
|
||||
function asyncTest(testName, expected) {
|
||||
return QUnit.asyncTest(testName, function() {
|
||||
var project = new Project();
|
||||
expected(function() {
|
||||
project.remove();
|
||||
QUnit.start();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// SVG
|
||||
|
||||
function createSVG(str, attrs) {
|
||||
if (attrs) {
|
||||
// Similar to SVGExport's createElement / setAttributes.
|
||||
var node = document.createElementNS('http://www.w3.org/2000/svg', str);
|
||||
for (var key in attrs)
|
||||
node.setAttribute(key, attrs[key]);
|
||||
return node;
|
||||
} else {
|
||||
return new window.DOMParser().parseFromString(
|
||||
'<svg xmlns="http://www.w3.org/2000/svg">' + str + '</svg>',
|
||||
'text/xml');
|
||||
}
|
||||
}
|
|
@ -3,11 +3,10 @@
|
|||
<head>
|
||||
<title>Paper.js Tests</title>
|
||||
<link rel="stylesheet" href="../node_modules/qunitjs/qunit/qunit.css">
|
||||
<script type="text/javascript" src="../node_modules/qunitjs/qunit/qunit.js"></script>
|
||||
<script type="text/javascript" src="../node_modules/resemblejs/resemble.js"></script>
|
||||
<script type="text/javascript" src="js/helpers.js"></script>
|
||||
<script type="text/javascript" src="../src/load.js"></script>
|
||||
<script type="text/javascript" src="tests/load.js"></script>
|
||||
<script src="../node_modules/qunitjs/qunit/qunit.js"></script>
|
||||
<script src="../dist/paper-full.js"></script>
|
||||
<script src="../node_modules/prepro/lib/browser.js"></script>
|
||||
<script src="load.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">QUnit Test Suite</h1>
|
||||
|
|
15
test/load.js
Normal file
15
test/load.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
|
||||
* http://paperjs.org/
|
||||
*
|
||||
* Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
|
||||
* http://scratchdisk.com/ & http://jonathanpuckey.com/
|
||||
*
|
||||
* Distributed under the MIT license. See LICENSE file for details.
|
||||
*
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/*#*/ include('helpers.js');
|
||||
/*#*/ include('../node_modules/resemblejs/resemble.js', { namespace: 'resemble' });
|
||||
/*#*/ include('tests/load.js');
|
|
@ -10,7 +10,7 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('Color');
|
||||
QUnit.module('Color');
|
||||
|
||||
test('Set named color', function() {
|
||||
var path = new Path();
|
||||
|
@ -222,6 +222,3 @@ test('Color#divide', function() {
|
|||
var color = new Color(1, 1, 1);
|
||||
equals(color.divide(4), new Color([0.25, 0.25, 0.25]));
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('Compound Path');
|
||||
QUnit.module('Compound Path');
|
||||
|
||||
test('moveTo / lineTo', function() {
|
||||
var path = new CompoundPath();
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('Curve');
|
||||
QUnit.module('Curve');
|
||||
|
||||
test('Curve#getParameterOf()', function() {
|
||||
// For issue #708:
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('CurveLocation');
|
||||
QUnit.module('CurveLocation');
|
||||
|
||||
test('CurveLocation#offset', function() {
|
||||
var path = new Path();
|
||||
|
|
|
@ -10,10 +10,10 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('Emitter');
|
||||
QUnit.module('Emitter');
|
||||
|
||||
test('on()', function() {
|
||||
var emitter = new Base(Emitter),
|
||||
var emitter = new Item(),
|
||||
installed;
|
||||
// fake event type registration
|
||||
emitter._eventTypes = {mousemove: {install: function(){ installed = true;} } };
|
||||
|
@ -37,7 +37,7 @@ test('on()', function() {
|
|||
});
|
||||
|
||||
test('off()', function() {
|
||||
var emitter = new Base(Emitter),
|
||||
var emitter = new Item(),
|
||||
uninstalled, called = 0,
|
||||
handler = function () {called++},
|
||||
handler2 = function () {};
|
||||
|
@ -68,7 +68,7 @@ test('off()', function() {
|
|||
});
|
||||
|
||||
test('emit()', function() {
|
||||
var emitter = new Base(Emitter),
|
||||
var emitter = new Item(),
|
||||
called,
|
||||
handler = function (e) {called = e};
|
||||
// fake event type registration
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('Group');
|
||||
QUnit.module('Group');
|
||||
|
||||
test('new Group()', function() {
|
||||
var group = new Group();
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('HitResult');
|
||||
QUnit.module('HitResult');
|
||||
|
||||
test('Hit-testing options', function() {
|
||||
var defaultOptions = {
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('Item');
|
||||
QUnit.module('Item');
|
||||
|
||||
test('copyTo(project)', function() {
|
||||
var project = paper.project;
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('Item Bounds');
|
||||
QUnit.module('Item Bounds');
|
||||
|
||||
test('item.bounds caching', function() {
|
||||
var circle = new Path.Circle(new Point(100, 100), 50);
|
||||
|
@ -94,5 +94,5 @@ test('text.bounds', function() {
|
|||
var text = new PointText(new Point(50, 100));
|
||||
text.fillColor = 'black';
|
||||
text.content = 'This is a test';
|
||||
equals(text.bounds, new Rectangle(50, 89.2, 67, 14.4), 'text.bounds', { tolerance: 0.5 });
|
||||
equals(text.bounds, new Rectangle(50, 89.2, 67, 14.4), 'text.bounds', { tolerance: 1 });
|
||||
});
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
QUnit.module('Item Cloning');
|
||||
|
||||
function cloneAndCompare(item) {
|
||||
var copy = item.clone();
|
||||
equals(function() {
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('Getting and Matching Items');
|
||||
QUnit.module('Getting and Matching Items');
|
||||
|
||||
test('Item#getItems()', function() {
|
||||
var group = new Group([new Path({ selected: true }), new Raster()]);
|
||||
|
@ -72,14 +72,14 @@ test('Project#getItems()', function() {
|
|||
className: 'Group'
|
||||
});
|
||||
equals(function() {
|
||||
return matches.length == 1 && matches[0] === group
|
||||
return matches.length == 1 && matches[0] === group;
|
||||
}, true);
|
||||
|
||||
var matches = paper.project.getItems({
|
||||
type: 'group'
|
||||
});
|
||||
equals(function() {
|
||||
return matches.length == 1 && matches[0] === group
|
||||
return matches.length == 1 && matches[0] === group;
|
||||
}, true);
|
||||
|
||||
var raster = new Raster();
|
||||
|
@ -87,7 +87,7 @@ test('Project#getItems()', function() {
|
|||
class: Raster
|
||||
});
|
||||
equals(function() {
|
||||
return matches.length == 1 && matches[0] === raster
|
||||
return matches.length == 1 && matches[0] === raster;
|
||||
}, true);
|
||||
|
||||
equals(function() {
|
||||
|
@ -120,7 +120,7 @@ test('Project#getItems() with compare function', function() {
|
|||
|
||||
var items = paper.project.getItems({
|
||||
opacity: function(value) {
|
||||
return value < 1
|
||||
return value < 1;
|
||||
}
|
||||
});
|
||||
equals(function() {
|
||||
|
@ -162,23 +162,26 @@ test('Project#getItems() with color', function() {
|
|||
});
|
||||
|
||||
test('Project#getItems() with regex function', function() {
|
||||
var decoyPath = new Path({
|
||||
var layer = paper.project.activeLayer;
|
||||
var stopPath = new Path({
|
||||
name: 'stop'
|
||||
});
|
||||
|
||||
var decoyPath2 = new Path({
|
||||
var pausePath = new Path({
|
||||
name: 'pause'
|
||||
});
|
||||
|
||||
var path = new Path({
|
||||
var startPath = new Path({
|
||||
name: 'starting'
|
||||
});
|
||||
|
||||
var items = paper.project.getItems({
|
||||
name: /^start/g
|
||||
});
|
||||
|
||||
// console.log(paper.project.activeLayer);
|
||||
equals(function() {
|
||||
return items.length == 1 && items[0] == path;
|
||||
return items.length == 1 && items[0] == startPath;
|
||||
}, true);
|
||||
|
||||
equals(function() {
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
QUnit.module('Item Order');
|
||||
|
||||
test('Item Order', function() {
|
||||
var line = new Path();
|
||||
line.add([0, 0], [100, 100]);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('JSON');
|
||||
QUnit.module('JSON');
|
||||
|
||||
function testExportImportJSON(project) {
|
||||
// Use higher precision than in comparissons, for bounds
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('Layer');
|
||||
QUnit.module('Layer');
|
||||
|
||||
test('previousSibling / nextSibling', function() {
|
||||
var project = paper.project;
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('Matrix');
|
||||
QUnit.module('Matrix');
|
||||
|
||||
test('Decomposition: rotate()', function() {
|
||||
function testAngle(a, ea) {
|
||||
var m = new Matrix().rotate(a),
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('Path');
|
||||
QUnit.module('Path');
|
||||
|
||||
test('path.join(path)', function() {
|
||||
var path = new Path();
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('PathItem Contains');
|
||||
QUnit.module('PathItem Contains');
|
||||
|
||||
function testPoint(item, point, inside, message) {
|
||||
equals(item.contains(point), inside, message || ('The point ' + point
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('Path Boolean Operations');
|
||||
QUnit.module('Path Boolean Operations');
|
||||
|
||||
function createPath(str) {
|
||||
var ctor = (str.match(/z/gi) || []).length > 1 ? CompoundPath : Path;
|
||||
|
@ -30,7 +30,7 @@ function compareBoolean(actual, expected, message, options) {
|
|||
strokeColor: 'black',
|
||||
fillColor: expected.closed ? 'yellow' : null
|
||||
};
|
||||
equals(actual, expected, message, options || { rasterize: true });
|
||||
equals(actual, expected, message, Base.set({ rasterize: true }, options));
|
||||
}
|
||||
|
||||
test('#541', function() {
|
||||
|
@ -884,7 +884,8 @@ test('Isolated edge-cases from @iconexperience\'s boolean-test suite', function(
|
|||
closed: true
|
||||
});
|
||||
compareBoolean(function() { return path1.unite(); },
|
||||
'M428.65987,123.24313c0,0 18.24445,159.97772 20.21157,166.76806c-3.05664,-6.18082 -73.53131,-139.25432 -73.53131,-139.25432z M448.97323,290.23336c0,0 0,0 0,0c0.22704,0.04317 -0.06896,-0.00471 0,0c-0.02659,-0.00506 -0.06063,-0.08007 -0.1018,-0.22217c0.07286,0.14733 0.10741,0.22256 0.1018,0.22217z');
|
||||
'M428.65987,123.24313c0,0 18.24445,159.97772 20.21157,166.76806c-3.05664,-6.18082 -73.53131,-139.25432 -73.53131,-139.25432z M448.97323,290.23336c0,0 0,0 0,0c0.22704,0.04317 -0.06896,-0.00471 0,0c-0.02659,-0.00506 -0.06063,-0.08007 -0.1018,-0.22217c0.07286,0.14733 0.10741,0.22256 0.1018,0.22217z',
|
||||
null, { tolerance: 1e-3 });
|
||||
|
||||
// #784#issuecomment-168605018
|
||||
var path1 = new CompoundPath();
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('Path Bounds');
|
||||
QUnit.module('Path Bounds');
|
||||
|
||||
test('path.bounds', function() {
|
||||
var path = new Path([
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('Path Curves');
|
||||
QUnit.module('Path Curves');
|
||||
|
||||
test('path.curves synchronisation', function() {
|
||||
var path = new Path();
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('Path Drawing Commands');
|
||||
QUnit.module('Path Drawing Commands');
|
||||
|
||||
test('path.lineTo(point);', function() {
|
||||
var path = new Path();
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('Path Intersections');
|
||||
QUnit.module('Path Intersections');
|
||||
|
||||
function testIntersection(intersections, results) {
|
||||
equals(intersections.length, results.length, 'intersections.length');
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('Path Length');
|
||||
QUnit.module('Path Length');
|
||||
|
||||
test('path.length', function() {
|
||||
var path = new Path([
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('Predefined Path Shapes');
|
||||
QUnit.module('Predefined Path Shapes');
|
||||
|
||||
test('new Path.Rectangle([50, 50], [100, 100])', function() {
|
||||
var path = new Path.Rectangle([50, 50], [100, 100]);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('Symbol & Placed Symbol');
|
||||
QUnit.module('Symbol & Placed Symbol');
|
||||
|
||||
test('placedSymbol bounds', function() {
|
||||
var path = new Path.Circle([50, 50], 50);
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('Point');
|
||||
QUnit.module('Point');
|
||||
|
||||
test('new Point(10, 20)', function() {
|
||||
var point = new Point(10, 20);
|
||||
equals(point.x, 10, 'point.x');
|
||||
|
@ -44,8 +45,6 @@ test('new Point({ angle: 45, length: 20})', function() {
|
|||
equals(point, new Point(15.32089, 12.85575));
|
||||
});
|
||||
|
||||
module('Point vector operations');
|
||||
|
||||
test('normalize(length)', function() {
|
||||
var point = new Point(0, 10).normalize(20);
|
||||
equals(point, new Point(0, 20));
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('Project');
|
||||
QUnit.module('Project');
|
||||
|
||||
test('activate()', function() {
|
||||
var project = new Project();
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('Raster');
|
||||
QUnit.module('Raster');
|
||||
|
||||
test('Create a raster without a source and check its size', function() {
|
||||
var raster = new Raster();
|
||||
|
@ -23,23 +23,34 @@ test('Create a raster without a source and set its size', function() {
|
|||
equals(raster.size, new Size(640, 480), true);
|
||||
});
|
||||
|
||||
asyncTest('Create a raster from a url', function(callback) {
|
||||
test('Create a raster from a url', function(assert) {
|
||||
var done = assert.async();
|
||||
var raster = new Raster('assets/paper-js.gif');
|
||||
raster.onLoad = function() {
|
||||
equals(raster.size, new Size(146, 146), true);
|
||||
callback();
|
||||
done();
|
||||
};
|
||||
raster.onError = function(event) {
|
||||
pushFailure(event.event);
|
||||
done();
|
||||
};
|
||||
});
|
||||
|
||||
asyncTest('Create a raster from a data url', function(callback) {
|
||||
test('Create a raster from a data url', function(assert) {
|
||||
var done = assert.async();
|
||||
var raster = new Raster('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABlJREFUeNpi+s/AwPCfgYmR4f9/hv8AAQYAHiAFAS8Lwy8AAAAASUVORK5CYII=');
|
||||
raster.onLoad = function() {
|
||||
equals(raster.size, new Size(2, 2), true);
|
||||
callback();
|
||||
done();
|
||||
};
|
||||
raster.onError = function(event) {
|
||||
pushFailure(event.event);
|
||||
done();
|
||||
};
|
||||
});
|
||||
|
||||
asyncTest('Create a raster from a dom image', function(callback) {
|
||||
test('Create a raster from a dom image', function(assert) {
|
||||
var done = assert.async();
|
||||
var img = document.createElement('img');
|
||||
img.src = 'assets/paper-js.gif';
|
||||
document.body.appendChild(img);
|
||||
|
@ -48,19 +59,19 @@ asyncTest('Create a raster from a dom image', function(callback) {
|
|||
var raster = new Raster(img);
|
||||
equals(raster.size, new Size(146, 146), true);
|
||||
document.body.removeChild(img);
|
||||
callback();
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test('Create a raster from a canvas', function(callback) {
|
||||
var canvas = CanvasProvider.getCanvas(30, 20);
|
||||
test('Create a raster from a canvas', function() {
|
||||
var canvas = paper.createCanvas(30, 20);
|
||||
var raster = new Raster(canvas);
|
||||
equals(raster.size, new Size(30, 20), true);
|
||||
CanvasProvider.release(canvas);
|
||||
});
|
||||
|
||||
asyncTest('Create a raster from a dom id', function(callback) {
|
||||
test('Create a raster from a dom id', function(assert) {
|
||||
var done = assert.async();
|
||||
var img = document.createElement('img');
|
||||
img.src = 'assets/paper-js.gif';
|
||||
img.id = 'testimage';
|
||||
|
@ -70,12 +81,13 @@ asyncTest('Create a raster from a dom id', function(callback) {
|
|||
var raster = new Raster('testimage');
|
||||
equals(raster.size, new Size(146, 146), true);
|
||||
document.body.removeChild(img);
|
||||
callback();
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('Raster#getPixel / setPixel', function(callback) {
|
||||
test('Raster#getPixel / setPixel', function(assert) {
|
||||
var done = assert.async();
|
||||
var raster = new Raster('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABlJREFUeNpi+s/AwPCfgYmR4f9/hv8AAQYAHiAFAS8Lwy8AAAAASUVORK5CYII=');
|
||||
raster.onLoad = function() {
|
||||
equals(raster.getPixel(0, 0), new Color(1, 0, 0, 1));
|
||||
|
@ -86,12 +98,17 @@ asyncTest('Raster#getPixel / setPixel', function(callback) {
|
|||
// Alpha
|
||||
var color = new Color(1, 1, 0, 0.50196);
|
||||
raster.setPixel([0, 0], color);
|
||||
equals(raster.getPixel([0, 0]), color, 'alpha');
|
||||
callback();
|
||||
equals(raster.getPixel([0, 0]), color, 'alpha', { tolerance: 1e-2 });
|
||||
done();
|
||||
};
|
||||
raster.onError = function(event) {
|
||||
pushFailure(event.event);
|
||||
done();
|
||||
};
|
||||
});
|
||||
|
||||
asyncTest('Raster#getSubCanvas', function(callback) {
|
||||
test('Raster#getSubCanvas', function(assert) {
|
||||
var done = assert.async();
|
||||
var raster = new Raster('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABlJREFUeNpi+s/AwPCfgYmR4f9/hv8AAQYAHiAFAS8Lwy8AAAAASUVORK5CYII=');
|
||||
raster.onLoad = function() {
|
||||
var canvas = raster.getSubCanvas(new Rectangle({
|
||||
|
@ -114,7 +131,11 @@ asyncTest('Raster#getSubCanvas', function(callback) {
|
|||
equals(function() {
|
||||
return Base.equals(Array.prototype.slice.call(ctx.getImageData(0, 0, 1, 2).data), expected);
|
||||
}, true);
|
||||
callback();
|
||||
done();
|
||||
};
|
||||
raster.onError = function(event) {
|
||||
pushFailure(event.event);
|
||||
done();
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -132,7 +153,7 @@ test('Raster#getAverageColor(path)', function() {
|
|||
var raster = paper.project.activeLayer.rasterize(72);
|
||||
circle.scale(0.8);
|
||||
equals(raster.getAverageColor(circle), circle.fillColor, null,
|
||||
{ tolerance: 10e-4 });
|
||||
{ tolerance: 1e-3 });
|
||||
});
|
||||
|
||||
test('Raster#getAverageColor(path) with compound path', function() {
|
||||
|
@ -155,5 +176,5 @@ test('Raster#getAverageColor(path) with compound path', function() {
|
|||
path.scale(0.8);
|
||||
path2.scale(1.2);
|
||||
equals(raster.getAverageColor(compoundPath), new Color(1, 0, 0), null,
|
||||
{ tolerance: 10e-4 });
|
||||
{ tolerance: 1e-3 });
|
||||
});
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('Rectangle');
|
||||
QUnit.module('Rectangle');
|
||||
|
||||
test('new Rectangle(new Point(10, 20), new Size(30, 40));', function() {
|
||||
var rect = new Rectangle(new Point(10, 20), new Size(30, 40));
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('SVGExport');
|
||||
QUnit.module('SVGExport');
|
||||
|
||||
test('Export SVG line', function() {
|
||||
var attrs = {
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('SVGImport');
|
||||
QUnit.module('SVGImport');
|
||||
|
||||
test('Import SVG line', function() {
|
||||
var attrs = {
|
||||
|
@ -59,7 +59,7 @@ test('Import SVG ellipse', function() {
|
|||
cy: 80,
|
||||
rx: 100,
|
||||
ry: 50
|
||||
}
|
||||
};
|
||||
var imported = paper.project.importSVG(createSVG('ellipse', attrs),
|
||||
{ expandShapes: true });
|
||||
var path = new Path.Ellipse({
|
||||
|
@ -74,7 +74,7 @@ test('Import SVG circle', function() {
|
|||
cx: 100,
|
||||
cy: 80,
|
||||
r: 50
|
||||
}
|
||||
};
|
||||
var imported = paper.project.importSVG(createSVG('circle', attrs),
|
||||
{ expandShapes: true });
|
||||
var path = new Path.Circle({
|
||||
|
@ -115,7 +115,8 @@ test('Import SVG polyline', function() {
|
|||
});
|
||||
|
||||
test('Import complex CompoundPath and clone', function() {
|
||||
var svg = createSVG('<path id="path" fill="red" d="M4,14h20v-2H4V14z M15,26h7v-2h-7V26z M15,22h9v-2h-9V22z M15,18h9v-2h-9V18z M4,26h9V16H4V26z M28,10V6H0v22c0,0,0,4,4,4 h25c0,0,3-0.062,3-4V10H28z M4,30c-2,0-2-2-2-2V8h24v20c0,0.921,0.284,1.558,0.676,2H4z"/>;');
|
||||
var item = paper.project.importSVG(svg.getElementById('path'));
|
||||
var svg = createSVG('<path fill="red" d="M4,14h20v-2H4V14z M15,26h7v-2h-7V26z M15,22h9v-2h-9V22z M15,18h9v-2h-9V18z M4,26h9V16H4V26z M28,10V6H0v22c0,0,0,4,4,4 h25c0,0,3-0.062,3-4V10H28z M4,30c-2,0-2-2-2-2V8h24v20c0,0.921,0.284,1.558,0.676,2H4z"/>;');
|
||||
var item = paper.project.importSVG(svg.firstChild);
|
||||
equals(item.clone(), item, null, { cloned: true });
|
||||
return;
|
||||
});
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('Segment');
|
||||
QUnit.module('Segment');
|
||||
|
||||
test('new Segment(point)', function() {
|
||||
var segment = new Segment(new Point(10, 10));
|
||||
equals(segment.toString(), '{ point: { x: 10, y: 10 } }');
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('Shape');
|
||||
QUnit.module('Shape');
|
||||
|
||||
test('shape.toPath().toShape()', function() {
|
||||
var shapes = {
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('Size');
|
||||
QUnit.module('Size');
|
||||
|
||||
test('new Size(10, 20)', function() {
|
||||
var size = new Size(10, 20);
|
||||
equals(size.toString(), '{ width: 10, height: 20 }');
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('Style');
|
||||
QUnit.module('Style');
|
||||
|
||||
test('style defaults', function() {
|
||||
var path = new Path();
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
module('TextItem');
|
||||
QUnit.module('TextItem');
|
||||
|
||||
test('PointText', function() {
|
||||
var text = new PointText({
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue