diff --git a/build/rollup_plugins.js b/build/rollup_plugins.js index 844f7091e1..664ad1c672 100644 --- a/build/rollup_plugins.js +++ b/build/rollup_plugins.js @@ -5,7 +5,7 @@ import commonjs from '@rollup/plugin-commonjs'; import unassert from 'rollup-plugin-unassert'; import json from '@rollup/plugin-json'; import {terser} from 'rollup-plugin-terser'; -import minifyStyleSpec from './rollup_plugin_minify_style_spec'; +import minifyStyleSpec from './rollup_plugin_minify_style_spec.js'; import strip from '@rollup/plugin-strip'; // Common set of plugins/transformations shared across different rollup diff --git a/build/test/build-tape.js b/build/test/build-tape.js index 78f11d8d1e..81345061ee 100644 --- a/build/test/build-tape.js +++ b/build/test/build-tape.js @@ -1,11 +1,9 @@ -/* eslint-disable import/no-commonjs */ -/* eslint-disable flowtype/require-valid-file-annotation */ -const browserify = require('browserify'); -const fs = require('fs'); +import browserify from 'browserify'; +import fs from 'fs'; -module.exports = function() { +export default function() { return new Promise((resolve, reject) => { - browserify(require.resolve('../../test/util/tape_config.js'), { standalone: 'tape' }) + browserify('./test/util/tape_config.js', { standalone: 'tape' }) .transform("babelify", {presets: ["@babel/preset-env"], global: true}) .bundle((err, buff) => { if (err) { throw err; } diff --git a/package.json b/package.json index fa774ea5af..200f5a8f45 100644 --- a/package.json +++ b/package.json @@ -194,8 +194,8 @@ "test-browser": "tap --node-arg --no-warnings --node-arg --experimental-specifier-resolution=node --node-arg --experimental-json-modules --reporter classic --no-coverage test/browser/**/*.test.js", "test-render": "node --experimental-specifier-resolution=node --experimental-json-modules --max-old-space-size=2048 test/render.test.js", "test-query-node": "node --experimental-specifier-resolution=node --experimental-json-modules test/query.test.js", - "watch-query": "testem -f test/integration/testem.js", - "test-query": "testem ci -f test/integration/testem.js -R xunit > test/integration/query-tests/test-results.xml", + "watch-query": "testem -f test/integration/testem.cjs", + "test-query": "testem ci -f test/integration/testem.cjs -R xunit > test/integration/query-tests/test-results.xml", "test-expressions": "node --experimental-specifier-resolution=node test/expression.test.js", "test-cov": "nyc --reporter=text-summary --reporter=lcov --cache run-s test-unit test-expressions test-query test-render", "prepublishOnly": "run-s prepare-publish build-dev build-prod-min build-prod build-csp build-css build-style-spec test-build diff-tarball", diff --git a/rollup.config.js b/rollup.config.js index 9cf8ce2afd..770e8b265f 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,7 +1,7 @@ import fs from 'fs'; import sourcemaps from 'rollup-plugin-sourcemaps'; -import {plugins} from './build/rollup_plugins'; -import banner from './build/banner'; +import {plugins} from './build/rollup_plugins.js'; +import banner from './build/banner.js'; const {BUILD, MINIFY} = process.env; const minified = MINIFY === 'true'; @@ -40,7 +40,7 @@ export default [{ format: 'umd', sourcemap: production ? true : 'inline', indent: false, - intro: fs.readFileSync(require.resolve('./rollup/bundle_prelude.js'), 'utf8'), + intro: fs.readFileSync('./rollup/bundle_prelude.js', 'utf8'), banner }, treeshake: false, diff --git a/test/integration/lib/generate-fixture-json.js b/test/integration/lib/generate-fixture-json.js index b4bf77377f..17af524bcc 100644 --- a/test/integration/lib/generate-fixture-json.js +++ b/test/integration/lib/generate-fixture-json.js @@ -1,13 +1,14 @@ -/* eslint-disable import/no-commonjs */ -const path = require('path'); -const fs = require('fs'); -const glob = require('glob'); -const localizeURLs = require('./localize-urls'); +import path from 'path'; +import fs from 'fs'; +import glob from 'glob'; +import localizeURLs from './localize-urls.js'; const OUTPUT_FILE = 'fixtures.json'; -exports.generateFixtureJson = generateFixtureJson; -exports.getAllFixtureGlobs = getAllFixtureGlobs; +export default { + generateFixtureJson: generateFixtureJson, + getAllFixtureGlobs: getAllFixtureGlobs +} /** * Analyzes the contents of the specified `path.join(rootDirectory, suiteDirectory)`, and inlines diff --git a/test/integration/lib/localize-urls.js b/test/integration/lib/localize-urls.js index 39a6fcb018..8556761144 100644 --- a/test/integration/lib/localize-urls.js +++ b/test/integration/lib/localize-urls.js @@ -50,23 +50,23 @@ export default function localizeURLs(style, port) { }; function localizeURL(url, port) { - return url.replace(/^local:\/\//, `test://localhost:${port}/`); + return url.replace(/^local:\/\//, `http://localhost:${port}/`); } function localizeMapboxSpriteURL(url, port) { - return url.replace(/^mapbox:\/\//, `test://localhost:${port}/`); + return url.replace(/^mapbox:\/\//, `http://localhost:${port}/`); } function localizeMapboxFontsURL(url, port) { - return url.replace(/^mapbox:\/\/fonts/, `test://localhost:${port}/glyphs`); + return url.replace(/^mapbox:\/\/fonts/, `http://localhost:${port}/glyphs`); } function localizeMapboxTilesURL(url, port) { - return url.replace(/^mapbox:\/\//, `test://localhost:${port}/tiles/`); + return url.replace(/^mapbox:\/\//, `http://localhost:${port}/tiles/`); } function localizeMapboxTilesetURL(url, port) { - return url.replace(/^mapbox:\/\//, `test://localhost:${port}/tilesets/`); + return url.replace(/^mapbox:\/\//, `http://localhost:${port}/tilesets/`); } function localizeSourceURLs(source, port) { diff --git a/test/integration/lib/server.js b/test/integration/lib/server.js index bfa28bcd14..f4ab33875d 100644 --- a/test/integration/lib/server.js +++ b/test/integration/lib/server.js @@ -2,7 +2,7 @@ import path, {dirname} from 'path'; import fs from 'fs'; import st from 'st'; import {createServer} from 'http'; -import localizeURLs from './localize-urls'; +import localizeURLs from './localize-urls.js'; import { fileURLToPath } from 'url'; import { createRequire } from 'module'; diff --git a/test/integration/rollup.config.test.js b/test/integration/rollup.config.test.js index 668ef4e013..f3dbf92b03 100644 --- a/test/integration/rollup.config.test.js +++ b/test/integration/rollup.config.test.js @@ -1,4 +1,4 @@ -import {plugins} from '../../build/rollup_plugins'; +import {plugins} from '../../build/rollup_plugins.js'; export default { input: 'test/integration/lib/query-browser.js', diff --git a/test/integration/testem.js b/test/integration/testem.cjs similarity index 75% rename from test/integration/testem.js rename to test/integration/testem.cjs index 777c010a23..d41cf750a4 100644 --- a/test/integration/testem.js +++ b/test/integration/testem.cjs @@ -1,16 +1,8 @@ -/* eslint-disable no-global-assign */ -/* eslint-disable import/no-commonjs */ -/* eslint-disable flowtype/require-valid-file-annotation */ -require = require("esm")(module); -const {generateFixtureJson, getAllFixtureGlobs} = require('./lib/generate-fixture-json'); -const createServer = require('./lib/server'); -const buildTape = require('../../build/test/build-tape'); const runAll = require('npm-run-all'); const chokidar = require('chokidar'); const rollup = require('rollup'); const notifier = require('node-notifier'); -const rollupDevConfig = require('../../rollup.config').default; -const rollupTestConfig = require('./rollup.config.test').default; +let generateFixtureJson, getAllFixtureGlobs, buildTape, rollupDevConfig, rollupTestConfig, createServer const rootFixturePath = 'test/integration/'; const suitePath = 'query-tests'; @@ -22,21 +14,31 @@ let server; let fixtureWatcher; const rollupWatchers = {}; -module.exports = { - "test_page": "test/integration/testem_page.html", - "src_files": [ +async function loadEs6StyleFiles() { + let importGenerate = (await import('./lib/generate-fixture-json.js')).default; + generateFixtureJson = importGenerate.generateFixtureJson; + getAllFixtureGlobs = importGenerate.getAllFixtureGlobs; + buildTape = (await import('../../build/test/build-tape.js')).default; + rollupDevConfig = (await import('../../rollup.config.js')).default; + rollupTestConfig = (await import('./rollup.config.test.js')).default; + createServer = (await import('./lib/server.js')).default; +} + +module.exports = { + test_page: "test/integration/testem_page.html", + src_files: [ "dist/maplibre-gl-dev.js", "test/integration/dist/query-test.js" ], - "launch_in_dev": [], - "launch_in_ci": [ "Chrome" ], - "browser_args": { - "Chrome": { - "mode": "ci", - "args": [ "--headless", "--disable-gpu", "--remote-debugging-port=9222" ] + launch_in_dev: [], + launch_in_ci: [ "Chrome" ], + browser_args: { + Chrome: { + mode: "ci", + args: [ "--headless", "--disable-gpu", "--remote-debugging-port=9222" ] } }, - "proxies": { + proxies: { "/tiles":{ "target": "http://localhost:2900" }, @@ -56,20 +58,21 @@ module.exports = { "target": "http://localhost:2900" } }, - "before_tests"(config, data, callback) { + before_tests(config, data, callback) { if (!beforeHookInvoked) { - server = createServer(); - const buildPromise = config.appMode === 'ci' ? buildArtifactsCi() : buildArtifactsDev(); - buildPromise.then(() => { - server.listen(callback); - }).catch((e) => { - callback(e); + loadEs6StyleFiles().then(() => { + server = createServer(); + const buildPromise = config.appMode === 'ci' ? buildArtifactsCi() : buildArtifactsDev(); + buildPromise.then(() => { + server.listen(callback); + }).catch((e) => { + callback(e); + }); + beforeHookInvoked = true; }); - - beforeHookInvoked = true; } }, - "after_tests"(config, data, callback) { + after_tests(config, data, callback) { if (config.appMode === 'ci') { server.close(callback); } diff --git a/test/stub_loader.js b/test/stub_loader.js index dda5c268d0..108c49c06b 100644 --- a/test/stub_loader.js +++ b/test/stub_loader.js @@ -28,6 +28,11 @@ global.removeEventListener = window.removeEventListener; global.matchMedia = window.matchMedia; global.caches = window.caches; global.WheelEvent = window.WheelEvent; +global.Blob = window.Blob; +global.URL = window.URL; +global.fetch = window.fetch; +global.document = window.document; +global.window = window; // stubbing image load as it is not implemented in jsdom // eslint-disable-next-line accessor-pairs Object.defineProperty(global.Image.prototype, 'src', { @@ -35,6 +40,18 @@ Object.defineProperty(global.Image.prototype, 'src', { if (!this.onload) { return; } + if (src.startsWith('data:image/png')) { + let base64 = src.replace(/data:.*;base64,/, ''); + let buff = Buffer.from(base64, 'base64'); + new PNG().parse(buff, (err, png) => { + if (err) throw new Error("Couldn't parse PNG"); + this.data = png.data; + this.height = png.height; + this.width = png.width; + this.onload(); + }); + return; + } if (src && typeof src === 'string' && !src.startsWith('blob')) { this.onload(); return; @@ -62,11 +79,7 @@ Object.defineProperty(global.Image.prototype, 'src', { reader.readAsArrayBuffer(lastDataFromUrl); } }); -global.Blob = window.Blob; -global.URL = window.URL; -global.fetch = window.fetch; -global.document = window.document; -global.window = window; + // Delete local and session storage from JSDOM and stub them out with a warning log // Accessing these properties during extend() produces an error in Node environments diff --git a/test/suite_implementation.js b/test/suite_implementation.js index 7476c08b8d..f10551ea7f 100644 --- a/test/suite_implementation.js +++ b/test/suite_implementation.js @@ -26,7 +26,13 @@ rtlTextPlugin['processBidirectionalText'] = rtlText.processBidirectionalText; rtlTextPlugin['processStyledBidirectionalText'] = rtlText.processStyledBidirectionalText; // replacing the browser method of get image in order to avoid usage of context and canvas 2d with Image object... -browser.getImageData = function({width, height, data}, padding = 0) { +browser.getImageData = function (img, padding = 0) { + if (!img.data) { + return {width: 1, height: 1, data: new Uint8Array(1)} + } + let width = img.width; + let height = img.height; + let data = img.data; const source = new Uint8Array(data); const dest = new Uint8Array((2 * padding + width) * (2 * padding + height) * 4); @@ -53,10 +59,20 @@ export default function(style, options, _callback) { } window.devicePixelRatio = options.pixelRatio; - - maplibregl.addProtocol('test', (req, callback) => { - handleProtocolRequest(req, callback); - }) + window.useFakeXMLHttpRequest(); + XMLHttpRequest.onCreate = req => { + setTimeout(() => { + let reqObj = req.url + if (req.responseType == 'arraybuffer') { + reqObj = { url: req.url, encoding: null } + } + request(reqObj, (error, response, body) => { + req.setStatus(response.statusCode); + req.response = body; + req.onload(); + }); + }, 0); + } if (options.addFakeCanvas) { const fakeCanvas = createFakeCanvas(window.document, options.addFakeCanvas.id, options.addFakeCanvas.image); @@ -227,43 +243,3 @@ function updateFakeCanvas(document, id, imagePath) { fakeCanvas.data = image.data; } -function handleProtocolRequest(req, callback) { - const getJSON = function({url}, callback) { - if (cache[url]) return cached(cache[url], callback); - return request(url, (error, response, body) => { - if (!error && response.statusCode >= 200 && response.statusCode < 300) { - let data; - try { - body = body.replace('http', 'test'); - data = JSON.parse(body); - } catch (err) { - return callback(err); - } - cache[url] = data; - callback(null, data); - } else { - callback(error || new Error(response.statusCode)); - } - }); - }; - - const getArrayBuffer = function({url}, callback) { - if (cache[url]) return cached(cache[url], callback); - return request({url, encoding: null}, (error, response, body) => { - if (!error && response.statusCode >= 200 && response.statusCode < 300) { - cache[url] = body; - callback(null, body); - } else { - if (!error) error = {status: +response.statusCode}; - callback(error); - } - }); - }; - - req.url = req.url.replace('test', 'http'); - if (req.type === 'json') { - getJSON(req, callback); - } else { - getArrayBuffer(req, callback) - } -} \ No newline at end of file