Skip to content

Commit

Permalink
feat(rxjs-no-patched): Add rule.
Browse files Browse the repository at this point in the history
  • Loading branch information
cartant committed Jul 15, 2017
1 parent 86a5f74 commit c9b7405
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ The package includes the following rules:
| --- | --- | --- |
| `rxjs-add` | Enforces the importation of patched observables and operators used in the module. | See below |
| `rxjs-no-add` | Disallows the importation of patched observables and operators. | None |
| `rxjs-no-patched` | Disallows the calling of patched methods. Operators must be imported and called explicitly - not via the `Observable` prototype. | None |
| `rxjs-no-subject-unsubscribe` | Disallows the calling of `unsubscribe` directly upon `Subject` instances. For an explanation of why this can be a problem, see [this](https://stackoverflow.com/a/45112125/6680611) Stack Overflow answer. | None |
| `rxjs-no-unused-add` | Disallows the importation of patched observables or operators that are not used in the module. | None |
| `rxjs-prefer-add` | Disallows the importation of `rxjs` or `rxjs/Rx`. | None |
Expand Down
1 change: 1 addition & 0 deletions fixtures/no-patched/adds.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import "rxjs/add/operator/map";
7 changes: 7 additions & 0 deletions fixtures/no-patched/fixture.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Observable } from "rxjs/Observable";
import { Subject } from "rxjs/Subject";
import { filter } from "rxjs/operator/filter";

const subject = new Subject<number>();
const filtered = filter.call(subject, (value) => value > 1) as Observable<number>;
const mapped = filtered.map((value) => value + 1);
13 changes: 13 additions & 0 deletions fixtures/no-patched/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"compilerOptions": {
"baseUrl": ".",
"lib": ["es2015"],
"noEmit": true,
"paths": {
"rxjs": ["../node_modules/rxjs"]
},
"skipLibCheck": true,
"target": "es5"
},
"include": ["adds.ts", "fixture.ts"]
}
8 changes: 8 additions & 0 deletions fixtures/no-patched/tslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"defaultSeverity": "error",
"jsRules": {},
"rules": {
"rxjs-no-patched": { "severity": "error" }
},
"rulesDirectory": "../../build/rules"
}
11 changes: 11 additions & 0 deletions source/fixtures-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,17 @@ describe("fixtures", function (): void {
});
});

describe("no-patched", () => {

it("should effect an 'rxjs-no-patched' error", () => {

const result = lint("no-patched", "tslint.json");

expect(result).to.have.property("errorCount", 1);
expect(result.failures[0]).to.have.property("ruleName", "rxjs-no-patched");
});
});

describe("observable-create", () => {

it("should effect an error unless explicit typing is used", () => {
Expand Down
54 changes: 54 additions & 0 deletions source/rules/rxjsNoPatchedRule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* @license Copyright © 2017 Nicholas Jamieson. All Rights Reserved.
* 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
*/
/*tslint:disable:no-use-before-declare*/

import * as Lint from "tslint";
import * as path from "path";
import * as ts from "typescript";

import { UsedWalker } from "../support/used-walker";

export class Rule extends Lint.Rules.TypedRule {

public static metadata: Lint.IRuleMetadata = {
description: "Disallows the calling of patched methods.",
options: null,
optionsDescription: "Not configurable.",
requiresTypeInfo: true,
ruleName: "rxjs-no-patched",
type: "functionality",
typescriptOnly: true
};

public static FAILURE_STRING = "RxJS patched methods are forbidden";

public applyWithProgram(sourceFile: ts.SourceFile, program: ts.Program): Lint.RuleFailure[] {

return this.applyWithWalker(new Walker(sourceFile, this.getOptions(), program));
}
}

class Walker extends UsedWalker {

protected onSourceFileEnd(): void {

Object.keys(this.usedObservables).forEach((key) => {

this.usedObservables[key].forEach((node) => this.addFailureAtNode(
node,
`${Rule.FAILURE_STRING}: ${key}`
));
});

Object.keys(this.usedOperators).forEach((key) => {

this.usedOperators[key].forEach((node) => this.addFailureAtNode(
node,
`${Rule.FAILURE_STRING}: ${key}`
));
});
}
}
1 change: 1 addition & 0 deletions source/rules/rxjsNoSubjectUnsubscribeRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import * as Lint from "tslint";
import * as ts from "typescript";

import { couldBeType, isReferenceType } from "../support/util";

export class Rule extends Lint.Rules.TypedRule {
Expand Down

0 comments on commit c9b7405

Please sign in to comment.