From 2f7052a414f2f5cedff588a59cf81caaa4754513 Mon Sep 17 00:00:00 2001 From: Dave Pagurek Date: Sat, 7 Sep 2024 12:07:22 -0400 Subject: [PATCH 1/4] Fix some more async issues --- src/io/files.js | 45 +++++++++++++++------------------ src/webgl/loading.js | 14 +++++----- test/unit/visual/cases/webgl.js | 8 +++--- vitest.workspace.mjs | 6 ++--- 4 files changed, 34 insertions(+), 39 deletions(-) diff --git a/src/io/files.js b/src/io/files.js index 02fb681e32..e6711ea20f 100644 --- a/src/io/files.js +++ b/src/io/files.js @@ -240,7 +240,7 @@ import Renderer from '../core/p5.Renderer'; * * */ -p5.prototype.loadJSON = function (...args) { +p5.prototype.loadJSON = async function (...args) { p5._validateParameters('loadJSON', args); const path = args[0]; let callback; @@ -266,8 +266,7 @@ p5.prototype.loadJSON = function (...args) { } } - const self = this; - this.httpDo( + await new Promise(resolve => this.httpDo( path, 'GET', options, @@ -280,7 +279,7 @@ p5.prototype.loadJSON = function (...args) { callback(resp); } - self._decrementPreload(); + resolve() }, err => { // Error handling @@ -292,7 +291,7 @@ p5.prototype.loadJSON = function (...args) { throw err; } } - ); + )); return ret; }; @@ -431,7 +430,7 @@ p5.prototype.loadJSON = function (...args) { * * */ -p5.prototype.loadStrings = function (...args) { +p5.prototype.loadStrings = async function (...args) { p5._validateParameters('loadStrings', args); const ret = []; @@ -448,8 +447,7 @@ p5.prototype.loadStrings = function (...args) { } } - const self = this; - p5.prototype.httpDo.call( + await new Promise(resolve => p5.prototype.httpDo.call( this, args[0], 'GET', @@ -476,7 +474,7 @@ p5.prototype.loadStrings = function (...args) { callback(ret); } - self._decrementPreload(); + resolve() }, function (err) { // Error handling @@ -488,7 +486,7 @@ p5.prototype.loadStrings = function (...args) { throw err; } } - ); + )); return ret; }; @@ -563,7 +561,7 @@ p5.prototype.loadStrings = function (...args) { * * */ -p5.prototype.loadTable = function (path) { +p5.prototype.loadTable = async function (path) { // p5._validateParameters('loadTable', arguments); let callback; let errorCallback; @@ -604,8 +602,7 @@ p5.prototype.loadTable = function (path) { const t = new p5.Table(); - const self = this; - this.httpDo( + await new Promise(resolve => this.httpDo( path, 'GET', 'table', @@ -737,7 +734,7 @@ p5.prototype.loadTable = function (path) { callback(t); } - self._decrementPreload(); + resolve() }, err => { // Error handling @@ -749,7 +746,7 @@ p5.prototype.loadTable = function (path) { console.error(err); } } - ); + )); return t; }; @@ -929,7 +926,7 @@ function makeObject(row, headers) { * * */ -p5.prototype.loadXML = function (...args) { +p5.prototype.loadXML = async function (...args) { const ret = new p5.XML(); let callback, errorCallback; @@ -944,8 +941,7 @@ p5.prototype.loadXML = function (...args) { } } - const self = this; - this.httpDo( + await new Promise(resolve => this.httpDo( args[0], 'GET', 'xml', @@ -957,7 +953,7 @@ p5.prototype.loadXML = function (...args) { callback(ret); } - self._decrementPreload(); + resolve() }, function (err) { // Error handling @@ -969,7 +965,7 @@ p5.prototype.loadXML = function (...args) { throw err; } } - ); + )); return ret; }; @@ -1000,11 +996,10 @@ p5.prototype.loadXML = function (...args) { * } * */ -p5.prototype.loadBytes = function (file, callback, errorCallback) { +p5.prototype.loadBytes = async function (file, callback, errorCallback) { const ret = {}; - const self = this; - this.httpDo( + await new Promise(resolve => this.httpDo( file, 'GET', 'arrayBuffer', @@ -1015,7 +1010,7 @@ p5.prototype.loadBytes = function (file, callback, errorCallback) { callback(ret); } - self._decrementPreload(); + resolve(); }, err => { // Error handling @@ -1027,7 +1022,7 @@ p5.prototype.loadBytes = function (file, callback, errorCallback) { throw err; } } - ); + )); return ret; }; diff --git a/src/webgl/loading.js b/src/webgl/loading.js index bef14a8e15..0d72e1aa9b 100755 --- a/src/webgl/loading.js +++ b/src/webgl/loading.js @@ -335,7 +335,7 @@ import './p5.Geometry'; * @param {Boolean} [options.flipV] * @return {p5.Geometry} new p5.Geometry object. */ -p5.prototype.loadModel = function (path, options) { +p5.prototype.loadModel = async function (path, options) { p5._validateParameters('loadModel', arguments); let normalize = false; let successCallback; @@ -420,7 +420,7 @@ p5.prototype.loadModel = function (path, options) { } } if (fileType.match(/\.stl$/i)) { - this.httpDo( + await new Promise(resolve => this.httpDo( path, 'GET', 'arrayBuffer', @@ -439,15 +439,15 @@ p5.prototype.loadModel = function (path, options) { model.flipV(); } - self._decrementPreload(); + resolve(); if (typeof successCallback === 'function') { successCallback(model); } }, failureCallback - ); + )); } else if (fileType.match(/\.obj$/i)) { - this.loadStrings( + await new Promise(resolve => this.loadStrings( path, async lines => { try { @@ -474,14 +474,14 @@ p5.prototype.loadModel = function (path, options) { model.flipV(); } - self._decrementPreload(); + resolve(); if (typeof successCallback === 'function') { successCallback(model); } } }, failureCallback - ); + )); } else { p5._friendlyFileLoadError(3, path); if (failureCallback) { diff --git a/test/unit/visual/cases/webgl.js b/test/unit/visual/cases/webgl.js index c2fe4003c1..e5e8a9be7a 100644 --- a/test/unit/visual/cases/webgl.js +++ b/test/unit/visual/cases/webgl.js @@ -87,7 +87,7 @@ visualSuite('WebGL', function() { visualTest('OBJ model with MTL file displays diffuse colors correctly', function(p5, screenshot) { return new Promise(resolve => { p5.createCanvas(50, 50, p5.WEBGL); - p5.loadModel('unit/assets/octa-color.obj', model => { + p5.loadModel('/unit/assets/octa-color.obj', model => { p5.background(255); p5.rotateX(10 * 0.01); p5.rotateY(10 * 0.01); @@ -101,7 +101,7 @@ visualSuite('WebGL', function() { visualTest('Object with no colors takes on fill color', function(p5, screenshot) { return new Promise(resolve => { p5.createCanvas(50, 50, p5.WEBGL); - p5.loadModel('unit/assets/cube.obj', model => { + p5.loadModel('/unit/assets/cube.obj', model => { p5.background(255); p5.fill('blue'); // Setting a fill color p5.rotateX(p5.frameCount * 0.01); @@ -117,8 +117,8 @@ visualSuite('WebGL', function() { 'Object with different texture coordinates per use of vertex keeps the coordinates intact', async function(p5, screenshot) { p5.createCanvas(50, 50, p5.WEBGL); - const tex = await new Promise(resolve => p5.loadImage('unit/assets/cat.jpg', resolve)); - const cube = await new Promise(resolve => p5.loadModel('unit/assets/cube-textures.obj', resolve)); + const tex = await new Promise(resolve => p5.loadImage('/unit/assets/cat.jpg', resolve)); + const cube = await new Promise(resolve => p5.loadModel('/unit/assets/cube-textures.obj', resolve)); cube.normalize(); p5.background(255); p5.texture(tex); diff --git a/vitest.workspace.mjs b/vitest.workspace.mjs index 991ff2ce94..2a42a04a31 100644 --- a/vitest.workspace.mjs +++ b/vitest.workspace.mjs @@ -10,7 +10,7 @@ const plugins = [ ]; export default defineWorkspace([ - { + /*{ plugins, publicDir: './test', test: { @@ -21,7 +21,7 @@ export default defineWorkspace([ ], environment: 'node' } - }, + },*/ { plugins, publicDir: './test', @@ -34,7 +34,7 @@ export default defineWorkspace([ exclude: [ './test/unit/spec.js', './test/unit/assets/**/*', - './test/unit/visual/**/*' + './test/unit/visual/visualTest.js', ], testTimeout: 1000, globals: true, From 190d5169412f74754e973068d3ce7990c04f18ee Mon Sep 17 00:00:00 2001 From: Dave Pagurek Date: Sat, 7 Sep 2024 13:49:13 -0400 Subject: [PATCH 2/4] Update tests, use a diff library --- package-lock.json | 458 ++++++++++++++++++ package.json | 1 + src/image/loading_displaying.js | 6 - src/typography/loading_displaying.js | 10 +- src/webgl/loading.js | 1 + test/unit/visual/cases/typography.js | 2 +- .../With the default font/000.png | Bin 848 -> 1068 bytes .../With the default monospace font/000.png | Bin 694 -> 830 bytes .../000.png | Bin 3260 -> 542 bytes .../000.png | Bin 7309 -> 7356 bytes .../000.png | Bin 302 -> 304 bytes .../2D objects maintain correct size/000.png | Bin 265 -> 267 bytes .../000.png | Bin 219 -> 211 bytes .../001.png | Bin 209 -> 205 bytes .../000.png | Bin 1205 -> 1118 bytes .../000.png | Bin 415 -> 347 bytes .../WebGL/filter/On a framebuffer/000.png | Bin 415 -> 347 bytes test/unit/visual/visualTest.js | 105 ++-- 18 files changed, 514 insertions(+), 69 deletions(-) diff --git a/package-lock.json b/package-lock.json index eedd2a2fd9..adcd72577d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,6 +33,7 @@ "i18next": "^19.0.2", "i18next-browser-languagedetector": "^4.0.1", "lint-staged": "^15.1.0", + "resemblejs": "^5.0.0", "rollup": "^4.9.6", "rollup-plugin-string": "^3.0.0", "rollup-plugin-visualizer": "^5.12.0", @@ -1163,6 +1164,67 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", + "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", + "dev": true, + "optional": true, + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "optional": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "optional": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "optional": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@mswjs/interceptors": { "version": "0.29.1", "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.29.1.tgz", @@ -2530,6 +2592,13 @@ "node": ">=16.5.0" } }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true, + "optional": true + }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -2670,6 +2739,13 @@ "node": ">= 8" } }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "dev": true, + "optional": true + }, "node_modules/archiver": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz", @@ -2762,6 +2838,36 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "deprecated": "This package is no longer supported.", + "dev": true, + "optional": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/are-we-there-yet/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "optional": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -3097,6 +3203,22 @@ } ] }, + "node_modules/canvas": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/canvas/-/canvas-2.11.2.tgz", + "integrity": "sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.0", + "nan": "^2.17.0", + "simple-get": "^3.0.3" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/ccount": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", @@ -3262,6 +3384,16 @@ "fsevents": "~2.3.2" } }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=10" + } + }, "node_modules/ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", @@ -3410,6 +3542,16 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "dev": true, + "optional": true, + "bin": { + "color-support": "bin.js" + } + }, "node_modules/colorette": { "version": "2.0.20", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", @@ -3495,6 +3637,13 @@ "qs": "^6.3.1" } }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "dev": true, + "optional": true + }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -3675,6 +3824,19 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "dev": true, + "optional": true, + "dependencies": { + "mimic-response": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/deep-eql": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", @@ -3748,6 +3910,13 @@ "node": ">= 14" } }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "dev": true, + "optional": true + }, "node_modules/dequal": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", @@ -3757,6 +3926,16 @@ "node": ">=6" } }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "dev": true, + "optional": true, + "engines": { + "node": ">=8" + } + }, "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", @@ -4883,6 +5062,39 @@ "node": ">= 10.0.0" } }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "optional": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "optional": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs-minipass/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "optional": true + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -4912,6 +5124,35 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "deprecated": "This package is no longer supported.", + "dev": true, + "optional": true, + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gauge/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "optional": true + }, "node_modules/geckodriver": { "version": "4.4.4", "resolved": "https://registry.npmjs.org/geckodriver/-/geckodriver-4.4.4.tgz", @@ -5256,6 +5497,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "dev": true, + "optional": true + }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -6626,6 +6874,22 @@ "@jridgewell/sourcemap-codec": "^1.5.0" } }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "optional": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", @@ -7549,6 +7813,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "dev": true, + "optional": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -7570,6 +7847,53 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "optional": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "optional": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "optional": true + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "optional": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/mri": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", @@ -7725,6 +8049,13 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "dev": true }, + "node_modules/nan": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.20.0.tgz", + "integrity": "sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==", + "dev": true, + "optional": true + }, "node_modules/nanoid": { "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", @@ -7803,6 +8134,22 @@ "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", "dev": true }, + "node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dev": true, + "optional": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/normalize-package-data": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", @@ -7866,6 +8213,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "deprecated": "This package is no longer supported.", + "dev": true, + "optional": true, + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, "node_modules/nth-check": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", @@ -7878,6 +8239,16 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-inspect": { "version": "1.13.2", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", @@ -9009,6 +9380,15 @@ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", "dev": true }, + "node_modules/resemblejs": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resemblejs/-/resemblejs-5.0.0.tgz", + "integrity": "sha512-+B0eP9k9VDP/YhBbH+ZdYmHiotdtuc6blVI+h8wwkY2cOow+uiIpSmgkBBBtrEAL0D31/gR/AJPwDeX5TcwmIA==", + "dev": true, + "optionalDependencies": { + "canvas": "2.11.2" + } + }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -9541,6 +9921,39 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "optional": true + }, + "node_modules/simple-get": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", + "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", + "dev": true, + "optional": true, + "dependencies": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, "node_modules/sirv": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", @@ -9950,6 +10363,24 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dev": true, + "optional": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/tar-fs": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.6.tgz", @@ -9975,6 +10406,23 @@ "streamx": "^2.15.0" } }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "optional": true + }, "node_modules/terser": { "version": "5.31.6", "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz", @@ -11072,6 +11520,16 @@ "node": ">=8" } }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dev": true, + "optional": true, + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", diff --git a/package.json b/package.json index 9f7bef5acd..4ca4afb76d 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "i18next": "^19.0.2", "i18next-browser-languagedetector": "^4.0.1", "lint-staged": "^15.1.0", + "resemblejs": "^5.0.0", "rollup": "^4.9.6", "rollup-plugin-string": "^3.0.0", "rollup-plugin-visualizer": "^5.12.0", diff --git a/src/image/loading_displaying.js b/src/image/loading_displaying.js index 2dde427048..90184ab915 100644 --- a/src/image/loading_displaying.js +++ b/src/image/loading_displaying.js @@ -140,7 +140,6 @@ p5.prototype.loadImage = async function( successCallback, failureCallback, (pImg => { - self._decrementPreload(); resolve(pImg); }).bind(self) ); @@ -148,7 +147,6 @@ p5.prototype.loadImage = async function( console.error(e.toString(), e.stack); if (typeof failureCallback === 'function') { failureCallback(e); - self._decrementPreload(); } else { console.error(e); } @@ -160,7 +158,6 @@ p5.prototype.loadImage = async function( e => { if (typeof failureCallback === 'function') { failureCallback(e); - self._decrementPreload(); } else { console.error(e); } @@ -182,14 +179,12 @@ p5.prototype.loadImage = async function( successCallback(pImg); } resolve(); - self._decrementPreload(); }; img.onerror = e => { p5._friendlyFileLoadError(0, img.src); if (typeof failureCallback === 'function') { failureCallback(e); - self._decrementPreload(); } else { console.error(e); } @@ -215,7 +210,6 @@ p5.prototype.loadImage = async function( p5._friendlyFileLoadError(0, path); if (typeof failureCallback === 'function') { failureCallback(e); - self._decrementPreload(); } else { console.error(e); } diff --git a/src/typography/loading_displaying.js b/src/typography/loading_displaying.js index f625db3d99..14410e66b9 100644 --- a/src/typography/loading_displaying.js +++ b/src/typography/loading_displaying.js @@ -126,12 +126,11 @@ import '../core/friendly_errors/fes_core'; * * */ -p5.prototype.loadFont = function(path, onSuccess, onError) { +p5.prototype.loadFont = async function(path, onSuccess, onError) { p5._validateParameters('loadFont', arguments); const p5Font = new p5.Font(this); - const self = this; - opentype.load(path, (err, font) => { + await new Promise(resolve => opentype.load(path, (err, font) => { if (err) { p5._friendlyFileLoadError(4, path); if (typeof onError !== 'undefined') { @@ -146,8 +145,7 @@ p5.prototype.loadFont = function(path, onSuccess, onError) { if (typeof onSuccess !== 'undefined') { onSuccess(p5Font); } - - self._decrementPreload(); + resolve(); // check that we have an acceptable font type const validFontTypes = ['ttf', 'otf', 'woff', 'woff2']; @@ -174,7 +172,7 @@ p5.prototype.loadFont = function(path, onSuccess, onError) { ); document.head.appendChild(newStyle); } - }); + })); return p5Font; }; diff --git a/src/webgl/loading.js b/src/webgl/loading.js index 0d72e1aa9b..414c62315b 100755 --- a/src/webgl/loading.js +++ b/src/webgl/loading.js @@ -665,6 +665,7 @@ function parseObj(model, lines, materials = {}) { model.vertexColors.push(materialDiffuseColor[0]); model.vertexColors.push(materialDiffuseColor[1]); model.vertexColors.push(materialDiffuseColor[2]); + model.vertexColors.push(1); } } else { hasColorlessVertices = true; diff --git a/test/unit/visual/cases/typography.js b/test/unit/visual/cases/typography.js index 6066acfe83..98121ec94b 100644 --- a/test/unit/visual/cases/typography.js +++ b/test/unit/visual/cases/typography.js @@ -6,7 +6,7 @@ visualSuite('Typography', function() { p5.createCanvas(50, 50); p5.textSize(20); p5.textAlign(p5.LEFT, p5.TOP); - p5.text('test', 0, 0); + p5.text('broken', 0, 0); screenshot(); }); diff --git a/test/unit/visual/screenshots/Typography/textFont() with default fonts/With the default font/000.png b/test/unit/visual/screenshots/Typography/textFont() with default fonts/With the default font/000.png index 2df2de71259f776212ffee2a1de6b7a60ee09a40..a6f522d460ae4dfa93993f15ecc2e27e83169695 100644 GIT binary patch delta 1034 zcmV+l1oivS2CN8>F@NSsL_t(&L+zG(=+9Re$6sqnqD@DuQ|rssMfZ!D1iu77FV>g>M)dXVU z`+N$JnlcDvRivG}-~yl@P!Bi*ECMbC7oQJw17-n(f$6|5;8*kM;&Of-&=+U{{0Z!F z^{~>_!>b@pB_NG}B|sD41hCfpYXeh(A$ImP;CEmR@K`=^YTXAu2L83&_2&)%j@!p6 z;7i~rFv!*x8h-)9fJ3&X7!QCB_I(=Y54^DN7>F)^80h1OJP8c9+Gzmn4bJj+RG7=a zP~c`IAfrqP1=!@A#{pN32{Gz{DA00XJMa(i47hGY%rRzP10C&RZA_`f6@b(=VtN6` zfRPqYuF3!rbpaRy+;HbM1Gbt%2jw3FQ2_nnt)-Lnj(>gh2F?XQq=-_>o1|AN2z2MD zhU6!<#pWjwkoLenpojT<9e_}(Ju-hWuNdB%x^eN)K3c{=>I2WCOZ??(psOjfI{-2X z*cSM%0DiDqm=VQLtq6pyvE{W-Eve|!uN81N*xS>{(~^M1^G4^Z6b6Jql+$7$whh1( zyX2|>h<_No7&srXJe~mTtPsb~D$NcRs|OOgu5&=91q&sCtaq%c8OXk}n$m9-{BPzz@jZaf z$3WuCePlrt!~a(mkY5}Lvw{7t<&KUHRRa+Tp?~TghzGXJo=8fy&y7%}v{GBvI;dA4 z{yS^cYhxhl7|KQ8@4p2$TANdFb)l+&47AP@AF4N;K#1L+T@B8)TU2VlT2s!86m>q$ zvcIi{^bS-Vdh@Mb~?^OXr z%YS2Sxazmk`MfLka5kxibU!I2HDr_3ibEi`Ew_E2_sA7oli8alswV#z7BtKvrHLlE zf`_KVm0n64Z(fnOEW;h~aK^`JJar%B2aTWz$vd*0}2 zp%@~`cdZCxwLdi)q{OGz%Kvcb_n+VWA%CCk)xL3xV*!%FTFyO1k(}(N#4d`Yu$FUA zQ6wk3DY1(pDXit(QxwU`Zc6N;ND6B?_Y_5PvYQgSD3Zcj&OJquob0B=E{deEmUB;0 zBqzHmv5O)ptmWKO6v@eMO6;OY3Trv{6h(5fn-cpi5I)}#(~2C|00000NkvXXt^-0~ Eg70?lG5`Po delta 812 zcmV+{1JnGh2+#(QF@Fk4L_t(&L+#f|s2x=h2H-E^6hTA~6N7>nH@b0141z{6IDoTJ z5k#{|2*e3-SOmmG-DKeejtc{d3qizS)CdZ?aGpVNqoNq1hzmzhk!a+Hy3jOv?_$5# z_etopx|~y0r~d!1Q`L8#J!H*m;W!vSO#s{e*bBeU)?FhYM}Of_yoyb;6?}>~XW%hh zjkjj&t`U$MaUa%C0LWHcfKvt_yOA-9T#Ku4GTz7AcmQ9P{n1#1AaADpr>Y zXXD6v6R}ANJy)R8&VOn7PF#`CaO{{uP5mEHHY@NH4u5U=Jc;Y-!RKh=K=Rnr>u+t8 zMH|;&c(1X!HS zJ&KJ$j(@4(@yDa~dpVvi^CXi`l{fK1F`uLR@i(rh)|&Guk-ZGfwCb$Si-3i=xZ3xf z*ih#Ieof7q4B&wJd3>tVTa182_H?Fm$~-MK-(LF`sEw^KsrefkD&;urXWm@du#KAW zO{`tDAJDHA8QIF5`CztyjN%+p7yj6|IA{6fPJeeg2;0XnI3LI0dwe%Vf*~*iH}hu3 zYUGag|B;yzGiUw-kU67%np*w8<D)}zy)NRQ-p3Oy*&iMAe{21R-#w^Qgr zkxsPr=rkzOBe|VI4~lf6tw*OpksitI6napk6Ky>@4T|(gZl}bmM{+xb q9wij%L|czegCaeW+bQ%OqsYIIgP}9nQB33j0000#(#fg2n&f!8Ip|*zGHqmGOq4Q*A`}U6o_cScu6sZC`_6a%>fbq=?|$c=_r1^i zJnwK?_eD&we)oA3W#Ba{o^Qvw<(bHmj!@PL+jb z(;s;4*~_26N`JK@z!N~s&$FOccxUUz(`b!Mcg$Y24-W>Oc_0o0i+}^ba&P~)Jx>F! zmWb$n}z3&*M`a zeYZ{3(k^>efnNfy0_T8VH3Ewoh`P)G$M{j;Q3(j8(tl3ir@hyZRm!QJG^etqnpp~5 z`yZ)w+2#3EU;%Kvjx^EHcEB)T4zSV)x#1L=)a*bqwnqbMgGFn<6|z!gU7dmW$A?%g zX|L=iQ3Vf0#jd=a>~ecOu%iUzSZ_|~`F8HyIG0vk0V$`|9+(B3_i9G_69B29rS|W) z`^;q(Jb#6OtO0hL7j+(89+mG3?3D+2kNfay`+ov>Xt}Qx(QwtU++goj^xtgeoU(SU z^qOh6h)pi#ww91q2~UwC9f8HbDr=XSe_cb=LbD}X74KdHRRtMk=pn;iR znm0<%vTIExJVk+&5L0to`K`gIDgWGETRxSXmVYvXfL?Y+gYg6NB2oD_*bYLLsMNDzGyjFTb}NDXq?W)%4Y YF%xy4Ghf8fIsgCw07*qoM6N<$f*#3iumAu6 literal 694 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nC-#^NA%Cx&(BWL`2bFco;ZIEG|6 zzrE(Y!Z%Rn_{Z~KJu3MPCNiqYsWPi*c6mrnXfbk_c${M*W2=bqlz^Z~jBIMB4kRm_ zS{$%wPq30^OF+<<^-KMJ-@ARcJiXXzt?kX{Z}wiR|NC$M`})7v^DZleM|VG2m?|9E zGJVHol_g%UHH9pjc3WIi>6~)ya#81+Loq&w*=@80ZuZZX4T$QxI-|#bN2BeI`8JBZy>pOf7M65Z=9izjsvuk^6`f)?{+XdXUf==a%S-)cv{}jpi zb-L||sAl{2kR{Bl=l!;MtCntMS#HSI&)sC6pzrpm_VDf%-{(aHOYG-dEcm%A{B89U zoqdVk?A_mw*{;zJnAz)nqw{vfEUPE}U!3mzuT zo;?2V@q|aOe6z2+Dl z9J(f=eawBibywnya0RjVr(b1G_o$z9FGWy!YfZU#zdJ)MqB2n1>M{=OD#=_ eI-Ju2KY5-1_8L!nW0nU@hzy>telF{r5}E+EgfSfe diff --git a/test/unit/visual/screenshots/WebGL/3DModel/OBJ model with MTL file displays diffuse colors correctly/000.png b/test/unit/visual/screenshots/WebGL/3DModel/OBJ model with MTL file displays diffuse colors correctly/000.png index 0426415f3168304051ad1720fc515d85dee3ff5a..d3f818229342835946d4efaed192d6f9c3ff0b80 100644 GIT binary patch delta 504 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 diff --git a/test/unit/visual/screenshots/WebGL/3DModel/Object with no colors takes on fill color/000.png b/test/unit/visual/screenshots/WebGL/3DModel/Object with no colors takes on fill color/000.png index 5d7801aa044825f2bfed429715e51d64085d3320..28dd2a7fd5ecb0ad460796a8e229864fddf41dd5 100644 GIT binary patch delta 86 zcmV-c0IC130L_t(&L)Fqp4#Pkc0#N4UaZWz5B}-{8Q+@$9te>C&sKBz; s1Ij7DvO}~n1*jExu48NvUCa*IPLXP~5PQ3v%m4rY07*qoM6N<$g8v~R;Q#;t delta 84 zcmV-a0IUD70E~ qP+kF+9iojXK&`+N+bg=59kND|Y_t&H=MtL$0000fM}J#PJb3hrqPvN{9i{->89_~tYb(=(ja!^lpd1qNs|ff z^L4OyAG;XDMl~nI5t|$Th>hwaBw98vqGh8ZS{W*$mGNS0*;~AbmW_(7m7yY9885b$ z&5LN+sMuN=Dx#I~TC%nFxS-3xu2aVsbnA|mbz+c=S6_`Iea2Y_9Lad~)i}~;oOQsF cj8|WM0fq8TGdGEb?EnA(07*qoM6N<$f~p>E0{{R3 delta 224 zcmeBX>SUT=Sbx~l#W5tq`R$C0yv+sz&U4T1l6;$%muyi<0b zedR_9pW%u1mYvELK}rr=yb_kjcPn3h;l=*{`b6)lmzA?h`Cj@+9qEg?6n$x;$;=CN z$1We&W7`;bmb384vt#y2i+8oUoPOrIB`3s1+u3!CQCyDhZ1Ibcn*uj(H3AAfK6-6a zrJ$~~Xf#CDd)qZR@e;`!rLTT8<=tJLI#)vF@zwCh9`g&YF}fSY)tdHwkxZ8@014JJ Ywtn(64l#dlf&mCTUHx3vIVCg!02Yd7fB*mh diff --git a/test/unit/visual/screenshots/WebGL/Camera/Custom camera before and after resize/000.png b/test/unit/visual/screenshots/WebGL/Camera/Custom camera before and after resize/000.png index b3cc6ed6097a9f86ddf39cef8be973a9de4915a8..d4000e5a1495aa037b2d59c0e4b272015bf7e6ef 100644 GIT binary patch delta 170 zcmcc3c$sm6VSTTsi(^QH``hW>Tn7v|T-41^pZ)So*GZ#9)V(9c@b0x|SC{|fHL+RT z$mpnX`jTqw6h^IxyU5gxx9i%aYFXpi3mM9+Cf9ZBKCClcB6xDVTGJaT_gyP~cb0gH zFGzj5FE#bt&fhEF*H+ql3OD?+v1IKmjP7$$W;`XnxZ+)s&Qz{=rX%k9;Zh#2ZFd&T9lg&h)c^nh07*qoM6N<$g5~8+`2YX_ diff --git a/test/unit/visual/screenshots/WebGL/Camera/Custom camera before and after resize/001.png b/test/unit/visual/screenshots/WebGL/Camera/Custom camera before and after resize/001.png index 74fb513043820a27027baced6e58dcec97e53d13..788178ce2fc7145f6b98db5190b0ab2b7d517707 100644 GIT binary patch delta 164 zcmV;V09*gj0nGuBF@J|iL_t(oN9~hQ4!|G?L-AEQmOxt4_T|KF!P~B9@H;nz28O7*ot9!bH^iE=!5j z8aox`|2IZNVt|;LS~~&U4@QiqF=P`05V>+ewY)u2^r)5=A|0xQYCQ=oyO9G^_gWfO SzGF840000w0nyf=WB6lvVmbXU(Jt3<#3X#=fwVni)?Z^Q+ WOL!XJrH|kM0000X!JA3E6hTD9Dq2sihnlzjri`Dnn`}14B{Z;Xp=GmA-+5=|n>oOgd=5+r2m2sR zQ*vLCB1P^)=NNDVmh@jb1TEcvLVpYR0c=2bWAK0u^e3h4M1K@{0G&BlIt;CuotNie zdPDmHLD=;Z__YJn{{k;=Z!^{V)B;HW?W4e9z(WWmf4D$?r%NCLl0y2thVI=OKx2X2 zgU)$qAK3|^T>ydTfr5w>(F+@hpiCLvHxtwvTv{F@Ea40-dwaKItH2ZVyrvR(aNn z!pjt~yFdi=8CV;n>g5rX845DU^{qwd9Z%t829MM*Z-3~acKM|0Q*fTaJd7Z`GOwUJ z$j_xIdML;f*pd=Hq`bj%Z+M6({dyS7VCEHXd=DaJuKkida}l z2~$INpMR~Yctq+*g*+8ok+gJds#Q7Ju6r%NyN$BnquMAiiZWRn&tCbf;>(}mm+!nu-+<4y>&y&x?vBK z*OQM0h7Unh&F2B@t*q0{`z!B}DE&s+C9mvdt%_<%IvVfxUhBZs!0;i+Q`nkoD9ERR zc7J8MLu+cxuJgx2Y8D%qe*4R#W-Z_KHmM-0D83v(MDwu1Uh6q*HL*o`T@^&NWWHfd zqiV>FDovyE|J1bcf|-hgl|ZKEs4Ey7K9pszqJvf4;e(w+Y7Za0D*t&L6sBC?%MBd| z>5uaPoy~mrVnFAI4ig>F8MWrVbI|t6?0?nB)I#b5bZ?C?WsDASrQ4RN7-ActR%_?> zc&(sG{HRLUdyV9gT&5LhorRtbT9aJ#D5Tzwxw#q(#K5$IZXcuxDpc;Zn)cGs`}_e!qMlJ3^-Q$@0000;{6c_3jgxfQGy9_?I!$bU#yp+<{^l`b)r9z;Op*ApY?L@}XJ+5s(zp-=9Ib zH3d*7kQ-2ZR{?zO0HPX#@QUbn1JS>NF`zeq)()&+?+|jWLAEOuP5@FuD%g?=w(P{90{I7c-U6l(h_cc-=%02FGPeiuA(aEs!<$c1 z#utdpZ+`g`c-atUB1j3vMd+I+>ePr~RTo+j#KOx|@qfxR$!HTneudF8;6utA+~^hIRPdMPAy0Q#ic5wWNuT#e37afu@I&_Vrt~VOF#x9zbM3>K&j`+ zmCag^hY2-&;S-2Yxpj(|KT?^?GMH6-E0j@{A8J&|g2)?Q4O7Iz$`?O<)`hx+R?J@J z6;s91v45%3�Gxd($)=&65-VHHzuEQGpf?!tA7_*5Lj>n~srhF4)d6<*2vZ9{Jv z2Hxbc07ie98mZK4H#Ue=3igJN1yUg<(+lSN%sWbg+<@LC7%1iXv>R(j%vd?2dk}p# zAm4Yz-pkh%E07AWr%q4upFj_tN z1BTa{f~cCW0M=W1qo>lZ@3Rb~N!E%jeau=ub1B3WT6@5c3BxDv_Zy7PI1pda4;!SK z@qfpaULd=fcBNBjrBZKH#ZQNIS<4qh8?<6kv<6ZjtwJkj_DSj2hgIE#m@A5Pq1DOk zbDn;OTTRVwGlQlDjW$UL+tnoIU!eX|Y7eHfhu=Ba6X z1;d}(G>ytKP22cfK}>bP-sFC`lF4JQHGi`uBvf^bKa##|mmgwBLK6#|lPcFn@99 zF^<0eP5BKvU;O+*kCf03e3z4}R-qN;vW%vSOmp-mfPE-`ZV^iHS*8N<3a!B9CFo5$ z4E1Wftqw!m9O!h~`<-Z*@Pz_;N&-vJmqL0=@p$?TJl2rZ)&rBCWhRPDy2)Yu{}ISx myyZ6cI8vm|+d7QzegqCVpHb*UH4RPx0000K@PZDLB@8=I+1Scf?jkYLB@8=I+1Scf?f4_-Fc6_)2m}h!ShIOMC}RH>kr_GKPfre%I6(b&7)Z+*i+I)`go~tx z6CvFsw44axA}p!lL`XLYEhj>_NNP9{(oI6ki4ZQ58XpTdTQj0rLOB2c002ovPDHLk FV1jRxgKz)< delta 375 zcmV--0f_$F0-pnrF@IS}L_t(&L+zJA4uUWcMTZ`$VW*xZRh>h!Z^@HUc*H=$U)9#(v7$gqXc|w83ikz){TgxGaBedjDi(U>qf-U84WZs zGLGYYUDqkse9P}M5q?@6{FOV}`mZjx>`(v` zBMrA$vr9~jm{q$ov4iwTeQ!-S;zo=T@U3MOtaw^CB96{zpc^p?Ry?g65l3e<@CO#y Va5L>M^&$WO002ovPDHLkV1lk^r6T|U diff --git a/test/unit/visual/screenshots/WebGL/filter/On a framebuffer/000.png b/test/unit/visual/screenshots/WebGL/filter/On a framebuffer/000.png index 90ccca1c5d13db664c01a5d531db4fc7f75adc6f..197629c93fc4078cdd31de9bfe9882cdf2bc59dc 100644 GIT binary patch delta 307 zcmV-30nGlN1KR?SF@F_FL_t(&L+zJA4udcd1H-5Cy_WCgQ&d#sLZK+}tcZ}g0w!a7 z({xG?xu%D3B!i5Wq!V!>K@PZDLB@8=I+1Scf?jkYLB@8=I+1Scf?f4_-Fc6_)2m}h!ShIOMC}RH>kr_GKPfre%I6(b&7)Z+*i+I)`go~tx z6CvFsw44axA}p!lL`XLYEhj>_NNP9{(oI6ki4ZQ58XpTdTQj0rLOB2c002ovPDHLk FV1jRxgKz)< delta 375 zcmV--0f_$F0-pnrF@IS}L_t(&L+zJA4uUWcMTZ`$VW*xZRh>h!Z^@HUc*H=$U)9#(v7$gqXc|w83ikz){TgxGaBedjDi(U>qf-U84WZs zGLGYYUDqkse9P}M5q?@6{FOV}`mZjx>`(v` zBMrA$vr9~jm{q$ov4iwTeQ!-S;zo=T@U3MOtaw^CB96{zpc^p?Ry?g65l3e<@CO#y Va5L>M^&$WO002ovPDHLkV1lk^r6T|U diff --git a/test/unit/visual/visualTest.js b/test/unit/visual/visualTest.js index e6ec8af501..7e41fc0f6c 100644 --- a/test/unit/visual/visualTest.js +++ b/test/unit/visual/visualTest.js @@ -1,15 +1,11 @@ import p5 from '../../../src/app.js'; +import { server } from '@vitest/browser/context' +import resemble from 'resemblejs' +const { readFile, writeFile } = server.commands -/** - * A helper class to contain an error and also the screenshot data that - * caused the error. - */ -class ScreenshotError extends Error { - constructor(message, actual, expected) { - super(message); - this.actual = actual; - this.expected = expected; - } +function writeImageFile(filename, base64Data) { + const prefix = /^data:image\/\w+;base64,/; + writeFile(filename, base64Data.replace(prefix, ''), 'base64'); } function toBase64(img) { @@ -37,45 +33,49 @@ export function visualSuite( callback, { focus = false, skip = false } = {} ) { - const lastPrefix = namePrefix; - namePrefix += escapeName(name) + '/'; - - let suiteFn = suite; + let suiteFn = describe; if (focus) { suiteFn = suiteFn.only; } if (skip) { suiteFn = suiteFn.skip; } - suiteFn(name, callback); + suiteFn(name, () => { + let lastPrefix; + beforeAll(() => { + lastPrefix = namePrefix; + namePrefix += escapeName(name) + '/'; + }) - namePrefix = lastPrefix; + callback() + + afterAll(() => { + namePrefix = lastPrefix; + }); + }); } -export function checkMatch(actual, expected, p5) { +export async function checkMatch(actual, expected, p5) { const maxSide = 50; const scale = Math.min(maxSide/expected.width, maxSide/expected.height); + for (const img of [actual, expected]) { img.resize( Math.ceil(img.width * scale), Math.ceil(img.height * scale) ); } - const diff = p5.createImage(actual.width, actual.height); - diff.drawingContext.drawImage(actual.canvas, 0, 0); - diff.drawingContext.globalCompositeOperation = 'difference'; - diff.drawingContext.drawImage(expected.canvas, 0, 0); - diff.filter(p5.ERODE, false); - diff.loadPixels(); - - let ok = true; - for (let i = 0; i < diff.pixels.length; i++) { - if (i % 4 === 3) continue; // Skip alpha checks - if (Math.abs(diff.pixels[i]) > 10) { - ok = false; - break; - } - } + + resemble.outputSettings({ useCrossOrigin: false }); + const diff = await new Promise(resolve => resemble(toBase64(actual)) + .compareTo(toBase64(expected)) + .ignoreAntialiasing() + .onComplete((data) => { + resolve(data) + }) + ) + const ok = diff.rawMisMatchPercentage === 0; + return { ok, diff }; } @@ -103,8 +103,7 @@ export function visualTest( callback, { focus = false, skip = false } = {} ) { - const name = namePrefix + escapeName(testName); - let suiteFn = suite; + let suiteFn = describe; if (focus) { suiteFn = suiteFn.only; } @@ -113,9 +112,11 @@ export function visualTest( } suiteFn(testName, function() { + let name; let myp5; beforeAll(function() { + name = namePrefix + escapeName(testName); return new Promise(res => { myp5 = new p5(function(p) { p.setup = function() { @@ -132,20 +133,15 @@ export function visualTest( test('matches expected screenshots', async function() { let expectedScreenshots; try { - metadata = await fetch( - `unit/visual/screenshots/${name}/metadata.json` - ).then(res => res.json()); + const metadata = JSON.parse(await readFile( + `../screenshots/${name}/metadata.json` + )); expectedScreenshots = metadata.numScreenshots; } catch (e) { + console.log(e); expectedScreenshots = 0; } - if (!window.shouldGenerateScreenshots && !expectedScreenshots) { - // If running on CI, all expected screenshots should already - // be generated - throw new Error('No expected screenshots found'); - } - const actual = []; // Generate screenshots @@ -163,34 +159,31 @@ export function visualTest( ); } if (!expectedScreenshots) { - writeTextFile( - `unit/visual/screenshots/${name}/metadata.json`, + await writeFile( + `../screenshots/${name}/metadata.json`, JSON.stringify({ numScreenshots: actual.length }, null, 2) ); } const expectedFilenames = actual.map( - (_, i) => `unit/visual/screenshots/${name}/${i.toString().padStart(3, '0')}.png` + (_, i) => `../screenshots/${name}/${i.toString().padStart(3, '0')}.png` ); const expected = expectedScreenshots ? ( await Promise.all( - expectedFilenames.map(path => new Promise((resolve, reject) => { - myp5.loadImage(path, resolve, reject); - })) + expectedFilenames.map(path => myp5.loadImage('/unit/visual' + path.slice(2))) ) ) : []; for (let i = 0; i < actual.length; i++) { if (expected[i]) { - if (!checkMatch(actual[i], expected[i], myp5).ok) { - throw new ScreenshotError( - `Screenshots do not match! Expected:\n${toBase64(expected[i])}\n\nReceived:\n${toBase64(actual[i])}\n\n` + - 'If this is unexpected, paste these URLs into your browser to inspect them, or run grunt yui:dev and go to http://127.0.0.1:9001/test/visual.html.\n\n' + - `If this change is expected, please delete the test/unit/visual/screenshots/${name} folder and run tests again to generate a new screenshot.`, - actual[i], - expected[i] + const result = await checkMatch(actual[i], expected[i], myp5); + if (!result.ok) { + throw new Error( + `Screenshots do not match! Expected:\n${toBase64(expected[i])}\n\nReceived:\n${toBase64(actual[i])}\n\nDiff:\n${result.diff.getImageDataUrl()}\n\n` + + 'If this is unexpected, paste these URLs into your browser to inspect them.\n\n' + + `If this change is expected, please delete the screenshots/${name} folder and run tests again to generate a new screenshot.`, ); } } else { From a00a986e486416df5d548a003dfe4d700ada86fc Mon Sep 17 00:00:00 2001 From: Dave Pagurek Date: Sat, 7 Sep 2024 13:52:07 -0400 Subject: [PATCH 3/4] Remove old workspace --- vitest.workspace.mjs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/vitest.workspace.mjs b/vitest.workspace.mjs index 2a42a04a31..18ec5254c1 100644 --- a/vitest.workspace.mjs +++ b/vitest.workspace.mjs @@ -10,18 +10,6 @@ const plugins = [ ]; export default defineWorkspace([ - /*{ - plugins, - publicDir: './test', - test: { - name: 'visual', - root: './', - include: [ - './test/unit/visual/*' - ], - environment: 'node' - } - },*/ { plugins, publicDir: './test', From 00ad3d1257ff65f62073968425f9e61eec595a3c Mon Sep 17 00:00:00 2001 From: Dave Pagurek Date: Sat, 7 Sep 2024 13:54:45 -0400 Subject: [PATCH 4/4] Put back changed test --- test/unit/visual/cases/typography.js | 2 +- .../With the default font/000.png | Bin 1068 -> 829 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/visual/cases/typography.js b/test/unit/visual/cases/typography.js index 98121ec94b..6066acfe83 100644 --- a/test/unit/visual/cases/typography.js +++ b/test/unit/visual/cases/typography.js @@ -6,7 +6,7 @@ visualSuite('Typography', function() { p5.createCanvas(50, 50); p5.textSize(20); p5.textAlign(p5.LEFT, p5.TOP); - p5.text('broken', 0, 0); + p5.text('test', 0, 0); screenshot(); }); diff --git a/test/unit/visual/screenshots/Typography/textFont() with default fonts/With the default font/000.png b/test/unit/visual/screenshots/Typography/textFont() with default fonts/With the default font/000.png index a6f522d460ae4dfa93993f15ecc2e27e83169695..9412be344069b600d55c68b79ad7ebc049b63ed3 100644 GIT binary patch delta 794 zcmZ3(v6pRvK|RxVPZ!6K4ClAgB3JYUinPracI9l1nIJvWxWuS6XbLxHq2f{2i7G`( zi+B`cG*bFf{E8AiVib);=kj&>Oq>#w!Y6(se{F1h{Qde@U)Fz~|LgYecfY^gdms0@ z_Iil()HSoTJ~qENVUb`}Ai3kxnRB`fY>c}b#N+Z^-Cs4x9;m8MSS((_Ij8$TN`g(n z-PdbZ6{T$7Xv|Q-XTqS}u>DwAd_pG2&WR4U3%;opi0zn`yjfNuRdmtb#_I=|6PgoC z8NV?JH-0;i%e{7|+$xWW=??Q{W+eSEG+^Bk@Mz)F17)|fQ+Jvk+&7=W_RNEP#>HYk zCM&8tWvy?Xu6#)I)WmbgR@L8#=8@UJuAVwaT58T(_G1j&8_K7hnBRD9TKTTsY&UYg zYtK`Dt)ugRX7J8ouw$@w&iJ?C^WBEl#Q&*3>h~;_={zILYgn)K z{6s{8ZUMgp>lfyEw8^&o*BIGheeXqW> zG2ne6f90a=)Vn*}qGw*+e(JsZ0;Rqj=CE0!#SO~S4(w%^>b2JFKxlHc;0E~{Ne>sV zbhzvovrGKAKYIvf_r2LYH`ce_t9V+EEoY7q`#Yw?YXeWM+<$OGq*zgq zbG7|i{}nvhZ<$N{YhAAT^oH@4w7osvwfv7&`qlNCX5#aD`#RPdUn?yw@OW{d|4_p9 zlM?-IE&{yMf*$*_mD&}ocpz$erBW^LS6I-_24@vd|^vB|44 zTvsn%S-+&_N7CQLS6WufedhiVvP~u~r$Qn~udRE{Q>llA_Lh$hE>d?3Ix^Xpf6bB( z_U?HSo`U{nwi_lX$>~%jskqwQ{Bppnt75~8&WR!)Q!X=WYZ9#?(6s9hJBRRsS;mU5 R9$jSs0#8>zmvv4FO#olRYcT)- delta 1035 zcmV+m1oZp82CN8>Fn5{ii0en7Iq(zkvZm*HAa5*?|9`G&-0JMV0(=HE1fEo9 z!~1*+keV_GWL2b{yWj$#A5afC11thA1s9(WbOUAqgMsP5F5p-5>Ed#J9?%zP0sIN< zarLm$)x)bGP9-3XfF(c^-~_PN{A&YKfgyJGHQ;w(4e(e#acbQMJ_i1^-1X-U0FK+o zDd0=sC@{#@7JnK6!+=A!rWg-^4)%Q-=nuTG?-+&U_0;+@C>+aM9eW}UjrTOVr@*R#T9_mHDY=J z$AFO*Pp--U5p@9=1Ke=uHUqYrLI>p^15p6|;jN{U^nZ?h^ajoaK%|IL%bTQEDhPDv zsD|Vxw#DWr5s>!4KA?yBd>w#Lsy#A)F|Qcjn!0iE&^}tmK_Pc5nF)2|h9H`v?L$kUR5#Pdeys}u%=K$O#BAhr#_ z6uacA0Dp)Wycjqiu{@pt?5q&S&nnFh6{`mlx~_9TrUeV*fgKfM#Y=BFzKY46Jvosu{?>vYOIw75s1JKk+?) z&c{IF%Y9@)6vO{l6_8&X3A2IyuH}x74pjpY34fvL9*76F%$`U}wa<-ErLKMvJ-|xQ#Hd>ogaCM=ofDE+G6CbKKoIr@(pIr^kwOdqbzgknyixhP} z&9c9(hV%|p9eVSvUgR{3fyhY%OdUx9zp-6mH>(PWTz#FWuvJe_t!^}jbYLepK<`xn zM1RX;ZMf>U()qkA_HZ_-hIBtEB{gJ|)rvzPw=K7QpZCZWT$9Gz-C{eK~!?bW_