diff --git a/package.json b/package.json index 45e9678..0c90c49 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "test": "yarn run lint && yarn run test:build && yarn run test:mocha && yarn run test:tslint-v5 && yarn run test:tslint-v6 && yarn run test:tslint-v6-compat", "test:build": "yarn run test:clean && tsc -p tsconfig.json", "test:clean": "rimraf build", - "test:debug": "tslint --test \"./test/v6/fixtures/no-unsafe-subject-next/**/tslint.json\"", + "test:debug": "tslint --test \"./test/v6/fixtures/no-ignored-takewhile-value/**/tslint.json\"", "test:issues": "yarn run test:clean && tsc -p tsconfig.json && tslint --test \"./test/v6/fixtures/issues/**/tslint.json\"", "test:mocha": "mocha \"./build/**/*-spec.js\"", "test:tslint-v5": "yarn --cwd ./test/v5 install && yarn --cwd ./test/v5 upgrade && tslint --test \"./test/v5/fixtures/**/tslint.json\"", diff --git a/source/rules/rxjsNoIgnoredTakewhileValueRule.ts b/source/rules/rxjsNoIgnoredTakewhileValueRule.ts new file mode 100644 index 0000000..b66b13a --- /dev/null +++ b/source/rules/rxjsNoIgnoredTakewhileValueRule.ts @@ -0,0 +1,66 @@ +/** + * @license Use of this source code is governed by an MIT-style license that + * can be found in the LICENSE file at https://github.com/cartant/rxjs-tslint-rules + */ + +import { tsquery } from "@phenomnomnominal/tsquery"; +import * as Lint from "tslint"; +import * as ts from "typescript"; +import * as peer from "../support/peer"; + +export class Rule extends Lint.Rules.TypedRule { + public static metadata: Lint.IRuleMetadata = { + deprecationMessage: peer.v5 ? peer.v5NotSupportedMessage : undefined, + description: "Disallows the ignoring of the `takeWhile` value.", + options: null, + optionsDescription: "Not configurable.", + requiresTypeInfo: true, + ruleName: "rxjs-no-ignored-takewhile-value", + type: "functionality", + typescriptOnly: true + }; + + public static FAILURE_STRING = "Ignoring the takeWhile value is forbidden"; + + public applyWithProgram( + sourceFile: ts.SourceFile, + program: ts.Program + ): Lint.RuleFailure[] { + const failures: Lint.RuleFailure[] = []; + + const callExpressions = tsquery( + sourceFile, + `CallExpression[expression.text="takeWhile"]` + ) as ts.CallExpression[]; + callExpressions.forEach(callExpression => { + let fail = false; + + const [arg] = callExpression.arguments; + if (ts.isArrowFunction(arg) || ts.isFunctionExpression(arg)) { + const [parameter] = arg.parameters; + if (parameter) { + const identifiers = tsquery( + arg, + `Identifier[name="${parameter.name.getText()}"]` + ) as ts.Identifier[]; + fail = identifiers.length < 2; + } else { + fail = true; + } + } + + if (fail) { + failures.push( + new Lint.RuleFailure( + sourceFile, + arg.getStart(), + arg.getStart() + arg.getWidth(), + Rule.FAILURE_STRING, + this.ruleName + ) + ); + } + }); + return failures; + } +} diff --git a/source/rules/rxjsNoUnsafeTakewhileRule.ts b/source/rules/rxjsNoUnsafeTakewhileRule.ts index 5b6779a..6b1d926 100644 --- a/source/rules/rxjsNoUnsafeTakewhileRule.ts +++ b/source/rules/rxjsNoUnsafeTakewhileRule.ts @@ -12,6 +12,7 @@ import { isConstDeclaration, isThis } from "../support/util"; export class Rule extends Lint.Rules.TypedRule { public static metadata: Lint.IRuleMetadata = { + deprecationMessage: "Use rxjs-no-ignored-takewhile instead.", description: "Disallows the use of variables/properties from outer scopes in takeWhile.", options: null, diff --git a/test/v6/fixtures/no-ignored-takewhile-value/default/fixture.ts.lint b/test/v6/fixtures/no-ignored-takewhile-value/default/fixture.ts.lint new file mode 100644 index 0000000..cec5011 --- /dev/null +++ b/test/v6/fixtures/no-ignored-takewhile-value/default/fixture.ts.lint @@ -0,0 +1,46 @@ +import { Observable } from "rxjs"; +import { takeWhile } from "rxjs/operators"; + +class Something { + private _alive = true; + constructor(private _source: Observable) { + + _source.pipe( + takeWhile(value => value) + ).subscribe(); + + _source.pipe( + takeWhile(value => value !== "42") + ).subscribe(); + + _source.pipe( + takeWhile(value => { return false; }) + ~~~~~~~~~~~~~~~~~~~~~~~~~~ [no-ignored-takewhile-value] + ).subscribe(); + + _source.pipe( + takeWhile(function (value) { return false; }) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [no-ignored-takewhile-value] + ).subscribe(); + + _source.pipe( + takeWhile(() => alive) + ~~~~~~~~~~~ [no-ignored-takewhile-value] + ).subscribe(); + + _source.pipe( + takeWhile(() => this._alive) + ~~~~~~~~~~~~~~~~~ [no-ignored-takewhile-value] + ).subscribe(); + + _source.pipe( + takeWhile(() => this.alive()) + ~~~~~~~~~~~~~~~~~~ [no-ignored-takewhile-value] + ).subscribe(); + } + alive(): boolean { + return this._alive; + } +} + +[no-ignored-takewhile-value]: Ignoring the takeWhile value is forbidden diff --git a/test/v6/fixtures/no-ignored-takewhile-value/default/tsconfig.json b/test/v6/fixtures/no-ignored-takewhile-value/default/tsconfig.json new file mode 100644 index 0000000..690be78 --- /dev/null +++ b/test/v6/fixtures/no-ignored-takewhile-value/default/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "lib": ["es2015"], + "noEmit": true, + "paths": { + "rxjs": ["../../node_modules/rxjs"] + }, + "skipLibCheck": true, + "target": "es5" + }, + "include": ["fixture.ts"] +} diff --git a/test/v6/fixtures/no-ignored-takewhile-value/default/tslint.json b/test/v6/fixtures/no-ignored-takewhile-value/default/tslint.json new file mode 100644 index 0000000..590a23a --- /dev/null +++ b/test/v6/fixtures/no-ignored-takewhile-value/default/tslint.json @@ -0,0 +1,8 @@ +{ + "defaultSeverity": "error", + "jsRules": {}, + "rules": { + "rxjs-no-ignored-takewhile-value": { "severity": "error" } + }, + "rulesDirectory": "../../../../../build/rules" +}