Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Core: Always define globalThis.QUnit #1771

Merged
merged 1 commit into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@
"sourceType": "script"
},
"env": {
"es2020": true,
"node": true
},
"rules": {
Expand All @@ -109,11 +110,11 @@
{
"files": ["test/cli/**"],
"env": {
"es2017": true,
"es2020": true,
"node": true
},
"parserOptions": {
"ecmaVersion": 2018
"ecmaVersion": 2020
},
"rules": {
"compat/compat": "off"
Expand Down
21 changes: 10 additions & 11 deletions build/tasks/test-on-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,24 @@ module.exports = function (grunt) {
grunt.log.ok(`Ran ${totals.files} files`);
}

// Refresh the QUnit global to be used in other tests
global.QUnit = requireFresh('../../qunit/qunit.js');

done(!totals.failed);
});

function requireFresh (path) {
let resolvedPath = require.resolve(path);
function requireFreshQUnit () {
// Resolve current QUnit path and remove it from the require cache
// to avoid stacking the QUnit logs.
const path = '../../qunit/qunit.js';
const resolvedPath = require.resolve(path);
delete require.cache[resolvedPath];

// Clear any QUnit global from a previous test
delete globalThis.QUnit;

return require(path);
}

async function runQUnit (file) {
// Resolve current QUnit path and remove it from the require cache
// to avoid stacking the QUnit logs.
let QUnit = requireFresh('../../qunit/qunit.js');

// Expose QUnit to the global scope to be seen on the other tests.
global.QUnit = QUnit;
const QUnit = requireFreshQUnit();

QUnit.config.autostart = false;
await import('../../' + file);
Expand Down
12 changes: 4 additions & 8 deletions src/cli/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ async function run (args, options) {

const files = utils.getFilesFromArgs(args);

QUnit = requireQUnit();
// Replace any previous instance, e.g. in watch mode
QUnit = globalThis.QUnit = requireQUnit();

if (options.filter) {
QUnit.config.filter = options.filter;
Expand All @@ -65,10 +66,6 @@ async function run (args, options) {
console.log(`Running tests with seed: ${QUnit.config.seed}`);
}

// TODO: Enable mode where QUnit is not auto-injected, but other setup is
// still done automatically.
global.QUnit = QUnit;

options.requires.forEach(requireFromCWD);

findReporter(options.reporter, QUnit.reporters).init(QUnit);
Expand Down Expand Up @@ -177,7 +174,7 @@ function abort (callback) {
process.off('exit', onExit);
running = false;

delete global.QUnit;
delete globalThis.QUnit;
QUnit = null;
if (callback) {
callback();
Expand All @@ -192,8 +189,7 @@ run.watch = function watch (args, options) {
const watch = require('node-watch');
const baseDir = process.cwd();

QUnit = requireQUnit();
global.QUnit = QUnit;
requireQUnit();
options.requires.forEach(requireFromCWD);

// Include TypeScript when in use (automatically via require.extensions),
Expand Down
39 changes: 25 additions & 14 deletions src/core/export.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,29 @@
/* global module, exports */
import { window, document, globalThis } from './globals.js';

/**
* Available exports:
*
* globalThis:
* - browser (globalThis === window)
* - Web Worker (globalThis === self)
* - Node.js
* - SpiderMonkey (mozjs)
* - Rhino 7.14+
* - any other embedded JS engine
*
* CommonJS module.exports (commonjs2):
* - Node.js
*
* CommonJS exports (commonjs, https://wiki.commonjs.org/wiki/Modules):
* - Rhino
*/
export default function exportQUnit (QUnit) {
let exportedModule = false;

if (window && document) {
// QUnit may be defined when it is preconfigured but then only QUnit and QUnit.config may be defined.
if (window.QUnit && window.QUnit.version) {
if (globalThis.QUnit && globalThis.QUnit.version) {
throw new Error('QUnit has already been defined.');
}

window.QUnit = QUnit;

exportedModule = true;
}

// For Node.js
Expand All @@ -21,20 +32,20 @@ export default function exportQUnit (QUnit) {

// For consistency with CommonJS environments' exports
module.exports.QUnit = QUnit;

exportedModule = true;
}

// For CommonJS with exports, but without module.exports, like Rhino
if (typeof exports !== 'undefined' && exports) {
exports.QUnit = QUnit;

exportedModule = true;
}

// For other environments, including Web Workers (globalThis === self),
// SpiderMonkey (mozjs), and other embedded JavaScript engines
if (!exportedModule) {
// Ensure the global is available in all environments.
//
// For backward compatibility, we only enforce load-once in browsers above.
// In other environments QUnit is accessible via import/require() and may
// load multiple times. Callers may decide whether their secondary instance
// should be global or not.
if (!globalThis.QUnit || !globalThis.QUnit.version) {
globalThis.QUnit = QUnit;
}
}
2 changes: 1 addition & 1 deletion test/benchmark/micro.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-env node */

global.QUnit = require('qunit');
require('qunit');
require('./micro-fixture.js');
require('./micro-bench.js');
6 changes: 3 additions & 3 deletions test/cli/fixtures/inception.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const outerQUnit = global.QUnit;
delete global.QUnit;
const outerQUnit = globalThis.QUnit;
delete globalThis.QUnit;
const myQUnit = require('../../../src/cli/require-qunit')();
global.QUnit = outerQUnit;
globalThis.QUnit = outerQUnit;

const data = [];
myQUnit.on('runStart', function () {
Expand Down