From 86779b83534609b93ce964ff2315f4067f1939b6 Mon Sep 17 00:00:00 2001 From: Manuel Lopez Date: Sat, 19 Nov 2016 16:39:52 -0600 Subject: [PATCH 01/15] [chore] fail build if there are typescript errors Currently these errors are could be left out by Travis CI. --- gulpfile.js | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index ed91d84..d124bd1 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -44,18 +44,28 @@ gulp.task('lint', function lint() { })); }); -gulp.task('build', argv.lint === false ? [] : ['lint'], function build() { - var tsResult = tsProject +gulp.task('build', argv.lint === false ? [] : ['lint'], function build(done) { + var hasError = false; + tsProject .src([SRC_FOLDER, DEF_FOLDER]) .pipe(sourcemaps.init()) - .pipe(tsProject()); - - return tsResult.js + .pipe(tsProject()) + .on('error', function onError() { + hasError = true; + }) + .js .pipe(sourcemaps.write({ includeContent: false, sourceRoot: path.join(__dirname, '/src') })) - .pipe(gulp.dest('dist')); + .pipe(gulp.dest('dist')) + .on('end', function() { + if (hasError) { + done('TypeScript has reported errors'); + } else { + done(); + } + }); }); gulp.task('test', ['build'], function test() { From 5c6984bff1e4935e447e9418f4ddff40e8b1372e Mon Sep 17 00:00:00 2001 From: Manuel Lopez Date: Sat, 19 Nov 2016 16:42:50 -0600 Subject: [PATCH 02/15] [lint] removing no-unused-variables from tslint.json This has been deprecated on tslint 4.0. They recommend we turn on noUnusedParameters and noUnusedLocals on the typescript configuration. --- src/readme/fetch.ts | 4 ++-- src/rules/terMaxLenRule.ts | 6 +++--- tsconfig.json | 2 ++ tslint.json | 1 - 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/readme/fetch.ts b/src/readme/fetch.ts index 4d16600..09e3ff6 100644 --- a/src/readme/fetch.ts +++ b/src/readme/fetch.ts @@ -34,7 +34,7 @@ function requestFromGithub(path, callback) { } function compareToESLint() { - return new Promise((fulfill, reject) => { + return new Promise((fulfill) => { requestFromGithub('/repos/eslint/eslint/contents/lib/rules', (data) => { const rules = data .filter(obj => obj.name.endsWith('.js')) @@ -71,7 +71,7 @@ function compareToESLint() { } function compareToTSLint() { - return new Promise((fulfill, reject) => { + return new Promise((fulfill) => { requestFromGithub('/repos/palantir/tslint/contents/src/rules', (data) => { const rules = data .filter(obj => obj.name.endsWith('.ts')) diff --git a/src/rules/terMaxLenRule.ts b/src/rules/terMaxLenRule.ts index 0e70e9c..9401afe 100644 --- a/src/rules/terMaxLenRule.ts +++ b/src/rules/terMaxLenRule.ts @@ -30,7 +30,7 @@ const IGNORE_IMPORTS: string = 'ignoreImports'; */ function computeLineLength(line: string, tabWidth: number) { let extraCharacterCount = 0; - line.replace(/\t/g, (match, offset) => { + line.replace(/\t/g, (_, offset) => { const totalOffset = offset + extraCharacterCount; const previousTabStopOffset = tabWidth ? totalOffset % tabWidth : 0; const spaceCount = tabWidth - previousTabStopOffset; @@ -66,7 +66,7 @@ function isTrailingComment(line: string, lineNumber: number, comment: INode) { /** * Gets the line after the comment and any remaining trailing whitespace is stripped. */ -function stripTrailingComment(line: string, lineNumber: number, comment: INode) { +function stripTrailingComment(line: string, comment: INode) { return line.slice(0, comment.start[1]).replace(/\s+$/, ''); } @@ -394,7 +394,7 @@ class MaxLenWalker extends Lint.SkippableTokenAwareRuleWalker { if (isFullLineComment(line, i, comment)) { lineIsComment = true; } else if (ignoreTrailingComments && isTrailingComment(line, i, comment)) { - line = stripTrailingComment(line, i, comment); + line = stripTrailingComment(line, comment); } } diff --git a/tsconfig.json b/tsconfig.json index ad43f0f..61a031c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,6 +2,8 @@ "compilerOptions": { "target": "es5", "module": "commonjs", + "noUnusedParameters": true, + "noUnusedLocals": true, "removeComments": true } } diff --git a/tslint.json b/tslint.json index daf3968..03b73cd 100644 --- a/tslint.json +++ b/tslint.json @@ -55,7 +55,6 @@ "no-trailing-whitespace": true, "no-unreachable": true, "no-unused-expression": true, - "no-unused-variable": true, "no-use-before-declare": true, "no-var-keyword": true, "no-var-requires": true, From 6d172e622dee2e1fcf4e15caf2b86abe6718eabb Mon Sep 17 00:00:00 2001 From: Manuel Lopez Date: Sat, 19 Nov 2016 17:29:03 -0600 Subject: [PATCH 03/15] [upgrade] tslint -> 4.0 See https://palantir.github.io/tslint/2016/11/17/new-for-4.0.html. Overall we had to remove deprecated rules from our tslint.json file and change our import statements. The helper file had major changes due to their new API. All tests are passing right now. --- package.json | 2 +- src/rules/arrayBracketSpacingRule.ts | 2 +- src/rules/blockSpacingRule.ts | 2 +- src/rules/braceStyleRule.ts | 2 +- src/rules/handleCallbackErrRule.ts | 2 +- src/rules/noConstantConditionRule.ts | 2 +- src/rules/noControlRegexRule.ts | 2 +- src/rules/noDuplicateCaseRule.ts | 2 +- src/rules/noEmptyCharacterClassRule.ts | 2 +- src/rules/noExAssignRule.ts | 2 +- src/rules/noExtraBooleanCastRule.ts | 2 +- src/rules/noExtraSemiRule.ts | 2 +- src/rules/noInnerDeclarationsRule.ts | 2 +- src/rules/noInvalidRegexpRule.ts | 2 +- src/rules/noIrregularWhitespaceRule.ts | 2 +- src/rules/noMultiSpacesRule.ts | 2 +- src/rules/noRegexSpacesRule.ts | 2 +- src/rules/noSparseArraysRule.ts | 2 +- src/rules/noUnexpectedMultilineRule.ts | 2 +- src/rules/objectCurlySpacingRule.ts | 2 +- src/rules/terIndentRule.ts | 3 ++- src/rules/terMaxLenRule.ts | 3 ++- src/rules/useIsnanRule.ts | 2 +- src/rules/validJsdocRule.ts | 2 +- src/rules/validTypeofRule.ts | 2 +- src/test/rules/helper.ts | 18 +++++++++--------- src/test/rules/terIndentRuleTests.ts | 2 +- src/test/rules/terMaxLenRuleTests.ts | 2 +- tslint.json | 7 ------- 29 files changed, 38 insertions(+), 43 deletions(-) diff --git a/package.json b/package.json index 55245e0..d22380c 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,6 @@ }, "dependencies": { "doctrine": "^0.7.2", - "tslint": "^3.15.1" + "tslint": "^4.0.0" } } diff --git a/src/rules/arrayBracketSpacingRule.ts b/src/rules/arrayBracketSpacingRule.ts index b3e1773..f6ba7e3 100644 --- a/src/rules/arrayBracketSpacingRule.ts +++ b/src/rules/arrayBracketSpacingRule.ts @@ -1,5 +1,5 @@ import * as ts from 'typescript'; -import * as Lint from 'tslint/lib/lint'; +import * as Lint from 'tslint'; const OPTION_ALWAYS = 'always'; diff --git a/src/rules/blockSpacingRule.ts b/src/rules/blockSpacingRule.ts index c32c22c..6ac9eeb 100644 --- a/src/rules/blockSpacingRule.ts +++ b/src/rules/blockSpacingRule.ts @@ -1,5 +1,5 @@ import * as ts from 'typescript'; -import * as Lint from 'tslint/lib/lint'; +import * as Lint from 'tslint'; const OPTION_ALWAYS = 'always'; diff --git a/src/rules/braceStyleRule.ts b/src/rules/braceStyleRule.ts index a10db5c..0d6a2ed 100644 --- a/src/rules/braceStyleRule.ts +++ b/src/rules/braceStyleRule.ts @@ -1,5 +1,5 @@ import * as ts from 'typescript'; -import * as Lint from 'tslint/lib/lint'; +import * as Lint from 'tslint'; const OPTION_1TBS = '1tbs'; const OPTION_ALLMAN = 'allman'; diff --git a/src/rules/handleCallbackErrRule.ts b/src/rules/handleCallbackErrRule.ts index 80f349a..2ede33d 100644 --- a/src/rules/handleCallbackErrRule.ts +++ b/src/rules/handleCallbackErrRule.ts @@ -1,5 +1,5 @@ import * as ts from 'typescript'; -import * as Lint from 'tslint/lib/lint'; +import * as Lint from 'tslint'; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = 'Expected error to be handled'; diff --git a/src/rules/noConstantConditionRule.ts b/src/rules/noConstantConditionRule.ts index 368454f..a307bcc 100644 --- a/src/rules/noConstantConditionRule.ts +++ b/src/rules/noConstantConditionRule.ts @@ -1,5 +1,5 @@ import * as ts from 'typescript'; -import * as Lint from 'tslint/lib/lint'; +import * as Lint from 'tslint'; import { isAssignmentToken } from '../support/token'; export class Rule extends Lint.Rules.AbstractRule { diff --git a/src/rules/noControlRegexRule.ts b/src/rules/noControlRegexRule.ts index cf583b8..f35922c 100644 --- a/src/rules/noControlRegexRule.ts +++ b/src/rules/noControlRegexRule.ts @@ -1,5 +1,5 @@ import * as ts from 'typescript'; -import * as Lint from 'tslint/lib/lint'; +import * as Lint from 'tslint'; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = 'unexpected control character in regular expression'; diff --git a/src/rules/noDuplicateCaseRule.ts b/src/rules/noDuplicateCaseRule.ts index 445a61e..6346300 100644 --- a/src/rules/noDuplicateCaseRule.ts +++ b/src/rules/noDuplicateCaseRule.ts @@ -1,5 +1,5 @@ import * as ts from 'typescript'; -import * as Lint from 'tslint/lib/lint'; +import * as Lint from 'tslint'; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = 'duplicate case label'; diff --git a/src/rules/noEmptyCharacterClassRule.ts b/src/rules/noEmptyCharacterClassRule.ts index 1acc2db..6985987 100644 --- a/src/rules/noEmptyCharacterClassRule.ts +++ b/src/rules/noEmptyCharacterClassRule.ts @@ -1,5 +1,5 @@ import * as ts from 'typescript'; -import * as Lint from 'tslint/lib/lint'; +import * as Lint from 'tslint'; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = `don't use empty classes in regular expressions`; diff --git a/src/rules/noExAssignRule.ts b/src/rules/noExAssignRule.ts index 2635f79..ff50a1f 100644 --- a/src/rules/noExAssignRule.ts +++ b/src/rules/noExAssignRule.ts @@ -1,5 +1,5 @@ import * as ts from 'typescript'; -import * as Lint from 'tslint/lib/lint'; +import * as Lint from 'tslint'; import { isAssignmentToken } from '../support/token'; export class Rule extends Lint.Rules.AbstractRule { diff --git a/src/rules/noExtraBooleanCastRule.ts b/src/rules/noExtraBooleanCastRule.ts index a5f7960..30f2741 100644 --- a/src/rules/noExtraBooleanCastRule.ts +++ b/src/rules/noExtraBooleanCastRule.ts @@ -1,5 +1,5 @@ import * as ts from 'typescript'; -import * as Lint from 'tslint/lib/lint'; +import * as Lint from 'tslint'; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = { diff --git a/src/rules/noExtraSemiRule.ts b/src/rules/noExtraSemiRule.ts index 6a5ba6c..4e83772 100644 --- a/src/rules/noExtraSemiRule.ts +++ b/src/rules/noExtraSemiRule.ts @@ -1,5 +1,5 @@ import * as ts from 'typescript'; -import * as Lint from 'tslint/lib/lint'; +import * as Lint from 'tslint'; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = 'unnecessary semicolon'; diff --git a/src/rules/noInnerDeclarationsRule.ts b/src/rules/noInnerDeclarationsRule.ts index c245a22..fb37b1b 100644 --- a/src/rules/noInnerDeclarationsRule.ts +++ b/src/rules/noInnerDeclarationsRule.ts @@ -1,5 +1,5 @@ import * as ts from 'typescript'; -import * as Lint from 'tslint/lib/lint'; +import * as Lint from 'tslint'; export class Rule extends Lint.Rules.AbstractRule { public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] { diff --git a/src/rules/noInvalidRegexpRule.ts b/src/rules/noInvalidRegexpRule.ts index 8974f9b..54602ea 100644 --- a/src/rules/noInvalidRegexpRule.ts +++ b/src/rules/noInvalidRegexpRule.ts @@ -1,5 +1,5 @@ import * as ts from 'typescript'; -import * as Lint from 'tslint/lib/lint'; +import * as Lint from 'tslint'; export class Rule extends Lint.Rules.AbstractRule { public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] { diff --git a/src/rules/noIrregularWhitespaceRule.ts b/src/rules/noIrregularWhitespaceRule.ts index 89293ec..7a18d52 100644 --- a/src/rules/noIrregularWhitespaceRule.ts +++ b/src/rules/noIrregularWhitespaceRule.ts @@ -1,5 +1,5 @@ import * as ts from 'typescript'; -import * as Lint from 'tslint/lib/lint'; +import * as Lint from 'tslint'; export class Rule extends Lint.Rules.AbstractRule { public static RULE_NAME = 'no-irregular-whitespace'; diff --git a/src/rules/noMultiSpacesRule.ts b/src/rules/noMultiSpacesRule.ts index 4cc5847..b001df3 100644 --- a/src/rules/noMultiSpacesRule.ts +++ b/src/rules/noMultiSpacesRule.ts @@ -1,5 +1,5 @@ import * as ts from 'typescript'; -import * as Lint from 'tslint/lib/lint'; +import * as Lint from 'tslint'; export class Rule extends Lint.Rules.AbstractRule { diff --git a/src/rules/noRegexSpacesRule.ts b/src/rules/noRegexSpacesRule.ts index c75f8c2..ddf0b05 100644 --- a/src/rules/noRegexSpacesRule.ts +++ b/src/rules/noRegexSpacesRule.ts @@ -1,5 +1,5 @@ import * as ts from 'typescript'; -import * as Lint from 'tslint/lib/lint'; +import * as Lint from 'tslint'; export class Rule extends Lint.Rules.AbstractRule { public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] { diff --git a/src/rules/noSparseArraysRule.ts b/src/rules/noSparseArraysRule.ts index df8eb3d..ce84051 100644 --- a/src/rules/noSparseArraysRule.ts +++ b/src/rules/noSparseArraysRule.ts @@ -1,5 +1,5 @@ import * as ts from 'typescript'; -import * as Lint from 'tslint/lib/lint'; +import * as Lint from 'tslint'; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = 'unexpected comma in middle of array'; diff --git a/src/rules/noUnexpectedMultilineRule.ts b/src/rules/noUnexpectedMultilineRule.ts index ea8889d..30ac03b 100644 --- a/src/rules/noUnexpectedMultilineRule.ts +++ b/src/rules/noUnexpectedMultilineRule.ts @@ -1,5 +1,5 @@ import * as ts from 'typescript'; -import * as Lint from 'tslint/lib/lint'; +import * as Lint from 'tslint'; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = { diff --git a/src/rules/objectCurlySpacingRule.ts b/src/rules/objectCurlySpacingRule.ts index ce60b31..82632ef 100644 --- a/src/rules/objectCurlySpacingRule.ts +++ b/src/rules/objectCurlySpacingRule.ts @@ -1,5 +1,5 @@ import * as ts from 'typescript'; -import * as Lint from 'tslint/lib/lint'; +import * as Lint from 'tslint'; const OPTION_ALWAYS = 'always'; diff --git a/src/rules/terIndentRule.ts b/src/rules/terIndentRule.ts index 9118cb0..588eddc 100644 --- a/src/rules/terIndentRule.ts +++ b/src/rules/terIndentRule.ts @@ -6,7 +6,7 @@ * */ import * as ts from 'typescript'; -import * as Lint from 'tslint/lib/lint'; +import * as Lint from 'tslint'; const RULE_NAME = 'ter-indent'; const DEFAULT_VARIABLE_INDENT = 1; @@ -161,6 +161,7 @@ export class Rule extends Lint.Rules.AbstractRule { ] ` ], + typescriptOnly: false, type: 'maintainability' }; diff --git a/src/rules/terMaxLenRule.ts b/src/rules/terMaxLenRule.ts index 9401afe..8b17860 100644 --- a/src/rules/terMaxLenRule.ts +++ b/src/rules/terMaxLenRule.ts @@ -7,7 +7,7 @@ * An addition exception has been added: ignoreImports. */ import * as ts from 'typescript'; -import * as Lint from 'tslint/lib/lint'; +import * as Lint from 'tslint'; import { IDisabledInterval } from 'tslint/lib/language/rule/rule'; @@ -192,6 +192,7 @@ export class Rule extends Lint.Rules.AbstractRule { ] ` ], + typescriptOnly: false, type: 'style' }; diff --git a/src/rules/useIsnanRule.ts b/src/rules/useIsnanRule.ts index eb3d581..b0ad317 100644 --- a/src/rules/useIsnanRule.ts +++ b/src/rules/useIsnanRule.ts @@ -1,5 +1,5 @@ import * as ts from 'typescript'; -import * as Lint from 'tslint/lib/lint'; +import * as Lint from 'tslint'; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = 'use the isNaN function to compare with NaN'; diff --git a/src/rules/validJsdocRule.ts b/src/rules/validJsdocRule.ts index 33740bf..ad9e53d 100644 --- a/src/rules/validJsdocRule.ts +++ b/src/rules/validJsdocRule.ts @@ -1,5 +1,5 @@ import * as ts from 'typescript'; -import * as Lint from 'tslint/lib/lint'; +import * as Lint from 'tslint'; import * as doctrine from 'doctrine'; export class Rule extends Lint.Rules.AbstractRule { diff --git a/src/rules/validTypeofRule.ts b/src/rules/validTypeofRule.ts index 91c3f59..77b48a2 100644 --- a/src/rules/validTypeofRule.ts +++ b/src/rules/validTypeofRule.ts @@ -1,5 +1,5 @@ import * as ts from 'typescript'; -import * as Lint from 'tslint/lib/lint'; +import * as Lint from 'tslint'; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = 'invalid typeof comparison value'; diff --git a/src/test/rules/helper.ts b/src/test/rules/helper.ts index 13bb08e..c26ee70 100644 --- a/src/test/rules/helper.ts +++ b/src/test/rules/helper.ts @@ -1,6 +1,6 @@ /// import { expect, assert } from 'chai'; -import * as Lint from 'tslint/lib/lint'; +import * as Lint from 'tslint'; export interface IScriptError { message: string; @@ -19,16 +19,16 @@ function arrayDiff(source, target) { export function testScript(rule: string, scriptText: string, config: Object): boolean { const options: Lint.ILinterOptions = { - configuration: config, + fix: false, formatter: 'json', formattersDirectory: 'dist/formatters/', rulesDirectory: 'dist/rules/' }; - const linter = new Lint.Linter(`${rule}.ts`, scriptText, options); - const result = linter.lint(); + const linter = new Lint.Linter(options); + linter.lint(`${rule}.ts`, scriptText, config); - const failures = JSON.parse(result.output); + const failures = JSON.parse(linter.getResult().output); return failures.length === 0; } @@ -50,16 +50,16 @@ export function makeTest(rule: string, scripts: Array, expected: boolean export function runScript(rule: string, scriptText: string, config: Object, errors: IScriptError[]): void { const options: Lint.ILinterOptions = { - configuration: config, + fix: false, formatter: 'json', formattersDirectory: 'dist/formatters/', rulesDirectory: 'dist/rules/' }; - const linter = new Lint.Linter(`${rule}.ts`, scriptText, options); - const result = linter.lint(); + const linter = new Lint.Linter(options); + linter.lint(`${rule}.ts`, scriptText, config); - const failures = JSON.parse(result.output); + const failures = JSON.parse(linter.getResult().output); const line = errors[0] ? 'line' in errors[0] : false; if (failures.length !== errors.length) { diff --git a/src/test/rules/terIndentRuleTests.ts b/src/test/rules/terIndentRuleTests.ts index c314e9d..6c6c88d 100644 --- a/src/test/rules/terIndentRuleTests.ts +++ b/src/test/rules/terIndentRuleTests.ts @@ -1,7 +1,7 @@ /// import * as fs from 'fs'; import * as path from 'path'; -import * as Lint from 'tslint/lib/lint'; +import * as Lint from 'tslint'; import { runTest, IScripts, IScriptError } from './helper'; const fixture = fs.readFileSync( diff --git a/src/test/rules/terMaxLenRuleTests.ts b/src/test/rules/terMaxLenRuleTests.ts index 75af67a..f9f6bfa 100644 --- a/src/test/rules/terMaxLenRuleTests.ts +++ b/src/test/rules/terMaxLenRuleTests.ts @@ -1,5 +1,5 @@ /// -import * as Lint from 'tslint/lib/lint'; +import * as Lint from 'tslint'; import { runTest, IScripts, IScriptError } from './helper'; function expectedErrors(errors: [[number, number] | [number, number, boolean]]): IScriptError[] { diff --git a/tslint.json b/tslint.json index 03b73cd..25514e7 100644 --- a/tslint.json +++ b/tslint.json @@ -22,7 +22,6 @@ "interface-name": [false], "jsdoc-format": true, "label-position": true, - "label-undefined": true, "max-line-length": [ true, 180 @@ -40,9 +39,7 @@ false ], "no-construct": false, - "no-constructor-vars": true, "no-debugger": true, - "no-duplicate-key": true, "no-duplicate-variable": true, "no-empty": true, "no-eval": true, @@ -53,7 +50,6 @@ "no-string-literal": false, "no-switch-case-fall-through": true, "no-trailing-whitespace": true, - "no-unreachable": true, "no-unused-expression": true, "no-use-before-declare": true, "no-var-keyword": true, @@ -95,9 +91,6 @@ "variable-declaration": "nospace" } ], - "use-strict": [ - false - ], "variable-name": [ true, "check-format", From 38485385f9a1bc33c6e27687b32f88bfae1e616c Mon Sep 17 00:00:00 2001 From: Manuel Lopez Date: Sat, 19 Nov 2016 21:35:41 -0600 Subject: [PATCH 04/15] [readme:deprecation] use-strict This was a core rule from TSLint and it has deprecated since typescript handles it. --- README.md | 2 +- src/readme/rules.ts | 20 ++++++-------------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 323ddee..fb141ec 100644 --- a/README.md +++ b/README.md @@ -171,7 +171,7 @@ These rules relate to using strict mode. | :grey_question: | ESLint | TSLint | Description | | :--- | :---: | :---: | :--- | -|:ballot_box_with_check:|[strict](http://eslint.org/docs/rules/strict)|[use-strict](http://palantir.github.io/tslint/rules/use-strict)|require effective use of strict mode directives| +|:no_entry_sign:|[strict](http://eslint.org/docs/rules/strict)|Not applicable|require effective use of strict mode directives| ### Variables diff --git a/src/readme/rules.ts b/src/readme/rules.ts index 464053e..2fb4ad1 100644 --- a/src/readme/rules.ts +++ b/src/readme/rules.ts @@ -960,9 +960,7 @@ const rules: IRule[] = [ category: 'Best Practices', description: 'disallow use of octal literals (recommended)', eslintUrl: 'http://eslint.org/docs/rules/no-octal', - tslintUrl: 'http://palantir.github.io/tslint/rules/Not applicable', - provider: 'Not applicable', - usage: `` + provider: 'Not applicable' }, { available: false, @@ -1292,15 +1290,13 @@ const rules: IRule[] = [ ~~~` }, { - available: true, + available: false, eslintRule: 'strict', - tslintRule: 'use-strict', + tslintRule: 'Not applicable', category: 'Strict Mode', description: 'require effective use of strict mode directives', eslintUrl: 'http://eslint.org/docs/rules/strict', - tslintUrl: 'http://palantir.github.io/tslint/rules/use-strict', - provider: 'native', - usage: '' + provider: 'Not applicable' }, { available: false, @@ -1349,9 +1345,7 @@ const rules: IRule[] = [ category: 'Variables', description: 'disallow deletion of variables (recommended)', eslintUrl: 'http://eslint.org/docs/rules/no-delete-var', - tslintUrl: 'http://palantir.github.io/tslint/rules/Not applicable', - provider: 'Not applicable', - usage: `` + provider: 'Not applicable' }, { available: false, @@ -1397,9 +1391,7 @@ const rules: IRule[] = [ category: 'Variables', description: 'disallow use of undeclared variables unless mentioned in a `/*global */` block (recommended)', eslintUrl: 'http://eslint.org/docs/rules/no-undef', - tslintUrl: 'http://palantir.github.io/tslint/rules/Not applicable', - provider: 'Not applicable', - usage: `` + provider: 'Not applicable' }, { available: false, From 342fb7e4afff016fa771f4bca8d755a4891423b9 Mon Sep 17 00:00:00 2001 From: Manuel Lopez Date: Sat, 19 Nov 2016 22:37:20 -0600 Subject: [PATCH 05/15] [non-applicable] added rules to list of unused rules --- src/readme/unusedTSLintRules.json | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/readme/unusedTSLintRules.json b/src/readme/unusedTSLintRules.json index 6839196..2cb78c5 100644 --- a/src/readme/unusedTSLintRules.json +++ b/src/readme/unusedTSLintRules.json @@ -1,6 +1,16 @@ [ + "adjacent-overload-signatures", + "member-access", + "member-ordering", "no-any", + "no-inferrable-types", + "no-internal-module", + "no-namespace", + "no-reference", + "no-var-requires", + "only-arrow-functions", + "prefer-for-of", "typedef", "typedef-whitespace", - "no-namespace" + "max-line-length" ] From 3a398c85e71b4800fadec73b6536399b6e610fc4 Mon Sep 17 00:00:00 2001 From: Manuel Lopez Date: Sat, 19 Nov 2016 23:15:17 -0600 Subject: [PATCH 06/15] [readme:deprecation] no-unused-variable --- README.md | 2 +- src/readme/rules.ts | 12 ++++-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index fb141ec..71e0579 100644 --- a/README.md +++ b/README.md @@ -188,7 +188,7 @@ These rules have to do with variable declarations. |:no_entry_sign:|[no-undef](http://eslint.org/docs/rules/no-undef)|Not applicable|disallow use of undeclared variables unless mentioned in a `/*global */` block (recommended)| |:x:|[no-undef-init](http://eslint.org/docs/rules/no-undef-init)|no-undef-init|disallow use of undefined when initializing variables| |:x:|[no-undefined](http://eslint.org/docs/rules/no-undefined)|no-undefined|disallow use of `undefined` variable| -|:ballot_box_with_check:|[no-unused-vars](http://eslint.org/docs/rules/no-unused-vars)|[no-unused-variable](http://palantir.github.io/tslint/rules/no-unused-variable)|disallow declaration of variables that are not used in the code (recommended)| +|:no_entry_sign:|[no-unused-vars](http://eslint.org/docs/rules/no-unused-vars)|Not applicable||DEPRECATION: [no-unused-variable](https://github.com/palantir/tslint/issues/1481)| disallow declaration of variables that are not used in the code (recommended).| |:ballot_box_with_check:|[no-use-before-define](http://eslint.org/docs/rules/no-use-before-define)|[no-use-before-declare](http://palantir.github.io/tslint/rules/no-use-before-declare)|disallow use of variables before they are defined| ### Node.js and CommonJS diff --git a/src/readme/rules.ts b/src/readme/rules.ts index 2fb4ad1..51b9582 100644 --- a/src/readme/rules.ts +++ b/src/readme/rules.ts @@ -1418,17 +1418,13 @@ const rules: IRule[] = [ ~~~` }, { - available: true, + available: false, eslintRule: 'no-unused-vars', - tslintRule: 'no-unused-variable', + tslintRule: 'Not applicable', category: 'Variables', - description: 'disallow declaration of variables that are not used in the code (recommended)', + description: '|DEPRECATION: [no-unused-variable](https://github.com/palantir/tslint/issues/1481)| disallow declaration of variables that are not used in the code (recommended).', eslintUrl: 'http://eslint.org/docs/rules/no-unused-vars', - tslintUrl: 'http://palantir.github.io/tslint/rules/no-unused-variable', - provider: 'native', - usage: `~~~json - "no-unused-variable": true - ~~~` + provider: 'Not applicable' }, { available: true, From a2a89a33ddd18bd334f56b4d21dcd23a4de076fa Mon Sep 17 00:00:00 2001 From: Manuel Lopez Date: Sat, 19 Nov 2016 23:29:41 -0600 Subject: [PATCH 07/15] [readme:fix] cannot use `|` in the description since these are use for the table --- README.md | 2 +- src/readme/rules.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 71e0579..2e5235c 100644 --- a/README.md +++ b/README.md @@ -188,7 +188,7 @@ These rules have to do with variable declarations. |:no_entry_sign:|[no-undef](http://eslint.org/docs/rules/no-undef)|Not applicable|disallow use of undeclared variables unless mentioned in a `/*global */` block (recommended)| |:x:|[no-undef-init](http://eslint.org/docs/rules/no-undef-init)|no-undef-init|disallow use of undefined when initializing variables| |:x:|[no-undefined](http://eslint.org/docs/rules/no-undefined)|no-undefined|disallow use of `undefined` variable| -|:no_entry_sign:|[no-unused-vars](http://eslint.org/docs/rules/no-unused-vars)|Not applicable||DEPRECATION: [no-unused-variable](https://github.com/palantir/tslint/issues/1481)| disallow declaration of variables that are not used in the code (recommended).| +|:no_entry_sign:|[no-unused-vars](http://eslint.org/docs/rules/no-unused-vars)|Not applicable|[**DEPRECATED**: [no-unused-variable](https://github.com/palantir/tslint/issues/1481)] disallow declaration of variables that are not used in the code (recommended).| |:ballot_box_with_check:|[no-use-before-define](http://eslint.org/docs/rules/no-use-before-define)|[no-use-before-declare](http://palantir.github.io/tslint/rules/no-use-before-declare)|disallow use of variables before they are defined| ### Node.js and CommonJS diff --git a/src/readme/rules.ts b/src/readme/rules.ts index 51b9582..f37b895 100644 --- a/src/readme/rules.ts +++ b/src/readme/rules.ts @@ -1422,7 +1422,7 @@ const rules: IRule[] = [ eslintRule: 'no-unused-vars', tslintRule: 'Not applicable', category: 'Variables', - description: '|DEPRECATION: [no-unused-variable](https://github.com/palantir/tslint/issues/1481)| disallow declaration of variables that are not used in the code (recommended).', + description: '[**DEPRECATED**: [no-unused-variable](https://github.com/palantir/tslint/issues/1481)] disallow declaration of variables that are not used in the code (recommended).', eslintUrl: 'http://eslint.org/docs/rules/no-unused-vars', provider: 'Not applicable' }, From 2910b5d4cea58fa68b09c1a86c32b26453d7f605 Mon Sep 17 00:00:00 2001 From: Manuel Lopez Date: Sat, 19 Nov 2016 23:36:57 -0600 Subject: [PATCH 08/15] [readme:deprecation] no-duplicate-key --- README.md | 2 +- src/readme/rules.ts | 14 ++++---------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 2e5235c..bd8c0df 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ The following rules point out areas where you might have made mistakes. |:white_check_mark:|[no-control-regex](http://eslint.org/docs/rules/no-control-regex)|[no-control-regex](https://github.com/buzinas/tslint-eslint-rules/blob/master/src/docs/rules/noControlRegexRule.md)|disallow control characters in regular expressions (recommended)| |:ballot_box_with_check:|[no-debugger](http://eslint.org/docs/rules/no-debugger)|[no-debugger](http://palantir.github.io/tslint/rules/no-debugger)|disallow use of `debugger` (recommended)| |:no_entry_sign:|[no-dupe-args](http://eslint.org/docs/rules/no-dupe-args)|Not applicable|disallow duplicate arguments in functions (recommended)| -|:ballot_box_with_check:|[no-dupe-keys](http://eslint.org/docs/rules/no-dupe-keys)|[no-duplicate-key](http://palantir.github.io/tslint/rules/no-duplicate-key)|disallow duplicate keys when creating object literals (recommended)| +|:no_entry_sign:|[no-dupe-keys](http://eslint.org/docs/rules/no-dupe-keys)|Not applicable|disallow duplicate keys when creating object literals (recommended)| |:white_check_mark:|[no-duplicate-case](http://eslint.org/docs/rules/no-duplicate-case)|[no-duplicate-case](https://github.com/buzinas/tslint-eslint-rules/blob/master/src/docs/rules/noDuplicateCaseRule.md)|disallow a duplicate case label. (recommended)| |:ballot_box_with_check:|[no-empty](http://eslint.org/docs/rules/no-empty)|[no-empty](http://palantir.github.io/tslint/rules/no-empty)|disallow empty statements (recommended)| |:white_check_mark:|[no-empty-character-class](http://eslint.org/docs/rules/no-empty-character-class)|[no-empty-character-class](https://github.com/buzinas/tslint-eslint-rules/blob/master/src/docs/rules/noEmptyCharacterClassRule.md)|disallow the use of empty character classes in regular expressions (recommended)| diff --git a/src/readme/rules.ts b/src/readme/rules.ts index f37b895..66e6d6e 100644 --- a/src/readme/rules.ts +++ b/src/readme/rules.ts @@ -128,22 +128,16 @@ const rules: IRule[] = [ category: 'Possible Errors', description: 'disallow duplicate arguments in functions (recommended)', eslintUrl: 'http://eslint.org/docs/rules/no-dupe-args', - tslintUrl: 'http://palantir.github.io/tslint/rules/Not applicable', - provider: 'Not applicable', - usage: `` + provider: 'Not applicable' }, { - available: true, + available: false, eslintRule: 'no-dupe-keys', - tslintRule: 'no-duplicate-key', + tslintRule: 'Not applicable', category: 'Possible Errors', description: 'disallow duplicate keys when creating object literals (recommended)', eslintUrl: 'http://eslint.org/docs/rules/no-dupe-keys', - tslintUrl: 'http://palantir.github.io/tslint/rules/no-duplicate-key', - provider: 'native', - usage: `~~~json - "no-duplicate-key": true - ~~~` + provider: 'Not applicable' }, { available: true, From c0ab535a57fcf394c8bfde773247ba1e827aa13a Mon Sep 17 00:00:00 2001 From: Manuel Lopez Date: Sat, 19 Nov 2016 23:41:58 -0600 Subject: [PATCH 09/15] [readme:deprecation] no-unreachable --- README.md | 2 +- src/readme/rules.ts | 10 +++------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index bd8c0df..ab8e67e 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ The following rules point out areas where you might have made mistakes. |:white_check_mark:|[no-regex-spaces](http://eslint.org/docs/rules/no-regex-spaces)|[no-regex-spaces](https://github.com/buzinas/tslint-eslint-rules/blob/master/src/docs/rules/noRegexSpacesRule.md)|disallow multiple spaces in a regular expression literal (recommended)| |:white_check_mark:|[no-sparse-arrays](http://eslint.org/docs/rules/no-sparse-arrays)|[no-sparse-arrays](https://github.com/buzinas/tslint-eslint-rules/blob/master/src/docs/rules/noSparseArraysRule.md)|disallow sparse arrays (recommended)| |:white_check_mark:|[no-unexpected-multiline](http://eslint.org/docs/rules/no-unexpected-multiline)|[no-unexpected-multiline](https://github.com/buzinas/tslint-eslint-rules/blob/master/src/docs/rules/noUnexpectedMultilineRule.md)|Avoid code that looks like two expressions but is actually one| -|:ballot_box_with_check:|[no-unreachable](http://eslint.org/docs/rules/no-unreachable)|[no-unreachable](http://palantir.github.io/tslint/rules/no-unreachable)|disallow unreachable statements after a return, throw, continue, or break statement (recommended)| +|:no_entry_sign:|[no-unreachable](http://eslint.org/docs/rules/no-unreachable)|Not applicable|disallow unreachable statements after a return, throw, continue, or break statement (recommended)| |:white_check_mark:|[use-isnan](http://eslint.org/docs/rules/use-isnan)|[use-isnan](https://github.com/buzinas/tslint-eslint-rules/blob/master/src/docs/rules/useIsnanRule.md)|disallow comparisons with the value `NaN` (recommended)| |:white_check_mark:|[valid-jsdoc](http://eslint.org/docs/rules/valid-jsdoc)|[valid-jsdoc](https://github.com/buzinas/tslint-eslint-rules/blob/master/src/docs/rules/validJsdocRule.md)|Ensure JSDoc comments are valid| |:white_check_mark:|[valid-typeof](http://eslint.org/docs/rules/valid-typeof)|[valid-typeof](https://github.com/buzinas/tslint-eslint-rules/blob/master/src/docs/rules/validTypeofRule.md)|Ensure that the results of typeof are compared against a valid string (recommended)| diff --git a/src/readme/rules.ts b/src/readme/rules.ts index 66e6d6e..7160a34 100644 --- a/src/readme/rules.ts +++ b/src/readme/rules.ts @@ -350,17 +350,13 @@ const rules: IRule[] = [ ~~~` }, { - available: true, + available: false, eslintRule: 'no-unreachable', - tslintRule: 'no-unreachable', + tslintRule: 'Not applicable', category: 'Possible Errors', description: 'disallow unreachable statements after a return, throw, continue, or break statement (recommended)', eslintUrl: 'http://eslint.org/docs/rules/no-unreachable', - tslintUrl: 'http://palantir.github.io/tslint/rules/no-unreachable', - provider: 'native', - usage: `~~~json - "no-unreachable": true - ~~~` + provider: 'Not applicable' }, { available: true, From e268d695636d66c621d9763026707b54a75e1a66 Mon Sep 17 00:00:00 2001 From: Manuel Lopez Date: Sun, 20 Nov 2016 23:02:28 -0600 Subject: [PATCH 10/15] [feat] RuleTester MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The rule tester will replace the helper file in the tests. A few more modifications need to be done before the release. For instance Iā€™m not happy with the `IFailure` interface name. This needs to be changed. All the tests for the ter-max-len rule have been updated to make use of the RuleTester. --- src/test/rules/ruleTester.ts | 269 ++++++++++ src/test/rules/terMaxLenRuleTests.ts | 769 ++++++++++++++------------- 2 files changed, 665 insertions(+), 373 deletions(-) create mode 100644 src/test/rules/ruleTester.ts diff --git a/src/test/rules/ruleTester.ts b/src/test/rules/ruleTester.ts new file mode 100644 index 0000000..c684881 --- /dev/null +++ b/src/test/rules/ruleTester.ts @@ -0,0 +1,269 @@ +import { assert } from 'chai'; +import * as Lint from 'tslint'; + +const dedent = Lint.Utils.dedent; +const empty = 'ā–‘'; + +class Position { + private line: number | undefined; + private character: number | undefined; + private position: number | undefined; + + constructor(line?: number, character?: number, position?: number) { + this.line = line; + this.character = character; + this.position = position; + } + + /** + * Returns the string representation of a Position in the form of `[line:char|pos]`. If + * any of its properties is undefined an empty block will appear. For instance, if we only + * provide only the line then the result will be `[line:ā–‘|ā–‘]`. + * @returns {string} + */ + public toString(): string { + const line = this.line === undefined ? empty : this.line; + const char = this.character === undefined ? empty : this.character; + const pos = this.position === undefined ? empty : this.position; + return `[${line}:${char}|${pos}]`; + } + + /** + * A comparable Position to the calling object is a Position that has the same undefined + * properties. For instance, `new Position(1)` and `new Position(10, 2)` are not comparable + * since the second position defines its character location. + * + * Returns a copy of the Position parameter object with some properties set to undefined. Those + * properties are set to undefined only in the case the calling object has them to set to + * undefined. Thus, the returned object will be comparable to the calling object. + * + * @param pos The object we wish to compare. + * @returns {Position} A comparable position. + */ + public getComparablePosition(obj: Position): Position { + const line = this.line === undefined ? undefined : obj.line; + const char = this.character === undefined ? undefined : obj.character; + const pos = this.position === undefined ? undefined : obj.position; + return new Position(line, char, pos); + } +} + +interface IFailure { + failure: string; + startPosition: Position; + endPosition: Position; +} + +class Failure { + private name: string; + private ruleName: string; + private failure: string; + private startPosition: Position; + private endPosition: Position; + + constructor(name: string, ruleName: string, failure: string, start?: Position, end?: Position) { + this.name = name; + this.ruleName = ruleName; + this.failure = failure; + this.startPosition = start || new Position(); + this.endPosition = end || new Position(); + } + + /** + * Returns the string representation of the Failure object in the following form: + * + * ``` + * [name@{startPos -> endPos}] ruleName: failure + * ``` + * + * @returns {string} + */ + public toString(): string { + const pos = `${this.name}@{${this.startPosition} -> ${this.endPosition}}`; + return `[${pos}] ${this.ruleName}: ${this.failure}`; + } + + /** + * Return a clone of the Failure where the start and end positions are comparable to the + * ones of the calling Failure. + * @param obj The Failure to compare. + * @returns {Failure} A comparable Failure. + */ + public getComparableFailure(obj: Failure): Failure { + return new Failure( + obj.name, + obj.ruleName, + obj.failure, + this.startPosition.getComparablePosition(obj.startPosition), + this.endPosition.getComparablePosition(obj.endPosition) + ); + } +} + +interface ITest { + code: string; + output?: string; + options?: any; + errors?: IFailure[]; +} + +class Test { + private name: string; + public code: string; + public output: string; + public options: any; + public errors: Failure[]; + + constructor(name: string, code: string, output: string, options: any, errors: Failure[]) { + this.name = name; + this.code = code; + this.output = output; + this.options = options; + this.errors = errors; + } + + public runTest(): void { + const options: Lint.ILinterOptions = { + fix: false, + formatter: 'json', + formattersDirectory: 'dist/formatters/', + rulesDirectory: 'dist/rules/' + }; + + const linter = new Lint.Linter(options); + linter.lint(this.name, this.code, this.options); + const failures = JSON.parse(linter.getResult().output); + this.compareErrors(this.errors || [], failures.map((error: any) => { + const start = error.startPosition; + const end = error.endPosition; + return new Failure( + error.name, + error.ruleName, + error.failure, + new Position(start.line, start.character, start.position), + new Position(end.line, end.character, end.position) + ); + })); + } + + private compareErrors(expectedErrors: Failure[], foundErrors: Failure[]): void { + const expected = this.arrayDiff(expectedErrors, foundErrors); + const found = this.arrayDiff(foundErrors, expectedErrors, false); + + const codeLines = this.code.split('\n'); + const total = codeLines.length.toString().length; + const codeStr = codeLines.map((x, i) => ` ${this.pad(i, total)}| ${x}`).join('\n'); + const expectedStr = expected.length ? `Expected:\n ${expected.join('\n ')}` : ''; + const foundStr = found.length ? `Found:\n ${found.join('\n ')}` : ''; + const msg = [ + `Error mismatch in ${this.name}:`, + '', + codeStr, + '', + ` ${expectedStr}`, + '', + ` ${foundStr}`, + '', + ].join('\n'); + assert(expected.length === 0 && found.length === 0, msg); + } + + private arrayDiff(source: Failure[], target: Failure[], compareToTarget: boolean = true) { + return source.filter(item => { + return this.findIndex(target, item, compareToTarget) === -1; + }).map((x) => { + if (compareToTarget) { + return x.toString(); + } else { + return target.length ? target[0].getComparableFailure(x).toString() : x.toString(); + } + }); + } + + private findIndex(source: Failure[], error: Failure, compareToError: boolean = true) { + const len = source.length; + let k = 0; + while (k < len) { + if (compareToError && `${error}` === `${error.getComparableFailure(source[k])}`) { + return k; + } else if (`${source[k]}` === `${source[k].getComparableFailure(error)}`) { + return k; + } + k++; + } + return -1; + } + + private pad(n: number, width: number) { + const numStr: string = n.toString(); + const padding: string = new Array(width - numStr.length + 1).join(' '); + return numStr.length >= width ? numStr : padding + numStr; + } +} + +class TestGroup { + public name: string; + public ruleName: string; + public description: string; + public tests: Test[]; + + constructor(name: string, description: string, ruleName: string, tests: (ITest | string)[]) { + this.name = name; + this.ruleName = ruleName; + this.description = description; + this.tests = tests.map((test: ITest | string, index) => { + const config: any = { rules: { [ruleName]: true } }; + const codeFileName = `${name}-${index}.ts`; + if (typeof test === 'string') { + return new Test(codeFileName, test, undefined, config, []); + } + if (test.options) { + config.rules[ruleName] = [true, ...test.options]; + } + const failures: Failure[] = (test.errors || []).map((error) => { + return new Failure( + codeFileName, + ruleName, + error.failure, + error.startPosition, + error.endPosition + ); + }); + return new Test(codeFileName, test.code, test.output, config, failures); + }); + } +} + +class RuleTester { + private ruleName: string; + private groups: TestGroup[] = []; + + constructor(ruleName: string) { + this.ruleName = ruleName; + } + + public addTestGroup(name: string, description: string, tests: (ITest | string)[]): this { + this.groups.push(new TestGroup(name, description, this.ruleName, tests)); + return this; + } + + public runTests(): void { + describe(this.ruleName, () => { + this.groups.forEach((group) => { + it(group.description, () => { + group.tests.forEach((test) => { + test.runTest(); + }); + }); + }); + }); + } +} + +export { + dedent, + Position, + IFailure, + TestGroup, + RuleTester +}; diff --git a/src/test/rules/terMaxLenRuleTests.ts b/src/test/rules/terMaxLenRuleTests.ts index f9f6bfa..1df30f0 100644 --- a/src/test/rules/terMaxLenRuleTests.ts +++ b/src/test/rules/terMaxLenRuleTests.ts @@ -1,35 +1,105 @@ -/// -import * as Lint from 'tslint'; -import { runTest, IScripts, IScriptError } from './helper'; +import { RuleTester, IFailure, Position, dedent } from './ruleTester'; +// ESLint Tests: https://github.com/eslint/eslint/blob/master/tests/lib/rules/max-len.js -function expectedErrors(errors: [[number, number] | [number, number, boolean]]): IScriptError[] { +const ruleTester = new RuleTester('ter-max-len'); + +function expecting(errors: [[number, number] | [number, number, boolean]]): IFailure[] { return errors.map((err) => { let message = `Line ${err[0] + 1} exceeds the maximum line length of ${err[1]}.`; if (err[2]) { message = `Line ${err[0] + 1} exceeds the maximum comment line length of ${err[1]}.`; } - return { message, line: err[0] }; + return { + failure: message, + startPosition: new Position(err[0]), + endPosition: new Position() + }; }); } -/** - * Borrowing tests from eslint: - * https://github.com/eslint/eslint/blob/master/tests/lib/rules/max-len.js - */ -const rule = 'ter-max-len'; -const scripts: { valid: IScripts, invalid: IScripts } = { - valid: [ - { - code: Lint.Utils.dedent` - var dep = require('really/really/really/really/really/really/really/long/module'); - const dep = require('another/really/really/really/really/really/really/long/module'); - foobar = 'this line will be ignored because it starts with foobar ...'; - `, - options: [50, { ignorePattern: '^\\s*(var|const)\\s.+=\\s*require\\s*\\(|^\\s*foobar' }] - }, - { - code: Lint.Utils.dedent` +ruleTester.addTestGroup('no-options', 'should warn when the line exceeds the limit', [ + { + code: '' + }, + { + code: 'var x = 5;\nvar x = 2;' + }, + { + code: 'var x = 5;\nvar x = 2;', + options: [80] + }, + { + code: 'var one\t\t= 1;\nvar three\t= 3;', + options: [16, 4] + }, + { + code: '\tvar one\t\t= 1;\n\tvar three\t= 3;', + options: [20, 4] + }, + { + code: 'var i = 1;\r\nvar i = 1;\n', + options: [10, 4] + }, + { + code: '\n// Blank line on top\nvar foo = module.exports = {};\n', + options: [80, 4] + }, + { + code: '\n// Blank line on top\nvar foo = module.exports = {};\n' + }, + { + code: '\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tvar i = 1;', + errors: expecting([[0, 80]]) + }, + { + code: 'var x = 5, y = 2, z = 5;', + options: [10], + errors: expecting([[0, 10]]) + }, + { + code: '\t\t\tvar i = 1;', + options: [15], + errors: expecting([[0, 15]]) + }, + { + code: '\t\t\tvar i = 1;\n\t\t\tvar j = 1;', + options: [15, { tabWidth: 4 }], + errors: expecting([[0, 15], [1, 15]]) + } +]); + +ruleTester.addTestGroup('patterns', 'should ignore specified patterns', [ + { + code: dedent` + var dep = require('really/really/really/really/really/really/really/long/module'); + const dep = require('another/really/really/really/really/really/really/long/module'); + foobar = 'this line will be ignored because it starts with foobar ...'; + `, + options: [50, { ignorePattern: '^\\s*(var|const)\\s.+=\\s*require\\s*\\(|^\\s*foobar' }] + }, + { + code: `foo(bar(bazz('this is a long'), 'line of'), 'stuff');`, + options: [40, 4, { ignorePattern: 'foo.+bazz\\(' }] + }, + { + code: `foo(bar(bazz('this is a long'), 'line of'), 'stuff');`, + options: [40, 4], // ignorePattern is disabled + errors: expecting([[0, 40]]) + }, + { + code: dedent` + var foobar = 'this line isn\\'t matched by the regexp'; + var fizzbuzz = 'but this one is matched by the regexp'; + `, + options: [20, 4, { ignorePattern: 'fizzbuzz' }], + errors: expecting([[1, 20]]) + } +]); + +ruleTester.addTestGroup('imports', 'should ignore long module specifiers', [ + { + code: dedent` import { obj1, obj2, obj3, obj4 } from 'my-favorite-module/with/lots/of/deep/nested/modules'; import { obj1, @@ -38,364 +108,317 @@ const scripts: { valid: IScripts, invalid: IScripts } = { obj4, } from 'my-favorite-module/with/lots/of/deep/nested/modules'; `, - options: [50, { ignoreImports: true }] - }, - { - code: 'var x = 5;\nvar x = 2;' - }, - { - code: 'var x = 5;\nvar x = 2;', - options: [80] - }, - { - code: 'var one\t\t= 1;\nvar three\t= 3;', - options: [16, 4] - }, - { - code: '\tvar one\t\t= 1;\n\tvar three\t= 3;', - options: [20, 4] - }, - { - code: 'var i = 1;\r\nvar i = 1;\n', - options: [10, 4] - }, - { - code: '\n// Blank line on top\nvar foo = module.exports = {};\n', - options: [80, 4] - }, - { - code: '\n// Blank line on top\nvar foo = module.exports = {};\n' - }, - { - code: 'var foo = module.exports = {}; // really long trailing comment', - options: [40, 4, { ignoreComments: true }] - }, { - code: 'foo(); \t// strips entire comment *and* trailing whitespace', - options: [6, 4, { ignoreComments: true }] - }, { - code: '// really long comment on its own line sitting here', - options: [40, 4, { ignoreComments: true }] - }, - { - code: 'var /*inline-comment*/ i = 1;' - }, - { - code: 'var /*inline-comment*/ i = 1; // with really long trailing comment', - options: [40, 4, { ignoreComments: true }] - }, { - code: `foo('http://example.com/this/is/?a=longish&url=in#here');`, - options: [40, 4, { ignoreUrls: true }] - }, { - code: "foo(bar(bazz('this is a long'), 'line of'), 'stuff');", - options: [40, 4, { ignorePattern: 'foo.+bazz\\(' }] - }, { - code: Lint.Utils.dedent` - /* hey there! this is a multiline - comment with longish lines in various places - but - with a short line-length */`, - options: [10, 4, { ignoreComments: true }] - }, { - code: Lint.Utils.dedent` - // I like short comments - function butLongSourceLines() { weird(eh()) }`, - options: [80, {tabWidth: 4, comments: 30}] - }, { - code: Lint.Utils.dedent` - // Full line comment - someCode(); // With a long trailing comment.`, - options: [{ code: 30, tabWidth: 4, comments: 20, ignoreTrailingComments: true }] - }, { - code: 'var foo = module.exports = {}; // really long trailing comment', - options: [40, 4, { ignoreTrailingComments: true }] - }, { - code: 'var foo = module.exports = {}; // really long trailing comment', - options: [40, 4, { ignoreComments: true, ignoreTrailingComments: false }] - }, - // ignoreStrings, ignoreTemplateLiterals and ignoreRegExpLiterals options - { - code: `var foo = veryLongIdentifier;\nvar bar = 'this is a very long string';`, - options: [29, 4, { ignoreStrings: true }] - }, - { - code: `var foo = veryLongIdentifier;\nvar bar = "this is a very long string";`, - options: [29, 4, { ignoreStrings: true }] - }, - { - code: Lint.Utils.dedent` - var str = "this is a very long string\ - with continuation";`, - options: [29, 4, { ignoreStrings: true }] - }, - { - code: 'var str = \"this is a very long string\\\nwith continuation\\\nand with another very very long continuation\\\nand ending\";', - options: [29, 4, { ignoreStrings: true }] - }, - { - code: 'var foo = veryLongIdentifier;\nvar bar = `this is a very long string`;', - options: [29, 4, { ignoreTemplateLiterals: true }] - }, - { - code: 'var foo = veryLongIdentifier;\nvar bar = `this is a very long string\nand this is another line that is very long`;', - options: [29, 4, { ignoreTemplateLiterals: true }] - }, - { - code: Lint.Utils.dedent` - var foo = veryLongIdentifier; - var bar = \`this is a very long string - and this is another line that is very long - and here is another - and another!\`;`, - options: [29, 4, { ignoreTemplateLiterals: true }] - }, - { - code: 'var foo = /this is a very long pattern/;', - options: [29, 4, { ignoreRegExpLiterals: true }] - }, - // check indented comment lines - https://github.com/eslint/eslint/issues/6322 - { - code: Lint.Utils.dedent` - function foo() { - //this line has 29 characters - }`, - options: [40, 4, { comments: 29 }] - }, { - code: Lint.Utils.dedent` - function foo() { - //this line has 33 characters - }`, - options: [40, 4, { comments: 33 }] - }, { - code: Lint.Utils.dedent` - function foo() { - /*this line has 29 characters - and this one has 21*/ - }`, - options: [40, 4, { comments: 29 }] - }, { - code: Lint.Utils.dedent` - function foo() { - /*this line has 33 characters - and this one has 25*/ - }`, - options: [40, 4, { comments: 33 }] - }, { - code: Lint.Utils.dedent` - function foo() { - var a; /*this line has 40 characters - and this one has 36 characters*/ - }`, - options: [40, 4, { comments: 36 }] - }, { - code: Lint.Utils.dedent` - function foo() { - /*this line has 33 characters - and this one has 43 characters*/ var a; - }`, - options: [43, 4, { comments: 33 }] - }, - { - code: '' - } - ], - invalid: [ - { - code: Lint.Utils.dedent` + options: [50, { ignoreImports: true }] + }, + { + code: dedent` import { obj1, obj2, obj3, obj4, just, trying, to, be, a, rebel, here } from 'my-favorite-module/with/lots/of/deep/nested/modules'; `, - options: [50, { ignoreImports: true }], - errors: expectedErrors([[2, 50]]) - }, - { - code: '\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tvar i = 1;', - errors: expectedErrors([[0, 80]]) - }, - { - code: 'var x = 5, y = 2, z = 5;', - options: [10], - errors: expectedErrors([[0, 10]]) - }, - { - code: '\t\t\tvar i = 1;', - options: [15], - errors: expectedErrors([[0, 15]]) - }, - { - code: '\t\t\tvar i = 1;\n\t\t\tvar j = 1;', - options: [15, { tabWidth: 4 }], - errors: expectedErrors([[0, 15], [1, 15]]) - }, - { - code: 'var /*this is a long non-removed inline comment*/ i = 1;', - options: [20, { tabWidth: 4, ignoreComments: true }], - errors: expectedErrors([[0, 20]]) - }, - { - code: Lint.Utils.dedent` - var foobar = 'this line isn\\'t matched by the regexp'; - var fizzbuzz = 'but this one is matched by the regexp'; - `, - options: [20, 4, { ignorePattern: 'fizzbuzz' }], - errors: expectedErrors([[1, 20]]) - }, - { - code: `var longLine = 'will trigger'; // even with a comment`, - options: [10, 4, { ignoreComments: true }], - errors: expectedErrors([[0, 10]]) - }, - { - code: `var foo = module.exports = {}; // really long trailing comment`, - options: [40, 4], // ignoreComments is disabled - errors: expectedErrors([[0, 40]]) - }, - { - code: `foo('http://example.com/this/is/?a=longish&url=in#here');`, - options: [40, 4], // ignoreUrls is disabled - errors: expectedErrors([[0, 40]]) - }, - { - code: `foo(bar(bazz('this is a long'), 'line of'), 'stuff');`, - options: [40, 4], // ignorePattern is disabled - errors: expectedErrors([[0, 40]]) - }, - { - code: '// A comment that exceeds the max comment length.', - options: [80, 4, { comments: 20 }], - errors: expectedErrors([[0, 20, true]]) - }, - { - code: '// A comment that exceeds the max comment length.', - options: [{ code: 20 }], - errors: expectedErrors([[0, 20]]) - }, - { - code: '//This is very long comment with more than 40 characters which is invalid', - options: [40, 4, { ignoreTrailingComments: true }], - errors: expectedErrors([[0, 40]]) - }, - // check indented comment lines - https://github.com/eslint/eslint/issues/6322 - { - code: Lint.Utils.dedent` - function foo() { - //this line has 29 characters - }`, - options: [40, 4, { comments: 28 }], - errors: expectedErrors([[2, 28, true]]) - }, - { - code: Lint.Utils.dedent` - function foo() { - //this line has 33 characters - }`, - options: [40, 4, { comments: 32 }], - errors: expectedErrors([[2, 32, true]]) - }, - { - code: Lint.Utils.dedent` - function foo() { - /*this line has 29 characters - and this one has 32 characters*/ - }`, - options: [40, 4, { comments: 28 }], - errors: expectedErrors([ - [2, 28, true], - [3, 28, true] - ]) - }, - { - code: Lint.Utils.dedent` - function foo() { - /*this line has 33 characters - and this one has 36 characters*/ - }`, - options: [40, 4, { comments: 32 }], - errors: expectedErrors([ - [2, 32, true], - [3, 32, true] - ]) - }, - { - code: Lint.Utils.dedent` - function foo() { - var a; /*this line has 40 characters - and this one has 36 characters*/ - }`, - options: [39, 4, { comments: 35 }], - errors: expectedErrors([ - [2, 39], - [3, 35, true] - ]) - }, - { - code: Lint.Utils.dedent` - function foo() { - /*this line has 33 characters - and this one has 43 characters*/ var a; - }`, - options: [42, 4, { comments: 32 }], - errors: expectedErrors([ - [2, 32, true], - [3, 42] - ]) - }, - // check comments with the same length as non-comments - https://github.com/eslint/eslint/issues/6564 - { - code: Lint.Utils.dedent` - // This commented line has precisely 51 characters. - var x = 'This line also has exactly 51 characters';`, - options: [20, { ignoreComments: true }], - errors: expectedErrors([[2, 20]]) - }, - // ignoreStrings and ignoreTemplateLiterals options - { - code: `var foo = veryLongIdentifier;\nvar bar = 'this is a very long string';`, - options: [29, { ignoreStrings: false, ignoreTemplateLiterals: true }], - errors: expectedErrors([[1, 29]]) - }, - { - code: `var foo = veryLongIdentifier;\nvar bar = /this is a very very long pattern/;`, - options: [29, { ignoreStrings: false, ignoreRegExpLiterals: false }], - errors: expectedErrors([[1, 29]]) - }, - { - code: `var foo = veryLongIdentifier;\nvar bar = new RegExp('this is a very very long pattern');`, - options: [29, { ignoreStrings: false, ignoreRegExpLiterals: true }], - errors: expectedErrors([[1, 29]]) - }, - { - code: `var foo = veryLongIdentifier;\nvar bar = \"this is a very long string\";`, - options: [29, { ignoreStrings: false, ignoreTemplateLiterals: true }], - errors: expectedErrors([[1, 29]]) - }, - { - code: 'var foo = veryLongIdentifier;\nvar bar = `this is a very long string`;', - options: [29, { ignoreStrings: false, ignoreTemplateLiterals: false }], - errors: expectedErrors([[1, 29]]) - }, - { - code: Lint.Utils.dedent` + options: [50, { ignoreImports: true }], + errors: expecting([[2, 50]]) + } +]); + +ruleTester.addTestGroup('urls', 'should ignore lines that contain urls', [ + { + code: `foo('http://example.com/this/is/?a=longish&url=in#here');`, + options: [40, 4, { ignoreUrls: true }] + }, + { + code: `foo('http://example.com/this/is/?a=longish&url=in#here');`, + options: [40, 4], // ignoreUrls is disabled + errors: expecting([[0, 40]]) + } +]); + +ruleTester.addTestGroup('comments', 'should handle comments', [ + { + code: 'var foo = module.exports = {}; // really long trailing comment', + options: [40, 4, { ignoreComments: true }] + }, + { + code: 'foo(); \t// strips entire comment *and* trailing whitespace', + options: [6, 4, { ignoreComments: true }] + }, + { + code: '// really long comment on its own line sitting here', + options: [40, 4, { ignoreComments: true }] + }, + { + code: 'var /*inline-comment*/ i = 1;' + }, + { + code: 'var /*inline-comment*/ i = 1; // with really long trailing comment', + options: [40, 4, { ignoreComments: true }] + }, + { + code: dedent` + /* hey there! this is a multiline + comment with longish lines in various places + but + with a short line-length */`, + options: [10, 4, { ignoreComments: true }] + }, + { + code: dedent` + // I like short comments + function butLongSourceLines() { weird(eh()) }`, + options: [80, {tabWidth: 4, comments: 30}] + }, + { + code: dedent` + // Full line comment + someCode(); // With a long trailing comment.`, + options: [{ code: 30, tabWidth: 4, comments: 20, ignoreTrailingComments: true }] + }, + { + code: 'var foo = module.exports = {}; // really long trailing comment', + options: [40, 4, { ignoreTrailingComments: true }] + }, { + code: 'var foo = module.exports = {}; // really long trailing comment', + options: [40, 4, { ignoreComments: true, ignoreTrailingComments: false }] + }, + { + code: dedent` + function foo() { + //this line has 29 characters + }`, + options: [40, 4, { comments: 29 }] + }, + { + code: dedent` + function foo() { + //this line has 33 characters + }`, + options: [40, 4, { comments: 33 }] + }, + { + code: dedent` + function foo() { + /*this line has 29 characters + and this one has 21*/ + }`, + options: [40, 4, { comments: 29 }] + }, + { + code: dedent` + function foo() { + /*this line has 33 characters + and this one has 25*/ + }`, + options: [40, 4, { comments: 33 }] + }, + { + code: dedent` + function foo() { + var a; /*this line has 40 characters + and this one has 36 characters*/ + }`, + options: [40, 4, { comments: 36 }] + }, + { + code: dedent` + function foo() { + /*this line has 33 characters + and this one has 43 characters*/ var a; + }`, + options: [43, 4, { comments: 33 }] + }, + { + code: dedent` + function foo() { + //this line has 29 characters + }`, + options: [40, 4, { comments: 28 }], + errors: expecting([[2, 28, true]]) + }, + { + code: dedent` + function foo() { + //this line has 33 characters + }`, + options: [40, 4, { comments: 32 }], + errors: expecting([[2, 32, true]]) + }, + { + code: dedent` + function foo() { + /*this line has 29 characters + and this one has 32 characters*/ + }`, + options: [40, 4, { comments: 28 }], + errors: expecting([ + [2, 28, true], + [3, 28, true] + ]) + }, + { + code: dedent` + function foo() { + /*this line has 33 characters + and this one has 36 characters*/ + }`, + options: [40, 4, { comments: 32 }], + errors: expecting([ + [2, 32, true], + [3, 32, true] + ]) + }, + { + code: dedent` + function foo() { + var a; /*this line has 40 characters + and this one has 36 characters*/ + }`, + options: [39, 4, { comments: 35 }], + errors: expecting([ + [2, 39], + [3, 35, true] + ]) + }, + { + code: dedent` + function foo() { + /*this line has 33 characters + and this one has 43 characters*/ var a; + }`, + options: [42, 4, { comments: 32 }], + errors: expecting([ + [2, 32, true], + [3, 42] + ]) + }, + // check comments with the same length as non-comments - https://github.com/eslint/eslint/issues/6564 + { + code: dedent` + // This commented line has precisely 51 characters. + var x = 'This line also has exactly 51 characters';`, + options: [20, { ignoreComments: true }], + errors: expecting([[2, 20]]) + }, + { + code: 'var /*this is a long non-removed inline comment*/ i = 1;', + options: [20, { tabWidth: 4, ignoreComments: true }], + errors: expecting([[0, 20]]) + }, + { + code: `var longLine = 'will trigger'; // even with a comment`, + options: [10, 4, { ignoreComments: true }], + errors: expecting([[0, 10]]) + }, + { + code: `var foo = module.exports = {}; // really long trailing comment`, + options: [40, 4], // ignoreComments is disabled + errors: expecting([[0, 40]]) + }, + + { + code: '// A comment that exceeds the max comment length.', + options: [80, 4, { comments: 20 }], + errors: expecting([[0, 20, true]]) + }, + { + code: '// A comment that exceeds the max comment length.', + options: [{ code: 20 }], + errors: expecting([[0, 20]]) + }, + { + code: '//This is very long comment with more than 40 characters which is invalid', + options: [40, 4, { ignoreTrailingComments: true }], + errors: expecting([[0, 40]]) + } +]); + +ruleTester.addTestGroup('regex', 'should ignore long regular expression literals', [ + { + code: 'var foo = /this is a very long pattern/;', + options: [29, 4, { ignoreRegExpLiterals: true }] + } +]); + +ruleTester.addTestGroup('template-literals', 'should ignore template literals', [ + { + code: 'var foo = veryLongIdentifier;\nvar bar = `this is a very long string`;', + options: [29, 4, { ignoreTemplateLiterals: true }] + }, + { + code: 'var foo = veryLongIdentifier;\nvar bar = `this is a very long string\nand this is another line that is very long`;', + options: [29, 4, { ignoreTemplateLiterals: true }] + }, + { + code: dedent` var foo = veryLongIdentifier; var bar = \`this is a very long string - and this is another line that is very long\`;`, - options: [29, { ignoreStrings: false, ignoreTemplateLiterals: false }], - errors: expectedErrors([ - [2, 29], - [3, 29] - ]) - } - ] -}; + and this is another line that is very long + and here is another + and another!\`;`, + options: [29, 4, { ignoreTemplateLiterals: true }] + } +]); -describe(rule, () => { +ruleTester.addTestGroup('strings', 'should ignore strings', [ + { + code: `var foo = veryLongIdentifier;\nvar bar = 'this is a very long string';`, + options: [29, 4, { ignoreStrings: true }] + }, + { + code: `var foo = veryLongIdentifier;\nvar bar = "this is a very long string";`, + options: [29, 4, { ignoreStrings: true }] + }, + { + code: dedent` + var str = "this is a very long string\ + with continuation";`, + options: [29, 4, { ignoreStrings: true }] + }, + { + code: 'var str = \"this is a very long string\\\nwith continuation\\\nand with another very very long continuation\\\nand ending\";', + options: [29, 4, { ignoreStrings: true }] + } +]); - it('should pass when the line lengths complies with the rule', () => { - runTest(rule, scripts.valid); - }); +ruleTester.addTestGroup('strings-regex', 'should handle ignoreStrings and ignoreRegExpLiterals options', [ + { + code: `var foo = veryLongIdentifier;\nvar bar = /this is a very very long pattern/;`, + options: [29, { ignoreStrings: false, ignoreRegExpLiterals: false }], + errors: expecting([[1, 29]]) + }, + { + code: `var foo = veryLongIdentifier;\nvar bar = new RegExp('this is a very very long pattern');`, + options: [29, { ignoreStrings: false, ignoreRegExpLiterals: true }], + errors: expecting([[1, 29]]) + } +]); - it('should fail when the line length exceeds the limit imposed', () => { - runTest(rule, scripts.invalid); - }); +ruleTester.addTestGroup('strings-templates', 'should handle the ignoreStrings and ignoreTemplateLiterals options', [ + { + code: `var foo = veryLongIdentifier;\nvar bar = 'this is a very long string';`, + options: [29, { ignoreStrings: false, ignoreTemplateLiterals: true }], + errors: expecting([[1, 29]]) + }, + { + code: `var foo = veryLongIdentifier;\nvar bar = \"this is a very long string\";`, + options: [29, { ignoreStrings: false, ignoreTemplateLiterals: true }], + errors: expecting([[1, 29]]) + }, + { + code: 'var foo = veryLongIdentifier;\nvar bar = `this is a very long string`;', + options: [29, { ignoreStrings: false, ignoreTemplateLiterals: false }], + errors: expecting([[1, 29]]) + }, + { + code: dedent` + var foo = veryLongIdentifier; + var bar = \`this is a very long string + and this is another line that is very long\`;`, + options: [29, { ignoreStrings: false, ignoreTemplateLiterals: false }], + errors: expecting([ + [2, 29], + [3, 29] + ]) + } +]); -}); +ruleTester.runTests(); From 4e673364fb1bbc6900c0597d6747a1f085c95889 Mon Sep 17 00:00:00 2001 From: Manuel Lopez Date: Sun, 20 Nov 2016 23:19:49 -0600 Subject: [PATCH 11/15] [upgrade] gulp-tslint -> 7.0.0 It now supports tslint 4.0, the tests should be passing now. I had to turn off the max-line-length rule since I violate it on the readme. I will try to run a check on our files with our own custom rules. --- gulpfile.js | 6 ++---- package.json | 2 +- src/test/rules/ruleTester.ts | 2 +- tslint.json | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index d124bd1..b6bb5b0 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -37,11 +37,9 @@ gulp.task('lint', function lint() { return gulp .src(SRC_FOLDER) .pipe(tslint({ - tslint: require('tslint') + formatter: 'verbose', })) - .pipe(tslint.report('prose', { - summarizeFailureOutput: false - })); + .pipe(tslint.report()); }); gulp.task('build', argv.lint === false ? [] : ['lint'], function build(done) { diff --git a/package.json b/package.json index d22380c..440534b 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "gulp": "^3.9.1", "gulp-sourcemaps": "^1.6.0", "gulp-spawn-mocha": "^2.2.2", - "gulp-tslint": "^3.6.0", + "gulp-tslint": "^7.0.0", "gulp-typescript": "^3.0.1", "typescript": "^2.0.3", "yargs": "^5.0.0" diff --git a/src/test/rules/ruleTester.ts b/src/test/rules/ruleTester.ts index c684881..cacb14f 100644 --- a/src/test/rules/ruleTester.ts +++ b/src/test/rules/ruleTester.ts @@ -163,7 +163,7 @@ class Test { ` ${expectedStr}`, '', ` ${foundStr}`, - '', + '' ].join('\n'); assert(expected.length === 0 && found.length === 0, msg); } diff --git a/tslint.json b/tslint.json index 25514e7..e23ffdd 100644 --- a/tslint.json +++ b/tslint.json @@ -23,7 +23,7 @@ "jsdoc-format": true, "label-position": true, "max-line-length": [ - true, + false, 180 ], "member-access": true, From 2fd9ba4ba6071bf4149d9dc4243e975ca09d6f0f Mon Sep 17 00:00:00 2001 From: Manuel Lopez Date: Sun, 20 Nov 2016 23:53:06 -0600 Subject: [PATCH 12/15] [chore] using project rules to self lint our source files In this case I have turned on the `ter-max-len` rule on so that we may stop the linter from warning us when a line exceeds 180 due to a url encounter. Travis should pass now I believe. Lets see. --- gulpfile.js | 10 ++++++++++ package.json | 2 +- tslint_eslint_rules.json | 8 ++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 tslint_eslint_rules.json diff --git a/gulpfile.js b/gulpfile.js index b6bb5b0..8f41e33 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -42,6 +42,16 @@ gulp.task('lint', function lint() { .pipe(tslint.report()); }); +gulp.task('self-lint', function selfLint() { + return gulp + .src(SRC_FOLDER) + .pipe(tslint({ + configuration: 'tslint_eslint_rules.json', + formatter: 'verbose' + })) + .pipe(tslint.report()); +}); + gulp.task('build', argv.lint === false ? [] : ['lint'], function build(done) { var hasError = false; tsProject diff --git a/package.json b/package.json index 440534b..679dcc3 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "Improve your TSLint with the missing ESLint Rules", "main": "index.js", "scripts": { - "test": "gulp test" + "test": "gulp test && gulp self-lint" }, "repository": { "type": "git", diff --git a/tslint_eslint_rules.json b/tslint_eslint_rules.json new file mode 100644 index 0000000..f6305e3 --- /dev/null +++ b/tslint_eslint_rules.json @@ -0,0 +1,8 @@ +{ + "rulesDirectory": "dist/rules", + "rules": { + "ter-max-len": [true, 180, { + "ignoreUrls": true + }] + } +} From e9370dd068fe5c04280b6f4f3a5cdd5429a97909 Mon Sep 17 00:00:00 2001 From: Manuel Lopez Date: Mon, 21 Nov 2016 00:09:11 -0600 Subject: [PATCH 13/15] [lint] turning on no-multi-spaces Tried to turn on object-curly-spacing but there are way too many errors on the ter-indent tests. The tests will be split into groups soon so I will turn on the rule once this is done. --- src/rules/validJsdocRule.ts | 2 +- src/test/rules/terIndentRuleTests.ts | 46 ++++++++++++++-------------- tslint_eslint_rules.json | 4 ++- 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/rules/validJsdocRule.ts b/src/rules/validJsdocRule.ts index ad9e53d..7efa0f5 100644 --- a/src/rules/validJsdocRule.ts +++ b/src/rules/validJsdocRule.ts @@ -174,7 +174,7 @@ class ValidJsdocWalker extends Lint.SkippableTokenAwareRuleWalker { } private checkJSDoc(node: ts.Node) { - const {comments, start, width} = this.getJSDocComment(node); + const { comments, start, width } = this.getJSDocComment(node); if (!comments) return; diff --git a/src/test/rules/terIndentRuleTests.ts b/src/test/rules/terIndentRuleTests.ts index 6c6c88d..800f0b2 100644 --- a/src/test/rules/terIndentRuleTests.ts +++ b/src/test/rules/terIndentRuleTests.ts @@ -263,39 +263,39 @@ const scripts: { valid: IScripts, invalid: IScripts } = { files.concat(fileList) }; `, - options: [2, {VariableDeclarator: { var: 2, let: 2, const: 3}}] + options: [2, { VariableDeclarator: { var: 2, let: 2, const: 3 } }] }, { code: ' ', - options: [2, {VariableDeclarator: 1, SwitchCase: 1}] + options: [2, { VariableDeclarator: 1, SwitchCase: 1 }] }, { code: Lint.Utils.dedent` if(data) { console.log('hi'); b = true;};`, - options: [2, {VariableDeclarator: 1, SwitchCase: 1}] + options: [2, { VariableDeclarator: 1, SwitchCase: 1 }] }, { code: Lint.Utils.dedent` foo = () => { console.log('hi'); return true;};`, - options: [2, {VariableDeclarator: 1, SwitchCase: 1}] + options: [2, { VariableDeclarator: 1, SwitchCase: 1 }] }, { code: Lint.Utils.dedent` function test(data) { console.log('hi'); return true;};`, - options: [2, {VariableDeclarator: 1, SwitchCase: 1}] + options: [2, { VariableDeclarator: 1, SwitchCase: 1}] }, { code: Lint.Utils.dedent` var test = function(data) { console.log('hi'); };`, - options: [2, {VariableDeclarator: 1, SwitchCase: 1}] + options: [2, { VariableDeclarator: 1, SwitchCase: 1}] }, { code: Lint.Utils.dedent` @@ -303,14 +303,14 @@ const scripts: { valid: IScripts, invalid: IScripts } = { otherdata.forEach(function(zero) { console.log('hi'); }) });`, - options: [2, {VariableDeclarator: 1, SwitchCase: 1}] + options: [2, { VariableDeclarator: 1, SwitchCase: 1}] }, { code: Lint.Utils.dedent` a = [ ,3 ]`, - options: [4, {VariableDeclarator: 1, SwitchCase: 1}] + options: [4, { VariableDeclarator: 1, SwitchCase: 1}] }, { code: Lint.Utils.dedent` @@ -323,7 +323,7 @@ const scripts: { valid: IScripts, invalid: IScripts } = { console.log(method); }); `, - options: [2, {SwitchCase: 1, VariableDeclarator: 2}] + options: [2, { SwitchCase: 1, VariableDeclarator: 2}] }, { code: Lint.Utils.dedent` @@ -336,7 +336,7 @@ const scripts: { valid: IScripts, invalid: IScripts } = { ] } });`, - options: [4, {VariableDeclarator: 1, SwitchCase: 1}] + options: [4, { VariableDeclarator: 1, SwitchCase: 1}] }, { code: Lint.Utils.dedent` @@ -346,7 +346,7 @@ const scripts: { valid: IScripts, invalid: IScripts } = { a: 1 } ];`, - options: [4, {VariableDeclarator: 1, SwitchCase: 1}] + options: [4, { VariableDeclarator: 1, SwitchCase: 1}] }, { code: Lint.Utils.dedent` @@ -359,7 +359,7 @@ const scripts: { valid: IScripts, invalid: IScripts } = { { x: 2 }];`, - options: [4, {VariableDeclarator: 1, SwitchCase: 1}] + options: [4, { VariableDeclarator: 1, SwitchCase: 1}] }, { code: Lint.Utils.dedent` @@ -372,7 +372,7 @@ const scripts: { valid: IScripts, invalid: IScripts } = { ].join(',') ] });`, - options: [4, {VariableDeclarator: 1, SwitchCase: 1}] + options: [4, { VariableDeclarator: 1, SwitchCase: 1}] }, { code: Lint.Utils.dedent` @@ -385,7 +385,7 @@ const scripts: { valid: IScripts, invalid: IScripts } = { ] ] };`, - options: [2, {VariableDeclarator: 1, SwitchCase: 1}] + options: [2, { VariableDeclarator: 1, SwitchCase: 1}] }, { code: Lint.Utils.dedent` @@ -395,7 +395,7 @@ const scripts: { valid: IScripts, invalid: IScripts } = { b: 2 } );`, - options: [2, {VariableDeclarator: 1, SwitchCase: 1}] + options: [2, { VariableDeclarator: 1, SwitchCase: 1}] }, { code: Lint.Utils.dedent` @@ -403,7 +403,7 @@ const scripts: { valid: IScripts, invalid: IScripts } = { a: 1, b: 2 });`, - options: [4, {VariableDeclarator: 1, SwitchCase: 1}] + options: [4, { VariableDeclarator: 1, SwitchCase: 1}] }, { code: Lint.Utils.dedent` @@ -416,7 +416,7 @@ const scripts: { valid: IScripts, invalid: IScripts } = { b: 2 } ];`, - options: [2, {VariableDeclarator: 1, SwitchCase: 1}] + options: [2, { VariableDeclarator: 1, SwitchCase: 1}] }, { code: Lint.Utils.dedent` @@ -428,7 +428,7 @@ const scripts: { valid: IScripts, invalid: IScripts } = { b: 2 } ];`, - options: [2, {VariableDeclarator: 1, SwitchCase: 1}] + options: [2, { VariableDeclarator: 1, SwitchCase: 1}] }, { code: Lint.Utils.dedent` @@ -439,7 +439,7 @@ const scripts: { valid: IScripts, invalid: IScripts } = { a: 1, b: 2 };`, - options: [2, {VariableDeclarator: 2, SwitchCase: 1}] + options: [2, { VariableDeclarator: 2, SwitchCase: 1}] }, { code: Lint.Utils.dedent` @@ -448,7 +448,7 @@ const scripts: { valid: IScripts, invalid: IScripts } = { a: 1, b: 2 };`, - options: [2, {VariableDeclarator: 2, SwitchCase: 1}] + options: [2, { VariableDeclarator: 2, SwitchCase: 1}] }, { code: Lint.Utils.dedent` @@ -457,7 +457,7 @@ const scripts: { valid: IScripts, invalid: IScripts } = { b: 2 }), b = 2;`, - options: [4, {VariableDeclarator: 1, SwitchCase: 1}] + options: [4, { VariableDeclarator: 1, SwitchCase: 1}] }, { code: Lint.Utils.dedent` @@ -467,7 +467,7 @@ const scripts: { valid: IScripts, invalid: IScripts } = { b: 2 }, b = 2;`, - options: [2, {VariableDeclarator: 1, SwitchCase: 1}] + options: [2, { VariableDeclarator: 1, SwitchCase: 1}] }, { code: Lint.Utils.dedent` @@ -477,7 +477,7 @@ const scripts: { valid: IScripts, invalid: IScripts } = { b: 2 }, b = 2;`, - options: [2, {VariableDeclarator: 2, SwitchCase: 1}] + options: [2, { VariableDeclarator: 2, SwitchCase: 1}] }, { code: Lint.Utils.dedent` diff --git a/tslint_eslint_rules.json b/tslint_eslint_rules.json index f6305e3..e4bf600 100644 --- a/tslint_eslint_rules.json +++ b/tslint_eslint_rules.json @@ -3,6 +3,8 @@ "rules": { "ter-max-len": [true, 180, { "ignoreUrls": true - }] + }], + "no-multi-spaces": [true], + "object-curly-spacing": [false, "always"] } } From 356ab60f49881ed9a28e390ae046d4e11237bb11 Mon Sep 17 00:00:00 2001 From: Manuel Lopez Date: Mon, 21 Nov 2016 00:17:21 -0600 Subject: [PATCH 14/15] [refactor] changed IFailure to Failure All the tests need are: RuleTester, Failure, Position, and decent from the ruleTester module. --- src/test/rules/ruleTester.ts | 28 ++++++++++++++-------------- src/test/rules/terMaxLenRuleTests.ts | 4 ++-- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/test/rules/ruleTester.ts b/src/test/rules/ruleTester.ts index cacb14f..65bfe9d 100644 --- a/src/test/rules/ruleTester.ts +++ b/src/test/rules/ruleTester.ts @@ -48,13 +48,13 @@ class Position { } } -interface IFailure { +interface Failure { failure: string; startPosition: Position; endPosition: Position; } -class Failure { +class LintFailure { private name: string; private ruleName: string; private failure: string; @@ -89,8 +89,8 @@ class Failure { * @param obj The Failure to compare. * @returns {Failure} A comparable Failure. */ - public getComparableFailure(obj: Failure): Failure { - return new Failure( + public getComparableFailure(obj: LintFailure): LintFailure { + return new LintFailure( obj.name, obj.ruleName, obj.failure, @@ -104,7 +104,7 @@ interface ITest { code: string; output?: string; options?: any; - errors?: IFailure[]; + errors?: Failure[]; } class Test { @@ -112,9 +112,9 @@ class Test { public code: string; public output: string; public options: any; - public errors: Failure[]; + public errors: LintFailure[]; - constructor(name: string, code: string, output: string, options: any, errors: Failure[]) { + constructor(name: string, code: string, output: string, options: any, errors: LintFailure[]) { this.name = name; this.code = code; this.output = output; @@ -136,7 +136,7 @@ class Test { this.compareErrors(this.errors || [], failures.map((error: any) => { const start = error.startPosition; const end = error.endPosition; - return new Failure( + return new LintFailure( error.name, error.ruleName, error.failure, @@ -146,7 +146,7 @@ class Test { })); } - private compareErrors(expectedErrors: Failure[], foundErrors: Failure[]): void { + private compareErrors(expectedErrors: LintFailure[], foundErrors: LintFailure[]): void { const expected = this.arrayDiff(expectedErrors, foundErrors); const found = this.arrayDiff(foundErrors, expectedErrors, false); @@ -168,7 +168,7 @@ class Test { assert(expected.length === 0 && found.length === 0, msg); } - private arrayDiff(source: Failure[], target: Failure[], compareToTarget: boolean = true) { + private arrayDiff(source: LintFailure[], target: LintFailure[], compareToTarget: boolean = true) { return source.filter(item => { return this.findIndex(target, item, compareToTarget) === -1; }).map((x) => { @@ -180,7 +180,7 @@ class Test { }); } - private findIndex(source: Failure[], error: Failure, compareToError: boolean = true) { + private findIndex(source: LintFailure[], error: LintFailure, compareToError: boolean = true) { const len = source.length; let k = 0; while (k < len) { @@ -220,8 +220,8 @@ class TestGroup { if (test.options) { config.rules[ruleName] = [true, ...test.options]; } - const failures: Failure[] = (test.errors || []).map((error) => { - return new Failure( + const failures: LintFailure[] = (test.errors || []).map((error) => { + return new LintFailure( codeFileName, ruleName, error.failure, @@ -263,7 +263,7 @@ class RuleTester { export { dedent, Position, - IFailure, + Failure, TestGroup, RuleTester }; diff --git a/src/test/rules/terMaxLenRuleTests.ts b/src/test/rules/terMaxLenRuleTests.ts index 1df30f0..3173351 100644 --- a/src/test/rules/terMaxLenRuleTests.ts +++ b/src/test/rules/terMaxLenRuleTests.ts @@ -1,9 +1,9 @@ -import { RuleTester, IFailure, Position, dedent } from './ruleTester'; +import { RuleTester, Failure, Position, dedent } from './ruleTester'; // ESLint Tests: https://github.com/eslint/eslint/blob/master/tests/lib/rules/max-len.js const ruleTester = new RuleTester('ter-max-len'); -function expecting(errors: [[number, number] | [number, number, boolean]]): IFailure[] { +function expecting(errors: [[number, number] | [number, number, boolean]]): Failure[] { return errors.map((err) => { let message = `Line ${err[0] + 1} exceeds the maximum line length of ${err[1]}.`; if (err[2]) { From 0566e69b5f3b50e92f5214a20db2c9952360f67f Mon Sep 17 00:00:00 2001 From: Manuel Lopez Date: Mon, 21 Nov 2016 01:00:48 -0600 Subject: [PATCH 15/15] [refactor] no-multi-spaces tests using the ruleTesters to simplify the tests. --- src/test/rules/noMultiSpacesRuleTests.ts | 568 +++++++++-------------- tslint_eslint_rules.json | 6 +- 2 files changed, 234 insertions(+), 340 deletions(-) diff --git a/src/test/rules/noMultiSpacesRuleTests.ts b/src/test/rules/noMultiSpacesRuleTests.ts index 3c30498..d2a65dd 100644 --- a/src/test/rules/noMultiSpacesRuleTests.ts +++ b/src/test/rules/noMultiSpacesRuleTests.ts @@ -1,344 +1,234 @@ -/// -import { runTest, IScripts } from './helper'; +import { RuleTester, Failure, Position } from './ruleTester'; +// ESLint Tests: https://github.com/eslint/eslint/blob/master/tests/lib/rules/no-multi-spaces.js -/** - * Borrowing tests from eslint: - * https://github.com/eslint/eslint/blob/master/tests/lib/rules/no-multi-spaces.js - */ -const rule = 'no-multi-spaces'; -const scripts: { valid: IScripts, invalid: IScripts } = { - valid: [ - 'var a = 1;', - 'var a=1;', - 'var a = 1, b = 2;', - 'var arr = [1, 2];', - 'var arr = [ (1), (2) ];', - `var obj = {'a': 1, 'b': (2)};`, - `var obj = {'a': 1,\n 'b': (2)};`, - '\t\tvar x = 5,\n\t\t y = 2;', - 'a, b', - 'a >>> b', - 'a ^ b', - '(a) | (b)', - 'a & b', - 'a << b', - 'a !== b', - 'a >>>= b', - 'if (a & b) { }', - 'function foo(a,b) {}', - 'function foo(a, b) {}', - 'if ( a === 3 && b === 4) {}', - 'if ( a === 3||b === 4 ) {}', - 'if ( a <= 4) {}', - 'var foo = bar === 1 ? 2: 3', - '[1, , 3]', - '[1, ]', - '[ ( 1 ) , ( 2 ) ]', - 'a = 1, b = 2;', - '(function(a, b){})', - 'x.in = 0;', - '(function(a,/* b, */c){})', - '(function(a,/*b,*/c){})', - '(function(a, /*b,*/c){})', - '(function(a,/*b,*/ c){})', - '(function(a, /*b,*/ c){})', - '(function(/*a, b, */c){})', - '(function(/*a, */b, c){})', - '(function(a, b/*, c*/){})', - '(function(a, b/*,c*/){})', - '(function(a, b /*,c*/){})', - '(function(a/*, b ,c*/){})', - '(function(a /*, b ,c*/){})', - '(function(a /*, b ,c*/){})', - '/**\n * hello\n * @param {foo} int hi\n * set.\n * @private\n*/', - '/**\n * hello\n * @param {foo} int hi\n * set.\n * set.\n * @private\n*/', - 'var a,/* b,*/c;', - 'var foo = [1,/* 2,*/3];', - 'var bar = {a: 1,/* b: 2*/c: 3};', - 'var foo = \'hello world\';', - 'var foo = \' \';', - 'var foo = ` `;', - 'var foo = " ";', - 'var foo = " \' ";', - 'function foo() {\n return;\n}', - 'function foo() {\n if (foo) {\n return;\n }\n}', - 'var foo = `hello world`;', - '({ a: b })', - { - code: '({ a: b })', - options: [{ exceptions: { PropertyAssignment: false } }] - }, - { - code: 'var answer = 6 * 7;', - options: [{ exceptions: { VariableDeclaration: true, BinaryExpression: true } }] - } - ], - invalid: [ - { - code: 'function foo(a, b) {}', - errors: [{ - message: "Multiple spaces found before 'b'." - }] - }, - { - code: 'var foo = (a, b) => {}', - errors: [{ - message: "Multiple spaces found before 'b'." - }] - }, - { - code: 'var a = 1', - errors: [{ - message: "Multiple spaces found before '1'." - }] - }, - { - code: 'var a = 1, b = 2;', - errors: [{ - message: "Multiple spaces found before 'b'." - }] - }, - { - code: 'a << b', - errors: [{ - message: "Multiple spaces found before 'b'." - }] - }, - { - code: "var arr = {'a': 1, 'b': 2};", - errors: [{ - message: "Multiple spaces found before ''b''." - }] - }, - { - code: 'if (a & b) { }', - errors: [{ - message: "Multiple spaces found before 'b'." - }] - }, - { - code: 'if ( a === 3 && b === 4) {}', - errors: [{ - message: "Multiple spaces found before '&&'." - }, { - message: "Multiple spaces found before 'b'." - }] - }, - { - code: 'var foo = bar === 1 ? 2: 3', - errors: [{ - message: "Multiple spaces found before '2'." - }, { - message: "Multiple spaces found before '3'." - }] - }, - { - code: 'var a = [1, 2, 3, 4]', - errors: [{ - message: "Multiple spaces found before '2'." - }, { - message: "Multiple spaces found before '3'." - }, { - message: "Multiple spaces found before '4'." - }] - }, - { - code: 'var arr = [1, 2];', - errors: [{ - message: "Multiple spaces found before '2'." - }] - }, - { - code: '[ , 1, , 3, , ]', - errors: [{ - message: "Multiple spaces found before ','." - }, { - message: "Multiple spaces found before ','." - }, { - message: "Multiple spaces found before ','." - }, { - message: "Multiple spaces found before ']'." - }] - }, - { - code: 'a >>> b', - errors: [{ - message: "Multiple spaces found before 'b'." - }] - }, - { - code: 'a = 1, b = 2;', - errors: [{ - message: "Multiple spaces found before 'b'." - }, { - message: "Multiple spaces found before '2'." - }] - }, - { - code: '(function(a, b){})', - errors: [{ - message: "Multiple spaces found before 'b'." - }] - }, - { - code: 'function foo(a, b){}', - errors: [{ - message: "Multiple spaces found before 'b'." - }] - }, - { - code: 'var o = { fetch: function () {} };', - errors: [{ - message: "Multiple spaces found before '('." - }] - }, - { - code: 'var o = { fetch: function () {} };', - errors: [{ - message: "Multiple spaces found before '('." - }] - }, - { - code: 'function foo () {}', - errors: [{ - message: "Multiple spaces found before '('." - }] - }, - { - code: 'if (foo) {}', - errors: [{ - message: "Multiple spaces found before '{'." - }] - }, - { - code: 'function foo(){}', - errors: [{ - message: "Multiple spaces found before 'foo'." - }] - }, - { - code: 'if (foo) {}', - errors: [{ - message: "Multiple spaces found before '('." - }] - }, - { - code: 'try {} catch(ex) {}', - errors: [{ - message: "Multiple spaces found before '{'." - }] - }, - { - code: 'try {} catch (ex) {}', - errors: [{ - message: "Multiple spaces found before '('." - }] - }, - { - code: 'var o = { fetch: function () {} };', - errors: [{ - message: "Multiple spaces found before '('." - }] - }, - { - code: 'throw error;', - errors: [{ - message: "Multiple spaces found before 'error'." - }] - }, - { - code: 'function foo() { return bar; }', - errors: [{ - message: "Multiple spaces found before 'bar'." - }] - }, - { - code: 'switch (a) {default: foo(); break;}', - errors: [{ - message: "Multiple spaces found before '('." - }] - }, - { - code: 'var answer = 6 * 7;', - errors: [{ - message: "Multiple spaces found before 'answer'." - }, { - message: "Multiple spaces found before '7'." - }] - }, - { - code: '({ a: 6 * 7 })', - errors: [{ - message: "Multiple spaces found before '*'." - }] - }, - { - code: '({ a: ( 6 / 4 * 7) })', - errors: [{ - message: "Multiple spaces found before '6'." - }, { - message: "Multiple spaces found before '/'." - }, { - message: "Multiple spaces found before '4'." - }, { - message: "Multiple spaces found before '*'." - }, { - message: "Multiple spaces found before '}'." - }] - }, - { - code: '({ a: ( 6 / 4 * 7) })', - options: [{ exceptions: { PropertyAssignment: false } }], - errors: [{ - message: "Multiple spaces found before '('." - }, { - message: "Multiple spaces found before '6'." - }, { - message: "Multiple spaces found before '/'." - }, { - message: "Multiple spaces found before '4'." - }, { - message: "Multiple spaces found before '*'." - }, { - message: "Multiple spaces found before '}'." - }] - }, - { - code: '({ a: b })', - options: [{ exceptions: { PropertyAssignment: false } }], - errors: [{ - message: "Multiple spaces found before 'b'." - }] - }, - { - code: 'var foo = { bar: function() { return 1 + 2; } };', - errors: [{ - message: "Multiple spaces found before '+'." - }] - }, - { - code: '\t\tvar x = 5,\n\t\t y = 2;', - errors: [{ - message: "Multiple spaces found before '2'." - }] - }, - { - code: 'var x =\t 5;', - errors: [{ - message: "Multiple spaces found before '5'." - }] - } - ] -}; +const ruleTester = new RuleTester('no-multi-spaces'); -describe(rule, () => { - - it('should pass when avoiding unnecessary spaces', () => { - runTest(rule, scripts.valid); +function expecting(errors: [string]): Failure[] { + return errors.map((token) => { + return { + failure: `Multiple spaces found before '${token}'.`, + startPosition: new Position(), + endPosition: new Position() + }; }); +} - it('should fail when using multiple spaces', () => { - runTest(rule, scripts.invalid); - }); +ruleTester.addTestGroup('valid', 'should pass when avoiding unnecessary spaces', [ + 'var a = 1;', + 'var a=1;', + 'var a = 1, b = 2;', + 'var arr = [1, 2];', + 'var arr = [ (1), (2) ];', + `var obj = {'a': 1, 'b': (2)};`, + `var obj = {'a': 1,\n 'b': (2)};`, + '\t\tvar x = 5,\n\t\t y = 2;', + 'a, b', + 'a >>> b', + 'a ^ b', + '(a) | (b)', + 'a & b', + 'a << b', + 'a !== b', + 'a >>>= b', + 'if (a & b) { }', + 'function foo(a,b) {}', + 'function foo(a, b) {}', + 'if ( a === 3 && b === 4) {}', + 'if ( a === 3||b === 4 ) {}', + 'if ( a <= 4) {}', + 'var foo = bar === 1 ? 2: 3', + '[1, , 3]', + '[1, ]', + '[ ( 1 ) , ( 2 ) ]', + 'a = 1, b = 2;', + '(function(a, b){})', + 'x.in = 0;', + '(function(a,/* b, */c){})', + '(function(a,/*b,*/c){})', + '(function(a, /*b,*/c){})', + '(function(a,/*b,*/ c){})', + '(function(a, /*b,*/ c){})', + '(function(/*a, b, */c){})', + '(function(/*a, */b, c){})', + '(function(a, b/*, c*/){})', + '(function(a, b/*,c*/){})', + '(function(a, b /*,c*/){})', + '(function(a/*, b ,c*/){})', + '(function(a /*, b ,c*/){})', + '(function(a /*, b ,c*/){})', + '/**\n * hello\n * @param {foo} int hi\n * set.\n * @private\n*/', + '/**\n * hello\n * @param {foo} int hi\n * set.\n * set.\n * @private\n*/', + 'var a,/* b,*/c;', + 'var foo = [1,/* 2,*/3];', + 'var bar = {a: 1,/* b: 2*/c: 3};', + 'var foo = \'hello world\';', + 'var foo = \' \';', + 'var foo = ` `;', + 'var foo = " ";', + 'var foo = " \' ";', + 'function foo() {\n return;\n}', + 'function foo() {\n if (foo) {\n return;\n }\n}', + 'var foo = `hello world`;', + '({ a: b })' +]); + +ruleTester.addTestGroup('invalid', 'should fail when using multiple spaces', [ + { + code: 'function foo(a, b) {}', + errors: expecting(['b']) + }, + { + code: 'var foo = (a, b) => {}', + errors: expecting(['b']) + }, + { + code: 'var a = 1', + errors: expecting(['1']) + }, + { + code: 'var a = 1, b = 2;', + errors: expecting(['b']) + }, + { + code: 'a << b', + errors: expecting(['b']) + }, + { + code: "var arr = {'a': 1, 'b': 2};", + errors: expecting([`'b'`]) + }, + { + code: 'if (a & b) { }', + errors: expecting(['b']) + }, + { + code: 'if ( a === 3 && b === 4) {}', + errors: expecting(['&&', 'b']) + }, + { + code: 'var foo = bar === 1 ? 2: 3', + errors: expecting(['2', '3']) + }, + { + code: 'var a = [1, 2, 3, 4]', + errors: expecting(['2', '3', '4']) + }, + { + code: 'var arr = [1, 2];', + errors: expecting(['2']) + }, + { + code: '[ , 1, , 3, , ]', + errors: expecting([',', ',', ',', ']']) + }, + { + code: 'a >>> b', + errors: expecting(['b']) + }, + { + code: 'a = 1, b = 2;', + errors: expecting(['b', '2']) + }, + { + code: '(function(a, b){})', + errors: expecting(['b']) + }, + { + code: 'function foo(a, b){}', + errors: expecting(['b']) + }, + { + code: 'var o = { fetch: function () {} };', + errors: expecting(['(']) + }, + { + code: 'function foo () {}', + errors: expecting(['(']) + }, + { + code: 'if (foo) {}', + errors: expecting(['{']) + }, + { + code: 'function foo(){}', + errors: expecting(['foo']) + }, + { + code: 'if (foo) {}', + errors: expecting(['(']) + }, + { + code: 'try {} catch(ex) {}', + errors: expecting(['{']) + }, + { + code: 'try {} catch (ex) {}', + errors: expecting(['(']) + }, + { + code: 'var o = { fetch: function () {} };', + errors: expecting(['(']) + }, + { + code: 'throw error;', + errors: expecting(['error']) + }, + { + code: 'function foo() { return bar; }', + errors: expecting(['bar']) + }, + { + code: 'switch (a) {default: foo(); break;}', + errors: expecting(['(']) + }, + { + code: 'var answer = 6 * 7;', + errors: expecting(['answer', '7']) + }, + { + code: '({ a: 6 * 7 })', + errors: expecting(['*']) + }, + { + code: '({ a: ( 6 / 4 * 7) })', + errors: expecting(['6', '/', '4', '*', '}']) + }, + { + code: 'var foo = { bar: function() { return 1 + 2; } };', + errors: expecting(['+']) + }, + { + code: '\t\tvar x = 5,\n\t\t y = 2;', + errors: expecting(['2']) + }, + { + code: 'var x =\t 5;', + errors: expecting(['5']) + } +]); + +ruleTester.addTestGroup('property-assignment', 'should report error when PropertyAssignment exception is off', [ + { + code: '({ a: b })', + options: [{ exceptions: { PropertyAssignment: false } }] + }, + { + code: '({ a: ( 6 / 4 * 7) })', + options: [{ exceptions: { PropertyAssignment: false } }], + errors: expecting(['(', '6', '/', '4', '*', '}']) + }, + { + code: '({ a: b })', + options: [{ exceptions: { PropertyAssignment: false } }], + errors: expecting(['b']) + } +]); + +ruleTester.addTestGroup('exceptions', 'should not report when exceptions are turn on', [ + { + code: 'var answer = 6 * 7;', + options: [{ exceptions: { VariableDeclaration: true, BinaryExpression: true } }] + } +]); -}); +ruleTester.runTests(); diff --git a/tslint_eslint_rules.json b/tslint_eslint_rules.json index e4bf600..aa134dd 100644 --- a/tslint_eslint_rules.json +++ b/tslint_eslint_rules.json @@ -4,7 +4,11 @@ "ter-max-len": [true, 180, { "ignoreUrls": true }], - "no-multi-spaces": [true], + "no-multi-spaces": [true, { + "exceptions": { + "PropertyAssignment": false + } + }], "object-curly-spacing": [false, "always"] } }