Skip to content

Commit

Permalink
feat(finnish): Support whitelist.
Browse files Browse the repository at this point in the history
  • Loading branch information
cartant committed May 1, 2018
1 parent 33721d8 commit 5051876
Show file tree
Hide file tree
Showing 12 changed files with 182 additions and 1 deletion.
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,28 @@ For example, to enforce Finnish notation for variables only:
}
```

The options also support `names` and `types` properties that can be used to prevent the enforcement of Finnish notation for certain names or types.

For example, the following configuration will not enforce Finnish notation for names ending with `Stream` or for the `EventEmitter` type:

```json
"rules": {
"rxjs-finnish": {
"options": [{
"names": {
"Stream$": false
},
"types": {
"^EventEmitter$": false
}
}],
"severity": "error"
}
}
```

If the `types` property is not specified, it will default to not enforcing Finnish notation for Angular's `EventEmitter` type.

<a name="rxjs-no-add"></a>

#### rxjs-no-add and rxjs-no-patched
Expand Down
22 changes: 22 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,28 @@ For example, to enforce Finnish notation for variables only:
}
```

The options also support `names` and `types` properties that can be used to prevent the enforcement of Finnish notation for certain names or types.

For example, the following configuration will not enforce Finnish notation for names ending with `Stream` or for the `EventEmitter` type:

```json
"rules": {
"rxjs-finnish": {
"options": [{
"names": {
"Stream$": false
},
"types": {
"^EventEmitter$": false
}
}],
"severity": "error"
}
}
```

If the `types` property is not specified, it will default to not enforcing Finnish notation for Angular's `EventEmitter` type.

<a name="rxjs-no-add"></a>

#### rxjs-no-add and rxjs-no-patched
Expand Down
6 changes: 6 additions & 0 deletions fixtures/v5/finnish-whitelist/fixture-blacklist.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Subject } from "rxjs/Subject";
import { of } from "rxjs/observable/of";

class SomeSubject<T> extends Subject<T> {}
let someSubject: SomeSubject<any>;
const finnish = of(1);
6 changes: 6 additions & 0 deletions fixtures/v5/finnish-whitelist/fixture.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Subject } from "rxjs/Subject";
import { of } from "rxjs/observable/of";

class EventEmitter<T> extends Subject<T> {}
let eventEmitter: EventEmitter<any>;
const foreign = of(1);
13 changes: 13 additions & 0 deletions fixtures/v5/finnish-whitelist/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": ["fixture.ts", "fixture-blacklist.ts"]
}
20 changes: 20 additions & 0 deletions fixtures/v5/finnish-whitelist/tslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"defaultSeverity": "error",
"jsRules": {},
"rules": {
"rxjs-finnish": {
"options": [{
"names": {
"^finnish$": true,
"^foreign$": false
},
"types": {
"^EventEmitter$": false,
"^SomeSubject$": true
}
}],
"severity": "error"
}
},
"rulesDirectory": "../../../build/rules"
}
5 changes: 5 additions & 0 deletions fixtures/v6/finnish-whitelist/fixture-blacklist.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { of, Subject } from "rxjs";

class SomeSubject<T> extends Subject<T> {}
let someSubject: SomeSubject<any>;
const finnish = of(1);
5 changes: 5 additions & 0 deletions fixtures/v6/finnish-whitelist/fixture.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { of, Subject } from "rxjs";

class EventEmitter<T> extends Subject<T> {}
let eventEmitter: EventEmitter<any>;
const foreign = of(1);
13 changes: 13 additions & 0 deletions fixtures/v6/finnish-whitelist/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": ["fixture.ts", "fixture-blacklist.ts"]
}
20 changes: 20 additions & 0 deletions fixtures/v6/finnish-whitelist/tslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"defaultSeverity": "error",
"jsRules": {},
"rules": {
"rxjs-finnish": {
"options": [{
"names": {
"^finnish$": true,
"^foreign$": false
},
"types": {
"^EventEmitter$": false,
"^SomeSubject$": true
}
}],
"severity": "error"
}
},
"rulesDirectory": "../../../build/rules"
}
18 changes: 18 additions & 0 deletions source/fixtures-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,24 @@ describe(`${fixtureVersion} fixtures`, function (): void {

if (["v5", "v6"].includes(fixtureVersion)) {

describe("finnish-whitelist", () => {

it("should not effect 'rxjs-finnish' errors for whitelisted usage", () => {

const result = lint("finnish-whitelist", "tslint.json");

expect(result).to.have.property("errorCount", 0);
});

it("should effect 'rxjs-finnish' errors for blacklisted usage", () => {

const result = lint("finnish-whitelist", "tslint.json", "fixture-blacklist.ts");

expect(result).to.have.property("errorCount", 2);
result.failures.forEach(failure => expect(failure).to.have.property("ruleName", "rxjs-finnish"));
});
});

describe("finnish-with-$", () => {

it("should effect no errors", () => {
Expand Down
33 changes: 32 additions & 1 deletion source/rules/rxjsFinnishRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ export class Rule extends Lint.Rules.TypedRule {
properties: {
functions: { type: "boolean" },
methods: { type: "boolean" },
names: { type: "object" },
parameters: { type: "boolean" },
properties: { type: "boolean" },
types: { type: "object" },
variables: { type: "boolean" }
},
type: "object"
Expand All @@ -27,7 +29,10 @@ export class Rule extends Lint.Rules.TypedRule {
An optional object with optional \`functions\`, \`methods\`, \`parameters\`,
\`properties\` and \`variables\` properties.
The properies are booleans and determine whether or not Finnish notation is enforced.
All properties default to \`true\`.`,
All properties default to \`true\`.
The object also has optional \`names\` and \`types\` properties which are themselves
objects containing keys that are regular expressions and values that are booleans -
indicating whether Finnish notation is required for particular names or types.`,
requiresTypeInfo: true,
ruleName: "rxjs-finnish",
type: "style",
Expand All @@ -42,6 +47,8 @@ export class Rule extends Lint.Rules.TypedRule {

class Walker extends Lint.ProgramAwareRuleWalker {

private names: { regExp: RegExp, validate: boolean }[] = [];
private types: { regExp: RegExp, validate: boolean }[] = [];
private validate = {
functions: true,
methods: true,
Expand All @@ -56,6 +63,18 @@ class Walker extends Lint.ProgramAwareRuleWalker {

const [options] = this.getOptions();
if (options) {
if (options.names) {
Object.entries(options.names).forEach(([key, validate]: [string, boolean]) => {
this.names.push({ regExp: new RegExp(key), validate });
});
}
if (options.types) {
Object.entries(options.types).forEach(([key, validate]: [string, boolean]) => {
this.types.push({ regExp: new RegExp(key), validate });
});
} else {
this.types.push({ regExp: /^EventEmitter$/, validate: true });
}
this.validate = { ...this.validate, ...options };
}
}
Expand Down Expand Up @@ -161,6 +180,18 @@ class Walker extends Lint.ProgramAwareRuleWalker {
const text = name.getText();
const type = this.getTypeChecker().getTypeAtLocation(typeNode || node);
if (!/\$$/.test(text) && couldBeType(type, "Observable")) {
for (let i = 0; i < this.names.length; ++i) {
const { regExp, validate } = this.names[i];
if (regExp.test(text) && !validate) {
return;
}
}
for (let i = 0; i < this.types.length; ++i) {
const { regExp, validate } = this.types[i];
if (regExp.test(type.symbol.name) && !validate) {
return;
}
}
this.addFailureAtNode(node, `Finnish notation required for ${text}`);
}
}
Expand Down

0 comments on commit 5051876

Please sign in to comment.