From fd9d19d369fcea13518ca97b669b9e358cd137a8 Mon Sep 17 00:00:00 2001 From: Luis Aleman Date: Thu, 23 May 2019 05:09:39 -0400 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20`no-deprecated-api`=20adheres=20to?= =?UTF-8?q?=20targeted=20node=20version=20(fixes=20#141)=20(#164)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/rules/no-deprecated-api.md | 29 ++- lib/rules/no-deprecated-api.js | 354 ++++++++++++++++++++++----- tests/lib/rules/no-deprecated-api.js | 143 +++++++++++ 3 files changed, 464 insertions(+), 62 deletions(-) diff --git a/docs/rules/no-deprecated-api.md b/docs/rules/no-deprecated-api.md index 236a796d..e2db6dfe 100644 --- a/docs/rules/no-deprecated-api.md +++ b/docs/rules/no-deprecated-api.md @@ -143,14 +143,34 @@ This rule reports the following deprecated API. > For example, `require("punycode")` still imports the deprecated core module even if you executed `npm install punycode`. > Use `require("punycode/")` to import userland modules rather than core modules. +### Configured Node.js version range + +This rule reads the [engines] field of `package.json` to detect which Node.js versions your module is supporting. + +I recommend the use of the [engines] field because it's the official way that indicates which Node.js versions your module is supporting. +For example of `package.json`: + +```json +{ + "name": "your-module", + "version": "1.0.0", + "engines": { + "node": ">=8.0.0" + } +} +``` + +If you omit the [engines] field, this rule chooses `>=8.0.0` as the configured Node.js version since `8` is the minimum version the community is maintaining (see also [Node.js Release Working Group](https://github.com/nodejs/Release#readme)). + ### Options -This rule has 2 options. +This rule has 3 options. ```json { "rules": { "node/no-deprecated-api": ["error", { + "version": ">=8.0.0", "ignoreModuleItems": [], "ignoreGlobalItems": [] }] @@ -158,6 +178,13 @@ This rule has 2 options. } ``` +#### version + +As mentioned above, this rule reads the [engines] field of `package.json`. +But, you can overwrite the version by `version` option. + +The `version` option accepts [the valid version range of `node-semver`](https://github.com/npm/node-semver#range-grammar). + #### ignoreModuleItems This is the array of module names and module's member names. diff --git a/lib/rules/no-deprecated-api.js b/lib/rules/no-deprecated-api.js index 6eb3405f..b7c427ea 100644 --- a/lib/rules/no-deprecated-api.js +++ b/lib/rules/no-deprecated-api.js @@ -6,6 +6,8 @@ const { CALL, CONSTRUCT, READ, ReferenceTracker } = require("eslint-utils") const enumeratePropertyNames = require("../util/enumerate-property-names") +const getConfiguredNodeVersion = require("../util/get-configured-node-version") +const getSemverRange = require("../util/get-semver-range") const modules = { _linklist: { @@ -19,28 +21,40 @@ const modules = { deepEqual: { [READ]: { since: "10.0.0", - replacedBy: - "'assert.deepStrictEqual' or 'assert.strict.deepEqual'", + replacedBy: [ + { name: "'assert.deepStrictEqual'", supported: "1.2.0" }, + { name: "'assert.strict.deepEqual'", supported: "9.9.0" }, + ], }, }, equal: { [READ]: { since: "10.0.0", - replacedBy: "'assert.strictEqual' or 'assert.strict.equal'", + replacedBy: [ + { name: "'assert.strictEqual'", supported: "0.1.21" }, + { name: "'assert.strict.equal'", supported: "9.9.0" }, + ], }, }, notDeepEqual: { [READ]: { since: "10.0.0", - replacedBy: - "'assert.notDeepStrictEqual' or 'assert.strict.notDeepEqual'", + replacedBy: [ + { name: "'assert.notDeepStrictEqual'", supported: "1.2.0" }, + { + name: "'assert.strict.notDeepEqual'", + supported: "9.9.0", + }, + ], }, }, notEqual: { [READ]: { since: "10.0.0", - replacedBy: - "'assert.notStrictEqual' or 'assert.strict.notEqual'", + replacedBy: [ + { name: "'assert.notStrictEqual'", supported: "0.1.21" }, + { name: "'assert.strict.notEqual'", supported: "9.9.0" }, + ], }, }, }, @@ -49,7 +63,12 @@ const modules = { currentId: { [READ]: { since: "8.2.0", - replacedBy: "'async_hooks.executionAsyncId()'", + replacedBy: [ + { + name: "'async_hooks.executionAsyncId()'", + supported: "8.1.0", + }, + ], }, }, triggerId: { @@ -63,17 +82,28 @@ const modules = { Buffer: { [CONSTRUCT]: { since: "6.0.0", - replacedBy: "'buffer.Buffer.alloc()' or 'buffer.Buffer.from()'", + replacedBy: [ + { name: "'buffer.Buffer.alloc()'", supported: "5.10.0" }, + { name: "'buffer.Buffer.from()'", supported: "5.10.0" }, + ], }, [CALL]: { since: "6.0.0", - replacedBy: "'buffer.Buffer.alloc()' or 'buffer.Buffer.from()'", + replacedBy: [ + { name: "'buffer.Buffer.alloc()'", supported: "5.10.0" }, + { name: "'buffer.Buffer.from()'", supported: "5.10.0" }, + ], }, }, SlowBuffer: { [READ]: { since: "6.0.0", - replacedBy: "'buffer.Buffer.allocUnsafeSlow()'", + replacedBy: [ + { + name: "'buffer.Buffer.allocUnsafeSlow()'", + supported: "5.12.0", + }, + ], }, }, }, @@ -96,35 +126,67 @@ const modules = { createCipher: { [READ]: { since: "10.0.0", - replacedBy: "'crypto.createCipheriv()'", + replacedBy: [ + { name: "'crypto.createCipheriv()'", supported: "0.1.94" }, + ], }, }, createCredentials: { [READ]: { since: "0.12.0", - replacedBy: "'tls.createSecureContext()'", + replacedBy: [ + { + name: "'tls.createSecureContext()'", + supported: "0.11.13", + }, + ], }, }, createDecipher: { [READ]: { since: "10.0.0", - replacedBy: "'crypto.createDecipheriv()'", + replacedBy: [ + { + name: "'crypto.createDecipheriv()'", + supported: "0.1.94", + }, + ], }, }, fips: { [READ]: { since: "10.0.0", - replacedBy: "'crypto.getFips()' and 'crypto.setFips()'", + replacedBy: [ + { + name: "'crypto.getFips()' and 'crypto.setFips()'", + supported: "10.0.0", + }, + ], }, }, prng: { - [READ]: { since: "11.0.0", replacedBy: "'crypto.randomBytes()'" }, + [READ]: { + since: "11.0.0", + replacedBy: [ + { name: "'crypto.randomBytes()'", supported: "0.5.8" }, + ], + }, }, pseudoRandomBytes: { - [READ]: { since: "11.0.0", replacedBy: "'crypto.randomBytes()'" }, + [READ]: { + since: "11.0.0", + replacedBy: [ + { name: "'crypto.randomBytes()'", supported: "0.5.8" }, + ], + }, }, rng: { - [READ]: { since: "11.0.0", replacedBy: "'crypto.randomBytes()'" }, + [READ]: { + since: "11.0.0", + replacedBy: [ + { name: "'crypto.randomBytes()'", supported: "0.5.8" }, + ], + }, }, }, domain: { @@ -135,14 +197,24 @@ const modules = { listenerCount: { [READ]: { since: "4.0.0", - replacedBy: "'events.EventEmitter#listenerCount()'", + replacedBy: [ + { + name: "'events.EventEmitter#listenerCount()'", + supported: "3.2.0", + }, + ], }, }, }, listenerCount: { [READ]: { since: "4.0.0", - replacedBy: "'events.EventEmitter#listenerCount()'", + replacedBy: [ + { + name: "'events.EventEmitter#listenerCount()'", + supported: "3.2.0", + }, + ], }, }, }, @@ -156,7 +228,10 @@ const modules = { exists: { [READ]: { since: "4.0.0", - replacedBy: "'fs.stat()' or 'fs.access()'", + replacedBy: [ + { name: "'fs.stat()'", supported: "0.0.2" }, + { name: "'fs.access()'", supported: "0.11.15" }, + ], }, }, lchmod: { @@ -174,20 +249,29 @@ const modules = { }, http: { createClient: { - [READ]: { since: "0.10.0", replacedBy: "'http.request()'" }, + [READ]: { + since: "0.10.0", + replacedBy: [{ name: "'http.request()'", supported: "0.3.6" }], + }, }, }, module: { Module: { requireRepl: { - [READ]: { since: "6.0.0", replacedBy: "'require(\"repl\")'" }, + [READ]: { + since: "6.0.0", + replacedBy: "'require(\"repl\")'", + }, }, _debug: { [READ]: { since: "9.0.0", replacedBy: null }, }, }, requireRepl: { - [READ]: { since: "6.0.0", replacedBy: "'require(\"repl\")'" }, + [READ]: { + since: "6.0.0", + replacedBy: "'require(\"repl\")'", + }, }, _debug: { [READ]: { since: "9.0.0", replacedBy: null }, @@ -200,30 +284,52 @@ const modules = { }, os: { getNetworkInterfaces: { - [READ]: { since: "0.6.0", replacedBy: "'os.networkInterfaces()'" }, + [READ]: { + since: "0.6.0", + replacedBy: [ + { name: "'os.networkInterfaces()'", supported: "0.6.0" }, + ], + }, }, tmpDir: { - [READ]: { since: "7.0.0", replacedBy: "'os.tmpdir()'" }, + [READ]: { + since: "7.0.0", + replacedBy: [{ name: "'os.tmpdir()'", supported: "0.9.9" }], + }, }, }, path: { _makeLong: { - [READ]: { since: "9.0.0", replacedBy: "'path.toNamespacedPath()'" }, + [READ]: { + since: "9.0.0", + replacedBy: [ + { name: "'path.toNamespacedPath()'", supported: "9.0.0" }, + ], + }, }, }, process: { EventEmitter: { - [READ]: { since: "0.6.0", replacedBy: "'require(\"events\")'" }, + [READ]: { + since: "0.6.0", + replacedBy: "'require(\"events\")'", + }, }, assert: { - [READ]: { since: "10.0.0", replacedBy: "'require(\"assert\")'" }, + [READ]: { + since: "10.0.0", + replacedBy: "'require(\"assert\")'", + }, }, binding: { [READ]: { since: "10.9.0", replacedBy: null }, }, env: { NODE_REPL_HISTORY_FILE: { - [READ]: { since: "4.0.0", replacedBy: "'NODE_REPL_HISTORY'" }, + [READ]: { + since: "4.0.0", + replacedBy: "'NODE_REPL_HISTORY'", + }, }, }, report: { @@ -261,34 +367,54 @@ const modules = { Buffer: { [CONSTRUCT]: { since: "6.0.0", - replacedBy: "'buffer.Buffer.alloc()' or 'buffer.Buffer.from()'", + replacedBy: [ + { name: "'buffer.Buffer.alloc()'", supported: "5.10.0" }, + { name: "'buffer.Buffer.from()'", supported: "5.10.0" }, + ], }, [CALL]: { since: "6.0.0", - replacedBy: "'buffer.Buffer.alloc()' or 'buffer.Buffer.from()'", + replacedBy: [ + { name: "'buffer.Buffer.alloc()'", supported: "5.10.0" }, + { name: "'buffer.Buffer.from()'", supported: "5.10.0" }, + ], }, }, SlowBuffer: { [READ]: { since: "6.0.0", - replacedBy: "'buffer.Buffer.allocUnsafeSlow()'", + replacedBy: [ + { + name: "'buffer.Buffer.allocUnsafeSlow()'", + supported: "5.12.0", + }, + ], }, }, }, sys: { - [READ]: { since: "0.3.0", replacedBy: "'util' module" }, + [READ]: { + since: "0.3.0", + replacedBy: "'util' module", + }, }, timers: { enroll: { [READ]: { since: "10.0.0", - replacedBy: "'setTimeout()' or 'setInterval()'", + replacedBy: [ + { name: "'setTimeout()'", supported: "0.0.1" }, + { name: "'setInterval()'", supported: "0.0.1" }, + ], }, }, unenroll: { [READ]: { since: "10.0.0", - replacedBy: "'clearTimeout()' or 'clearInterval()'", + replacedBy: [ + { name: "'clearTimeout()'", supported: "0.0.1" }, + { name: "'clearInterval()'", supported: "0.0.1" }, + ], }, }, }, @@ -297,19 +423,33 @@ const modules = { [READ]: { since: "0.10.0", replacedBy: null }, }, CryptoStream: { - [READ]: { since: "0.12.0", replacedBy: "'tls.TLSSocket'" }, + [READ]: { + since: "0.12.0", + replacedBy: [{ name: "'tls.TLSSocket'", supported: "0.11.4" }], + }, }, SecurePair: { - [READ]: { since: "6.0.0", replacedBy: "'tls.TLSSocket'" }, + [READ]: { + since: "6.0.0", + replacedBy: [{ name: "'tls.TLSSocket'", supported: "0.11.4" }], + }, }, convertNPNProtocols: { [READ]: { since: "10.0.0", replacedBy: null }, }, createSecurePair: { - [READ]: { since: "6.0.0", replacedBy: "'tls.TLSSocket'" }, + [READ]: { + since: "6.0.0", + replacedBy: [{ name: "'tls.TLSSocket'", supported: "0.11.4" }], + }, }, parseCertString: { - [READ]: { since: "8.6.0", replacedBy: "'querystring.parse()'" }, + [READ]: { + since: "8.6.0", + replacedBy: [ + { name: "'querystring.parse()'", supported: "0.1.25" }, + ], + }, }, }, tty: { @@ -323,27 +463,57 @@ const modules = { }, url: { parse: { - [READ]: { since: "11.0.0", replacedBy: "'url.URL' constructor" }, + [READ]: { + since: "11.0.0", + replacedBy: [ + { name: "'url.URL' constructor", supported: "6.13.0" }, + ], + }, }, resolve: { - [READ]: { since: "11.0.0", replacedBy: "'url.URL' constructor" }, + [READ]: { + since: "11.0.0", + replacedBy: [ + { name: "'url.URL' constructor", supported: "6.13.0" }, + ], + }, }, }, util: { debug: { - [READ]: { since: "0.12.0", replacedBy: "'console.error()'" }, + [READ]: { + since: "0.12.0", + replacedBy: [ + { name: "'console.error()'", supported: "0.1.100" }, + ], + }, }, error: { - [READ]: { since: "0.12.0", replacedBy: "'console.error()'" }, + [READ]: { + since: "0.12.0", + replacedBy: [ + { name: "'console.error()'", supported: "0.1.100" }, + ], + }, }, isArray: { - [READ]: { since: "4.0.0", replacedBy: "'Array.isArray()'" }, + [READ]: { + since: "4.0.0", + replacedBy: [ + { name: "'Array.isArray()'", supported: "0.1.100" }, + ], + }, }, isBoolean: { [READ]: { since: "4.0.0", replacedBy: null }, }, isBuffer: { - [READ]: { since: "4.0.0", replacedBy: "'Buffer.isBuffer()'" }, + [READ]: { + since: "4.0.0", + replacedBy: [ + { name: "'Buffer.isBuffer()'", supported: "0.1.101" }, + ], + }, }, isDate: { [READ]: { since: "4.0.0", replacedBy: null }, @@ -385,16 +555,30 @@ const modules = { [READ]: { since: "6.0.0", replacedBy: "a third party module" }, }, print: { - [READ]: { since: "0.12.0", replacedBy: "'console.log()'" }, + [READ]: { + since: "0.12.0", + replacedBy: [{ name: "'console.log()'", supported: "0.1.100" }], + }, }, pump: { - [READ]: { since: "0.10.0", replacedBy: "'stream.Readable#pipe()'" }, + [READ]: { + since: "0.10.0", + replacedBy: [ + { name: "'stream.Readable#pipe()'", supported: "0.9.4" }, + ], + }, }, puts: { - [READ]: { since: "0.12.0", replacedBy: "'console.log()'" }, + [READ]: { + since: "0.12.0", + replacedBy: [{ name: "'console.log()'", supported: "0.1.100" }], + }, }, _extend: { - [READ]: { since: "6.0.0", replacedBy: "'Object.assign()'" }, + [READ]: { + since: "6.0.0", + replacedBy: [{ name: "'Object.assign()'", supported: "4.0.0" }], + }, }, }, vm: { @@ -407,11 +591,17 @@ const globals = { Buffer: { [CONSTRUCT]: { since: "6.0.0", - replacedBy: "'Buffer.alloc()' or 'Buffer.from()'", + replacedBy: [ + { name: "'Buffer.alloc()'", supported: "5.10.0" }, + { name: "'Buffer.from()'", supported: "5.10.0" }, + ], }, [CALL]: { since: "6.0.0", - replacedBy: "'Buffer.alloc()' or 'Buffer.from()'", + replacedBy: [ + { name: "'Buffer.alloc()'", supported: "5.10.0" }, + { name: "'Buffer.from()'", supported: "5.10.0" }, + ], }, }, COUNTER_NET_SERVER_CONNECTION: { @@ -433,7 +623,10 @@ const globals = { [READ]: { since: "11.0.0", replacedBy: null }, }, GLOBAL: { - [READ]: { since: "6.0.0", replacedBy: "'global'" }, + [READ]: { + since: "6.0.0", + replacedBy: [{ name: "'global'", supported: "0.1.27" }], + }, }, Intl: { v8BreakIterator: { @@ -449,7 +642,10 @@ const globals = { }, }, root: { - [READ]: { since: "6.0.0", replacedBy: "'global'" }, + [READ]: { + since: "6.0.0", + replacedBy: [{ name: "'global'", supported: "0.1.27" }], + }, }, process: modules.process, } @@ -457,11 +653,26 @@ const globals = { /** * Makes a replacement message. * - * @param {string|null} replacedBy - The text of substitute way. + * @param {string|array|null} replacedBy - The text of substitute way. + * @param {Range} version - The configured version range * @returns {string} Replacement message. */ -function toReplaceMessage(replacedBy) { - return replacedBy ? `. Use ${replacedBy} instead` : "" +function toReplaceMessage(replacedBy, version) { + let message = replacedBy + + if (Array.isArray(replacedBy)) { + message = replacedBy + .reduce( + (collector, { name, supported }) => + version.intersects(getSemverRange(`>=${supported}`)) + ? collector.concat(name) + : collector, + [] + ) + .join(" or ") + } + + return message ? `. Use ${message} instead` : "" } /** @@ -479,6 +690,22 @@ function toName(type, path) { : baseName } +/** + * Parses the options. + * @param {RuleContext} context The rule context. + * @returns {{version:Range,ignoredGlobalItems:Set,ignoredModuleItems:Set}} Parsed + * value. + */ +function parseOptions(context) { + const raw = context.options[0] || {} + const filePath = context.getFilename() + const version = getConfiguredNodeVersion(raw.version, filePath) + const ignoredModuleItems = new Set(raw.ignoreModuleItems || []) + const ignoredGlobalItems = new Set(raw.ignoreGlobalItems || []) + + return Object.freeze({ version, ignoredGlobalItems, ignoredModuleItems }) +} + module.exports = { meta: { docs: { @@ -494,6 +721,9 @@ module.exports = { { type: "object", properties: { + version: { + type: "string", + }, ignoreModuleItems: { type: "array", items: { @@ -519,9 +749,11 @@ module.exports = { ], }, create(context) { - const options = context.options[0] || {} - const ignoredModuleItems = new Set(options.ignoreModuleItems || []) - const ignoredGlobalItems = new Set(options.ignoreGlobalItems || []) + const { + ignoredModuleItems, + ignoredGlobalItems, + version, + } = parseOptions(context) /** * Reports a use of a deprecated API. @@ -540,7 +772,7 @@ module.exports = { data: { name, version: info.since, - replace: toReplaceMessage(info.replacedBy), + replace: toReplaceMessage(info.replacedBy, version), }, }) } diff --git a/tests/lib/rules/no-deprecated-api.js b/tests/lib/rules/no-deprecated-api.js index dc82cb9d..3b19884f 100644 --- a/tests/lib/rules/no-deprecated-api.js +++ b/tests/lib/rules/no-deprecated-api.js @@ -182,6 +182,7 @@ ruleTester.run("no-deprecated-api", rule, { //---------------------------------------------------------------------- { code: "new (require('buffer').Buffer)()", + options: [{ version: "6.0.0" }], env: { node: true }, errors: [ "'new buffer.Buffer()' was deprecated since v6.0.0. Use 'buffer.Buffer.alloc()' or 'buffer.Buffer.from()' instead.", @@ -189,6 +190,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('buffer').Buffer()", + options: [{ version: "6.0.0" }], env: { node: true }, errors: [ "'buffer.Buffer()' was deprecated since v6.0.0. Use 'buffer.Buffer.alloc()' or 'buffer.Buffer.from()' instead.", @@ -196,6 +198,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "var b = require('buffer'); new b.Buffer()", + options: [{ version: "6.0.0" }], env: { node: true }, errors: [ "'new buffer.Buffer()' was deprecated since v6.0.0. Use 'buffer.Buffer.alloc()' or 'buffer.Buffer.from()' instead.", @@ -203,6 +206,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "var b = require('buffer'); new b['Buffer']()", + options: [{ version: "6.0.0" }], env: { node: true }, errors: [ "'new buffer.Buffer()' was deprecated since v6.0.0. Use 'buffer.Buffer.alloc()' or 'buffer.Buffer.from()' instead.", @@ -210,6 +214,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "var b = require('buffer'); new b[`Buffer`]()", + options: [{ version: "6.0.0" }], env: { node: true, es6: true }, errors: [ "'new buffer.Buffer()' was deprecated since v6.0.0. Use 'buffer.Buffer.alloc()' or 'buffer.Buffer.from()' instead.", @@ -217,6 +222,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "var b = require('buffer').Buffer; new b()", + options: [{ version: "6.0.0" }], env: { node: true }, errors: [ "'new buffer.Buffer()' was deprecated since v6.0.0. Use 'buffer.Buffer.alloc()' or 'buffer.Buffer.from()' instead.", @@ -225,6 +231,7 @@ ruleTester.run("no-deprecated-api", rule, { { code: "var b; new ((b = require('buffer')).Buffer)(); new b.Buffer()", + options: [{ version: "6.0.0" }], env: { node: true }, errors: [ "'new buffer.Buffer()' was deprecated since v6.0.0. Use 'buffer.Buffer.alloc()' or 'buffer.Buffer.from()' instead.", @@ -233,6 +240,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "var {Buffer: b} = require('buffer'); new b()", + options: [{ version: "6.0.0" }], env: { node: true, es6: true }, errors: [ "'new buffer.Buffer()' was deprecated since v6.0.0. Use 'buffer.Buffer.alloc()' or 'buffer.Buffer.from()' instead.", @@ -240,6 +248,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "var {['Buffer']: b = null} = require('buffer'); new b()", + options: [{ version: "6.0.0" }], env: { node: true, es6: true }, errors: [ "'new buffer.Buffer()' was deprecated since v6.0.0. Use 'buffer.Buffer.alloc()' or 'buffer.Buffer.from()' instead.", @@ -247,6 +256,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "var {'Buffer': b = null} = require('buffer'); new b()", + options: [{ version: "6.0.0" }], env: { node: true, es6: true }, errors: [ "'new buffer.Buffer()' was deprecated since v6.0.0. Use 'buffer.Buffer.alloc()' or 'buffer.Buffer.from()' instead.", @@ -254,6 +264,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "var {Buffer: b = require('buffer').Buffer} = {}; new b()", + options: [{ version: "6.0.0" }], env: { node: true, es6: true }, errors: [ "'new buffer.Buffer()' was deprecated since v6.0.0. Use 'buffer.Buffer.alloc()' or 'buffer.Buffer.from()' instead.", @@ -261,6 +272,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('buffer').SlowBuffer", + options: [{ version: "6.0.0" }], env: { node: true }, errors: [ "'buffer.SlowBuffer' was deprecated since v6.0.0. Use 'buffer.Buffer.allocUnsafeSlow()' instead.", @@ -268,6 +280,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "var b = require('buffer'); b.SlowBuffer", + options: [{ version: "6.0.0" }], env: { node: true }, errors: [ "'buffer.SlowBuffer' was deprecated since v6.0.0. Use 'buffer.Buffer.allocUnsafeSlow()' instead.", @@ -275,6 +288,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "var {SlowBuffer: b} = require('buffer');", + options: [{ version: "6.0.0" }], env: { node: true, es6: true }, errors: [ "'buffer.SlowBuffer' was deprecated since v6.0.0. Use 'buffer.Buffer.allocUnsafeSlow()' instead.", @@ -284,11 +298,60 @@ ruleTester.run("no-deprecated-api", rule, { //---------------------------------------------------------------------- { code: "require('_linklist');", + options: [{ version: "5.0.0" }], env: { node: true }, errors: ["'_linklist' module was deprecated since v5.0.0."], }, + { + code: "require('assert').deepEqual", + options: [{ version: "10.0.0" }], + env: { node: true }, + errors: [ + "'assert.deepEqual' was deprecated since v10.0.0. Use 'assert.deepStrictEqual' or 'assert.strict.deepEqual' instead.", + ], + }, + // https://github.com/mysticatea/eslint-plugin-node/issues/141 + { + code: "require('assert').deepEqual", + options: [{ version: "6.0.0" }], + env: { node: true }, + errors: [ + "'assert.deepEqual' was deprecated since v10.0.0. Use 'assert.deepStrictEqual' instead.", + ], + }, + { + code: "require('assert').deepEqual", + options: [{ version: "1.0.0" }], + env: { node: true }, + errors: ["'assert.deepEqual' was deprecated since v10.0.0."], + }, + { + code: "require('assert').equal", + options: [{ version: "10.0.0" }], + env: { node: true }, + errors: [ + "'assert.equal' was deprecated since v10.0.0. Use 'assert.strictEqual' or 'assert.strict.equal' instead.", + ], + }, + { + code: "require('assert').notDeepEqual", + options: [{ version: "10.0.0" }], + env: { node: true }, + errors: [ + "'assert.notDeepEqual' was deprecated since v10.0.0. Use 'assert.notDeepStrictEqual' or 'assert.strict.notDeepEqual' instead.", + ], + }, + { + code: "require('assert').notEqual", + options: [{ version: "10.0.0" }], + env: { node: true }, + errors: [ + "'assert.notEqual' was deprecated since v10.0.0. Use 'assert.notStrictEqual' or 'assert.strict.notEqual' instead.", + ], + }, { code: "require('async_hooks').currentId;", + options: [{ version: "8.2.0" }], env: { node: true }, errors: [ "'async_hooks.currentId' was deprecated since v8.2.0. Use 'async_hooks.executionAsyncId()' instead.", @@ -296,6 +359,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('async_hooks').triggerId;", + options: [{ version: "8.2.0" }], env: { node: true }, errors: [ "'async_hooks.triggerId' was deprecated since v8.2.0. Use 'async_hooks.triggerAsyncId()' instead.", @@ -303,6 +367,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('constants');", + options: [{ version: "6.3.0" }], env: { node: true }, errors: [ "'constants' module was deprecated since v6.3.0. Use 'constants' property of each module instead.", @@ -310,6 +375,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('crypto').Credentials;", + options: [{ version: "0.12.0" }], env: { node: true }, errors: [ "'crypto.Credentials' was deprecated since v0.12.0. Use 'tls.SecureContext' instead.", @@ -317,6 +383,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('crypto').createCredentials;", + options: [{ version: "0.12.0" }], env: { node: true }, errors: [ "'crypto.createCredentials' was deprecated since v0.12.0. Use 'tls.createSecureContext()' instead.", @@ -324,11 +391,13 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('domain');", + options: [{ version: "4.0.0" }], env: { node: true }, errors: ["'domain' module was deprecated since v4.0.0."], }, { code: "require('events').EventEmitter.listenerCount;", + options: [{ version: "4.0.0" }], env: { node: true }, errors: [ "'events.EventEmitter.listenerCount' was deprecated since v4.0.0. Use 'events.EventEmitter#listenerCount()' instead.", @@ -336,6 +405,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('events').listenerCount;", + options: [{ version: "4.0.0" }], env: { node: true }, errors: [ "'events.listenerCount' was deprecated since v4.0.0. Use 'events.EventEmitter#listenerCount()' instead.", @@ -343,16 +413,19 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('freelist');", + options: [{ version: "4.0.0" }], env: { node: true }, errors: ["'freelist' module was deprecated since v4.0.0."], }, { code: "require('fs').SyncWriteStream;", + options: [{ version: "4.0.0" }], env: { node: true }, errors: ["'fs.SyncWriteStream' was deprecated since v4.0.0."], }, { code: "require('fs').exists;", + options: [{ version: "4.0.0" }], env: { node: true }, errors: [ "'fs.exists' was deprecated since v4.0.0. Use 'fs.stat()' or 'fs.access()' instead.", @@ -360,26 +433,31 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('fs').lchmod;", + options: [{ version: "0.4.0" }], env: { node: true }, errors: ["'fs.lchmod' was deprecated since v0.4.0."], }, { code: "require('fs').lchmodSync;", + options: [{ version: "0.4.0" }], env: { node: true }, errors: ["'fs.lchmodSync' was deprecated since v0.4.0."], }, { code: "require('fs').lchown;", + options: [{ version: "0.4.0" }], env: { node: true }, errors: ["'fs.lchown' was deprecated since v0.4.0."], }, { code: "require('fs').lchownSync;", + options: [{ version: "0.4.0" }], env: { node: true }, errors: ["'fs.lchownSync' was deprecated since v0.4.0."], }, { code: "require('http').createClient;", + options: [{ version: "0.10.0" }], env: { node: true }, errors: [ "'http.createClient' was deprecated since v0.10.0. Use 'http.request()' instead.", @@ -387,6 +465,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('module').requireRepl;", + options: [{ version: "6.0.0" }], env: { node: true }, errors: [ "'module.requireRepl' was deprecated since v6.0.0. Use 'require(\"repl\")' instead.", @@ -394,6 +473,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('module').Module.requireRepl;", + options: [{ version: "6.0.0" }], env: { node: true }, errors: [ "'module.Module.requireRepl' was deprecated since v6.0.0. Use 'require(\"repl\")' instead.", @@ -401,16 +481,19 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('module')._debug;", + options: [{ version: "9.0.0" }], env: { node: true }, errors: ["'module._debug' was deprecated since v9.0.0."], }, { code: "require('module').Module._debug;", + options: [{ version: "9.0.0" }], env: { node: true }, errors: ["'module.Module._debug' was deprecated since v9.0.0."], }, { code: "require('os').getNetworkInterfaces;", + options: [{ version: "0.6.0" }], env: { node: true }, errors: [ "'os.getNetworkInterfaces' was deprecated since v0.6.0. Use 'os.networkInterfaces()' instead.", @@ -418,6 +501,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('os').tmpDir;", + options: [{ version: "7.0.0" }], env: { node: true }, errors: [ "'os.tmpDir' was deprecated since v7.0.0. Use 'os.tmpdir()' instead.", @@ -425,6 +509,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('path')._makeLong;", + options: [{ version: "9.0.0" }], env: { node: true }, errors: [ "'path._makeLong' was deprecated since v9.0.0. Use 'path.toNamespacedPath()' instead.", @@ -432,6 +517,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('punycode');", + options: [{ version: "7.0.0" }], env: { node: true }, errors: [ "'punycode' module was deprecated since v7.0.0. Use 'https://www.npmjs.com/package/punycode' instead.", @@ -439,16 +525,19 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('readline').codePointAt;", + options: [{ version: "4.0.0" }], env: { node: true }, errors: ["'readline.codePointAt' was deprecated since v4.0.0."], }, { code: "require('readline').getStringWidth;", + options: [{ version: "6.0.0" }], env: { node: true }, errors: ["'readline.getStringWidth' was deprecated since v6.0.0."], }, { code: "require('readline').isFullWidthCodePoint;", + options: [{ version: "6.0.0" }], env: { node: true }, errors: [ "'readline.isFullWidthCodePoint' was deprecated since v6.0.0.", @@ -456,6 +545,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('readline').stripVTControlCharacters;", + options: [{ version: "6.0.0" }], env: { node: true }, errors: [ "'readline.stripVTControlCharacters' was deprecated since v6.0.0.", @@ -463,6 +553,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('sys');", + options: [{ version: "0.3.0" }], env: { node: true }, errors: [ "'sys' module was deprecated since v0.3.0. Use 'util' module instead.", @@ -470,11 +561,13 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('tls').CleartextStream;", + options: [{ version: "0.10.0" }], env: { node: true }, errors: ["'tls.CleartextStream' was deprecated since v0.10.0."], }, { code: "require('tls').CryptoStream;", + options: [{ version: "0.12.0" }], env: { node: true }, errors: [ "'tls.CryptoStream' was deprecated since v0.12.0. Use 'tls.TLSSocket' instead.", @@ -482,6 +575,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('tls').SecurePair;", + options: [{ version: "6.0.0" }], env: { node: true }, errors: [ "'tls.SecurePair' was deprecated since v6.0.0. Use 'tls.TLSSocket' instead.", @@ -489,6 +583,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('tls').createSecurePair;", + options: [{ version: "6.0.0" }], env: { node: true }, errors: [ "'tls.createSecurePair' was deprecated since v6.0.0. Use 'tls.TLSSocket' instead.", @@ -496,6 +591,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('tls').parseCertString;", + options: [{ version: "8.6.0" }], env: { node: true }, errors: [ "'tls.parseCertString' was deprecated since v8.6.0. Use 'querystring.parse()' instead.", @@ -503,6 +599,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('tty').setRawMode;", + options: [{ version: "0.10.0" }], env: { node: true }, errors: [ "'tty.setRawMode' was deprecated since v0.10.0. Use 'tty.ReadStream#setRawMode()' (e.g. 'process.stdin.setRawMode()') instead.", @@ -510,6 +607,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('util').debug;", + options: [{ version: "0.12.0" }], env: { node: true }, errors: [ "'util.debug' was deprecated since v0.12.0. Use 'console.error()' instead.", @@ -517,6 +615,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('util').error;", + options: [{ version: "0.12.0" }], env: { node: true }, errors: [ "'util.error' was deprecated since v0.12.0. Use 'console.error()' instead.", @@ -524,6 +623,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('util').isArray;", + options: [{ version: "4.0.0" }], env: { node: true }, errors: [ "'util.isArray' was deprecated since v4.0.0. Use 'Array.isArray()' instead.", @@ -531,11 +631,13 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('util').isBoolean;", + options: [{ version: "4.0.0" }], env: { node: true }, errors: ["'util.isBoolean' was deprecated since v4.0.0."], }, { code: "require('util').isBuffer;", + options: [{ version: "4.0.0" }], env: { node: true }, errors: [ "'util.isBuffer' was deprecated since v4.0.0. Use 'Buffer.isBuffer()' instead.", @@ -543,66 +645,79 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('util').isDate;", + options: [{ version: "4.0.0" }], env: { node: true }, errors: ["'util.isDate' was deprecated since v4.0.0."], }, { code: "require('util').isError;", + options: [{ version: "4.0.0" }], env: { node: true }, errors: ["'util.isError' was deprecated since v4.0.0."], }, { code: "require('util').isFunction;", + options: [{ version: "4.0.0" }], env: { node: true }, errors: ["'util.isFunction' was deprecated since v4.0.0."], }, { code: "require('util').isNull;", + options: [{ version: "4.0.0" }], env: { node: true }, errors: ["'util.isNull' was deprecated since v4.0.0."], }, { code: "require('util').isNullOrUndefined;", + options: [{ version: "4.0.0" }], env: { node: true }, errors: ["'util.isNullOrUndefined' was deprecated since v4.0.0."], }, { code: "require('util').isNumber;", + options: [{ version: "4.0.0" }], env: { node: true }, errors: ["'util.isNumber' was deprecated since v4.0.0."], }, { code: "require('util').isObject;", + options: [{ version: "4.0.0" }], env: { node: true }, errors: ["'util.isObject' was deprecated since v4.0.0."], }, { code: "require('util').isPrimitive;", + options: [{ version: "4.0.0" }], env: { node: true }, errors: ["'util.isPrimitive' was deprecated since v4.0.0."], }, { code: "require('util').isRegExp;", + options: [{ version: "4.0.0" }], env: { node: true }, errors: ["'util.isRegExp' was deprecated since v4.0.0."], }, { code: "require('util').isString;", + options: [{ version: "4.0.0" }], env: { node: true }, errors: ["'util.isString' was deprecated since v4.0.0."], }, { code: "require('util').isSymbol;", + options: [{ version: "4.0.0" }], env: { node: true }, errors: ["'util.isSymbol' was deprecated since v4.0.0."], }, { code: "require('util').isUndefined;", + options: [{ version: "4.0.0" }], env: { node: true }, errors: ["'util.isUndefined' was deprecated since v4.0.0."], }, { code: "require('util').log;", + options: [{ version: "6.0.0" }], env: { node: true }, errors: [ "'util.log' was deprecated since v6.0.0. Use a third party module instead.", @@ -610,6 +725,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('util').print;", + options: [{ version: "0.12.0" }], env: { node: true }, errors: [ "'util.print' was deprecated since v0.12.0. Use 'console.log()' instead.", @@ -617,6 +733,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('util').pump;", + options: [{ version: "0.10.0" }], env: { node: true }, errors: [ "'util.pump' was deprecated since v0.10.0. Use 'stream.Readable#pipe()' instead.", @@ -624,6 +741,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('util').puts;", + options: [{ version: "0.12.0" }], env: { node: true }, errors: [ "'util.puts' was deprecated since v0.12.0. Use 'console.log()' instead.", @@ -631,6 +749,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('util')._extend;", + options: [{ version: "6.0.0" }], env: { node: true }, errors: [ "'util._extend' was deprecated since v6.0.0. Use 'Object.assign()' instead.", @@ -638,6 +757,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "require('vm').runInDebugContext;", + options: [{ version: "8.0.0" }], env: { node: true }, errors: ["'vm.runInDebugContext' was deprecated since v8.0.0."], }, @@ -645,6 +765,7 @@ ruleTester.run("no-deprecated-api", rule, { // ES2015 Modules { code: "import b from 'buffer'; new b.Buffer()", + options: [{ version: "6.0.0" }], parserOptions: { sourceType: "module" }, env: { es6: true }, errors: [ @@ -653,6 +774,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "import * as b from 'buffer'; new b.Buffer()", + options: [{ version: "6.0.0" }], parserOptions: { sourceType: "module" }, env: { es6: true }, errors: [ @@ -661,6 +783,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "import * as b from 'buffer'; new b.default.Buffer()", + options: [{ version: "6.0.0" }], parserOptions: { sourceType: "module" }, env: { es6: true }, errors: [ @@ -669,6 +792,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "import {Buffer as b} from 'buffer'; new b()", + options: [{ version: "6.0.0" }], parserOptions: { sourceType: "module" }, env: { es6: true }, errors: [ @@ -677,6 +801,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "import b from 'buffer'; b.SlowBuffer", + options: [{ version: "6.0.0" }], parserOptions: { sourceType: "module" }, env: { es6: true }, errors: [ @@ -685,6 +810,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "import * as b from 'buffer'; b.SlowBuffer", + options: [{ version: "6.0.0" }], parserOptions: { sourceType: "module" }, env: { es6: true }, errors: [ @@ -693,6 +819,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "import * as b from 'buffer'; b.default.SlowBuffer", + options: [{ version: "6.0.0" }], parserOptions: { sourceType: "module" }, env: { es6: true }, errors: [ @@ -701,6 +828,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "import {SlowBuffer as b} from 'buffer';", + options: [{ version: "6.0.0" }], parserOptions: { sourceType: "module" }, env: { es6: true }, errors: [ @@ -709,6 +837,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "import domain from 'domain';", + options: [{ version: "4.0.0" }], parserOptions: { sourceType: "module" }, env: { es6: true }, errors: ["'domain' module was deprecated since v4.0.0."], @@ -721,6 +850,7 @@ ruleTester.run("no-deprecated-api", rule, { // ignoreModuleItems: ["buffer.Buffer()"], ignoreGlobalItems: ["Buffer()", "new Buffer()"], + version: "6.0.0", }, ], env: { node: true }, @@ -735,6 +865,7 @@ ruleTester.run("no-deprecated-api", rule, { // ignoreModuleItems: ["new buffer.Buffer()"], ignoreGlobalItems: ["Buffer()", "new Buffer()"], + version: "6.0.0", }, ], env: { node: true }, @@ -748,6 +879,7 @@ ruleTester.run("no-deprecated-api", rule, { //---------------------------------------------------------------------- { code: "new Buffer;", + options: [{ version: "6.0.0" }], env: { node: true }, errors: [ "'new Buffer()' was deprecated since v6.0.0. Use 'Buffer.alloc()' or 'Buffer.from()' instead.", @@ -755,6 +887,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "Buffer();", + options: [{ version: "6.0.0" }], env: { node: true }, errors: [ "'Buffer()' was deprecated since v6.0.0. Use 'Buffer.alloc()' or 'Buffer.from()' instead.", @@ -762,6 +895,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "GLOBAL; /*globals GLOBAL*/", + options: [{ version: "6.0.0" }], env: { node: true }, errors: [ "'GLOBAL' was deprecated since v6.0.0. Use 'global' instead.", @@ -769,11 +903,13 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "Intl.v8BreakIterator;", + options: [{ version: "7.0.0" }], env: { node: true }, errors: ["'Intl.v8BreakIterator' was deprecated since v7.0.0."], }, { code: "require.extensions;", + options: [{ version: "0.12.0" }], env: { node: true }, errors: [ "'require.extensions' was deprecated since v0.12.0. Use compiling them ahead of time instead.", @@ -781,6 +917,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "root;", + options: [{ version: "6.0.0" }], globals: { root: false }, env: { node: true }, errors: [ @@ -789,6 +926,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "process.EventEmitter;", + options: [{ version: "0.6.0" }], env: { node: true }, errors: [ "'process.EventEmitter' was deprecated since v0.6.0. Use 'require(\"events\")' instead.", @@ -796,6 +934,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "process.env.NODE_REPL_HISTORY_FILE;", + options: [{ version: "4.0.0" }], env: { node: true }, errors: [ "'process.env.NODE_REPL_HISTORY_FILE' was deprecated since v4.0.0. Use 'NODE_REPL_HISTORY' instead.", @@ -803,6 +942,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "let {env: {NODE_REPL_HISTORY_FILE}} = process;", + options: [{ version: "4.0.0" }], env: { node: true, es6: true }, errors: [ "'process.env.NODE_REPL_HISTORY_FILE' was deprecated since v4.0.0. Use 'NODE_REPL_HISTORY' instead.", @@ -810,6 +950,7 @@ ruleTester.run("no-deprecated-api", rule, { }, { code: "import domain from 'domain';", + options: [{ version: "4.0.0" }], parserOptions: { sourceType: "module" }, errors: ["'domain' module was deprecated since v4.0.0."], }, @@ -824,6 +965,7 @@ ruleTester.run("no-deprecated-api", rule, { "new buffer.Buffer()", ], ignoreGlobalItems: ["Buffer()"], + version: "6.0.0", }, ], env: { node: true }, @@ -841,6 +983,7 @@ ruleTester.run("no-deprecated-api", rule, { "new buffer.Buffer()", ], ignoreGlobalItems: ["new Buffer()"], + version: "6.0.0", }, ], env: { node: true },