Skip to content
This repository has been archived by the owner on Mar 25, 2021. It is now read-only.

Commit

Permalink
Add OPTION_ALLOW_SNAKE_CASE to variable name options
Browse files Browse the repository at this point in the history
  • Loading branch information
AJamesPhillips committed Mar 23, 2017
1 parent d33f538 commit 6767f45
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 14 deletions.
24 changes: 21 additions & 3 deletions src/rules/variableNameRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const OPTION_TRAILING_UNDERSCORE = "allow-trailing-underscore";
const OPTION_BAN_KEYWORDS = "ban-keywords";
const OPTION_CHECK_FORMAT = "check-format";
const OPTION_ALLOW_PASCAL_CASE = "allow-pascal-case";
const OPTION_ALLOW_SNAKE_CASE = "allow-snake-case";

export class Rule extends Lint.Rules.AbstractRule {
public static metadata: Lint.IRuleMetadata = {
Expand All @@ -42,6 +43,7 @@ export class Rule extends Lint.Rules.AbstractRule {
* \`"${OPTION_LEADING_UNDERSCORE}"\` allows underscores at the beginning (only has an effect if "check-format" specified)
* \`"${OPTION_TRAILING_UNDERSCORE}"\` allows underscores at the end. (only has an effect if "check-format" specified)
* \`"${OPTION_ALLOW_PASCAL_CASE}"\` allows PascalCase in addition to camelCase.
* \`"${OPTION_ALLOW_SNAKE_CASE}"\` allows snake_case in addition to camelCase.
* \`"${OPTION_BAN_KEYWORDS}"\`: disallows the use of certain TypeScript keywords as variable or parameter names.
* These are: ${bannedKeywordsStr}`,
options: {
Expand All @@ -53,6 +55,7 @@ export class Rule extends Lint.Rules.AbstractRule {
OPTION_LEADING_UNDERSCORE,
OPTION_TRAILING_UNDERSCORE,
OPTION_ALLOW_PASCAL_CASE,
OPTION_ALLOW_SNAKE_CASE,
OPTION_BAN_KEYWORDS,
],
},
Expand All @@ -64,7 +67,6 @@ export class Rule extends Lint.Rules.AbstractRule {
typescriptOnly: false,
};

public static FORMAT_FAILURE = "variable name must be in camelcase or uppercase";
public static KEYWORD_FAILURE = "variable name clashes with keyword/type";

public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
Expand All @@ -78,6 +80,7 @@ interface Options {
leadingUnderscore: boolean;
trailingUnderscore: boolean;
allowPascalCase: boolean;
allowSnakeCase: boolean;
}
function parseOptions(ruleArguments: string[]): Options {
const banKeywords = hasOption(OPTION_BAN_KEYWORDS);
Expand All @@ -88,6 +91,7 @@ function parseOptions(ruleArguments: string[]): Options {
leadingUnderscore: hasOption(OPTION_LEADING_UNDERSCORE),
trailingUnderscore: hasOption(OPTION_TRAILING_UNDERSCORE),
allowPascalCase: hasOption(OPTION_ALLOW_PASCAL_CASE),
allowSnakeCase: hasOption(OPTION_ALLOW_SNAKE_CASE),
};

function hasOption(name: string): boolean {
Expand Down Expand Up @@ -148,7 +152,7 @@ function walk(ctx: Lint.WalkContext<Options>): void {
}

if (!isCamelCase(text, options) && !isUpperCase(text)) {
ctx.addFailureAtNode(name, Rule.FORMAT_FAILURE);
ctx.addFailureAtNode(name, formatFailure());
}
}

Expand All @@ -157,6 +161,17 @@ function walk(ctx: Lint.WalkContext<Options>): void {
ctx.addFailureAtNode(name, Rule.KEYWORD_FAILURE);
}
}

function formatFailure(): string {
let failureMessage = "variable name must be in camelcase";
if (options.allowPascalCase) {
failureMessage += ", pascalcase";
}
if (options.allowSnakeCase) {
failureMessage += ", snakecase";
}
return failureMessage + " or uppercase";
}
}

function isAlias(name: string, initializer: ts.Expression): boolean {
Expand Down Expand Up @@ -184,7 +199,10 @@ function isCamelCase(name: string, options: Options): boolean {
if (!options.allowPascalCase && !isLowerCase(firstCharacter)) {
return false;
}
return middle.indexOf("_") === -1;
if (!options.allowSnakeCase && middle.indexOf("_") !== -1) {
return false;
}
return true;
}

function isLowerCase(name: string): boolean {
Expand Down
22 changes: 11 additions & 11 deletions test/rules/variable-name/allow-pascal-case/test.ts.lint
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
var validName1 = "hi";
var VALIDNAME2 = "there";
var ValidName3 = ",";
var invalid_name2 = " "; // failure
~~~~~~~~~~~~~ [variable name must be in camelcase or uppercase]
var invalid_name1 = " "; // failure
~~~~~~~~~~~~~ [variable name must be in camelcase, pascalcase or uppercase]

class Test {
private Invalid_name3 = "how"; // failure
~~~~~~~~~~~~~ [variable name must be in camelcase or uppercase]
~~~~~~~~~~~~~ [variable name must be in camelcase, pascalcase or uppercase]
private _optionallyValid = "are"; // sometimes a failure
~~~~~~~~~~~~~~~~ [variable name must be in camelcase or uppercase]
~~~~~~~~~~~~~~~~ [variable name must be in camelcase, pascalcase or uppercase]
}

function test() {
Expand All @@ -20,26 +20,26 @@ function test() {
declare var DeclaresAreValid: any;

export function functionWithInvalidParamNames (bad_name, AnotherOne) { // 1 failure
~~~~~~~~ [variable name must be in camelcase or uppercase]
~~~~~~~~ [variable name must be in camelcase, pascalcase or uppercase]
//
}

let { foo, bar } = { foo: 1, bar: 2 };
let [ invalid_bar, ...invalid_baz ] = [1, 2, 3, 4]; // 3 failures
~~~~~~~~~~~ [variable name must be in camelcase or uppercase]
~~~~~~~~~~~ [variable name must be in camelcase or uppercase]
~~~~~~~~~~~ [variable name must be in camelcase, pascalcase or uppercase]
~~~~~~~~~~~ [variable name must be in camelcase, pascalcase or uppercase]

export function anotherFunctionWithInvalidParamNames ([first_element, SecondElement]) { // 1 failure
~~~~~~~~~~~~~ [variable name must be in camelcase or uppercase]
~~~~~~~~~~~~~ [variable name must be in camelcase, pascalcase or uppercase]
//
}

export function functionWithInvalidSpread(invalid_arg: ...number) { // 1 failure
~~~~~~~~~~~ [variable name must be in camelcase or uppercase]
~~~~~~~~~~~ [variable name must be in camelcase, pascalcase or uppercase]
//
}

let optionallyValid_ = "bar";
~~~~~~~~~~~~~~~~ [variable name must be in camelcase or uppercase]
~~~~~~~~~~~~~~~~ [variable name must be in camelcase, pascalcase or uppercase]
let _$httpBackend_ = "leading and trailing";
~~~~~~~~~~~~~~ [variable name must be in camelcase or uppercase]
~~~~~~~~~~~~~~ [variable name must be in camelcase, pascalcase or uppercase]
64 changes: 64 additions & 0 deletions test/rules/variable-name/allow-snake-case/test.ts.lint
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
var validName1 = "hi";
var VALIDNAME2 = "there";
var valid_name3 = "tslint";
var Invalid_name1 = " "; // failure
~~~~~~~~~~~~~ [variable name must be in camelcase, snakecase or uppercase]
var InvalidName2 = " "; // failure
~~~~~~~~~~~~ [variable name must be in camelcase, snakecase or uppercase]

class Test {
private valid_name = " ";
private Invalid_name1 = "how"; // failure
~~~~~~~~~~~~~ [variable name must be in camelcase, snakecase or uppercase]
private _optionallyValid = "are"; // sometimes a failure
~~~~~~~~~~~~~~~~ [variable name must be in camelcase, snakecase or uppercase]
}

function test() {
() => {
var valid_name = " ";
var InVaLiDnAmE4 = "you"; // failure
~~~~~~~~~~~~ [variable name must be in camelcase, snakecase or uppercase]
};
}

declare var DeclaresAreValid: any;

export function functionWithInvalidParamNames (ok_name, BadName) { // 1 failure
~~~~~~~ [variable name must be in camelcase, snakecase or uppercase]
}

let { foo, bar } = { foo: 1, bar: 2 };
let [ InvalidFoo, invalid_bar, ...invalid_baz ] = [1, 2, 3, 4]; // 1 failure
~~~~~~~~~~ [variable name must be in camelcase, snakecase or uppercase]

export function anotherFunctionWithInvalidParamNames ([first_element, SecondElement]) { // 1 failure
~~~~~~~~~~~~~ [variable name must be in camelcase, snakecase or uppercase]
//
}

export function functionWithInvalidSpread(InvalidArg: ...number) { // 1 failure
~~~~~~~~~~ [variable name must be in camelcase, snakecase or uppercase]
//
}

let optionallyValid_ = "bar";
~~~~~~~~~~~~~~~~ [variable name must be in camelcase, snakecase or uppercase]
let _$httpBackend_ = "leading and trailing";
~~~~~~~~~~~~~~ [variable name must be in camelcase, snakecase or uppercase]

// Aliases.
class X {
ValidAlias = ValidAlias;
}

var ValidAlias = some.ValidAlias;
var ValidAlias = some.InValidAlias;
~~~~~~~~~~ [variable name must be in camelcase, snakecase or uppercase]

var someObject = {MoreValidAlias: 1};
var {MoreValidAlias: localVar} = someObject;
var {MoreValidAlias: local_var} = someObject;
var {MoreValidAlias: LocalVar} = someObject;
~~~~~~~~ [variable name must be in camelcase, snakecase or uppercase]
var {MoreValidAlias} = someObject;
5 changes: 5 additions & 0 deletions test/rules/variable-name/allow-snake-case/tslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"rules": {
"variable-name": [true, "allow-snake-case"]
}
}

0 comments on commit 6767f45

Please sign in to comment.