This repository has been archived by the owner on Feb 21, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 105
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[feat] added object-curly-spacing rule
- Loading branch information
Manuel Lopez
committed
Aug 27, 2016
1 parent
cd64e4b
commit 28c5727
Showing
3 changed files
with
132 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import * as ts from 'typescript'; | ||
import * as Lint from 'tslint/lib/lint'; | ||
|
||
const OPTION_ALWAYS = 'always'; | ||
|
||
export class Rule extends Lint.Rules.AbstractRule { | ||
public static FAILURE_STRING = { | ||
always: { | ||
start: `A space is required after '{'`, | ||
end: `A space is required before '}'` | ||
}, | ||
never: { | ||
start: `There should be no space after '{'`, | ||
end: `There should be no space before '}'` | ||
} | ||
}; | ||
|
||
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] { | ||
const walker = new BlockSpacingWalker(sourceFile, this.getOptions()); | ||
return this.applyWithWalker(walker); | ||
} | ||
} | ||
|
||
class BlockSpacingWalker extends Lint.RuleWalker { | ||
|
||
private always: boolean; | ||
|
||
constructor(sourceFile: ts.SourceFile, options: Lint.IOptions) { | ||
super(sourceFile, options); | ||
this.always = this.hasOption(OPTION_ALWAYS) || (this.getOptions() && this.getOptions().length === 0); | ||
} | ||
|
||
protected visitNode(node: ts.Node): void { | ||
const bracedKind = [ | ||
ts.SyntaxKind.ObjectLiteralExpression, | ||
ts.SyntaxKind.ObjectBindingPattern, | ||
ts.SyntaxKind.NamedImports, | ||
ts.SyntaxKind.NamedExports | ||
]; | ||
if (bracedKind.indexOf(node.kind) > -1) { | ||
this.checkSpacingInsideBraces(node); | ||
} | ||
super.visitNode(node); | ||
} | ||
|
||
private checkSpacingInsideBraces(node: ts.Node): void { | ||
const text = node.getText(); | ||
if (text.indexOf('\n') !== -1 || text === '{}') { | ||
// Rule does not apply when the braces span multiple lines | ||
return; | ||
} | ||
const leadingSpace = text.match(/^\{(\s{0,2})/)[1].length; | ||
const trailingSpace = text.match(/(\s{0,2})}$/)[1].length; | ||
if (this.always) { | ||
if (leadingSpace === 0) { | ||
this.addFailure(this.createFailure(node.getStart(), 1, Rule.FAILURE_STRING.always.start)); | ||
} | ||
if (trailingSpace === 0) { | ||
this.addFailure(this.createFailure(node.getEnd() - 1, 1, Rule.FAILURE_STRING.always.end)); | ||
} | ||
} else { | ||
if (leadingSpace > 0) { | ||
this.addFailure(this.createFailure(node.getStart(), 1, Rule.FAILURE_STRING.never.start)); | ||
} | ||
if (trailingSpace > 0) { | ||
this.addFailure(this.createFailure(node.getEnd() - 1, 1, Rule.FAILURE_STRING.never.end)); | ||
} | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
/// <reference path='../../../typings/mocha/mocha.d.ts' /> | ||
import { makeTest } from './helper'; | ||
|
||
const rule = 'object-curly-spacing'; | ||
const scripts = { | ||
always: { | ||
valid: [ | ||
`const obj = { foo: 'bar' };`, | ||
`const obj = { foo: { zoo: 'bar' } };`, | ||
`const { x, y } = y;`, | ||
`import { foo } from 'bar';`, | ||
`export { foo };` | ||
], | ||
invalid: [ | ||
`const obj = {foo: 'bar'};`, | ||
`const obj = {foo: { zoo: 'bar' } };`, | ||
`const {x, y} = y;`, | ||
`import {foo } from 'bar';`, | ||
`export { foo};` | ||
] | ||
}, | ||
never: { | ||
valid: [ | ||
`const obj = {foo: 'bar'};`, | ||
`const obj = {foo: {zoo: 'bar'}};`, | ||
`const {x, y} = y;`, | ||
`import {foo} from 'bar';`, | ||
`export {foo};` | ||
], | ||
invalid: [ | ||
`const obj = { foo: 'bar' };`, | ||
`const obj = { foo: { zoo: 'bar' } };`, | ||
`const { x, y } = y;`, | ||
`import {foo } from 'bar';`, | ||
`export { foo};` | ||
] | ||
} | ||
}; | ||
|
||
describe(rule, function test() { | ||
|
||
const alwaysConfig = { rules: { 'object-curly-spacing': [true, 'always'] } }; | ||
const neverConfig = { rules: { 'object-curly-spacing': [true, 'never'] } }; | ||
|
||
it('should pass when "always" and there are spaces inside brackets', function testVariables() { | ||
makeTest(rule, scripts.always.valid, true, alwaysConfig); | ||
}); | ||
|
||
it('should fail when "always" and there are not spaces inside brackets', function testVariables() { | ||
makeTest(rule, scripts.always.invalid, false, alwaysConfig); | ||
}); | ||
|
||
it('should pass when "never" and there are not spaces inside brackets', function testVariables() { | ||
makeTest(rule, scripts.never.valid, true, neverConfig); | ||
}); | ||
|
||
it('should fail when "never" and there are spaces inside brackets', function testVariables() { | ||
makeTest(rule, scripts.never.invalid, false, neverConfig); | ||
}); | ||
}); |