diff --git a/apps/oxlint/conformance/snapshot.md b/apps/oxlint/conformance/snapshot.md index 8bd4df774e7f6..56732b574b5af 100644 --- a/apps/oxlint/conformance/snapshot.md +++ b/apps/oxlint/conformance/snapshot.md @@ -7,8 +7,8 @@ | Status | Count | % | | ----------------- | ----- | ------ | | Total rules | 292 | 100.0% | -| Fully passing | 284 | 97.3% | -| Partially passing | 8 | 2.7% | +| Fully passing | 288 | 98.6% | +| Partially passing | 4 | 1.4% | | Fully failing | 0 | 0.0% | | Load errors | 0 | 0.0% | | No tests run | 0 | 0.0% | @@ -19,8 +19,8 @@ | ----------- | ----- | ------ | | Total tests | 33090 | 100.0% | | Passing | 32799 | 99.1% | -| Failing | 20 | 0.1% | -| Skipped | 271 | 0.8% | +| Failing | 6 | 0.0% | +| Skipped | 285 | 0.9% | ## Fully Passing Rules @@ -142,6 +142,7 @@ - `no-extra-bind` (43 tests) - `no-extra-boolean-cast` (501 tests) (1 skipped) - `no-extra-label` (34 tests) +- `no-extra-parens` (1072 tests) (5 skipped) - `no-extra-semi` (53 tests) - `no-fallthrough` (87 tests) (1 skipped) - `no-floating-decimal` (8 tests) @@ -154,6 +155,7 @@ - `no-inline-comments` (49 tests) - `no-inner-declarations` (68 tests) - `no-invalid-regexp` (108 tests) +- `no-invalid-this` (562 tests) (4 skipped) - `no-iterator` (9 tests) - `no-label-var` (5 tests) - `no-labels` (29 tests) @@ -233,9 +235,11 @@ - `no-unsafe-finally` (28 tests) - `no-unsafe-negation` (29 tests) - `no-unsafe-optional-chaining` (187 tests) +- `no-unused-expressions` (124 tests) (4 skipped) - `no-unused-labels` (26 tests) - `no-unused-private-class-members` (39 tests) - `no-unused-vars` (436 tests) (21 skipped) +- `no-use-before-define` (347 tests) (1 skipped) - `no-useless-assignment` (85 tests) (2 skipped) - `no-useless-backreference` (190 tests) (1 skipped) - `no-useless-call` (44 tests) @@ -311,12 +315,8 @@ ## Rules with Failures -- `no-eval` - 99 / 101 (98.0%) -- `no-extra-parens` - 1068 / 1072 (99.6%) -- `no-invalid-this` - 558 / 562 (99.3%) +- `no-eval` - 100 / 101 (99.0%) - `no-irregular-whitespace` - 279 / 280 (99.6%) -- `no-unused-expressions` - 120 / 124 (96.8%) -- `no-use-before-define` - 346 / 347 (99.7%) - `prefer-object-spread` - 86 / 87 (98.9%) - `unicode-bom` - 4 / 7 (57.1%) @@ -325,8 +325,8 @@ ### `no-eval` Pass: 99 / 101 (98.0%) -Fail: 2 / 101 (2.0%) -Skip: 0 / 101 (0.0%) +Fail: 1 / 101 (1.0%) +Skip: 1 / 101 (1.0%) #### no-eval > invalid @@ -360,361 +360,6 @@ AssertionError [ERR_ASSERTION]: Should have 1 error but had 0: [] at apps/oxlint/dist/index.js -#### no-eval > invalid - -```js -function foo() { 'use strict'; this.eval(); } -``` - -```json -{ - "languageOptions": { - "ecmaVersion": 3, - "sourceType": "script" - }, - "errors": [ - { - "messageId": "unexpected" - } - ] -} -``` - -AssertionError [ERR_ASSERTION]: Should have 1 error but had 0: [] - -0 !== 1 - - at assertErrorCountIsCorrect (apps/oxlint/dist/index.js) - at assertInvalidTestCasePasses (apps/oxlint/dist/index.js) - at runInvalidTestCase (apps/oxlint/dist/index.js) - at apps/oxlint/dist/index.js - - -### `no-extra-parens` - -Pass: 1067 / 1072 (99.5%) -Fail: 4 / 1072 (0.4%) -Skip: 1 / 1072 (0.1%) - -#### no-extra-parens > valid - -```js -(let[a] = b); -``` - -```json -{ - "languageOptions": { - "sourceType": "script", - "parserOptions": { - "ecmaFeatures": { - "jsx": true - } - } - } -} -``` - -AssertionError [ERR_ASSERTION]: Should have no errors but had 1: [ - { - ruleId: 'rule-to-test/no-extra-parens', - message: 'Unnecessary parentheses around expression.', - messageId: 'unexpected', - severity: 1, - nodeType: 'ExpressionStatement', - line: 1, - column: 0, - endLine: 1, - endColumn: 1, - suggestions: null - } -] - -1 !== 0 - - at assertErrorCountIsCorrect (apps/oxlint/dist/index.js) - at assertValidTestCasePasses (apps/oxlint/dist/index.js) - at runValidTestCase (apps/oxlint/dist/index.js) - at apps/oxlint/dist/index.js - - -#### no-extra-parens > valid - -```js -(let) -foo -``` - -```json -{ - "languageOptions": { - "sourceType": "script", - "parserOptions": { - "ecmaFeatures": { - "jsx": true - } - } - } -} -``` - -AssertionError [ERR_ASSERTION]: Should have no errors but had 1: [ - { - ruleId: 'rule-to-test/no-extra-parens', - message: 'Unnecessary parentheses around expression.', - messageId: 'unexpected', - severity: 1, - nodeType: 'ExpressionStatement', - line: 1, - column: 0, - endLine: 1, - endColumn: 1, - suggestions: null - } -] - -1 !== 0 - - at assertErrorCountIsCorrect (apps/oxlint/dist/index.js) - at assertValidTestCasePasses (apps/oxlint/dist/index.js) - at runValidTestCase (apps/oxlint/dist/index.js) - at apps/oxlint/dist/index.js - - -#### no-extra-parens > valid - -```js -(let[foo]) = 1 -``` - -```json -{ - "languageOptions": { - "sourceType": "script", - "parserOptions": { - "ecmaFeatures": { - "jsx": true - } - } - } -} -``` - -AssertionError [ERR_ASSERTION]: Should have no errors but had 1: [ - { - ruleId: 'rule-to-test/no-extra-parens', - message: 'Unnecessary parentheses around expression.', - messageId: 'unexpected', - severity: 1, - nodeType: 'AssignmentExpression', - line: 1, - column: 0, - endLine: 1, - endColumn: 1, - suggestions: null - } -] - -1 !== 0 - - at assertErrorCountIsCorrect (apps/oxlint/dist/index.js) - at assertValidTestCasePasses (apps/oxlint/dist/index.js) - at runValidTestCase (apps/oxlint/dist/index.js) - at apps/oxlint/dist/index.js - - -#### no-extra-parens > valid - -```js -(let)[foo] -``` - -```json -{ - "languageOptions": { - "sourceType": "script", - "parserOptions": { - "ecmaFeatures": { - "jsx": true - } - } - } -} -``` - -AssertionError [ERR_ASSERTION]: Should have no errors but had 1: [ - { - ruleId: 'rule-to-test/no-extra-parens', - message: 'Unnecessary parentheses around expression.', - messageId: 'unexpected', - severity: 1, - nodeType: 'MemberExpression', - line: 1, - column: 0, - endLine: 1, - endColumn: 1, - suggestions: null - } -] - -1 !== 0 - - at assertErrorCountIsCorrect (apps/oxlint/dist/index.js) - at assertValidTestCasePasses (apps/oxlint/dist/index.js) - at runValidTestCase (apps/oxlint/dist/index.js) - at apps/oxlint/dist/index.js - - -### `no-invalid-this` - -Pass: 558 / 562 (99.3%) -Fail: 4 / 562 (0.7%) -Skip: 0 / 562 (0.0%) - -#### no-invalid-this > valid - -```js -function foo() { 'use strict'; this.eval(); } -``` - -```json -{ - "languageOptions": { - "ecmaVersion": 3, - "sourceType": "script" - } -} -``` - -AssertionError [ERR_ASSERTION]: Should have no errors but had 1: [ - { - ruleId: 'rule-to-test/no-invalid-this', - message: "Unexpected 'this'.", - messageId: 'unexpectedThis', - severity: 1, - nodeType: 'ThisExpression', - line: 1, - column: 31, - endLine: 1, - endColumn: 35, - suggestions: null - } -] - -1 !== 0 - - at assertErrorCountIsCorrect (apps/oxlint/dist/index.js) - at assertValidTestCasePasses (apps/oxlint/dist/index.js) - at runValidTestCase (apps/oxlint/dist/index.js) - at apps/oxlint/dist/index.js - - -#### no-invalid-this > valid - -```js -"use strict"; function foo() { 'use strict'; this.eval(); } -``` - -```json -{ - "languageOptions": { - "ecmaVersion": 3, - "sourceType": "script" - } -} -``` - -AssertionError [ERR_ASSERTION]: Should have no errors but had 1: [ - { - ruleId: 'rule-to-test/no-invalid-this', - message: "Unexpected 'this'.", - messageId: 'unexpectedThis', - severity: 1, - nodeType: 'ThisExpression', - line: 1, - column: 45, - endLine: 1, - endColumn: 49, - suggestions: null - } -] - -1 !== 0 - - at assertErrorCountIsCorrect (apps/oxlint/dist/index.js) - at assertValidTestCasePasses (apps/oxlint/dist/index.js) - at runValidTestCase (apps/oxlint/dist/index.js) - at apps/oxlint/dist/index.js - - -#### no-invalid-this > valid - -```js -/* implied strict mode */ function foo() { 'use strict'; this.eval(); } -``` - -```json -{ - "languageOptions": { - "ecmaVersion": 3, - "sourceType": "script", - "parserOptions": { - "ecmaFeatures": { - "impliedStrict": true - } - } - } -} -``` - -AssertionError [ERR_ASSERTION]: Should have no errors but had 1: [ - { - ruleId: 'rule-to-test/no-invalid-this', - message: "Unexpected 'this'.", - messageId: 'unexpectedThis', - severity: 1, - nodeType: 'ThisExpression', - line: 1, - column: 57, - endLine: 1, - endColumn: 61, - suggestions: null - } -] - -1 !== 0 - - at assertErrorCountIsCorrect (apps/oxlint/dist/index.js) - at assertValidTestCasePasses (apps/oxlint/dist/index.js) - at runValidTestCase (apps/oxlint/dist/index.js) - at apps/oxlint/dist/index.js - - -#### no-invalid-this > valid - -```js - - z(function (x, this: context) { - console.log(x, this); - }); - -``` - -```json -{ - "languageOptions": { - "parser": {} - } -} -``` - -Error: Parsing failed - at parse (apps/oxlint/dist/index.js) - at lint (apps/oxlint/dist/index.js) - at assertValidTestCasePasses (apps/oxlint/dist/index.js) - at runValidTestCase (apps/oxlint/dist/index.js) - - ### `no-irregular-whitespace` Pass: 279 / 280 (99.6%) @@ -754,177 +399,6 @@ AssertionError [ERR_ASSERTION]: Should have no errors but had 1: [ at apps/oxlint/dist/index.js -### `no-unused-expressions` - -Pass: 120 / 124 (96.8%) -Fail: 4 / 124 (3.2%) -Skip: 0 / 124 (0.0%) - -#### no-unused-expressions > invalid - -```js -"use strict"; -``` - -```json -{ - "languageOptions": { - "ecmaVersion": 3, - "sourceType": "script" - }, - "errors": [ - { - "messageId": "unusedExpression" - } - ] -} -``` - -AssertionError [ERR_ASSERTION]: Should have 1 error but had 0: [] - -0 !== 1 - - at assertErrorCountIsCorrect (apps/oxlint/dist/index.js) - at assertInvalidTestCasePasses (apps/oxlint/dist/index.js) - at runInvalidTestCase (apps/oxlint/dist/index.js) - at apps/oxlint/dist/index.js - - -#### no-unused-expressions > invalid - -```js -"directive one"; "directive two"; f(); -``` - -```json -{ - "languageOptions": { - "ecmaVersion": 3, - "sourceType": "script" - }, - "errors": [ - { - "messageId": "unusedExpression" - }, - { - "messageId": "unusedExpression" - } - ] -} -``` - -AssertionError [ERR_ASSERTION]: Should have 2 errors but had 0: [] - -0 !== 2 - - at assertErrorCountIsCorrect (apps/oxlint/dist/index.js) - at assertInvalidTestCasePasses (apps/oxlint/dist/index.js) - at runInvalidTestCase (apps/oxlint/dist/index.js) - at apps/oxlint/dist/index.js - - -#### no-unused-expressions > invalid - -```js -function foo() {"use strict"; return true; } -``` - -```json -{ - "languageOptions": { - "ecmaVersion": 3, - "sourceType": "script" - }, - "errors": [ - { - "messageId": "unusedExpression" - } - ] -} -``` - -AssertionError [ERR_ASSERTION]: Should have 1 error but had 0: [] - -0 !== 1 - - at assertErrorCountIsCorrect (apps/oxlint/dist/index.js) - at assertInvalidTestCasePasses (apps/oxlint/dist/index.js) - at runInvalidTestCase (apps/oxlint/dist/index.js) - at apps/oxlint/dist/index.js - - -#### no-unused-expressions > invalid - -```js -function foo() {"directive one"; "directive two"; f(); } -``` - -```json -{ - "languageOptions": { - "ecmaVersion": 3, - "sourceType": "script" - }, - "errors": [ - { - "messageId": "unusedExpression" - }, - { - "messageId": "unusedExpression" - } - ] -} -``` - -AssertionError [ERR_ASSERTION]: Should have 2 errors but had 0: [] - -0 !== 2 - - at assertErrorCountIsCorrect (apps/oxlint/dist/index.js) - at assertInvalidTestCasePasses (apps/oxlint/dist/index.js) - at runInvalidTestCase (apps/oxlint/dist/index.js) - at apps/oxlint/dist/index.js - - -### `no-use-before-define` - -Pass: 346 / 347 (99.7%) -Fail: 1 / 347 (0.3%) -Skip: 0 / 347 (0.0%) - -#### no-use-before-define > invalid - -```js -"use strict"; a(); { function a() {} } -``` - -```json -{ - "languageOptions": { - "ecmaVersion": 5, - "sourceType": "script" - }, - "errors": [ - { - "messageId": "usedBeforeDefined", - "data": { - "name": "a" - } - } - ] -} -``` - -AssertionError [ERR_ASSERTION]: Should have 1 error but had 0: [] - -0 !== 1 - - at assertErrorCountIsCorrect (apps/oxlint/dist/index.js) - at assertInvalidTestCasePasses (apps/oxlint/dist/index.js) - at runInvalidTestCase (apps/oxlint/dist/index.js) - at apps/oxlint/dist/index.js - - ### `prefer-object-spread` Pass: 84 / 87 (96.6%) diff --git a/apps/oxlint/conformance/src/capture.ts b/apps/oxlint/conformance/src/capture.ts index 98f5a6d5893fe..6b0060c00e799 100644 --- a/apps/oxlint/conformance/src/capture.ts +++ b/apps/oxlint/conformance/src/capture.ts @@ -2,7 +2,7 @@ * `describe` and `it` functions for capturing test results. */ -import type { TestCase } from "./rule_tester.ts"; +import type { TestCase, LanguageOptionsInternal } from "./rule_tester.ts"; /** * Result of running all tests in a rule file. @@ -139,6 +139,46 @@ function shouldSkipTest(ruleName: string, test: TestCase, code: string, err: Err // These are not handled by `RuleTester`. if (code.match(/\/\/\s*eslint-disable((-next)?-line)?(\s|$)/)) return true; + const languageOptions = test.languageOptions as LanguageOptionsInternal | undefined; + + // Tests rely on directives being parsed as plain `StringLiteral`s in ES3. + // Oxc parser does not support parsing as ES3. + if ( + (ruleName === "no-eval" || + ruleName === "no-invalid-this" || + ruleName === "no-unused-expressions") && + languageOptions?.ecmaVersion === 3 + ) { + return true; + } + + // Test relies on scope analysis to follow ES5 semantics where function declarations in blocks are bound in parent scope. + // TS-ESLint scope manager does not support ES5. Oxc also doesn't support parsing/semantic as ES5. + if ( + ruleName === "no-use-before-define" && + code === '"use strict"; a(); { function a() {} }' && + languageOptions?.ecmaVersion === 5 + ) { + return true; + } + + // Code contains unrecoverable syntax error - `function (x, this: context) {}` + if ( + ruleName === "no-invalid-this" && + code.includes("function (x, this: context) {") && + err?.message === "Parsing failed" + ) { + return true; + } + + // TypeScript parser incorrectly tokenizes `let` as a `Keyword` instead of an `Identifier` token + if ( + ruleName === "no-extra-parens" && + ["(let[a] = b);", "(let)\nfoo", "(let[foo]) = 1", "(let)[foo]"].includes(code) + ) { + return true; + } + return false; }