Skip to content
This repository has been archived by the owner on Dec 26, 2022. It is now read-only.

Commit

Permalink
improves jasmine-no-lambda-expression-callbacks rule, extends chang…
Browse files Browse the repository at this point in the history
…elog, upgrades packages
  • Loading branch information
BendingBender committed Dec 30, 2016
1 parent d02d578 commit f85f16f
Show file tree
Hide file tree
Showing 16 changed files with 242 additions and 66 deletions.
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ src/
.editorconfig
runTests.js
tsconfig.json
yarn.lock
13 changes: 12 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
Change Log
===

v2.0.1
---
* [enhancement] Added preliminary checks for `jasmine-no-lambda-expression-callbacks` rule to skip walking file if there are no jasmine
top-level statements.

v2.0.0
---
* [enhancement] Upgrades to tslint@4
* **BREAKING CHANGES**
* [enhancement] Upgraded to tslint@4

v1.0.0
---
* [new-rule] `import-barrels` rule added
* [new-rule] `jasmine-no-lambda-expression-callbacks` rule added
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,16 @@
},
"homepage": "https://github.com/BendingBender/tslint-rules#readme",
"dependencies": {
"lodash": "^4.16.4"
"lodash": "^4.17.3"
},
"devDependencies": {
"@types/lodash": "^4.14.37",
"@types/node": "^6.0.45",
"@types/lodash": "^4.14.45",
"@types/node": "^6.0.55",
"coveralls": "^2.11.14",
"glob": "^7.1.1",
"istanbul": "^0.4.5",
"rimraf": "^2.5.4",
"tslint": "^4.0.2",
"tslint": "^4.2.0",
"tslint-microsoft-contrib": "^4.0.0",
"typescript": "~2.1.4",
"yargs": "^6.0.0"
Expand Down
19 changes: 10 additions & 9 deletions runTests.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#!/usr/bin/env node
'use strict';

const argv = require('yargs')
Expand Down Expand Up @@ -27,17 +28,17 @@ glob('src/tests/**/*.ts.lint', (error, files) => {
throw error;
}

files
.map(file => path.dirname(file))
.forEach(dir => {
const pathToBuildDir = path.resolve(dir, buildDir);
const pathToCoverageDir = path.resolve(dir, coverageDir);
const uniqueDirs = new Set(files.map(path.dirname));

child_process.execSync(getTestCommand(pathToBuildDir, pathToCoverageDir), {
cwd: dir,
stdio: 'inherit'
});
uniqueDirs.forEach(dir => {
const pathToBuildDir = path.resolve(dir, buildDir);
const pathToCoverageDir = path.resolve(dir, coverageDir);

child_process.execSync(getTestCommand(pathToBuildDir, pathToCoverageDir), {
cwd: dir,
stdio: 'inherit'
});
});
});

function getTestCommand(buildDir, coverageDir) {
Expand Down
2 changes: 1 addition & 1 deletion src/importBarrelsRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class ImportBarrelsWalker extends RuleWalker {
const moduleExpressionError = this.getModuleExpressionErrorMessage(moduleExpression);

if (moduleExpressionError) {
this.addFailure(this.createFailure(moduleExpression.getStart(), moduleExpression.getWidth(), moduleExpressionError));
this.addFailureAtNode(moduleExpression, moduleExpressionError);
}

super.visitImportDeclaration(node);
Expand Down
42 changes: 17 additions & 25 deletions src/jasmineNoLambdaExpressionCallbacksRule.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { IRuleMetadata, RuleFailure, Rules, RuleWalker, Utils } from 'tslint/lib';
import { ArrowFunction, CallExpression, Expression, Identifier, SourceFile, SyntaxKind } from 'typescript';
import includes = require('lodash/includes');
import { ArrowFunction, CallExpression, Expression, SourceFile, SyntaxKind } from 'typescript';
import { isJasmineDescribe, isJasmineIt, isJasmineSetupTeardown, isJasmineTest } from './utils/jasmineUtils';
import find = require('lodash/find');

export class Rule extends Rules.AbstractRule {
Expand Down Expand Up @@ -33,52 +33,44 @@ export class Rule extends Rules.AbstractRule {
};

public static FAILURE_STRING = "Don't use lambda expressions as callbacks to jasmine functions";
public static JASMINE_BDD_API = [
'describe',
'it',
'fdescribe',
'fit',
'xdescribe',
'xit',
];
public static JASMINE_SETUP_TEARDOWN = [
'beforeEach',
'afterEach',
'beforeAll',
'afterAll',
];

public apply(sourceFile:SourceFile):RuleFailure[] {
return this.applyWithWalker(new JasmineNoLambdaExpressionCallbacksWalker(sourceFile, this.getOptions()));
}
}

class JasmineNoLambdaExpressionCallbacksWalker extends RuleWalker {
protected visitSourceFile(node:SourceFile) {
if (isJasmineTest(node)) {
super.visitSourceFile(node);
}
}

protected visitCallExpression(node:CallExpression) {
const invalidLambdaExpression = this.getInvalidLambdaExpression(node);

if (invalidLambdaExpression) {
this.addFailure(this.createFailure(invalidLambdaExpression.getStart(), invalidLambdaExpression.getWidth(), Rule.FAILURE_STRING));
this.addFailureAtNode(invalidLambdaExpression, Rule.FAILURE_STRING);
}

super.visitCallExpression(node);
}

private getInvalidLambdaExpression(node:CallExpression):ArrowFunction|null {
private getInvalidLambdaExpression(node:CallExpression):ArrowFunction|false {
if (node.expression.kind !== SyntaxKind.Identifier) {
return null;
return false;
}

const functionIdentifier = (<Identifier>node.expression).text;
const functionIdentifier = node.expression.getText();
const functionArgs = node.arguments;

if (includes(Rule.JASMINE_BDD_API, functionIdentifier) && functionArgs.length >= 2) {
return this.getLambdaExpressionFromArg(functionArgs[1]);
} else if (includes(Rule.JASMINE_SETUP_TEARDOWN, functionIdentifier) && functionArgs.length >= 1) {
return this.getLambdaExpressionFromArg(functionArgs[0]);
if ((isJasmineDescribe(functionIdentifier) || isJasmineIt(functionIdentifier)) && functionArgs.length > 1) {
return this.getLambdaExpressionFromArg(functionArgs[1]) || false;
} else if (isJasmineSetupTeardown(functionIdentifier) && functionArgs.length > 0) {
return this.getLambdaExpressionFromArg(functionArgs[0]) || false;
}

return null;
return false;
}

private getLambdaExpressionFromArg(apiArg:Expression):ArrowFunction|null {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
describe("this is ok", function() {
it("this is ok", function() {});
it("this is ok", wrap(function() {}));

describe("this is still ok", wrapAgain(function() {}));
});

// still ok
(() => {})();

// still ok
someOtherCallWithLambda(() => {})

describe("this", () => {
~~~~~~~
it("is an error", function() {
Expand Down Expand Up @@ -54,8 +67,6 @@ describe("this, too", function() {
~~~ [no-lambda-callback]
});

someOtherCallWithLambda(() => {})

fdescribe("this, too", wrapCallback(() => {
~~~~~~~
}));
Expand All @@ -73,8 +84,4 @@ describe("this, too", wrapCallback(function() {
~~~ [no-lambda-callback]
}));

(() => {})();



[no-lambda-callback]: Don't use lambda expressions as callbacks to jasmine functions
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
(function test() {
describe('some test in an IIFE', () => {});
~~~~~~~~ [no-lambda-callback]
})();

[no-lambda-callback]: Don't use lambda expressions as callbacks to jasmine functions
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
(() => {
describe('some test in an IIFE', () => {});
~~~~~~~~ [no-lambda-callback]
})();

[no-lambda-callback]: Don't use lambda expressions as callbacks to jasmine functions
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
(function test() {
describe('some test in an other IIFE', () => {});
~~~~~~~~ [no-lambda-callback]
}());

[no-lambda-callback]: Don't use lambda expressions as callbacks to jasmine functions
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export function test() {
describe('some test in a callback', () => {});
~~~~~~~~ [no-lambda-callback]
}

[no-lambda-callback]: Don't use lambda expressions as callbacks to jasmine functions
27 changes: 24 additions & 3 deletions src/tslint.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,22 @@
}
],
"no-any": false,
"no-empty-interface": true,
"no-inferrable-types": true,
"no-internal-module": true,
"no-magic-numbers": [
true,
0,
-1,
1,
1000
],
"no-namespace": true,
"no-reference": true,
"no-var-requires": true,
"only-arrow-functions": false,
"prefer-for-of": true,
"promise-function-async": false,
"typedef": false,
"typedef-whitespace": [
true,
Expand All @@ -40,6 +49,7 @@
"ban": false,
"curly": true,
"forin": true,
"import-blacklist": false,
"label-position": true,
"no-arg": true,
"no-bitwise": true,
Expand All @@ -57,23 +67,29 @@
"no-duplicate-variable": true,
"no-empty": true,
"no-eval": true,
// no-for-in-array requires type info
// "no-for-in-array" requires type info
"no-for-in-array": false,
// "no-inferred-empty-object-type" requires type info
"no-inferred-empty-object-type": false,
"no-invalid-this": [
true,
"check-function-in-method"
],
"no-null-keyword": false,
"no-shadowed-variable": false,
"no-string-literal": false,
"no-string-throw": true,
"no-switch-case-fall-through": true,
"no-unsafe-finally": true,
"no-unused-expression": true,
"no-unused-new": true,
"no-use-before-declare": true,
"no-var-keyword": true,
// "no-void-expression" requires type info
"no-void-expression": false,
"radix": true,
"restrict-plus-operands": false,
"strict-boolean-expressions": false,
"switch-default": true,
"triple-equals": [
true,
Expand Down Expand Up @@ -106,13 +122,18 @@
"no-require-imports": false,
"no-trailing-whitespace": true,
"object-literal-sort-keys": false,
"prefer-const": true,
"trailing-comma": true,
"align": false,
"array-type": [
true,
"array"
],
"arrow-parens": false,
"arrow-parens": [
true,
"ban-single-arg-parens"
],
"callable-types": true,
"class-name": true,
"comment-format": [
true,
Expand All @@ -124,6 +145,7 @@
true,
"never-prefix"
],
"interface-over-type-literal": true,
"jsdoc-format": true,
"new-parens": true,
"no-angle-bracket-type-assertion": false,
Expand Down Expand Up @@ -237,7 +259,6 @@
],
"possible-timing-attack": false,
"prefer-array-literal": true,
"prefer-const": true,
"prefer-type-cast": true,
"promise-must-complete": true,
"react-iframe-missing-sandbox": false,
Expand Down
Loading

0 comments on commit f85f16f

Please sign in to comment.