From 567f286774427a3fe7d96f962c06c2ddd69febfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Lehni?= Date: Thu, 28 Jan 2016 14:39:40 +0100 Subject: [PATCH] Tests: Switch to our own gulp-qunits module. Since it handles PhantomJS as well as Node.js execution, and formats errors identically and quickly. --- LICENSE.txt | 2 ++ gulp/tasks/test.js | 49 +++++++++++++------------------ gulp/utils/error.js | 6 ++-- package.json | 5 ++-- test/helpers.js | 68 ++------------------------------------------ test/tests/Raster.js | 16 +++-------- 6 files changed, 35 insertions(+), 111 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index 4a8b3d3e..28c2e83f 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -2,6 +2,8 @@ Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey http://scratchdisk.com/ & http://jonathanpuckey.com/ All rights reserved. +The MIT License (MIT) + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights diff --git a/gulp/tasks/test.js b/gulp/tasks/test.js index 5f430e15..d1966200 100644 --- a/gulp/tasks/test.js +++ b/gulp/tasks/test.js @@ -11,41 +11,32 @@ */ var gulp = require('gulp'), - gulp_qunit = require('gulp-qunit'), - node_qunit = require('qunit'), + qunits = require('gulp-qunits'), gutil = require('gulp-util'); gulp.task('test', ['test:browser', 'test:node']); gulp.task('test:browser', ['minify:acorn'], function() { - return gulp.src('test/index.html') - .pipe(gulp_qunit({ timeout: 20, noGlobals: true })); + return gulp.src('index.html', { cwd: 'test' }) + .pipe(qunits({ + noGlobals: true, + timeout: 20 + })); }); gulp.task('test:node', ['minify:acorn'], function(callback) { - // Use the correct working directory for tests: - process.chdir('./test'); - // Deactivate all logging since we're doing our own directly to gutil.log() - // from helpers.js - node_qunit.setup({ log: {} }); - 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) { - err = err || stats.failed > 0 && 'QUnit assertions failed'; - callback(err && new gutil.PluginError('node-qunit', err)); - }); + return gulp.src('load.js', { cwd: 'test' }) + .pipe(qunits({ + require: [ + // To dynamically load the tests files from the sources, we need + // to require Prepro.js first. + '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' } + ], + noGlobals: true, + timeout: 20 + })); }); diff --git a/gulp/utils/error.js b/gulp/utils/error.js index c9f0f8a4..cfd92c58 100644 --- a/gulp/utils/error.js +++ b/gulp/utils/error.js @@ -18,8 +18,10 @@ gulp.on('error', function(err) { var msg = err.toString(); if (msg === '[object Object]') msg = err; - gutil.log(ERROR, msg); if (err.stack) - gutil.log(ERROR, err.stack); + msg += err.stack; + msg.split(/\r\n|\n|\r/mg).forEach(function(line) { + gutil.log(ERROR, line); + }); this.emit('end'); }); diff --git a/package.json b/package.json index 5139791e..de12654b 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "README.md" ], "engines": { - "node": ">=0.8.0 <6.0.0" + "node": ">=0.10.0 <6.0.0" }, "dependencies": { "jsdom": "git://github.com/lehni/jsdom.git#3d55789d0f4d55392721b1e22890837fde472375", @@ -43,7 +43,7 @@ "gulp-cached": "^1.1.0", "gulp-jshint": "^2.0.0", "gulp-prepro": "^2.2.0", - "gulp-qunit": "git://github.com/lehni/gulp-qunit.git#459c5603ceac460327a40dc89df6f19c786dc61b", + "gulp-qunits": "^1.5.1", "gulp-rename": "^1.2.2", "gulp-rimraf": "^0.2.0", "gulp-shell": "^0.5.1", @@ -57,7 +57,6 @@ "jshint-summary": "^0.4.0", "merge-stream": "^1.0.0", "prepro": "^2.2.0", - "qunit": "^0.7.7", "qunitjs": "^1.20.0", "require-dir": "^0.3.0", "resemblejs": "^2.1.0", diff --git a/test/helpers.js b/test/helpers.js index 9ae47ae8..396f8f92 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -17,50 +17,6 @@ if (isNode) { root = global; // Resemble.js needs the Image constructor global. global.Image = paper.window.Image; - // Handle logging to gulp directly from here, imitating the way gulp-qunit - // logs and formats results and errors: - var gutil = require('gulp-util'), - colors = gutil.colors, - done = false; - QUnit.log(function(details) { - if (!details.result) { - var lines = [ - colors.red('Test failed') + ': ' + details.module + ': ' - + details.name - ]; - var line = 'Failed assertion: ' + (details.message || ''); - if (details.expected !== undefined) { - line += ', expected: ' + details.expected + ', but was: ' - + details.actual; - } - lines.push(line); - if (details.source) { - lines = lines.concat(details.source.split(/\r\n|\n|\r/mg)); - } - lines.forEach(function(line) { - gutil.log(line); - }); - } else if (false) { - gutil.log(colors.green('Test succeeded') + ': ' + details.module - + ': ' + details.name +': ' + (details.message || '')); - } - }); - QUnit.done(function(details) { - if (done) - return; - var color = colors[details.failed > 0 ? 'red' : 'green']; - gutil.log('Took ' + details.runtime + 'ms to run ' - + colors.blue(details.total) + ' tests. ' + color(details.passed - + ' passed, ' + details.failed + ' failed.')); - if (details.failed > 0) { - gutil.log('node-qunit: ' + gutil.colors.red('✖') - + ' QUnit assertions failed'); - } else { - gutil.log('node-qunit: ' + gutil.colors.green('✔') - + ' QUnit assertions all passed'); - } - done = true; - }); } else { root = window; // This is only required when running in the browser: @@ -93,37 +49,19 @@ QUnit.done(function(details) { console.error = errorHandler; }); -var currentProject, - // In case we're stuck with an old QUnit, use a fake assert object with just - // the functions that we need: - // For now, a async() function returning a done() function: - fakeAssert = { - async: function() { - return function() { - QUnit.start(); - }; - } - }; +var currentProject; // 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 test = function(testName, expected) { - // 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(); - var emulate = !QUnit.async && 'assert' === - // Get the parameter list from the passed function to see if we're - // expecting the assert object to do async... - expected.toString().match(/^\s*function[^\(]*\(([^\)]*)/)[1]; - return QUnit[emulate ? 'asyncTest' : 'test'](testName, function(assert) { + return QUnit.test(testName, function(assert) { // Since tests can be asynchronous, remove the old project before // running the next test. if (currentProject) currentProject.remove(); currentProject = new Project(); - expected(emulate ? fakeAssert : assert); + expected(assert); }); }; diff --git a/test/tests/Raster.js b/test/tests/Raster.js index 05c23d0b..7e8d2e60 100644 --- a/test/tests/Raster.js +++ b/test/tests/Raster.js @@ -23,7 +23,7 @@ test('Create a raster without a source and set its size', function() { equals(raster.size, new Size(640, 480), true); }); -test('Create a raster from a url', function(assert) { +test('Create a raster from a URL', function(assert) { var done = assert.async(); var raster = new Raster('assets/paper-js.gif'); raster.onLoad = function() { @@ -31,12 +31,12 @@ test('Create a raster from a url', function(assert) { done(); }; raster.onError = function(event) { - pushFailure(event.event); + pushFailure('Loading from a valid local URL should not give an error.'); done(); }; }); -test('Create a raster from a data url', function(assert) { +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() { @@ -44,7 +44,7 @@ test('Create a raster from a data url', function(assert) { done(); }; raster.onError = function(event) { - pushFailure(event.event); + pushFailure('Loading from a valid data URL should not give an error.'); done(); }; }); @@ -101,10 +101,6 @@ test('Raster#getPixel / setPixel', function(assert) { equals(raster.getPixel([0, 0]), color, 'alpha', { tolerance: 1e-2 }); done(); }; - raster.onError = function(event) { - pushFailure(event.event); - done(); - }; }); test('Raster#getSubCanvas', function(assert) { @@ -133,10 +129,6 @@ test('Raster#getSubCanvas', function(assert) { }, true); done(); }; - raster.onError = function(event) { - pushFailure(event.event); - done(); - }; }); test('Raster#getAverageColor(path)', function() {