Skip to content

Commit

Permalink
feat(finnish): Add options.
Browse files Browse the repository at this point in the history
  • Loading branch information
cartant committed Feb 19, 2018
1 parent d662a00 commit d249119
Show file tree
Hide file tree
Showing 9 changed files with 230 additions and 21 deletions.
27 changes: 26 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ The package includes the following rules (none of which are enabled by default):
| Rule | Description | Options |
| --- | --- | --- |
| `rxjs-add` | Enforces the importation of patched observables and operators used in the module. | [See below](#rxjs-add) |
| `rxjs-finnish` | Enforces the use of [Finnish notation](https://medium.com/@benlesh/observables-and-finnish-notation-df8356ed1c9b). | None |
| `rxjs-finnish` | Enforces the use of [Finnish notation](https://medium.com/@benlesh/observables-and-finnish-notation-df8356ed1c9b). | [See below](#rxjs-finnish) |
| `rxjs-no-add` | Disallows the importation of patched observables and operators. | [See below](#rxjs-no-add) |
| `rxjs-no-create` | Disallows the calling of `Observable.create`. Useful as a warning. | None |
| `rxjs-no-deep-operators` | Disallows deep importation from 'rxjs/operators'. Deep imports won't be in available in RxJS v6. | None |
Expand Down Expand Up @@ -119,6 +119,31 @@ Note that there is no `file` option for the `rxjs-no-unused-add` rule, so that r

If the `file` option is not specified, patched observables and operators must be imported in the modules in which they are used.

<a name="rxjs-finnish"></a>

#### `rxjs-finnish`

The `rxjs-finnish` rule takes 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`.

For example, to enforce Finnish notation for variables only:

```json
"rules": {
"rxjs-finnish": {
"options": [{
"functions": false,
"methods": false,
"parameters": false,
"properties": false,
"variables": true
}],
"severity": "error"
}
}
```

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

#### `rxjs-no-add` and `rxjs-no-patched`
Expand Down
27 changes: 26 additions & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ The package includes the following rules (none of which are enabled by default):
| Rule | Description | Options |
| --- | --- | --- |
| `rxjs-add` | Enforces the importation of patched observables and operators used in the module. | [See below](#rxjs-add) |
| `rxjs-finnish` | Enforces the use of [Finnish notation](https://medium.com/@benlesh/observables-and-finnish-notation-df8356ed1c9b). | None |
| `rxjs-finnish` | Enforces the use of [Finnish notation](https://medium.com/@benlesh/observables-and-finnish-notation-df8356ed1c9b). | [See below](#rxjs-finnish) |
| `rxjs-no-add` | Disallows the importation of patched observables and operators. | [See below](#rxjs-no-add) |
| `rxjs-no-create` | Disallows the calling of `Observable.create`. Useful as a warning. | None |
| `rxjs-no-deep-operators` | Disallows deep importation from 'rxjs/operators'. Deep imports won't be in available in RxJS v6. | None |
Expand Down Expand Up @@ -59,6 +59,31 @@ Note that there is no `file` option for the `rxjs-no-unused-add` rule, so that r

If the `file` option is not specified, patched observables and operators must be imported in the modules in which they are used.

<a name="rxjs-finnish"></a>

#### `rxjs-finnish`

The `rxjs-finnish` rule takes 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`.

For example, to enforce Finnish notation for variables only:

```json
"rules": {
"rxjs-finnish": {
"options": [{
"functions": false,
"methods": false,
"parameters": false,
"properties": false,
"variables": true
}],
"severity": "error"
}
}
```

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

#### `rxjs-no-add` and `rxjs-no-patched`
Expand Down
13 changes: 13 additions & 0 deletions fixtures/finnish-without-$/tslint-no-functions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"defaultSeverity": "error",
"jsRules": {},
"rules": {
"rxjs-finnish": {
"options": [{
"functions": false
}],
"severity": "error"
}
},
"rulesDirectory": "../../build/rules"
}
13 changes: 13 additions & 0 deletions fixtures/finnish-without-$/tslint-no-methods.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"defaultSeverity": "error",
"jsRules": {},
"rules": {
"rxjs-finnish": {
"options": [{
"methods": false
}],
"severity": "error"
}
},
"rulesDirectory": "../../build/rules"
}
13 changes: 13 additions & 0 deletions fixtures/finnish-without-$/tslint-no-parameters.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"defaultSeverity": "error",
"jsRules": {},
"rules": {
"rxjs-finnish": {
"options": [{
"parameters": false
}],
"severity": "error"
}
},
"rulesDirectory": "../../build/rules"
}
13 changes: 13 additions & 0 deletions fixtures/finnish-without-$/tslint-no-properties.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"defaultSeverity": "error",
"jsRules": {},
"rules": {
"rxjs-finnish": {
"options": [{
"parameters": false
}],
"severity": "error"
}
},
"rulesDirectory": "../../build/rules"
}
13 changes: 13 additions & 0 deletions fixtures/finnish-without-$/tslint-no-variables.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"defaultSeverity": "error",
"jsRules": {},
"rules": {
"rxjs-finnish": {
"options": [{
"variables": false
}],
"severity": "error"
}
},
"rulesDirectory": "../../build/rules"
}
40 changes: 40 additions & 0 deletions source/fixtures-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,46 @@ describe("fixtures", function (): void {
expect(result).to.have.property("errorCount", 1);
result.failures.forEach(failure => expect(failure).to.have.property("ruleName", "rxjs-finnish"));
});

