diff --git a/test/.eslintrc.yaml b/test/.eslintrc.yaml index 49c55de6b8ad0c..8eee5f39958dbe 100644 --- a/test/.eslintrc.yaml +++ b/test/.eslintrc.yaml @@ -22,6 +22,7 @@ rules: node-core/number-isnan: error ## common module is mandatory in tests node-core/required-modules: [error, common] + node-core/require-common-first: error node-core/no-duplicate-requires: off # Global scoped methods and vars diff --git a/test/async-hooks/hook-checks.js b/test/async-hooks/hook-checks.js index 44970378131c4a..ba3a8d2d1d52b2 100644 --- a/test/async-hooks/hook-checks.js +++ b/test/async-hooks/hook-checks.js @@ -1,6 +1,6 @@ 'use strict'; -const assert = require('assert'); require('../common'); +const assert = require('assert'); /** * Checks the expected invocations against the invocations that actually diff --git a/test/async-hooks/verify-graph.js b/test/async-hooks/verify-graph.js index 99b32e908165cd..54d6ed8ea9ade0 100644 --- a/test/async-hooks/verify-graph.js +++ b/test/async-hooks/verify-graph.js @@ -1,8 +1,8 @@ 'use strict'; +require('../common'); const assert = require('assert'); const util = require('util'); -require('../common'); function findInGraph(graph, type, n) { let found = 0; diff --git a/test/common/README.md b/test/common/README.md index 391b753f0481df..664b42aca3e66c 100644 --- a/test/common/README.md +++ b/test/common/README.md @@ -386,7 +386,7 @@ thread. The `ArrayStream` module provides a simple `Stream` that pushes elements from a given array. - + ```js const ArrayStream = require('../common/arraystream'); const stream = new ArrayStream(); @@ -402,7 +402,7 @@ require a particular action to be taken after a given number of completed tasks (for instance, shutting down an HTTP server after a specific number of requests). The Countdown will fail the test if the remainder did not reach 0. - + ```js const Countdown = require('../common/countdown'); @@ -574,7 +574,7 @@ one listed below. (`heap.validateSnapshotNodes(...)` is a shortcut for Create a heap dump and an embedder graph copy and validate occurrences. - + ```js validateSnapshotNodes('TLSWRAP', [ { @@ -592,7 +592,7 @@ validateSnapshotNodes('TLSWRAP', [ The `hijackstdio` module provides utility functions for temporarily redirecting `stdout` and `stderr` output. - + ```js const { hijackStdout, restoreStdout } = require('../common/hijackstdio'); @@ -638,7 +638,7 @@ original state after calling [`hijackstdio.hijackStdOut()`][]. The http2.js module provides a handful of utilities for creating mock HTTP/2 frames for testing of HTTP/2 endpoints - + ```js const http2 = require('../common/http2'); ``` @@ -648,7 +648,7 @@ const http2 = require('../common/http2'); The `http2.Frame` is a base class that creates a `Buffer` containing a serialized HTTP/2 frame header. - + ```js // length is a 24-bit unsigned integer // type is an 8-bit unsigned integer identifying the frame type @@ -667,7 +667,7 @@ The serialized `Buffer` may be retrieved using the `frame.data` property. The `http2.DataFrame` is a subclass of `http2.Frame` that serializes a `DATA` frame. - + ```js // id is the 32-bit stream identifier // payload is a Buffer containing the DATA payload @@ -684,7 +684,7 @@ socket.write(frame.data); The `http2.HeadersFrame` is a subclass of `http2.Frame` that serializes a `HEADERS` frame. - + ```js // id is the 32-bit stream identifier // payload is a Buffer containing the HEADERS payload (see either @@ -702,7 +702,7 @@ socket.write(frame.data); The `http2.SettingsFrame` is a subclass of `http2.Frame` that serializes an empty `SETTINGS` frame. - + ```js // ack is a boolean indicating whether or not to set the ACK flag. const frame = new http2.SettingsFrame(ack); @@ -715,7 +715,7 @@ socket.write(frame.data); Set to a `Buffer` instance that contains a minimal set of serialized HTTP/2 request headers to be used as the payload of a `http2.HeadersFrame`. - + ```js const frame = new http2.HeadersFrame(1, http2.kFakeRequestHeaders, 0, true); @@ -727,7 +727,7 @@ socket.write(frame.data); Set to a `Buffer` instance that contains a minimal set of serialized HTTP/2 response headers to be used as the payload a `http2.HeadersFrame`. - + ```js const frame = new http2.HeadersFrame(1, http2.kFakeResponseHeaders, 0, true); @@ -739,7 +739,7 @@ socket.write(frame.data); Set to a `Buffer` containing the preamble bytes an HTTP/2 client must send upon initial establishment of a connection. - + ```js socket.write(http2.kClientMagic); ``` diff --git a/test/common/arraystream.js b/test/common/arraystream.js index 9c497fcd9b40da..408d57712c73ef 100644 --- a/test/common/arraystream.js +++ b/test/common/arraystream.js @@ -1,4 +1,4 @@ -/* eslint-disable node-core/required-modules */ +/* eslint-disable node-core/require-common-first, node-core/required-modules */ 'use strict'; const { Stream } = require('stream'); diff --git a/test/common/benchmark.js b/test/common/benchmark.js index 0894146c4d1443..bb182fc6887636 100644 --- a/test/common/benchmark.js +++ b/test/common/benchmark.js @@ -1,4 +1,4 @@ -/* eslint-disable node-core/required-modules */ +/* eslint-disable node-core/require-common-first, node-core/required-modules */ 'use strict'; diff --git a/test/common/countdown.js b/test/common/countdown.js index 67252657ec28b7..31507b61257633 100644 --- a/test/common/countdown.js +++ b/test/common/countdown.js @@ -1,4 +1,4 @@ -/* eslint-disable node-core/required-modules */ +/* eslint-disable node-core/require-common-first, node-core/required-modules */ 'use strict'; diff --git a/test/common/dns.js b/test/common/dns.js index 01245c33d6997c..37f80dde02782c 100644 --- a/test/common/dns.js +++ b/test/common/dns.js @@ -1,4 +1,4 @@ -/* eslint-disable node-core/required-modules */ +/* eslint-disable node-core/require-common-first, node-core/required-modules */ 'use strict'; const assert = require('assert'); diff --git a/test/common/duplexpair.js b/test/common/duplexpair.js index fb4faca5483b76..0783aeb861100e 100644 --- a/test/common/duplexpair.js +++ b/test/common/duplexpair.js @@ -1,4 +1,4 @@ -/* eslint-disable node-core/required-modules */ +/* eslint-disable node-core/require-common-first, node-core/required-modules */ 'use strict'; const { Duplex } = require('stream'); const assert = require('assert'); diff --git a/test/common/fixtures.js b/test/common/fixtures.js index b45e5bc8091865..2390ee8284e421 100644 --- a/test/common/fixtures.js +++ b/test/common/fixtures.js @@ -1,4 +1,4 @@ -/* eslint-disable node-core/required-modules */ +/* eslint-disable node-core/require-common-first, node-core/required-modules */ 'use strict'; const path = require('path'); diff --git a/test/common/heap.js b/test/common/heap.js index 97686e05a7fccf..030ea773404d14 100644 --- a/test/common/heap.js +++ b/test/common/heap.js @@ -1,4 +1,4 @@ -/* eslint-disable node-core/required-modules */ +/* eslint-disable node-core/require-common-first, node-core/required-modules */ 'use strict'; const assert = require('assert'); const util = require('util'); diff --git a/test/common/hijackstdio.js b/test/common/hijackstdio.js index fcc98208f0ec8c..6995f6665891d3 100644 --- a/test/common/hijackstdio.js +++ b/test/common/hijackstdio.js @@ -1,4 +1,4 @@ -/* eslint-disable node-core/required-modules */ +/* eslint-disable node-core/require-common-first, node-core/required-modules */ 'use strict'; // Hijack stdout and stderr diff --git a/test/common/http2.js b/test/common/http2.js index f84a66861755b9..c4d430d1d93f98 100644 --- a/test/common/http2.js +++ b/test/common/http2.js @@ -1,4 +1,4 @@ -/* eslint-disable node-core/required-modules */ +/* eslint-disable node-core/require-common-first, node-core/required-modules */ 'use strict'; // An HTTP/2 testing tool used to create mock frames for direct testing diff --git a/test/common/index.js b/test/common/index.js index 02fe9039dd855b..32353621662827 100644 --- a/test/common/index.js +++ b/test/common/index.js @@ -19,7 +19,8 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. -/* eslint-disable node-core/required-modules, node-core/crypto-check */ +/* eslint-disable node-core/require-common-first, node-core/required-modules */ +/* eslint-disable node-core/crypto-check */ 'use strict'; const process = global.process; // Some tests tamper with the process global. const path = require('path'); diff --git a/test/common/index.mjs b/test/common/index.mjs index 41592098eb50d5..47587044020fcc 100644 --- a/test/common/index.mjs +++ b/test/common/index.mjs @@ -1,5 +1,5 @@ // Flags: --experimental-modules -/* eslint-disable node-core/required-modules */ +/* eslint-disable node-core/require-common-first, node-core/required-modules */ import { createRequireFromPath } from 'module'; import { fileURLToPath as toPath } from 'url'; diff --git a/test/common/internet.js b/test/common/internet.js index 3880aa114e3743..88153960f0d59c 100644 --- a/test/common/internet.js +++ b/test/common/internet.js @@ -1,4 +1,4 @@ -/* eslint-disable node-core/required-modules */ +/* eslint-disable node-core/require-common-first, node-core/required-modules */ 'use strict'; // Utilities for internet-related tests diff --git a/test/common/report.js b/test/common/report.js index f97cf10669cada..163daf286ef7c9 100644 --- a/test/common/report.js +++ b/test/common/report.js @@ -1,4 +1,4 @@ -/* eslint-disable node-core/required-modules */ +/* eslint-disable node-core/require-common-first, node-core/required-modules */ 'use strict'; const assert = require('assert'); const fs = require('fs'); diff --git a/test/common/tls.js b/test/common/tls.js index 3560af671bce25..e7cacde7456707 100644 --- a/test/common/tls.js +++ b/test/common/tls.js @@ -1,4 +1,5 @@ -/* eslint-disable node-core/required-modules, node-core/crypto-check */ +/* eslint-disable node-core/require-common-first, node-core/required-modules */ +/* eslint-disable node-core/crypto-check */ 'use strict'; const crypto = require('crypto'); diff --git a/test/common/tmpdir.js b/test/common/tmpdir.js index ca761b7f94a642..369c49019aa436 100644 --- a/test/common/tmpdir.js +++ b/test/common/tmpdir.js @@ -1,4 +1,4 @@ -/* eslint-disable node-core/required-modules */ +/* eslint-disable node-core/require-common-first, node-core/required-modules */ 'use strict'; const fs = require('fs'); diff --git a/test/common/wpt.js b/test/common/wpt.js index 5592ddfd4aed16..60be82564bf229 100644 --- a/test/common/wpt.js +++ b/test/common/wpt.js @@ -1,4 +1,4 @@ -/* eslint-disable node-core/required-modules */ +/* eslint-disable node-core/require-common-first, node-core/required-modules */ 'use strict'; const assert = require('assert'); diff --git a/test/es-module/test-esm-example-loader.js b/test/es-module/test-esm-example-loader.js index 0b0001acea2b55..c3ba95f2280857 100644 --- a/test/es-module/test-esm-example-loader.js +++ b/test/es-module/test-esm-example-loader.js @@ -1,5 +1,5 @@ // Flags: --experimental-modules --loader ./test/fixtures/es-module-loaders/example-loader.mjs -/* eslint-disable node-core/required-modules */ +/* eslint-disable node-core/require-common-first, node-core/required-modules */ import assert from 'assert'; import ok from '../fixtures/es-modules/test-esm-ok.mjs'; diff --git a/test/es-module/test-esm-loader-dependency.mjs b/test/es-module/test-esm-loader-dependency.mjs index 1ed8685a6f26ec..9cb2856009618a 100644 --- a/test/es-module/test-esm-loader-dependency.mjs +++ b/test/es-module/test-esm-loader-dependency.mjs @@ -1,5 +1,5 @@ // Flags: --experimental-modules --loader ./test/fixtures/es-module-loaders/loader-with-dep.mjs -/* eslint-disable node-core/required-modules */ +/* eslint-disable node-core/require-common-first, node-core/required-modules */ import '../fixtures/es-modules/test-esm-ok.mjs'; // We just test that this module doesn't fail loading diff --git a/test/es-module/test-esm-preserve-symlinks-not-found-plain.mjs b/test/es-module/test-esm-preserve-symlinks-not-found-plain.mjs index 2ca0f5658119e9..b9b2860dffa069 100644 --- a/test/es-module/test-esm-preserve-symlinks-not-found-plain.mjs +++ b/test/es-module/test-esm-preserve-symlinks-not-found-plain.mjs @@ -1,3 +1,3 @@ // Flags: --experimental-modules --loader ./test/fixtures/es-module-loaders/not-found-assert-loader.mjs -/* eslint-disable node-core/required-modules */ +/* eslint-disable node-core/require-common-first, node-core/required-modules */ import './not-found.js'; diff --git a/test/es-module/test-esm-preserve-symlinks-not-found.mjs b/test/es-module/test-esm-preserve-symlinks-not-found.mjs index b5be2d7e63b54f..1dbdfa03e69139 100644 --- a/test/es-module/test-esm-preserve-symlinks-not-found.mjs +++ b/test/es-module/test-esm-preserve-symlinks-not-found.mjs @@ -1,3 +1,3 @@ // Flags: --experimental-modules --loader ./test/fixtures/es-module-loaders/not-found-assert-loader.mjs -/* eslint-disable node-core/required-modules */ +/* eslint-disable node-core/require-common-first, node-core/required-modules */ import './not-found.mjs'; diff --git a/test/es-module/test-esm-resolve-hook.mjs b/test/es-module/test-esm-resolve-hook.mjs index e326d20b6d8b0e..bbf6c80cdab344 100644 --- a/test/es-module/test-esm-resolve-hook.mjs +++ b/test/es-module/test-esm-resolve-hook.mjs @@ -1,5 +1,5 @@ // Flags: --experimental-modules --loader ./test/fixtures/es-module-loaders/js-loader.mjs -/* eslint-disable node-core/required-modules */ +/* eslint-disable node-core/require-common-first, node-core/required-modules */ import { namedExport } from '../fixtures/es-module-loaders/js-as-esm.js'; import assert from 'assert'; import ok from '../fixtures/es-modules/test-esm-ok.mjs'; diff --git a/test/es-module/test-esm-type-flag.mjs b/test/es-module/test-esm-type-flag.mjs index e820c9ad67458f..8358da5c765288 100644 --- a/test/es-module/test-esm-type-flag.mjs +++ b/test/es-module/test-esm-type-flag.mjs @@ -1,6 +1,6 @@ // Flags: --experimental-modules -import cjs from '../fixtures/baz.js'; import '../common/index.mjs'; +import cjs from '../fixtures/baz.js'; import { message } from '../fixtures/es-modules/message.mjs'; import assert from 'assert'; diff --git a/test/js-native-api/test_general/testInstanceOf.js b/test/js-native-api/test_general/testInstanceOf.js index fb5b6334948182..d50ce7a27c3efa 100644 --- a/test/js-native-api/test_general/testInstanceOf.js +++ b/test/js-native-api/test_general/testInstanceOf.js @@ -1,7 +1,6 @@ 'use strict'; -const fs = require('fs'); - const common = require('../../common'); +const fs = require('fs'); const assert = require('assert'); // Addon is referenced through the eval expression in testFile diff --git a/test/parallel/test-buffer-constructor-node-modules-paths.js b/test/parallel/test-buffer-constructor-node-modules-paths.js index c6a419f82ade79..40d314aec08435 100644 --- a/test/parallel/test-buffer-constructor-node-modules-paths.js +++ b/test/parallel/test-buffer-constructor-node-modules-paths.js @@ -1,8 +1,8 @@ 'use strict'; +const common = require('../common'); const child_process = require('child_process'); const assert = require('assert'); -const common = require('../common'); if (process.env.NODE_PENDING_DEPRECATION) common.skip('test does not work when NODE_PENDING_DEPRECATION is set'); diff --git a/test/parallel/test-buffer-constructor-outside-node-modules.js b/test/parallel/test-buffer-constructor-outside-node-modules.js index 1a1e146f2dd9d7..71362599827dc4 100644 --- a/test/parallel/test-buffer-constructor-outside-node-modules.js +++ b/test/parallel/test-buffer-constructor-outside-node-modules.js @@ -1,9 +1,9 @@ // Flags: --no-warnings 'use strict'; +const common = require('../common'); const vm = require('vm'); const assert = require('assert'); -const common = require('../common'); if (new Error().stack.includes('node_modules')) common.skip('test does not work when inside `node_modules` directory'); diff --git a/test/parallel/test-buffer-includes.js b/test/parallel/test-buffer-includes.js index 5bad445adec524..ca5b94f9d9fa46 100644 --- a/test/parallel/test-buffer-includes.js +++ b/test/parallel/test-buffer-includes.js @@ -1,6 +1,6 @@ 'use strict'; -const assert = require('assert'); const common = require('../common'); +const assert = require('assert'); const b = Buffer.from('abcdef'); const buf_a = Buffer.from('a'); diff --git a/test/parallel/test-child-process-spawn-args.js b/test/parallel/test-child-process-spawn-args.js index 821525409c8fca..ef70fe844f9c12 100644 --- a/test/parallel/test-child-process-spawn-args.js +++ b/test/parallel/test-child-process-spawn-args.js @@ -6,12 +6,12 @@ // caused the third argument (`options`) to be ignored. // See https://github.com/nodejs/node/issues/24912. -const assert = require('assert'); -const { spawn } = require('child_process'); - const common = require('../common'); const tmpdir = require('../common/tmpdir'); +const assert = require('assert'); +const { spawn } = require('child_process'); + tmpdir.refresh(); const command = common.isWindows ? 'cd' : 'pwd'; diff --git a/test/parallel/test-child-process-spawnsync-args.js b/test/parallel/test-child-process-spawnsync-args.js index 96de8670f11da5..4e65b22f6e4587 100644 --- a/test/parallel/test-child-process-spawnsync-args.js +++ b/test/parallel/test-child-process-spawnsync-args.js @@ -6,12 +6,12 @@ // caused the third argument (`options`) to be ignored. // See https://github.com/nodejs/node/issues/24912. -const assert = require('assert'); -const { spawnSync } = require('child_process'); - const common = require('../common'); const tmpdir = require('../common/tmpdir'); +const assert = require('assert'); +const { spawnSync } = require('child_process'); + const command = common.isWindows ? 'cd' : 'pwd'; const options = { cwd: tmpdir.path }; diff --git a/test/parallel/test-dgram-deprecation-error.js b/test/parallel/test-dgram-deprecation-error.js index 89cde12fd37cf1..d244940b64d793 100644 --- a/test/parallel/test-dgram-deprecation-error.js +++ b/test/parallel/test-dgram-deprecation-error.js @@ -1,7 +1,7 @@ 'use strict'; -const assert = require('assert'); const common = require('../common'); +const assert = require('assert'); const dgram = require('dgram'); const fork = require('child_process').fork; diff --git a/test/parallel/test-eslint-require-common-first.js b/test/parallel/test-eslint-require-common-first.js new file mode 100644 index 00000000000000..018d4185d527e5 --- /dev/null +++ b/test/parallel/test-eslint-require-common-first.js @@ -0,0 +1,27 @@ +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +common.skipIfEslintMissing(); + +const RuleTester = require('../../tools/node_modules/eslint').RuleTester; +const rule = require('../../tools/eslint-rules/require-common-first'); + +new RuleTester().run('require-common-first', rule, { + valid: [ + { + code: 'require("common")\n' + + 'require("assert")' + } + ], + invalid: [ + { + code: 'require("assert")\n' + + 'require("common")', + errors: [{ message: 'Mandatory module "common" must be loaded ' + + 'before any other modules.' }] + } + ] +}); diff --git a/test/parallel/test-global-console-exists.js b/test/parallel/test-global-console-exists.js index f2e7ba5a9aa3a0..bcebfadf0d7620 100644 --- a/test/parallel/test-global-console-exists.js +++ b/test/parallel/test-global-console-exists.js @@ -1,4 +1,4 @@ -/* eslint-disable node-core/required-modules */ +/* eslint-disable node-core/require-common-first, node-core/required-modules */ 'use strict'; diff --git a/test/parallel/test-http-client-req-error-dont-double-fire.js b/test/parallel/test-http-client-req-error-dont-double-fire.js index d2c526eab69c6c..b162df03d6df48 100644 --- a/test/parallel/test-http-client-req-error-dont-double-fire.js +++ b/test/parallel/test-http-client-req-error-dont-double-fire.js @@ -4,12 +4,13 @@ // not get fired again when the 'error' event handler throws // an error. -const assert = require('assert'); -const http = require('http'); const common = require('../common'); const { addresses } = require('../common/internet'); const { errorLookupMock } = require('../common/dns'); +const assert = require('assert'); +const http = require('http'); + const host = addresses.INVALID_HOST; const req = http.get({ diff --git a/test/parallel/test-http-header-overflow.js b/test/parallel/test-http-header-overflow.js index a539a69c030ae8..442776fab08909 100644 --- a/test/parallel/test-http-header-overflow.js +++ b/test/parallel/test-http-header-overflow.js @@ -1,8 +1,8 @@ 'use strict'; +const { expectsError, mustCall } = require('../common'); const assert = require('assert'); const { createServer, maxHeaderSize } = require('http'); const { createConnection } = require('net'); -const { expectsError, mustCall } = require('../common'); const CRLF = '\r\n'; const DUMMY_HEADER_NAME = 'Cookie: '; diff --git a/test/parallel/test-http-parser-lazy-loaded.js b/test/parallel/test-http-parser-lazy-loaded.js index 79b6ac37b3cbfe..a6c19f9353ad50 100644 --- a/test/parallel/test-http-parser-lazy-loaded.js +++ b/test/parallel/test-http-parser-lazy-loaded.js @@ -1,7 +1,7 @@ // Flags: --expose-internals 'use strict'; - +const common = require('../common'); const { internalBinding } = require('internal/test/binding'); const { getOptionValue } = require('internal/options'); @@ -21,7 +21,6 @@ const binding = internalBinding('http_parser') : internalBinding('http_parser_llhttp'); binding.HTTPParser = DummyParser; -const common = require('../common'); const assert = require('assert'); const { spawn } = require('child_process'); const { parsers } = require('_http_common'); diff --git a/test/parallel/test-http2-client-write-empty-string.js b/test/parallel/test-http2-client-write-empty-string.js index de46507fb17137..087a498a37b462 100644 --- a/test/parallel/test-http2-client-write-empty-string.js +++ b/test/parallel/test-http2-client-write-empty-string.js @@ -1,10 +1,10 @@ 'use strict'; -const assert = require('assert'); const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); +const assert = require('assert'); const http2 = require('http2'); for (const chunkSequence of [ diff --git a/test/parallel/test-icu-data-dir.js b/test/parallel/test-icu-data-dir.js index daf15ba880ced7..5b37e27d32aa1f 100644 --- a/test/parallel/test-icu-data-dir.js +++ b/test/parallel/test-icu-data-dir.js @@ -1,7 +1,7 @@ // Flags: --expose-internals 'use strict'; -const { internalBinding } = require('internal/test/binding'); const common = require('../common'); +const { internalBinding } = require('internal/test/binding'); const os = require('os'); const { hasSmallICU } = internalBinding('config'); diff --git a/test/parallel/test-os-checked-function.js b/test/parallel/test-os-checked-function.js index 2a393f830d4b76..44337adb4063ae 100644 --- a/test/parallel/test-os-checked-function.js +++ b/test/parallel/test-os-checked-function.js @@ -1,3 +1,4 @@ +/* eslint-disable node-core/require-common-first */ 'use strict'; // Flags: --expose_internals diff --git a/test/parallel/test-process-env-allowed-flags.js b/test/parallel/test-process-env-allowed-flags.js index 9edc3504efa859..21beb5357a5f65 100644 --- a/test/parallel/test-process-env-allowed-flags.js +++ b/test/parallel/test-process-env-allowed-flags.js @@ -1,7 +1,7 @@ 'use strict'; -const assert = require('assert'); require('../common'); +const assert = require('assert'); // Assert legit flags are allowed, and bogus flags are disallowed { diff --git a/test/parallel/test-readline-position.js b/test/parallel/test-readline-position.js index 0e62761ca57b40..60ef476afe9ae3 100644 --- a/test/parallel/test-readline-position.js +++ b/test/parallel/test-readline-position.js @@ -1,7 +1,7 @@ // Flags: --expose-internals 'use strict'; -const { internalBinding } = require('internal/test/binding'); require('../common'); +const { internalBinding } = require('internal/test/binding'); const { PassThrough } = require('stream'); const readline = require('readline'); const assert = require('assert'); diff --git a/test/parallel/test-regression-object-prototype.js b/test/parallel/test-regression-object-prototype.js index 821c2af584ae3b..2ea1ba858a8d5a 100644 --- a/test/parallel/test-regression-object-prototype.js +++ b/test/parallel/test-regression-object-prototype.js @@ -19,7 +19,7 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. -/* eslint-disable node-core/required-modules */ +/* eslint-disable node-core/require-common-first, node-core/required-modules */ 'use strict'; Object.prototype.xadsadsdasasdxx = function() { diff --git a/test/parallel/test-stream-readable-pause-and-resume.js b/test/parallel/test-stream-readable-pause-and-resume.js index 3169023d90acaf..4d7d860a6373d4 100644 --- a/test/parallel/test-stream-readable-pause-and-resume.js +++ b/test/parallel/test-stream-readable-pause-and-resume.js @@ -1,7 +1,7 @@ 'use strict'; -const { Readable } = require('stream'); const common = require('../common'); +const { Readable } = require('stream'); let ticks = 18; let expectedData = 19; diff --git a/test/parallel/test-v8-serdes.js b/test/parallel/test-v8-serdes.js index def4914e2e4a36..58b919066ea990 100644 --- a/test/parallel/test-v8-serdes.js +++ b/test/parallel/test-v8-serdes.js @@ -2,9 +2,9 @@ 'use strict'; -const { internalBinding } = require('internal/test/binding'); const common = require('../common'); const fixtures = require('../common/fixtures'); +const { internalBinding } = require('internal/test/binding'); const assert = require('assert'); const v8 = require('v8'); const os = require('os'); diff --git a/test/parallel/test-worker-parent-port-ref.js b/test/parallel/test-worker-parent-port-ref.js index 0772d1c8601925..c1e79b9faa8d6e 100644 --- a/test/parallel/test-worker-parent-port-ref.js +++ b/test/parallel/test-worker-parent-port-ref.js @@ -1,6 +1,6 @@ 'use strict'; -const assert = require('assert'); const common = require('../common'); +const assert = require('assert'); const { isMainThread, parentPort, Worker } = require('worker_threads'); // This test makes sure that we manipulate the references of diff --git a/test/parallel/test-worker-process-cwd.js b/test/parallel/test-worker-process-cwd.js index dec70ac07c8f11..81c6edac3e4501 100644 --- a/test/parallel/test-worker-process-cwd.js +++ b/test/parallel/test-worker-process-cwd.js @@ -1,6 +1,6 @@ 'use strict'; -const assert = require('assert'); const common = require('../common'); +const assert = require('assert'); const { Worker, isMainThread, parentPort } = require('worker_threads'); // Do not use isMainThread directly, otherwise the test would time out in case diff --git a/test/parallel/test-worker-relative-path-double-dot.js b/test/parallel/test-worker-relative-path-double-dot.js index ff3ca84e697f84..86707c1590480e 100644 --- a/test/parallel/test-worker-relative-path-double-dot.js +++ b/test/parallel/test-worker-relative-path-double-dot.js @@ -1,7 +1,7 @@ 'use strict'; +const common = require('../common'); const path = require('path'); const assert = require('assert'); -const common = require('../common'); const { Worker, isMainThread, parentPort } = require('worker_threads'); if (isMainThread) { diff --git a/test/parallel/test-worker-relative-path.js b/test/parallel/test-worker-relative-path.js index e961447faaf74e..3b7bb95b0d78f4 100644 --- a/test/parallel/test-worker-relative-path.js +++ b/test/parallel/test-worker-relative-path.js @@ -1,7 +1,7 @@ 'use strict'; +const common = require('../common'); const path = require('path'); const assert = require('assert'); -const common = require('../common'); const { Worker, isMainThread, parentPort } = require('worker_threads'); if (isMainThread) { diff --git a/test/parallel/test-worker-unsupported-path.js b/test/parallel/test-worker-unsupported-path.js index 6dcfd230dc6d1d..0c86f2ead08a38 100644 --- a/test/parallel/test-worker-unsupported-path.js +++ b/test/parallel/test-worker-unsupported-path.js @@ -1,7 +1,7 @@ 'use strict'; -const path = require('path'); const common = require('../common'); +const path = require('path'); const assert = require('assert'); const { Worker } = require('worker_threads'); diff --git a/tools/eslint-rules/require-common-first.js b/tools/eslint-rules/require-common-first.js new file mode 100644 index 00000000000000..24e8dbff1a5d6b --- /dev/null +++ b/tools/eslint-rules/require-common-first.js @@ -0,0 +1,98 @@ +/** + * @fileoverview Require `common` module first in our tests. + */ +'use strict'; + +const path = require('path'); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = function(context) { + const requiredModule = 'common'; + const isESM = context.parserOptions.sourceType === 'module'; + const foundModules = []; + + /** + * Function to check if a node is a string literal. + * @param {ASTNode} node The node to check. + * @returns {boolean} If the node is a string literal. + */ + function isString(node) { + return node && node.type === 'Literal' && typeof node.value === 'string'; + } + + /** + * Function to check if a node is a require call. + * @param {ASTNode} node The node to check. + * @returns {boolean} If the node is a require call. + */ + function isRequireCall(node) { + return node.callee.type === 'Identifier' && node.callee.name === 'require'; + } + + /** + * Function to check if the path is a module and return its name. + * @param {String} str The path to check + * @returns {String} module name + */ + function getModuleName(str) { + if (str === '../common/index.mjs') { + return 'common'; + } + + return path.basename(str); + } + + /** + * Function to check if a node has an argument that is a module and + * return its name. + * @param {ASTNode} node The node to check + * @returns {undefined|String} module name or undefined + */ + function getModuleNameFromCall(node) { + // Node has arguments and first argument is string + if (node.arguments.length && isString(node.arguments[0])) { + return getModuleName(node.arguments[0].value.trim()); + } + + return undefined; + } + + const rules = { + 'Program:exit'(node) { + // The common module should be loaded in the first place. + const notLoadedFirst = foundModules.indexOf(requiredModule) !== 0; + if (notLoadedFirst) { + context.report( + node, + 'Mandatory module "{{moduleName}}" must be loaded ' + + 'before any other modules.', + { moduleName: requiredModule } + ); + } + } + }; + + if (isESM) { + rules.ImportDeclaration = (node) => { + const moduleName = getModuleName(node.source.value); + if (moduleName) { + foundModules.push(moduleName); + } + }; + } else { + rules.CallExpression = (node) => { + if (isRequireCall(node)) { + const moduleName = getModuleNameFromCall(node); + + if (moduleName) { + foundModules.push(moduleName); + } + } + }; + } + + return rules; +};