From 376648d51bc313f041bd40c47edfc75cae8fa45e Mon Sep 17 00:00:00 2001 From: Brandon Mills Date: Fri, 1 Jan 2021 17:30:48 -0500 Subject: [PATCH] WIP New: Add only to RuleTester (refs eslint/rfcs#73) --- Makefile.js | 2 +- lib/rule-tester/rule-tester.js | 56 +++++++++++++++++++++++++++++----- 2 files changed, 49 insertions(+), 9 deletions(-) diff --git a/Makefile.js b/Makefile.js index 840a51a86d7..e32fe62e612 100644 --- a/Makefile.js +++ b/Makefile.js @@ -545,7 +545,7 @@ target.mocha = () => { echo("Running unit tests"); - lastReturn = exec(`${getBinFile("nyc")} -- ${MOCHA} -R progress -t ${MOCHA_TIMEOUT} -c ${TEST_FILES}`); + lastReturn = exec(`${getBinFile("nyc")} -- ${MOCHA} --forbid-only -R progress -t ${MOCHA_TIMEOUT} -c ${TEST_FILES}`); if (lastReturn.code !== 0) { errors++; } diff --git a/lib/rule-tester/rule-tester.js b/lib/rule-tester/rule-tester.js index 905f3418121..7e788e7ca2a 100644 --- a/lib/rule-tester/rule-tester.js +++ b/lib/rule-tester/rule-tester.js @@ -120,7 +120,8 @@ const RuleTesterParameters = [ "filename", "options", "errors", - "output" + "output", + "only" ]; /* @@ -281,6 +282,7 @@ function wrapParser(parser) { // default separators for testing const DESCRIBE = Symbol("describe"); const IT = Symbol("it"); +const IT_ONLY = Symbol("itOnly"); /** * This is `it` default handler if `it` don't exist. @@ -400,6 +402,38 @@ class RuleTester { this[IT] = value; } + static only(item) { + if (typeof item === "string") { + return { code: item, only: true }; + } + + return { ...item, only: true }; + } + + static get itOnly() { + if (typeof this[IT_ONLY] === "function") { + return this[IT_ONLY]; + } + if (typeof it === "function" && typeof it.only === "function") { + return Function.bind.call(it.only, it); + } + + if (typeof RuleTester[DESCRIBE] === "function" || typeof RuleTester[IT] === "function") { + throw new Error( + "Set `RuleTester.itOnly` to use `only` with a custom test framework.\n" + + "See https://eslint.org/docs/developer-guide/nodejs-api#customizing-ruletester for more." + ); + } + if (typeof it === "function") { + throw new Error("The current test framework does not support `only`."); + } + throw new Error("To use `only`, use RuleTester with a test framework that provides `it.only()` like Mocha."); + } + + static set itOnly(value) { + this[IT_ONLY] = value; + } + /** * Define a rule for one particular run of tests. * @param {string} name The name of the rule to define. @@ -881,23 +915,29 @@ class RuleTester { RuleTester.describe(ruleName, () => { RuleTester.describe("valid", () => { test.valid.forEach(valid => { - RuleTester.it(sanitize(typeof valid === "object" ? valid.code : valid), () => { - testValidTemplate(valid); - }); + RuleTester[valid.only ? "itOnly" : "it"]( + sanitize(typeof valid === "object" ? valid.code : valid), + () => { + testValidTemplate(valid); + } + ); }); }); RuleTester.describe("invalid", () => { test.invalid.forEach(invalid => { - RuleTester.it(sanitize(invalid.code), () => { - testInvalidTemplate(invalid); - }); + RuleTester[invalid.only ? "itOnly" : "it"]( + sanitize(invalid.code), + () => { + testInvalidTemplate(invalid); + } + ); }); }); }); } } -RuleTester[DESCRIBE] = RuleTester[IT] = null; +RuleTester[DESCRIBE] = RuleTester[IT] = RuleTester[IT_ONLY] = null; module.exports = RuleTester;