it("should support not enforcing functions", () => {

const result = lint("finnish-without-$", "tslint-no-functions.json");

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

it("should support not enforcing methods", () => {

const result = lint("finnish-without-$", "tslint-no-methods.json");

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

it("should support not enforcing parameters", () => {

const result = lint("finnish-without-$", "tslint-no-parameters.json");

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

it("should support not enforcing properties", () => {

const result = lint("finnish-without-$", "tslint-no-properties.json");

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

it("should support not enforcing variables", () => {

const result = lint("finnish-without-$", "tslint-no-variables.json");

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

describe("no-finnish-with-$", () => {
Expand Down
92 changes: 73 additions & 19 deletions source/rules/rxjsFinnishRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,22 @@ export class Rule extends Lint.Rules.TypedRule {

public static metadata: Lint.IRuleMetadata = {
description: "Enforces the use of Finnish notation.",
options: null,
optionsDescription: "Not configurable.",
options: {
properties: {
functions: { type: "boolean" },
methods: { type: "boolean" },
parameters: { type: "boolean" },
properties: { type: "boolean" },
variables: { type: "boolean" }
},
type: "object"
},
optionsDescription: Lint.Utils.dedent`
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\`.
`,
requiresTypeInfo: true,
ruleName: "rxjs-finnish",
type: "style",
Expand All @@ -29,75 +43,115 @@ export class Rule extends Lint.Rules.TypedRule {

class Walker extends Lint.ProgramAwareRuleWalker {

private validate = {
functions: true,
methods: true,
parameters: true,
properties: true,
variables: true
};

constructor(sourceFile: ts.SourceFile, rawOptions: Lint.IOptions, program: ts.Program) {

super(sourceFile, rawOptions, program);

const [options] = this.getOptions();
if (options) {
this.validate = { ...this.validate, ...options };
}
}

protected visitFunctionDeclaration(node: ts.FunctionDeclaration): void {

this.validateNode(node, node.type);
if (this.validate.functions) {
this.validateNode(node, node.type);
}
super.visitFunctionDeclaration(node);
}

protected visitFunctionExpression(node: ts.FunctionExpression): void {

this.validateNode(node, node.type);
if (this.validate.functions) {
this.validateNode(node, node.type);
}
super.visitFunctionExpression(node);
}

protected visitGetAccessor(node: ts.AccessorDeclaration): void {

this.validateNode(node);
if (this.validate.properties) {
this.validateNode(node);
}
super.visitGetAccessor(node);
}

protected visitMethodDeclaration(node: ts.MethodDeclaration): void {

this.validateNode(node, node.type);
if (this.validate.methods) {
this.validateNode(node, node.type);
}
super.visitMethodDeclaration(node);
}

protected visitMethodSignature(node: ts.SignatureDeclaration): void {

this.validateNode(node, node.type);
if (this.validate.methods) {
this.validateNode(node, node.type);
}
super.visitMethodSignature(node);
}

protected visitObjectLiteralExpression(node: ts.ObjectLiteralExpression): void {

node.properties.forEach(property => {
if (property.name && !tsutils.isComputedPropertyName(property.name)) {
this.validateNode(property);
}
});
if (this.validate.properties) {
node.properties.forEach(property => {
if (property.name && !tsutils.isComputedPropertyName(property.name)) {
this.validateNode(property);
}
});
}
super.visitObjectLiteralExpression(node);
}

protected visitParameterDeclaration(node: ts.ParameterDeclaration): void {

this.validateNode(node);
if (this.validate.parameters) {
this.validateNode(node);
}
super.visitParameterDeclaration(node);
}

protected visitPropertyDeclaration(node: ts.PropertyDeclaration): void {

this.validateNode(node);
if (this.validate.properties) {
this.validateNode(node);
}
super.visitPropertyDeclaration(node);
}

protected visitPropertySignature(node: ts.Node): void {

this.validateNode(node);
if (this.validate.properties) {
this.validateNode(node);
}
super.visitPropertySignature(node);
}

protected visitSetAccessor(node: ts.AccessorDeclaration): void {

this.validateNode(node);
if (this.validate.properties) {
this.validateNode(node);
}
super.visitSetAccessor(node);
}

protected visitVariableDeclarationList(node: ts.VariableDeclarationList): void {

tsutils.forEachDeclaredVariable(node, variable => {
this.validateNode(variable);
});
if (this.validate.variables) {
tsutils.forEachDeclaredVariable(node, variable => {
this.validateNode(variable);
});
}
super.visitVariableDeclarationList(node);
}

Expand Down

0 comments on commit d249119

Please sign in to comment.