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

Add OPTION_ALLOW_SNAKE_CASE to variable name options #2383

Merged
merged 1 commit into from
Mar 24, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"]
}
}