-
-
Notifications
You must be signed in to change notification settings - Fork 679
Add name-property-casing
rule.
#94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# Name property casing for consistency purposes (name-property-casing) | ||
|
||
Define a style for the `name` property casing for consistency purposes | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing dot at the end of the sentence |
||
|
||
## :book: Rule Details | ||
|
||
:+1: Examples of **correct** code for `PascalCase`: | ||
|
||
```js | ||
export default { | ||
name: 'MyComponent' | ||
} | ||
``` | ||
|
||
:+1: Examples of **correct** code for `kebab-case`: | ||
|
||
```js | ||
export default { | ||
name: 'my-component' | ||
} | ||
``` | ||
|
||
:+1: Examples of **correct** code for `camelCase`: | ||
|
||
```js | ||
export default { | ||
name: 'myComponent' | ||
} | ||
``` | ||
|
||
## :wrench: Options | ||
|
||
Default casing is set to `PascalCase` | ||
|
||
``` | ||
'vue/name-property-casing': [2, 'camelCase'|'kebab-case'|'PascalCase'] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
/** | ||
* @fileoverview Name property casing for consistency purposes | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use the same title as in documentation |
||
* @author Armano | ||
*/ | ||
'use strict' | ||
|
||
const utils = require('../utils') | ||
|
||
function kebabCase (str) { | ||
return str.replace(/([a-z])([A-Z])/g, match => match[0] + '-' + match[1]).replace(/\s+/g, '-').toLowerCase() | ||
} | ||
|
||
function camelCase (str) { | ||
return str.replace(/(?:^\w|[A-Z]|\b\w)/g, (letter, index) => index === 0 ? letter.toLowerCase() : letter.toUpperCase()).replace(/[\s-]+/g, '') | ||
} | ||
|
||
function pascalCase (str) { | ||
str = camelCase(str) | ||
return str.length > 0 ? str.charAt(0).toUpperCase() + str.slice(1) : '' | ||
} | ||
|
||
function convertCase (str, caseType) { | ||
if (caseType === 'kebab-case') { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ideal case for
And use it like so:
WDYT? |
||
return kebabCase(str) | ||
} else if (caseType === 'PascalCase') { | ||
return pascalCase(str) | ||
} | ||
return camelCase(str) | ||
} | ||
|
||
// ------------------------------------------------------------------------------ | ||
// Rule Definition | ||
// ------------------------------------------------------------------------------ | ||
|
||
function create (context) { | ||
const options = context.options[0] | ||
const caseType = ['camelCase', 'kebab-case', 'PascalCase'].indexOf(options) !== -1 ? options : 'PascalCase' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please move the array with possible caseTypes out of the |
||
|
||
// ---------------------------------------------------------------------- | ||
// Public | ||
// ---------------------------------------------------------------------- | ||
|
||
return utils.executeOnVueComponent(context, (obj) => { | ||
const node = obj.properties | ||
.filter(item => item.type === 'Property' && item.key.name === 'name' && item.value.type === 'Literal')[0] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please wrap this line to make it more readable |
||
if (node) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add empty line above There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Btw. you can also do:
To not introduce unnecessary indentation. |
||
const value = convertCase(node.value.value, caseType) | ||
if (value !== node.value.value) { | ||
context.report({ | ||
node: node.value, | ||
message: 'Property name "{{value}}" is not {{caseType}}.', | ||
data: { | ||
value: node.value.value, | ||
caseType: caseType | ||
}, | ||
fix: fixer => fixer.replaceText(node.value, node.value.raw.replace(node.value.value, value)) | ||
}) | ||
} | ||
} | ||
}) | ||
} | ||
|
||
module.exports = { | ||
meta: { | ||
docs: { | ||
description: 'Name property casing for consistency purposes', | ||
category: 'Stylistic Issues', | ||
recommended: false | ||
}, | ||
fixable: 'code', // or "code" or "whitespace" | ||
schema: [ | ||
{ | ||
enum: ['camelCase', 'kebab-case', 'PascalCase'] | ||
} | ||
] | ||
}, | ||
|
||
create | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
/** | ||
* @fileoverview Define a style for the name property casing for consistency purposes | ||
* @author Armano | ||
*/ | ||
'use strict' | ||
|
||
// ------------------------------------------------------------------------------ | ||
// Requirements | ||
// ------------------------------------------------------------------------------ | ||
|
||
const rule = require('../../../lib/rules/name-property-casing') | ||
const RuleTester = require('eslint').RuleTester | ||
|
||
// ------------------------------------------------------------------------------ | ||
// Tests | ||
// ------------------------------------------------------------------------------ | ||
|
||
const ruleTester = new RuleTester() | ||
ruleTester.run('name-property-casing', rule, { | ||
|
||
valid: [ | ||
{ | ||
filename: 'test.vue', | ||
code: ` | ||
export default { | ||
} | ||
`, | ||
options: ['camelCase'], | ||
parserOptions: { ecmaVersion: 6, sourceType: 'module' } | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: ` | ||
export default { | ||
name: 'fooBar' | ||
} | ||
`, | ||
options: ['camelCase'], | ||
parserOptions: { ecmaVersion: 6, sourceType: 'module' } | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: ` | ||
export default { | ||
name: 'FooBar' | ||
} | ||
`, | ||
options: ['PascalCase'], | ||
parserOptions: { ecmaVersion: 6, sourceType: 'module' } | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: ` | ||
export default { | ||
name: 'foo-bar' | ||
} | ||
`, | ||
options: ['kebab-case'], | ||
parserOptions: { ecmaVersion: 6, sourceType: 'module' } | ||
} | ||
], | ||
|
||
invalid: [ | ||
{ | ||
filename: 'test.vue', | ||
code: ` | ||
export default { | ||
name: 'foo-bar' | ||
} | ||
`, | ||
options: ['camelCase'], | ||
parserOptions: { ecmaVersion: 6, sourceType: 'module' }, | ||
errors: [{ | ||
message: 'Property name "foo-bar" is not camelCase.', | ||
type: 'Literal', | ||
line: 3 | ||
}] | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: ` | ||
export default { | ||
name: 'foo bar' | ||
} | ||
`, | ||
options: ['PascalCase'], | ||
parserOptions: { ecmaVersion: 6, sourceType: 'module' }, | ||
errors: [{ | ||
message: 'Property name "foo bar" is not PascalCase.', | ||
type: 'Literal', | ||
line: 3 | ||
}] | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: ` | ||
export default { | ||
name: 'foo!bar' | ||
} | ||
`, | ||
options: ['camelCase'], | ||
parserOptions: { ecmaVersion: 6, sourceType: 'module' }, | ||
errors: [{ | ||
message: 'Property name "foo!bar" is not camelCase.', | ||
type: 'Literal', | ||
line: 3 | ||
}] | ||
}, | ||
{ | ||
filename: 'test.js', | ||
code: ` | ||
new Vue({ | ||
name: 'foo!bar' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add one more test with |
||
}) | ||
`, | ||
options: ['camelCase'], | ||
parserOptions: { ecmaVersion: 6 }, | ||
errors: [{ | ||
message: 'Property name "foo!bar" is not camelCase.', | ||
type: 'Literal', | ||
line: 3 | ||
}] | ||
} | ||
] | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Requires specific casing for the
nameproperty in Vue components (name-property-casing)