From bd6780aa4e56e13575e347260ba630def33d1b1b Mon Sep 17 00:00:00 2001 From: Harel M Date: Wed, 6 Dec 2023 12:39:12 +0200 Subject: [PATCH] Upgrade node to version 20 (#3452) --- .nvmrc | 2 +- build/generate-style-code.ts | 1 - jest.config.ts | 2 +- package-lock.json | 810 +-------------------------- package.json | 23 +- src/gl/render_pool.test.ts | 8 +- src/gl/state.test.ts | 125 +---- src/gl/vertex_buffer.test.ts | 13 +- src/render/render_to_texture.test.ts | 5 +- src/render/terrain.test.ts | 46 +- src/ui/control/logo_control.test.ts | 12 +- src/ui/map.test.ts | 41 +- src/util/test/mock_webgl.ts | 101 ---- src/util/test/util.ts | 33 +- 14 files changed, 150 insertions(+), 1072 deletions(-) delete mode 100644 src/util/test/mock_webgl.ts diff --git a/.nvmrc b/.nvmrc index 87ec8842b1..89e0c3dba3 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -18.18.2 +20.10 \ No newline at end of file diff --git a/build/generate-style-code.ts b/build/generate-style-code.ts index a78fb416b6..6b49d1aef3 100644 --- a/build/generate-style-code.ts +++ b/build/generate-style-code.ts @@ -196,7 +196,6 @@ import {StylePropertySpecification} from '@maplibre/maplibre-gl-style-spec'; ${overridables.reduce((imports, prop) => { imports.push(runtimeType(prop)); return imports; }, []).join(',\n ')} } from '@maplibre/maplibre-gl-style-spec'; `; - console.log(overridesArray); output.push(overridesArray); } diff --git a/jest.config.ts b/jest.config.ts index 6f6554cf6d..c27a41edc9 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -19,7 +19,7 @@ const config: Config = { displayName: 'unit', testEnvironment: 'jsdom', setupFiles: [ - 'jest-canvas-mock', + 'jest-webgl-canvas-mock', './test/unit/lib/web_worker_mock.ts' ], testMatch: [ diff --git a/package-lock.json b/package-lock.json index 1a61d029b8..def18d3297 100644 --- a/package-lock.json +++ b/package-lock.json @@ -87,12 +87,11 @@ "eslint-plugin-react": "^7.33.2", "eslint-plugin-tsdoc": "0.2.17", "expect": "^29.7.0", - "gl": "^6.0.2", "glob": "^10.3.10", "is-builtin-module": "^3.2.1", "jest": "^29.7.0", - "jest-canvas-mock": "^2.5.2", "jest-environment-jsdom": "^29.7.0", + "jest-webgl-canvas-mock": "^2.5.3", "jsdom": "^22.1.0", "json-stringify-pretty-compact": "^4.0.0", "minimist": "^1.2.8", @@ -923,11 +922,6 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/@gar/promisify": { - "version": "1.1.3", - "dev": true, - "license": "MIT" - }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.13", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", @@ -1649,30 +1643,6 @@ "node": ">= 8" } }, - "node_modules/@npmcli/fs": { - "version": "2.1.2", - "dev": true, - "license": "ISC", - "dependencies": { - "@gar/promisify": "^1.1.3", - "semver": "^7.3.5" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/@npmcli/move-file": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, "node_modules/@pdf-lib/standard-fonts": { "version": "1.0.0", "dev": true, @@ -3330,31 +3300,6 @@ "node": ">= 6.0.0" } }, - "node_modules/agentkeepalive": { - "version": "4.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.1.0", - "depd": "^1.1.2", - "humanize-ms": "^1.2.1" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -3847,19 +3792,6 @@ "node": ">=8" } }, - "node_modules/bindings": { - "version": "1.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/bit-twiddle": { - "version": "1.0.2", - "dev": true, - "license": "MIT" - }, "node_modules/boolbase": { "version": "1.0.0", "dev": true, @@ -4009,96 +3941,6 @@ "typewise-core": "^1.2" } }, - "node_modules/cacache": { - "version": "16.1.3", - "dev": true, - "license": "ISC", - "dependencies": { - "@npmcli/fs": "^2.1.0", - "@npmcli/move-file": "^2.0.0", - "chownr": "^2.0.0", - "fs-minipass": "^2.1.0", - "glob": "^8.0.1", - "infer-owner": "^1.0.4", - "lru-cache": "^7.7.1", - "minipass": "^3.1.6", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "mkdirp": "^1.0.4", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^9.0.0", - "tar": "^6.1.11", - "unique-filename": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/cacache/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/cacache/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/cacache/node_modules/lru-cache": { - "version": "7.14.0", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/cacache/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cacache/node_modules/p-map": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/call-bind": { "version": "1.0.2", "dev": true, @@ -4323,14 +4165,6 @@ "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", "dev": true }, - "node_modules/clean-stack": { - "version": "2.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -4452,11 +4286,6 @@ "safe-buffer": "~5.1.1" } }, - "node_modules/core-util-is": { - "version": "1.0.3", - "dev": true, - "license": "MIT" - }, "node_modules/cosmiconfig": { "version": "8.3.6", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", @@ -5305,14 +5134,6 @@ } } }, - "node_modules/deep-extend": { - "version": "0.6.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/deep-is": { "version": "0.1.4", "dev": true, @@ -5377,14 +5198,6 @@ "dev": true, "license": "MIT" }, - "node_modules/depd": { - "version": "1.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/dependency-graph": { "version": "0.11.0", "dev": true, @@ -5595,6 +5408,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "dependencies": { "iconv-lite": "^0.6.2" } @@ -5619,19 +5433,6 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/env-paths": { - "version": "2.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/err-code": { - "version": "2.0.3", - "dev": true, - "license": "MIT" - }, "node_modules/error-ex": { "version": "1.3.2", "dev": true, @@ -6412,14 +6213,6 @@ "node": ">= 0.8.0" } }, - "node_modules/expand-template": { - "version": "2.0.3", - "dev": true, - "license": "(MIT OR WTFPL)", - "engines": { - "node": ">=6" - } - }, "node_modules/expect": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", @@ -6570,11 +6363,6 @@ "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, "node_modules/filelist": { "version": "1.0.3", "dev": true, @@ -6739,11 +6527,6 @@ "node": ">= 0.12" } }, - "node_modules/fs-constants": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, "node_modules/fs-extra": { "version": "11.1.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz", @@ -6981,29 +6764,6 @@ "node": ">=0.10.0" } }, - "node_modules/github-from-package": { - "version": "0.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/gl": { - "version": "6.0.2", - "dev": true, - "hasInstallScript": true, - "license": "BSD-2-Clause", - "dependencies": { - "bindings": "^1.5.0", - "bit-twiddle": "^1.0.2", - "glsl-tokenizer": "^2.1.5", - "nan": "^2.17.0", - "node-abi": "^3.26.0", - "node-gyp": "^9.2.0", - "prebuild-install": "^7.1.1" - }, - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/gl-matrix": { "version": "3.4.3", "license": "MIT" @@ -7156,44 +6916,6 @@ "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", "dev": true }, - "node_modules/glsl-tokenizer": { - "version": "2.1.5", - "dev": true, - "license": "MIT", - "dependencies": { - "through2": "^0.6.3" - } - }, - "node_modules/glsl-tokenizer/node_modules/isarray": { - "version": "0.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/glsl-tokenizer/node_modules/readable-stream": { - "version": "1.0.34", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/glsl-tokenizer/node_modules/string_decoder": { - "version": "0.10.31", - "dev": true, - "license": "MIT" - }, - "node_modules/glsl-tokenizer/node_modules/through2": { - "version": "0.6.5", - "dev": true, - "license": "MIT", - "dependencies": { - "readable-stream": ">=1.0.33-1 <1.1.0-0", - "xtend": ">=4.0.0 <4.1.0-0" - } - }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -7421,12 +7143,6 @@ "entities": "^4.3.0" } }, - "node_modules/http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", - "dev": true - }, "node_modules/http-proxy-agent": { "version": "5.0.0", "dev": true, @@ -7461,14 +7177,6 @@ "node": ">=10.17.0" } }, - "node_modules/humanize-ms": { - "version": "1.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.0.0" - } - }, "node_modules/iconv-lite": { "version": "0.6.3", "dev": true, @@ -7566,19 +7274,6 @@ "node": ">=0.8.19" } }, - "node_modules/indent-string": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/infer-owner": { - "version": "1.0.4", - "dev": true, - "license": "ISC" - }, "node_modules/inflight": { "version": "1.0.6", "dev": true, @@ -7832,11 +7527,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-lambda": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, "node_modules/is-map": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", @@ -8245,16 +7935,6 @@ } } }, - "node_modules/jest-canvas-mock": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jest-canvas-mock/-/jest-canvas-mock-2.5.2.tgz", - "integrity": "sha512-vgnpPupjOL6+L5oJXzxTxFrlGEIbHdZqFU+LFNdtLxZ3lRDCl17FlTMM7IatoRQkrcyOTMlDinjUguqmQ6bR2A==", - "dev": true, - "dependencies": { - "cssfontparser": "^1.2.1", - "moo-color": "^1.0.2" - } - }, "node_modules/jest-changed-files": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", @@ -8949,6 +8629,16 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-webgl-canvas-mock": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/jest-webgl-canvas-mock/-/jest-webgl-canvas-mock-2.5.3.tgz", + "integrity": "sha512-aE5ym/VV8hpJgsu/zzmvJ/bhD4vnfAM9TY6TRQxQAy9lo3hxtNfa2rbLFt3Qx31spQd5fhlQHO58Aey6oFDxAA==", + "dev": true, + "dependencies": { + "cssfontparser": "^1.2.1", + "moo-color": "^1.0.2" + } + }, "node_modules/jest-worker": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", @@ -9435,47 +9125,13 @@ "dev": true, "license": "ISC" }, - "node_modules/make-fetch-happen": { - "version": "10.2.1", + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", "dev": true, - "license": "ISC", "dependencies": { - "agentkeepalive": "^4.2.1", - "cacache": "^16.1.0", - "http-cache-semantics": "^4.1.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^7.7.1", - "minipass": "^3.1.6", - "minipass-collect": "^1.0.2", - "minipass-fetch": "^2.0.3", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^7.0.0", - "ssri": "^9.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/make-fetch-happen/node_modules/lru-cache": { - "version": "7.14.0", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, - "dependencies": { - "tmpl": "1.0.5" + "tmpl": "1.0.5" } }, "node_modules/map-obj": { @@ -9791,66 +9447,6 @@ "node": ">=8" } }, - "node_modules/minipass-collect": { - "version": "1.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-fetch": { - "version": "2.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "minipass": "^3.1.6", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - }, - "optionalDependencies": { - "encoding": "^0.1.13" - } - }, - "node_modules/minipass-flush": { - "version": "1.0.5", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-pipeline": { - "version": "1.2.4", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-sized": { - "version": "1.0.3", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/minizlib": { "version": "2.1.2", "dev": true, @@ -9935,11 +9531,6 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/napi-build-utils": { - "version": "1.0.2", - "dev": true, - "license": "MIT" - }, "node_modules/natural-compare": { "version": "1.4.0", "dev": true, @@ -9986,17 +9577,6 @@ "path-to-regexp": "^1.7.0" } }, - "node_modules/node-abi": { - "version": "3.28.0", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/node-fetch": { "version": "2.6.12", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", @@ -10036,127 +9616,6 @@ "webidl-conversions": "^3.0.0" } }, - "node_modules/node-gyp": { - "version": "9.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "env-paths": "^2.2.0", - "glob": "^7.1.4", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^10.0.3", - "nopt": "^6.0.0", - "npmlog": "^6.0.0", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.2", - "which": "^2.0.2" - }, - "bin": { - "node-gyp": "bin/node-gyp.js" - }, - "engines": { - "node": "^12.22 || ^14.13 || >=16" - } - }, - "node_modules/node-gyp/node_modules/are-we-there-yet": { - "version": "3.0.1", - "dev": true, - "license": "ISC", - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/node-gyp/node_modules/gauge": { - "version": "4.0.4", - "dev": true, - "license": "ISC", - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^3.0.7", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/node-gyp/node_modules/glob": { - "version": "7.2.3", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/node-gyp/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/node-gyp/node_modules/nopt": { - "version": "6.0.0", - "dev": true, - "license": "ISC", - "dependencies": { - "abbrev": "^1.0.0" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/node-gyp/node_modules/npmlog": { - "version": "6.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "are-we-there-yet": "^3.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^4.0.3", - "set-blocking": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/node-gyp/node_modules/string-width": { - "version": "4.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -11500,88 +10959,6 @@ "version": "2.0.0", "license": "ISC" }, - "node_modules/prebuild-install": { - "version": "7.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", - "node-abi": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/prebuild-install/node_modules/decompress-response": { - "version": "6.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/prebuild-install/node_modules/detect-libc": { - "version": "2.0.1", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, - "node_modules/prebuild-install/node_modules/mimic-response": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/prebuild-install/node_modules/simple-get": { - "version": "4.0.1", - "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" - } - ], - "license": "MIT", - "dependencies": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -11645,23 +11022,6 @@ "node": ">=0.4.0" } }, - "node_modules/promise-inflight": { - "version": "1.0.1", - "dev": true, - "license": "ISC" - }, - "node_modules/promise-retry": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -11917,20 +11277,6 @@ "safe-buffer": "^5.1.0" } }, - "node_modules/rc": { - "version": "1.2.8", - "dev": true, - "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, "node_modules/react": { "version": "18.2.0", "dev": true, @@ -12310,14 +11656,6 @@ "node": ">=10" } }, - "node_modules/retry": { - "version": "0.12.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, "node_modules/reusify": { "version": "1.0.4", "dev": true, @@ -12788,19 +12126,6 @@ "npm": ">= 3.0.0" } }, - "node_modules/socks-proxy-agent": { - "version": "7.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^6.0.2", - "debug": "^4.3.3", - "socks": "^2.6.2" - }, - "engines": { - "node": ">= 10" - } - }, "node_modules/sort-asc": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/sort-asc/-/sort-asc-0.2.0.tgz", @@ -13073,17 +12398,6 @@ "dev": true, "license": "BSD-3-Clause" }, - "node_modules/ssri": { - "version": "9.0.1", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.1.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, "node_modules/st": { "version": "3.0.0", "dev": true, @@ -13403,14 +12717,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/strip-json-comments": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/style-search": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", @@ -13739,47 +13045,6 @@ "node": ">= 10" } }, - "node_modules/tar-fs": { - "version": "2.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "node_modules/tar-fs/node_modules/chownr": { - "version": "1.1.4", - "dev": true, - "license": "ISC" - }, - "node_modules/tar-stream": { - "version": "2.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tar-stream/node_modules/bl": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, "node_modules/terser": { "version": "5.17.4", "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.4.tgz", @@ -14079,17 +13344,6 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -14335,28 +13589,6 @@ "node": ">=0.10.0" } }, - "node_modules/unique-filename": { - "version": "2.0.1", - "dev": true, - "license": "ISC", - "dependencies": { - "unique-slug": "^3.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/unique-slug": { - "version": "3.0.0", - "dev": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, "node_modules/universalify": { "version": "0.2.0", "dev": true, @@ -14831,14 +14063,6 @@ "dev": true, "license": "MIT" }, - "node_modules/xtend": { - "version": "4.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4" - } - }, "node_modules/y18n": { "version": "5.0.8", "dev": true, diff --git a/package.json b/package.json index 8eb43ec664..8dfd7b3ff3 100644 --- a/package.json +++ b/package.json @@ -91,12 +91,11 @@ "eslint-plugin-react": "^7.33.2", "eslint-plugin-tsdoc": "0.2.17", "expect": "^29.7.0", - "gl": "^6.0.2", "glob": "^10.3.10", "is-builtin-module": "^3.2.1", "jest": "^29.7.0", - "jest-canvas-mock": "^2.5.2", "jest-environment-jsdom": "^29.7.0", + "jest-webgl-canvas-mock": "^2.5.3", "jsdom": "^22.1.0", "json-stringify-pretty-compact": "^4.0.0", "minimist": "^1.2.8", @@ -140,13 +139,13 @@ } }, "scripts": { - "generate-dist-package": "npm run tsnode build/generate-dist-package.js", - "generate-shaders": "npm run tsnode build/generate-shaders.ts", - "generate-struct-arrays": "npm run tsnode build/generate-struct-arrays.ts", - "generate-style-code": "npm run tsnode build/generate-style-code.ts", - "generate-typings": "npm run tsnode build/generate-typings.ts", - "generate-docs": "typedoc && npm run tsnode build/generate-docs.ts", - "generate-images": "npm run tsnode build/generate-doc-images.ts", + "generate-dist-package": "node --no-warnings --loader ts-node/esm build/generate-dist-package.js", + "generate-shaders": "node --no-warnings --loader ts-node/esm build/generate-shaders.ts", + "generate-struct-arrays": "node --no-warnings --loader ts-node/esm build/generate-struct-arrays.ts", + "generate-style-code": "node --no-warnings --loader ts-node/esm build/generate-style-code.ts", + "generate-typings": "node --no-warnings --loader ts-node/esm build/generate-typings.ts", + "generate-docs": "typedoc && node --no-warnings --loader ts-node/esm build/generate-docs.ts", + "generate-images": "node --no-warnings --loader ts-node/esm build/generate-doc-images.ts", "build-dist": "run-p --print-label generate-typings build-dev build-prod build-csp build-csp-dev build-css", "build-dev": "rollup --configPlugin @rollup/plugin-typescript -c --environment BUILD:dev", "watch-dev": "rollup --configPlugin @rollup/plugin-typescript -c --environment BUILD:dev --watch", @@ -168,12 +167,12 @@ "jest-ci": "jest --reporters=github-actions --reporters=summary", "test-build": "jest --selectProjects=build", "test-integration": "jest --selectProjects=integration", - "test-render": "npm run tsnode test/integration/render/run_render_tests.ts", + "test-render": "node --no-warnings --loader ts-node/esm test/integration/render/run_render_tests.ts", "test-unit": "jest --selectProjects=unit", "test-watch-roots": "jest --watch", "codegen": "run-p generate-dist-package generate-style-code generate-struct-arrays generate-shaders", - "benchmark": "npm run tsnode test/bench/run-benchmarks.ts", - "gl-stats": "npm run tsnode test/bench/gl-stats.ts", + "benchmark": "node --no-warnings --loader ts-node/esm test/bench/run-benchmarks.ts", + "gl-stats": "node --no-warnings --loader ts-node/esm test/bench/gl-stats.ts", "prepare": "npm run codegen", "typecheck": "tsc --noEmit && tsc --project tsconfig.dist.json", "tsnode": "node --experimental-loader=ts-node/esm --no-warnings" diff --git a/src/gl/render_pool.test.ts b/src/gl/render_pool.test.ts index 067b409423..a864c48bf9 100644 --- a/src/gl/render_pool.test.ts +++ b/src/gl/render_pool.test.ts @@ -1,12 +1,13 @@ import {Context} from './context'; import {RenderPool} from './render_pool'; -import gl from 'gl'; describe('render pool', () => { const POOL_SIZE = 3; function createAndFillPool(): RenderPool { - const pool = new RenderPool(new Context(gl(1, 1) as any), POOL_SIZE, 512); + const gl = document.createElement('canvas').getContext('webgl'); + jest.spyOn(gl, 'checkFramebufferStatus').mockReturnValue(gl.FRAMEBUFFER_COMPLETE); + const pool = new RenderPool(new Context(gl), POOL_SIZE, 512); for (let i = 0; i < POOL_SIZE; i++) { pool.useObject(pool.getOrCreateFreeObject()); } @@ -14,7 +15,8 @@ describe('render pool', () => { } test('create pool should not be full', () => { - const pool = new RenderPool(new Context(gl(1, 1) as any), POOL_SIZE, 512); + const gl = document.createElement('canvas').getContext('webgl'); + const pool = new RenderPool(new Context(gl), POOL_SIZE, 512); expect(pool.isFull()).toBeFalsy(); }); diff --git a/src/gl/state.test.ts b/src/gl/state.test.ts index 720fd5c0a5..82037f50fc 100644 --- a/src/gl/state.test.ts +++ b/src/gl/state.test.ts @@ -1,68 +1,56 @@ -import {ClearColor, ClearDepth, ClearStencil, ColorMask, DepthMask, StencilMask, StencilFunc, StencilOp, StencilTest, DepthRange, DepthTest, DepthFunc, Blend, BlendFunc, BlendColor, ProgramValue, ActiveTextureUnit, Viewport, BindFramebuffer, BindRenderbuffer, BindTexture, BindVertexBuffer, BindElementBuffer, BindVertexArray, PixelStoreUnpack, PixelStoreUnpackPremultiplyAlpha} from './value'; +import {IValue, ClearColor, ClearDepth, ClearStencil, ColorMask, DepthMask, StencilMask, StencilFunc, StencilOp, StencilTest, DepthRange, DepthTest, DepthFunc, Blend, BlendFunc, BlendColor, ProgramValue, ActiveTextureUnit, Viewport, BindFramebuffer, BindRenderbuffer, BindTexture, BindVertexBuffer, BindElementBuffer, BindVertexArray, PixelStoreUnpack, PixelStoreUnpackPremultiplyAlpha} from './value'; import {Context} from './context'; import {Color} from '@maplibre/maplibre-gl-style-spec'; import {deepEqual} from '../util/util'; -import gl from 'gl'; -import {setupMockWebGLContext} from '../util/test/mock_webgl'; -const context = new Context(gl(10, 10) as any); +describe('Value classes', () => { -setupMockWebGLContext(context.gl); + const gl = document.createElement('canvas').getContext('webgl') as WebGL2RenderingContext; + // Remove when https://github.com/Adamfsk/jest-webgl-canvas-mock/pull/5 is merged + gl.createVertexArray = gl.getExtension('OES_vertex_array_object')?.createVertexArrayOES; + gl.bindVertexArray = gl.getExtension('OES_vertex_array_object')?.bindVertexArrayOES; + const context = new Context(gl); -const valueTest = (Constructor: new (...args:any[]) => any, options) => { - test('#constructor', () => { - const v = new Constructor(context); - expect(v).toBeTruthy(); - const currentV = v.get(); - expect(typeof currentV).not.toBe('undefined'); - }); - - test('#set', () => { - const v = new Constructor(context); - v.set(options.setValue); - const equality = (options.equality) || ((a, b) => deepEqual(a, b)); - expect(equality(v.get(), options.setValue)).toBeTruthy(); - }); - -}; + const valueTest = (Constructor: new (...args:any[]) => IValue, + options: { + setValue: T; + equality?: (a: T, b: T) => boolean; + } + ) => { + test('#constructor', () => { + const v = new Constructor(context); + expect(v).toBeTruthy(); + const currentV = v.get(); + expect(typeof currentV).not.toBe('undefined'); + }); + + test('#set', () => { + const v = new Constructor(context); + v.set(options.setValue); + const equality = (options.equality) || ((a, b) => deepEqual(a, b)); + expect(equality(v.get(), options.setValue)).toBeTruthy(); + }); + }; -describe('ClearColor', () => { valueTest(ClearColor, { setValue: new Color(1, 1, 0, 1) }); -}); - -describe('ClearDepth', () => { valueTest(ClearDepth, { setValue: 0.5 }); -}); - -describe('ClearStencil', () => { valueTest(ClearStencil, { setValue: 0.5 }); -}); -describe('ColorMask', () => { valueTest(ColorMask, { setValue: [false, false, true, true] }); -}); - -describe('DepthMask', () => { valueTest(DepthMask, { setValue: false }); -}); - -describe('StencilMask', () => { valueTest(StencilMask, { - setValue: [0x00, 4] + setValue: 0x00 }); -}); - -describe('StencilFunc', () => { valueTest(StencilFunc, { setValue: { func: context.gl.LEQUAL, @@ -70,124 +58,67 @@ describe('StencilFunc', () => { mask: 0xFF } }); -}); - -describe('StencilOp', () => { valueTest(StencilOp, { setValue: [context.gl.KEEP, context.gl.REPLACE, context.gl.REPLACE] }); -}); - -describe('StencilTest', () => { valueTest(StencilTest, { setValue: true }); -}); - -describe('DepthRange', () => { valueTest(DepthRange, { setValue: [0, 0.1] }); -}); - -describe('DepthTest', () => { valueTest(DepthTest, { setValue: true }); -}); - -describe('DepthFunc', () => { valueTest(DepthFunc, { setValue: context.gl.EQUAL }); -}); - -describe('Blend', () => { valueTest(Blend, { setValue: false }); -}); - -describe('BlendFunc', () => { valueTest(BlendFunc, { setValue: [context.gl.SRC_ALPHA, context.gl.SRC_ALPHA] }); -}); - -describe('BlendColor', () => { valueTest(BlendColor, { setValue: Color.white }); -}); - -describe('Program', () => { valueTest(ProgramValue, { equality: (a, b) => a === b, setValue: context.gl.createProgram() }); -}); - -describe('ActiveTextureUnit', () => { valueTest(ActiveTextureUnit, { setValue: context.gl.TEXTURE1 }); -}); - -describe('Viewport', () => { valueTest(Viewport, { setValue: [0, 0, 1, 1] }); -}); - -describe('BindFramebuffer', () => { valueTest(BindFramebuffer, { equality: (a, b) => a === b, setValue: context.gl.createFramebuffer() }); -}); - -describe('BindRenderbuffer', () => { valueTest(BindRenderbuffer, { equality: (a, b) => a === b, setValue: context.gl.createRenderbuffer() }); -}); - -describe('BindTexture', () => { valueTest(BindTexture, { equality: (a, b) => a === b, setValue: context.gl.createTexture() }); -}); - -describe('BindVertexBuffer', () => { valueTest(BindVertexBuffer, { equality: (a, b) => a === b, setValue: context.gl.createBuffer() }); -}); - -describe('BindElementBuffer', () => { valueTest(BindElementBuffer, { equality: (a, b) => a === b, setValue: context.gl.createBuffer() }); -}); - -describe('BindVertexArray', () => { valueTest(BindVertexArray, { equality: (a, b) => a === b, setValue: context.createVertexArray() }); -}); - -describe('PixelStoreUnpack', () => { valueTest(PixelStoreUnpack, { setValue: 8 }); -}); - -describe('PixelStoreUnpackPremultiplyAlpha', () => { valueTest(PixelStoreUnpackPremultiplyAlpha, { setValue: true }); diff --git a/src/gl/vertex_buffer.test.ts b/src/gl/vertex_buffer.test.ts index 341bbab05b..e6a2df5082 100644 --- a/src/gl/vertex_buffer.test.ts +++ b/src/gl/vertex_buffer.test.ts @@ -1,10 +1,15 @@ import {VertexBuffer} from './vertex_buffer'; import {StructArrayLayout3i6} from '../data/array_types.g'; import {Context} from '../gl/context'; -import gl from 'gl'; import {StructArrayMember} from '../util/struct_array'; describe('VertexBuffer', () => { + let gl: WebGLRenderingContext; + + beforeEach(() => { + gl = document.createElement('canvas').getContext('webgl'); + }); + class TestArray extends StructArrayLayout3i6 {} const attributes = [ {name: 'map', components: 1, type: 'Int16', offset: 0}, @@ -12,7 +17,7 @@ describe('VertexBuffer', () => { ] as StructArrayMember[]; test('constructs itself', () => { - const context = new Context(gl(10, 10) as any); + const context = new Context(gl); const array = new TestArray(); array.emplaceBack(1, 1, 1); array.emplaceBack(1, 1, 1); @@ -29,7 +34,7 @@ describe('VertexBuffer', () => { }); test('enableAttributes', () => { - const context = new Context(gl(10, 10) as any); + const context = new Context(gl); const array = new TestArray(); const buffer = new VertexBuffer(context, array, attributes); const spy = jest.spyOn(context.gl, 'enableVertexAttribArray').mockImplementation(() => {}); @@ -38,7 +43,7 @@ describe('VertexBuffer', () => { }); test('setVertexAttribPointers', () => { - const context = new Context(gl(10, 10) as any); + const context = new Context(gl); const array = new TestArray(); const buffer = new VertexBuffer(context, array, attributes); const spy = jest.spyOn(context.gl, 'vertexAttribPointer').mockImplementation(() => {}); diff --git a/src/render/render_to_texture.test.ts b/src/render/render_to_texture.test.ts index f53892bd20..fc7e75259c 100644 --- a/src/render/render_to_texture.test.ts +++ b/src/render/render_to_texture.test.ts @@ -3,7 +3,6 @@ import type {Painter} from './painter'; import type {LineStyleLayer} from '../style/style_layer/line_style_layer'; import type {SymbolStyleLayer} from '../style/style_layer/symbol_style_layer'; import {Context} from '../gl/context'; -import gl from 'gl'; import {ColorMode} from '../gl/color_mode'; import {Terrain} from './terrain'; import {Style} from '../style/style'; @@ -18,6 +17,8 @@ import {HillshadeStyleLayer} from '../style/style_layer/hillshade_style_layer'; import {BackgroundStyleLayer} from '../style/style_layer/background_style_layer'; describe('render to texture', () => { + const gl = document.createElement('canvas').getContext('webgl'); + jest.spyOn(gl, 'checkFramebufferStatus').mockReturnValue(gl.FRAMEBUFFER_COMPLETE); const backgroundLayer = { id: 'maine-background', type: 'background', @@ -62,7 +63,7 @@ describe('render to texture', () => { let layersDrawn = 0; const painter = { layersDrawn: 0, - context: new Context(gl(1, 1) as any), + context: new Context(gl), transform: {zoom: 10, calculatePosMatrix: () => {}}, colorModeForRenderPass: () => ColorMode.alphaBlended, useProgram: () => { return {draw: () => { layersDrawn++; }}; }, diff --git a/src/render/terrain.test.ts b/src/render/terrain.test.ts index 7f6ae85ae7..30c0ae2403 100644 --- a/src/render/terrain.test.ts +++ b/src/render/terrain.test.ts @@ -1,9 +1,7 @@ import Point from '@mapbox/point-geometry'; import {Terrain} from './terrain'; -import gl from 'gl'; import {Context} from '../gl/context'; import {RGBAImage} from '../util/image'; -import {Texture} from './texture'; import type {SourceCache} from '../source/source_cache'; import {OverscaledTileID} from '../source/tile_id'; import type {TerrainSpecification} from '@maplibre/maplibre-gl-style-spec'; @@ -14,10 +12,27 @@ import {mat4} from 'gl-matrix'; import {LngLat} from '../geo/lng_lat'; describe('Terrain', () => { + let gl: WebGLRenderingContext; + + beforeEach(() => { + gl = document.createElement('canvas').getContext('webgl'); + jest.spyOn(gl, 'checkFramebufferStatus').mockReturnValue(gl.FRAMEBUFFER_COMPLETE); + jest.spyOn(gl, 'readPixels').mockImplementation((_1, _2, _3, _4, _5, _6, rgba) => { + rgba[0] = 0; + rgba[1] = 0; + rgba[2] = 255; + rgba[3] = 255; + }); + }); + + afterEach(() => { + jest.restoreAllMocks(); + }); + test('pointCoordiate should not return null', () => { expect.assertions(1); const painter = { - context: new Context(gl(1, 1) as any), + context: new Context(gl), width: 1, height: 1, transform: {center: {lng: 0}} @@ -39,12 +54,6 @@ describe('Terrain', () => { }; const terrain = new Terrain(painter, sourceCache, {} as any as TerrainSpecification); terrain.sourceCache.getTileByID = getTileByID; - const context = painter.context as Context; - const pixels = new Uint8Array([0, 0, 255, 255]); - const image = new RGBAImage({width: 1, height: 1}, pixels); - const imageTexture = new Texture(context, image, context.gl.RGBA); - terrain.getFramebuffer('coords'); // allow init of frame buffers - terrain._fboCoordsTexture.texture = imageTexture.texture; terrain.coordsIndex.push('abcd'); const coordinate = terrain.pointCoordinate(new Point(0, 0)); @@ -55,7 +64,7 @@ describe('Terrain', () => { const setupMercatorOverflow = () => { const WORLD_WIDTH = 4; const painter = { - context: new Context(gl(WORLD_WIDTH, 1) as any), + context: new Context(gl), width: WORLD_WIDTH, height: 1, } as any as Painter; @@ -72,11 +81,12 @@ describe('Terrain', () => { }; terrain.getElevation = () => 0; terrain.coordsIndex = Object.keys(tileIdsToWraps); - const pixels = new Uint8Array([0, 0, 0, 255, 0, 0, 0, 254, 0, 0, 0, 253, 0, 0, 0, 252]); - const image = new RGBAImage({width: WORLD_WIDTH, height: 1}, pixels); - const imageTexture = new Texture(painter.context, image, painter.context.gl.RGBA); - terrain.getFramebuffer('coords'); // allow init of frame buffers - terrain._fboCoordsTexture.texture = imageTexture.texture; + jest.spyOn(gl, 'readPixels').mockImplementation((x, _2, _3, _4, _5, _6, rgba) => { + rgba[0] = 0; + rgba[1] = 0; + rgba[2] = 0; + rgba[3] = 255 - x; + }); return terrain; }; @@ -114,7 +124,7 @@ describe('Terrain', () => { getUnpackVector: () => [6553.6, 25.6, 0.1, 10000.0], } as any as DEMData; const painter = { - context: new Context(gl(1, 1) as any), + context: new Context(gl), width: 1, height: 1, getTileTexture: () => null @@ -142,7 +152,7 @@ describe('Terrain', () => { test('Return null elevation values when no tile', () => { const tileID = new OverscaledTileID(5, 0, 5, 17, 11); const painter = { - context: new Context(gl(1, 1) as any), + context: new Context(gl), width: 1, height: 1, getTileTexture: () => null @@ -169,7 +179,7 @@ describe('Terrain', () => { const tile = new Tile(tileID, 256); tile.dem = null as any as DEMData; const painter = { - context: new Context(gl(1, 1) as any), + context: new Context(gl), width: 1, height: 1, getTileTexture: () => null diff --git a/src/ui/control/logo_control.test.ts b/src/ui/control/logo_control.test.ts index 78a1a94888..5dca836eea 100644 --- a/src/ui/control/logo_control.test.ts +++ b/src/ui/control/logo_control.test.ts @@ -20,14 +20,12 @@ beforeEach(() => { }); describe('LogoControl', () => { - test('does not appear by default', done => { + test('does not appear by default', async () => { const map = createMap(undefined, undefined); - map.on('load', () => { - expect(map.getContainer().querySelectorAll( - '.maplibregl-ctrl-logo' - )).toHaveLength(0); - done(); - }); + await map.once('load'); + expect(map.getContainer().querySelectorAll( + '.maplibregl-ctrl-logo' + )).toHaveLength(0); }); test('is not displayed when the maplibreLogo property is false', done => { diff --git a/src/ui/map.test.ts b/src/ui/map.test.ts index da48c360a9..50672e2cfc 100755 --- a/src/ui/map.test.ts +++ b/src/ui/map.test.ts @@ -1,9 +1,9 @@ import {Map, MapOptions} from './map'; -import {createMap, setErrorWebGlContext, beforeMapTest, sleep} from '../util/test/util'; +import {createMap, beforeMapTest, sleep} from '../util/test/util'; import {LngLat} from '../geo/lng_lat'; import {Tile} from '../source/tile'; import {OverscaledTileID} from '../source/tile_id'; -import {Event, ErrorEvent} from '../util/evented'; +import {Event as EventedEvent, ErrorEvent} from '../util/evented'; import simulate from '../../test/unit/lib/simulate_interaction'; import {fixedLngLat, fixedNum} from '../../test/unit/lib/fixed'; import {GeoJSONSourceSpecification, LayerSpecification, SourceSpecification, StyleSpecification} from '@maplibre/maplibre-gl-style-spec'; @@ -248,7 +248,7 @@ describe('Map', () => { }); test('fires *data and *dataloading events', () => { - createMap({}, (error, map) => { + createMap({}, (error, map: Map) => { expect(error).toBeFalsy(); const events = []; @@ -261,12 +261,12 @@ describe('Map', () => { map.on('tiledata', recordEvent); map.on('tiledataloading', recordEvent); - map.style.fire(new Event('data', {dataType: 'style'})); - map.style.fire(new Event('dataloading', {dataType: 'style'})); - map.style.fire(new Event('data', {dataType: 'source'})); - map.style.fire(new Event('dataloading', {dataType: 'source'})); - map.style.fire(new Event('data', {dataType: 'tile'})); - map.style.fire(new Event('dataloading', {dataType: 'tile'})); + map.style.fire(new EventedEvent('data', {dataType: 'style'})); + map.style.fire(new EventedEvent('dataloading', {dataType: 'style'})); + map.style.fire(new EventedEvent('data', {dataType: 'source'})); + map.style.fire(new EventedEvent('dataloading', {dataType: 'source'})); + map.style.fire(new EventedEvent('data', {dataType: 'tile'})); + map.style.fire(new EventedEvent('dataloading', {dataType: 'tile'})); expect(events).toEqual([ 'styledata', @@ -2611,7 +2611,7 @@ describe('Map', () => { test('fires sourcedataabort event on dataabort event', async () => { const map = createMap(); const sourcePromise = map.once('sourcedataabort'); - map.fire(new Event('dataabort')); + map.fire(new EventedEvent('dataabort')); await sourcePromise; }); @@ -2791,7 +2791,15 @@ describe('Map', () => { describe('webgl errors', () => { test('WebGL error while creating map', () => { - setErrorWebGlContext(); + const original = HTMLCanvasElement.prototype.getContext; + HTMLCanvasElement.prototype.getContext = function (type: string) { + if (type === 'webgl2' || type === 'webgl') { + const errorEvent = new Event('webglcontextcreationerror'); + (errorEvent as any).statusMessage = 'mocked webglcontextcreationerror message'; + (this as HTMLCanvasElement).dispatchEvent(errorEvent); + return null; + } + }; try { createMap(); } catch (e) { @@ -2802,8 +2810,9 @@ describe('Map', () => { // this is from test mock expect(errorMessageObject.statusMessage).toBe('mocked webglcontextcreationerror message'); + } finally { + HTMLCanvasElement.prototype.getContext = original; } - }); test('Hit WebGL max drawing buffer limit', () => { // Simulate a device with MAX_TEXTURE_SIZE=16834 and max rendering area of ~32Mpx @@ -2826,6 +2835,8 @@ describe('Map', () => { const container = window.document.createElement('div'); Object.defineProperty(container, 'clientWidth', {value: 2048}); Object.defineProperty(container, 'clientHeight', {value: 2048}); + jest.spyOn(WebGLRenderingContext.prototype, 'drawingBufferWidth', 'get').mockReturnValue(8192); + jest.spyOn(WebGLRenderingContext.prototype, 'drawingBufferHeight', 'get').mockReturnValue(8192); const map = createMap({container, maxCanvasSize: [8192, 8192], pixelRatio: 5}); map.resize(); expect(map.getCanvas().width).toBe(8192); @@ -2836,6 +2847,8 @@ describe('Map', () => { const container = window.document.createElement('div'); Object.defineProperty(container, 'clientWidth', {value: 1024}); Object.defineProperty(container, 'clientHeight', {value: 2048}); + jest.spyOn(WebGLRenderingContext.prototype, 'drawingBufferWidth', 'get').mockReturnValue(8192); + jest.spyOn(WebGLRenderingContext.prototype, 'drawingBufferHeight', 'get').mockReturnValue(4096); const map = createMap({container, maxCanvasSize: [8192, 4096], pixelRatio: 3}); map.resize(); expect(map.getCanvas().width).toBe(2048); @@ -2846,6 +2859,8 @@ describe('Map', () => { const container = window.document.createElement('div'); Object.defineProperty(container, 'clientWidth', {value: 12834}); Object.defineProperty(container, 'clientHeight', {value: 9000}); + jest.spyOn(WebGLRenderingContext.prototype, 'drawingBufferWidth', 'get').mockReturnValue(4096); + jest.spyOn(WebGLRenderingContext.prototype, 'drawingBufferHeight', 'get').mockReturnValue(8192); const map = createMap({container, maxCanvasSize: [4096, 8192], pixelRatio: 1}); map.resize(); expect(map.getCanvas().width).toBe(4096); @@ -2856,6 +2871,8 @@ describe('Map', () => { const container = window.document.createElement('div'); Object.defineProperty(container, 'clientWidth', {value: 2048}); Object.defineProperty(container, 'clientHeight', {value: 2048}); + jest.spyOn(WebGLRenderingContext.prototype, 'drawingBufferWidth', 'get').mockReturnValue(3072); + jest.spyOn(WebGLRenderingContext.prototype, 'drawingBufferHeight', 'get').mockReturnValue(3072); const map = createMap({container, maxCanvasSize: [3072, 3072], pixelRatio: 1.25}); map.resize(); expect(map.getCanvas().width).toBe(2560); diff --git a/src/util/test/mock_webgl.ts b/src/util/test/mock_webgl.ts deleted file mode 100644 index 3559ca2630..0000000000 --- a/src/util/test/mock_webgl.ts +++ /dev/null @@ -1,101 +0,0 @@ -import gl from 'gl'; - -export function setupMockWebGLContext(webglContext: any) { - - const mockVaoExtension = { - bindVertexArrayOES: jest.fn(), - deleteVertexArrayOES: jest.fn(), - createVertexArrayOES: jest.fn(), - }; - - const mockColorBufferExtension = { - RGB16F_EXT: jest.fn(), - }; - - const mockTextureHalfFloatExtension = { - HALF_FLOAT_OES: jest.fn(), - }; - - // Setup getExtension to return the correct mock extension - webglContext.getExtension = jest.fn((extensionName) => { - switch (extensionName) { - case 'OES_vertex_array_object': - return mockVaoExtension; - case 'EXT_color_buffer_half_float': - return mockColorBufferExtension; - case 'OES_texture_half_float': - return mockTextureHalfFloatExtension; - default: - return null; - } - }); - - // Update drawingBufferWidth and drawingBufferHeigth when viewport changes - webglContext.viewport = jest.fn((x, y, width, height) => { - webglContext.drawingBufferWidth = width; - webglContext.drawingBufferHeight = height; - }); - - // Define the properties on the WebGL context - Object.defineProperty(webglContext, 'bindVertexArray', { - get() { - const extension = this.getExtension('OES_vertex_array_object'); - return extension ? extension.bindVertexArrayOES : undefined; - }, - }); - - Object.defineProperty(webglContext, 'RGB16F', { - get() { - const extension = this.getExtension('EXT_color_buffer_half_float'); - return extension ? extension.RGB16F_EXT : undefined; - }, - }); - - Object.defineProperty(webglContext, 'HALF_FLOAT', { - get() { - const extension = this.getExtension('OES_texture_half_float'); - return extension ? extension.HALF_FLOAT_OES : undefined; - }, - }); - - Object.defineProperty(webglContext, 'deleteVertexArray', { - get() { - const extension = this.getExtension('OES_vertex_array_object'); - return extension ? extension.deleteVertexArrayOES : undefined; - }, - }); - - Object.defineProperty(webglContext, 'createVertexArray', { - get() { - const extension = this.getExtension('OES_vertex_array_object'); - return extension ? extension.createVertexArrayOES : undefined; - }, - }); - -} - -// Add webgl context with the supplied GL -export function setWebGlContext() { - const originalGetContext = global.HTMLCanvasElement.prototype.getContext; - - function imitateWebGlGetContext(type, attributes) { - if (type === 'webgl2') { - return null; - } - if (type === 'webgl') { - if (!this._webGLContext) { - this._webGLContext = gl(this.width, this.height, attributes); - if (!this._webGLContext) { - throw new Error('Failed to create a WebGL context'); - } - } - - setupMockWebGLContext(this._webGLContext); - - return this._webGLContext; - } - // Fallback to existing HTMLCanvasElement getContext behaviour - return originalGetContext.call(this, type, attributes); - } - global.HTMLCanvasElement.prototype.getContext = imitateWebGlGetContext; -} diff --git a/src/util/test/util.ts b/src/util/test/util.ts index 75514e39a1..308e64763b 100644 --- a/src/util/test/util.ts +++ b/src/util/test/util.ts @@ -1,7 +1,6 @@ import {Map} from '../../ui/map'; import {extend} from '../../util/util'; import {Dispatcher} from '../../util/dispatcher'; -import {setWebGlContext} from './mock_webgl'; import {IActor} from '../actor'; import type {Evented} from '../evented'; @@ -41,24 +40,6 @@ export function equalWithPrecision(test, expected, actual, multiplier, message, return test.equal(expectedRounded, actualRounded, message, extra); } -// mock failed webgl context by dispatching "webglcontextcreationerror" event -// and returning null -export function setErrorWebGlContext() { - const originalGetContext = global.HTMLCanvasElement.prototype.getContext; - - function imitateErrorWebGlGetContext(type, attributes) { - if (type === 'webgl2' || type === 'webgl') { - const errorEvent = new Event('webglcontextcreationerror'); - (errorEvent as any).statusMessage = 'mocked webglcontextcreationerror message'; - this.dispatchEvent(errorEvent); - return null; - } - // Fallback to existing HTMLCanvasElement getContext behaviour - return originalGetContext.call(this, type, attributes); - } - global.HTMLCanvasElement.prototype.getContext = imitateErrorWebGlGetContext; -} - export function setPerformance() { window.performance.mark = jest.fn(); window.performance.clearMeasures = jest.fn(); @@ -92,9 +73,21 @@ function setResizeObserver() { export function beforeMapTest() { setPerformance(); - setWebGlContext(); setMatchMedia(); setResizeObserver(); + // remove the following when the following is merged and released: https://github.com/Adamfsk/jest-webgl-canvas-mock/pull/5 + (WebGLRenderingContext.prototype as any).bindVertexArray = WebGLRenderingContext.prototype.getExtension('OES_vertex_array_object').bindVertexArrayOES; + (WebGLRenderingContext.prototype as any).createVertexArray = WebGLRenderingContext.prototype.getExtension('OES_vertex_array_object').createVertexArrayOES; + if (!WebGLRenderingContext.prototype.drawingBufferHeight && !WebGLRenderingContext.prototype.drawingBufferWidth) { + Object.defineProperty(WebGLRenderingContext.prototype, 'drawingBufferWidth', { + get: jest.fn(), + configurable: true, + }); + Object.defineProperty(WebGLRenderingContext.prototype, 'drawingBufferHeight', { + get: jest.fn(), + configurable: true, + }); + } } export function getWrapDispatcher() {