Skip to content

Commit 95cc17c

Browse files
committed
feat(deep-operators): Add rule.
1 parent c299a75 commit 95cc17c

File tree

7 files changed

+81
-4
lines changed

7 files changed

+81
-4
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,15 +73,16 @@ The package includes the following rules (none of which are enabled by default):
7373
| Rule | Description | Options |
7474
| --- | --- | --- |
7575
| `rxjs-add` | Enforces the importation of patched observables and operators used in the module. | [See below](#rxjs-add) |
76+
| `rxjs-deep-operators` | Enforces deep importation from within `rxjs/operators` - e.g. `rxjs/operators/map`. Until Webpack does not require configuration for tree shaking to work, there will be situations where deep imports are preferred. | None |
7677
| `rxjs-finnish` | Enforces the use of [Finnish notation](https://medium.com/@benlesh/observables-and-finnish-notation-df8356ed1c9b). | [See below](#rxjs-finnish) |
7778
| `rxjs-no-add` | Disallows the importation of patched observables and operators. | [See below](#rxjs-no-add) |
7879
| `rxjs-no-create` | Disallows the calling of `Observable.create`. Useful as a warning. | None |
79-
| `rxjs-no-deep-operators` | Disallows deep importation from 'rxjs/operators'. Deep imports won't be in available in RxJS v6. | None |
80+
| `rxjs-no-deep-operators` | Disallows deep importation from `rxjs/operators`. Deep imports won't be in available in RxJS v6. | None |
8081
| `rxjs-no-do` | I do without `do` operators. [Do you not?](https://youtu.be/spG-Yj0zEyc) Well, `do` isn't always a code smell, but this rule can be useful as a warning. | None |
8182
| `rxjs-no-finnish` | Disallows the use of [Finnish notation](https://medium.com/@benlesh/observables-and-finnish-notation-df8356ed1c9b). | None |
8283
| `rxjs-no-ignored-error` | Disallows the calling of `subscribe` without specifying an error handler. | None |
8384
| `rxjs-no-ignored-subscribe` | Disallows the calling of subscribe without specifying arguments. | None |
84-
| `rxjs-no-operator` | Disallows importation from 'rxjs/operator'. Useful if you prefer ['lettable' operators](https://github.com/ReactiveX/rxjs/blob/master/doc/lettable-operators.md) - which are located in the `operators` directory. | None |
85+
| `rxjs-no-operator` | Disallows importation from `rxjs/operator`. Useful if you prefer ['lettable' operators](https://github.com/ReactiveX/rxjs/blob/master/doc/lettable-operators.md) - which are located in the `operators` directory. | None |
8586
| `rxjs-no-patched` | Disallows the calling of patched methods. Methods must be imported and called explicitly - not via `Observable` or `Observable.prototype`. | [See below](#rxjs-no-add) |
8687
| `rxjs-no-subject-unsubscribe` | Disallows calling the `unsubscribe` method of a `Subject` instance. For an explanation of why this can be a problem, see [this](https://stackoverflow.com/a/45112125/6680611) Stack Overflow answer. | None |
8788
| `rxjs-no-subject-value` | Disallows accessing the `value` property of a `BehaviorSubject` instance. | None |

docs/index.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,16 @@ The package includes the following rules (none of which are enabled by default):
1313
| Rule | Description | Options |
1414
| --- | --- | --- |
1515
| `rxjs-add` | Enforces the importation of patched observables and operators used in the module. | [See below](#rxjs-add) |
16+
| `rxjs-deep-operators` | Enforces deep importation from within `rxjs/operators` - e.g. `rxjs/operators/map`. Until Webpack does not require configuration for tree shaking to work, there will be situations where deep imports are preferred. | None |
1617
| `rxjs-finnish` | Enforces the use of [Finnish notation](https://medium.com/@benlesh/observables-and-finnish-notation-df8356ed1c9b). | [See below](#rxjs-finnish) |
1718
| `rxjs-no-add` | Disallows the importation of patched observables and operators. | [See below](#rxjs-no-add) |
1819
| `rxjs-no-create` | Disallows the calling of `Observable.create`. Useful as a warning. | None |
19-
| `rxjs-no-deep-operators` | Disallows deep importation from 'rxjs/operators'. Deep imports won't be in available in RxJS v6. | None |
20+
| `rxjs-no-deep-operators` | Disallows deep importation from `rxjs/operators`. Deep imports won't be in available in RxJS v6. | None |
2021
| `rxjs-no-do` | I do without `do` operators. [Do you not?](https://youtu.be/spG-Yj0zEyc) Well, `do` isn't always a code smell, but this rule can be useful as a warning. | None |
2122
| `rxjs-no-finnish` | Disallows the use of [Finnish notation](https://medium.com/@benlesh/observables-and-finnish-notation-df8356ed1c9b). | None |
2223
| `rxjs-no-ignored-error` | Disallows the calling of `subscribe` without specifying an error handler. | None |
2324
| `rxjs-no-ignored-subscribe` | Disallows the calling of subscribe without specifying arguments. | None |
24-
| `rxjs-no-operator` | Disallows importation from 'rxjs/operator'. Useful if you prefer ['lettable' operators](https://github.com/ReactiveX/rxjs/blob/master/doc/lettable-operators.md) - which are located in the `operators` directory. | None |
25+
| `rxjs-no-operator` | Disallows importation from `rxjs/operator`. Useful if you prefer ['lettable' operators](https://github.com/ReactiveX/rxjs/blob/master/doc/lettable-operators.md) - which are located in the `operators` directory. | None |
2526
| `rxjs-no-patched` | Disallows the calling of patched methods. Methods must be imported and called explicitly - not via `Observable` or `Observable.prototype`. | [See below](#rxjs-no-add) |
2627
| `rxjs-no-subject-unsubscribe` | Disallows calling the `unsubscribe` method of a `Subject` instance. For an explanation of why this can be a problem, see [this](https://stackoverflow.com/a/45112125/6680611) Stack Overflow answer. | None |
2728
| `rxjs-no-subject-value` | Disallows accessing the `value` property of a `BehaviorSubject` instance. | None |

fixtures/deep-operators/fixture.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import { Observable } from "rxjs";
2+
import { map, tap } from "rxjs/operators";

fixtures/deep-operators/tsconfig.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"compilerOptions": {
3+
"baseUrl": ".",
4+
"lib": ["es2015"],
5+
"noEmit": true,
6+
"paths": {
7+
"rxjs": ["../node_modules/rxjs"]
8+
},
9+
"skipLibCheck": true,
10+
"target": "es5"
11+
},
12+
"include": ["fixture.ts"]
13+
}

fixtures/deep-operators/tslint.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"defaultSeverity": "error",
3+
"jsRules": {},
4+
"rules": {
5+
"rxjs-deep-operators": { "severity": "error" }
6+
},
7+
"rulesDirectory": "../../build/rules"
8+
}

source/fixtures-spec.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,17 @@ describe("fixtures", function (): void {
201201
});
202202
});
203203

204+
describe("deep-operators", () => {
205+
206+
it("should effect 'rxjs-deep-operators' errors", () => {
207+
208+
const result = lint("deep-operators", "tslint.json");
209+
210+
expect(result).to.have.property("errorCount", 1);
211+
result.failures.forEach(failure => expect(failure).to.have.property("ruleName", "rxjs-deep-operators"));
212+
});
213+
});
214+
204215
describe("elsewhere-with-file", () => {
205216

206217
it("should effect an 'rxjs-add' error", () => {

source/rules/rxjsDeepOperatorsRule.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**
2+
* @license Use of this source code is governed by an MIT-style license that
3+
* can be found in the LICENSE file at https://github.com/cartant/rxjs-tslint-rules
4+
*/
5+
/*tslint:disable:no-use-before-declare*/
6+
7+
import * as Lint from "tslint";
8+
import * as ts from "typescript";
9+
10+
export class Rule extends Lint.Rules.AbstractRule {
11+
12+
public static metadata: Lint.IRuleMetadata = {
13+
description: "Enforces deep importation from within 'rxjs/operators'.",
14+
options: null,
15+
optionsDescription: "Not configurable.",
16+
requiresTypeInfo: false,
17+
ruleName: "rxjs-deep-operators",
18+
type: "functionality",
19+
typescriptOnly: false
20+
};
21+
22+
public static FAILURE_STRING = "Deep importation from 'rxjs/operators' is required";
23+
24+
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
25+
return this.applyWithWalker(new Walker(sourceFile, this.getOptions()));
26+
}
27+
}
28+
29+
class Walker extends Lint.RuleWalker {
30+
31+
public visitImportDeclaration(node: ts.ImportDeclaration): void {
32+
33+
const moduleSpecifier = node.moduleSpecifier.getText();
34+
35+
if (/^['"]rxjs\/operators\/?['"]$/.test(moduleSpecifier)) {
36+
this.addFailureAtNode(node, Rule.FAILURE_STRING);
37+
}
38+
39+
super.visitImportDeclaration(node);
40+
}
41+
}

0 commit comments

Comments
 (0)