diff --git a/lib/rules/attribute-hyphenation.js b/lib/rules/attribute-hyphenation.js
index 9873d3657..e52d321b8 100644
--- a/lib/rules/attribute-hyphenation.js
+++ b/lib/rules/attribute-hyphenation.js
@@ -56,7 +56,7 @@ module.exports = {
ignoredAttributes = ignoredAttributes.concat(optionsPayload.ignore)
}
- const caseConverter = casing.getConverter(useHyphenated ? 'kebab-case' : 'camelCase')
+ const caseConverter = casing.getExactConverter(useHyphenated ? 'kebab-case' : 'camelCase')
function reportIssue (node, name) {
const text = sourceCode.getText(node.key)
diff --git a/lib/rules/component-definition-name-casing.js b/lib/rules/component-definition-name-casing.js
index 350ea9066..9012873a4 100644
--- a/lib/rules/component-definition-name-casing.js
+++ b/lib/rules/component-definition-name-casing.js
@@ -48,8 +48,7 @@ module.exports = {
range = node.range
}
- const value = casing.getConverter(caseType)(nodeValue)
- if (value !== nodeValue) {
+ if (!casing.getChecker(caseType)(nodeValue)) {
context.report({
node: node,
message: 'Property name "{{value}}" is not {{caseType}}.',
@@ -57,7 +56,7 @@ module.exports = {
value: nodeValue,
caseType: caseType
},
- fix: fixer => fixer.replaceTextRange([range[0] + 1, range[1] - 1], value)
+ fix: fixer => fixer.replaceTextRange([range[0] + 1, range[1] - 1], casing.getExactConverter(caseType)(nodeValue))
})
}
}
diff --git a/lib/rules/component-name-in-template-casing.js b/lib/rules/component-name-in-template-casing.js
index 2a8970555..91481b0f4 100644
--- a/lib/rules/component-name-in-template-casing.js
+++ b/lib/rules/component-name-in-template-casing.js
@@ -87,7 +87,7 @@ module.exports = {
}
// We only verify the components registered in the component.
if (registeredComponents
- .filter(name => casing.pascalCase(name) === name) // When defining a component with PascalCase, you can use either case
+ .filter(name => casing.isPascalCase(name)) // When defining a component with PascalCase, you can use either case
.some(name => node.rawName === name || casing.pascalCase(node.rawName) === name)) {
return true
}
@@ -108,11 +108,10 @@ module.exports = {
}
const name = node.rawName
- const casingName = casing.getConverter(caseType)(name)
- if (casingName !== name) {
+ if (!casing.getChecker(caseType)(name)) {
const startTag = node.startTag
const open = tokens.getFirstToken(startTag)
-
+ const casingName = casing.getExactConverter(caseType)(name)
context.report({
node: open,
loc: open.loc,
diff --git a/lib/rules/name-property-casing.js b/lib/rules/name-property-casing.js
index 041967cf0..26ae6bfa7 100644
--- a/lib/rules/name-property-casing.js
+++ b/lib/rules/name-property-casing.js
@@ -48,8 +48,8 @@ module.exports = {
if (!node) return
- const value = casing.getConverter(caseType)(node.value.value)
- if (value !== node.value.value) {
+ if (!casing.getChecker(caseType)(node.value.value)) {
+ const value = casing.getExactConverter(caseType)(node.value.value)
context.report({
node: node.value,
message: 'Property name "{{value}}" is not {{caseType}}.',
diff --git a/lib/rules/no-unregistered-components.js b/lib/rules/no-unregistered-components.js
index f387248ac..6ee325058 100644
--- a/lib/rules/no-unregistered-components.js
+++ b/lib/rules/no-unregistered-components.js
@@ -128,8 +128,7 @@ module.exports = {
// Component registered as `foo-bar` cannot be used as `FooBar`
if (
- name.indexOf('-') === -1 &&
- name === casing.pascalCase(name) &&
+ casing.isPascalCase(name) &&
componentsRegisteredAsKebabCase.indexOf(kebabCaseName) !== -1
) {
return true
diff --git a/lib/rules/no-unused-components.js b/lib/rules/no-unused-components.js
index 7f3920d20..21d2233cc 100644
--- a/lib/rules/no-unused-components.js
+++ b/lib/rules/no-unused-components.js
@@ -87,7 +87,7 @@ module.exports = {
// it can be used in various of ways inside template,
// like "theComponent", "The-component" etc.
// but except snake_case
- if (casing.pascalCase(name) === name || casing.camelCase(name) === name) {
+ if (casing.isPascalCase(name) || casing.isCamelCase(name)) {
return ![...usedComponents].some(n => {
return n.indexOf('_') === -1 && (name === casing.pascalCase(n) || casing.camelCase(n) === name)
})
diff --git a/lib/rules/prop-name-casing.js b/lib/rules/prop-name-casing.js
index 235dda23c..532b41ce7 100644
--- a/lib/rules/prop-name-casing.js
+++ b/lib/rules/prop-name-casing.js
@@ -15,7 +15,7 @@ const allowedCaseOptions = ['camelCase', 'snake_case']
function create (context) {
const options = context.options[0]
const caseType = allowedCaseOptions.indexOf(options) !== -1 ? options : 'camelCase'
- const converter = casing.getConverter(caseType)
+ const checker = casing.getChecker(caseType)
// ----------------------------------------------------------------------
// Public
@@ -31,8 +31,7 @@ function create (context) {
// (boolean | null | number | RegExp) Literal
continue
}
- const convertedName = converter(propName)
- if (convertedName !== propName) {
+ if (!checker(propName)) {
context.report({
node: item.node,
message: 'Prop "{{name}}" is not in {{caseType}}.',
diff --git a/lib/utils/casing.js b/lib/utils/casing.js
index 741481ef8..db01bc2e6 100644
--- a/lib/utils/casing.js
+++ b/lib/utils/casing.js
@@ -1,6 +1,27 @@
const assert = require('assert')
-const invalidChars = /[^a-zA-Z0-9:]+/g
+// ------------------------------------------------------------------------------
+// Helpers
+// ------------------------------------------------------------------------------
+
+/**
+ * Capitalize a string.
+ */
+function capitalize (str) {
+ return str.charAt(0).toUpperCase() + str.slice(1)
+}
+/**
+ * Checks whether the given string has symbols.
+ */
+function hasSymbols (str) {
+ return /[!"#%&'()*+,./:;<=>?@[\\\]^`{|}]/u.exec(str) // without " ", "$", "-" and "_"
+}
+/**
+ * Checks whether the given string has upper.
+ */
+function hasUpper (str) {
+ return /[A-Z]/u.exec(str)
+}
/**
* Convert text to kebab-case
@@ -9,13 +30,26 @@ const invalidChars = /[^a-zA-Z0-9:]+/g
*/
function kebabCase (str) {
return str
- .replace(/[A-Z]/g, match => '-' + match)
- .replace(/([^a-zA-Z])-([A-Z])/g, match => match[0] + match[2])
- .replace(/^-/, '')
- .replace(invalidChars, '-')
+ .replace(/_/gu, '-')
+ .replace(/\B([A-Z])/gu, '-$1')
.toLowerCase()
}
+/**
+ * Checks whether the given string is kebab-case.
+ */
+function isKebabCase (str) {
+ if (
+ hasUpper(str) ||
+ hasSymbols(str) ||
+ /^-/u.exec(str) || // starts with hyphen is not kebab-case
+ /_|--|\s/u.exec(str)
+ ) {
+ return false
+ }
+ return true
+}
+
/**
* Convert text to snake_case
* @param {string} str Text to be converted
@@ -23,25 +57,49 @@ function kebabCase (str) {
*/
function snakeCase (str) {
return str
- .replace(/[A-Z]/g, match => '_' + match)
- .replace(/([^a-zA-Z])_([A-Z])/g, match => match[0] + match[2])
- .replace(/^_/, '')
- .replace(invalidChars, '_')
+ .replace(/\B([A-Z])/gu, '_$1')
+ .replace(/-/gu, '_')
.toLowerCase()
}
+/**
+ * Checks whether the given string is snake_case.
+ */
+function isSnakeCase (str) {
+ if (
+ hasUpper(str) ||
+ hasSymbols(str) ||
+ /-|__|\s/u.exec(str)
+ ) {
+ return false
+ }
+ return true
+}
+
/**
* Convert text to camelCase
* @param {string} str Text to be converted
* @return {string} Converted string
*/
function camelCase (str) {
- return str
- .replace(/_/g, (_, index) => index === 0 ? _ : '-')
- .replace(/(?:^\w|[A-Z]|\b\w)/g, (letter, index) =>
- index === 0 ? letter.toLowerCase() : letter.toUpperCase()
- )
- .replace(invalidChars, '')
+ if (isPascalCase(str)) {
+ return str.charAt(0).toLowerCase() + str.slice(1)
+ }
+ return str.replace(/[-_](\w)/gu, (_, c) => c ? c.toUpperCase() : '')
+}
+
+/**
+ * Checks whether the given string is camelCase.
+ */
+function isCamelCase (str) {
+ if (
+ hasSymbols(str) ||
+ /^[A-Z]/u.exec(str) ||
+ /-|_|\s/u.exec(str) // kebab or snake or space
+ ) {
+ return false
+ }
+ return true
}
/**
@@ -50,10 +108,21 @@ function camelCase (str) {
* @return {string} Converted string
*/
function pascalCase (str) {
- return str
- .replace(/_/g, (_, index) => index === 0 ? _ : '-')
- .replace(/(?:^\w|[A-Z]|\b\w)/g, (letter, index) => letter.toUpperCase())
- .replace(invalidChars, '')
+ return capitalize(camelCase(str))
+}
+
+/**
+ * Checks whether the given string is PascalCase.
+ */
+function isPascalCase (str) {
+ if (
+ hasSymbols(str) ||
+ /^[a-z]/u.exec(str) ||
+ /-|_|\s/u.exec(str) // kebab or snake or space
+ ) {
+ return false
+ }
+ return true
}
const convertersMap = {
@@ -63,6 +132,34 @@ const convertersMap = {
'PascalCase': pascalCase
}
+const checkersMap = {
+ 'kebab-case': isKebabCase,
+ 'snake_case': isSnakeCase,
+ 'camelCase': isCamelCase,
+ 'PascalCase': isPascalCase
+}
+/**
+* Return case checker
+* @param {string} name type of checker to return ('camelCase', 'kebab-case', 'PascalCase')
+* @return {isKebabCase|isCamelCase|isPascalCase}
+*/
+function getChecker (name) {
+ assert(typeof name === 'string')
+
+ return checkersMap[name] || isPascalCase
+}
+
+/**
+ * Return case converter
+ * @param {string} name type of converter to return ('camelCase', 'kebab-case', 'PascalCase')
+ * @return {kebabCase|camelCase|pascalCase}
+ */
+function getConverter (name) {
+ assert(typeof name === 'string')
+
+ return convertersMap[name] || pascalCase
+}
+
module.exports = {
allowedCaseOptions: [
'camelCase',
@@ -75,14 +172,37 @@ module.exports = {
* @param {string} name type of converter to return ('camelCase', 'kebab-case', 'PascalCase')
* @return {kebabCase|camelCase|pascalCase}
*/
- getConverter (name) {
- assert(typeof name === 'string')
+ getConverter,
+
+ /**
+ * Return case checker
+ * @param {string} name type of checker to return ('camelCase', 'kebab-case', 'PascalCase')
+ * @return {isKebabCase|isCamelCase|isPascalCase}
+ */
+ getChecker,
- return convertersMap[name] || pascalCase
+ /**
+ * Return case exact converter.
+ * If the converted result is not the correct case, the original value is returned.
+ * @param {string} name type of converter to return ('camelCase', 'kebab-case', 'PascalCase')
+ * @return {kebabCase|camelCase|pascalCase}
+ */
+ getExactConverter (name) {
+ const converter = getConverter(name)
+ const checker = getChecker(name)
+ return (str) => {
+ const result = converter(str)
+ return checker(result) ? result : str/* cannot convert */
+ }
},
camelCase,
pascalCase,
kebabCase,
- snakeCase
+ snakeCase,
+
+ isCamelCase,
+ isPascalCase,
+ isKebabCase,
+ isSnakeCase
}
diff --git a/tests/lib/rules/component-definition-name-casing.js b/tests/lib/rules/component-definition-name-casing.js
index d14eedb7a..2317ea523 100644
--- a/tests/lib/rules/component-definition-name-casing.js
+++ b/tests/lib/rules/component-definition-name-casing.js
@@ -184,11 +184,7 @@ ruleTester.run('component-definition-name-casing', rule, {
name: 'foo bar'
}
`,
- output: `
- export default {
- name: 'FooBar'
- }
- `,
+ output: null,
parserOptions,
errors: [{
message: 'Property name "foo bar" is not PascalCase.',
@@ -203,11 +199,7 @@ ruleTester.run('component-definition-name-casing', rule, {
name: 'foo!bar'
}
`,
- output: `
- export default {
- name: 'FooBar'
- }
- `,
+ output: null,
parserOptions,
errors: [{
message: 'Property name "foo!bar" is not PascalCase.',
@@ -222,11 +214,7 @@ ruleTester.run('component-definition-name-casing', rule, {
name: 'foo!bar'
})
`,
- output: `
- new Vue({
- name: 'FooBar'
- })
- `,
+ output: null,
parserOptions: { ecmaVersion: 6 },
errors: [{
message: 'Property name "foo!bar" is not PascalCase.',
diff --git a/tests/lib/rules/component-name-in-template-casing.js b/tests/lib/rules/component-name-in-template-casing.js
index c1caf2e6d..d468dce84 100644
--- a/tests/lib/rules/component-name-in-template-casing.js
+++ b/tests/lib/rules/component-name-in-template-casing.js
@@ -686,6 +686,31 @@ tester.run('component-name-in-template-casing', rule, {
'Component name "the-component" is not PascalCase.',
'Component name "the-component" is not PascalCase.'
]
+ },
+ {
+ code: `
+
+
+
+
+
+ `,
+ output: `
+
+
+
+
+
+ `,
+ options: ['kebab-case', {
+ registeredComponentsOnly: false
+ }],
+ errors: [
+ 'Component name "foo--bar" is not kebab-case.',
+ 'Component name "Foo--Bar" is not kebab-case.',
+ 'Component name "FooBar" is not kebab-case.',
+ 'Component name "FooBar_Baz-qux" is not kebab-case.'
+ ]
}
]
})
diff --git a/tests/lib/rules/name-property-casing.js b/tests/lib/rules/name-property-casing.js
index 1bdeb8769..ae2ed7dec 100644
--- a/tests/lib/rules/name-property-casing.js
+++ b/tests/lib/rules/name-property-casing.js
@@ -99,11 +99,7 @@ ruleTester.run('name-property-casing', rule, {
name: 'foo bar'
}
`,
- output: `
- export default {
- name: 'FooBar'
- }
- `,
+ output: null,
parserOptions,
errors: [{
message: 'Property name "foo bar" is not PascalCase.',
@@ -118,11 +114,7 @@ ruleTester.run('name-property-casing', rule, {
name: 'foo!bar'
}
`,
- output: `
- export default {
- name: 'FooBar'
- }
- `,
+ output: null,
parserOptions,
errors: [{
message: 'Property name "foo!bar" is not PascalCase.',
@@ -137,11 +129,7 @@ ruleTester.run('name-property-casing', rule, {
name: 'foo!bar'
})
`,
- output: `
- new Vue({
- name: 'FooBar'
- })
- `,
+ output: null,
parserOptions: { ecmaVersion: 6 },
errors: [{
message: 'Property name "foo!bar" is not PascalCase.',
diff --git a/tests/lib/rules/prop-name-casing.js b/tests/lib/rules/prop-name-casing.js
index d80f7ab09..5290ec07d 100644
--- a/tests/lib/rules/prop-name-casing.js
+++ b/tests/lib/rules/prop-name-casing.js
@@ -287,6 +287,66 @@ ruleTester.run('prop-name-casing', rule, {
}
`,
parserOptions
+ },
+ {
+ // Japanese characters
+ filename: 'test.vue',
+ code: `
+ export default {
+ props: {
+ '漢字': String
+ }
+ }
+ `,
+ parserOptions
+ },
+ {
+ // emoji
+ filename: 'test.vue',
+ code: `
+ export default {
+ props: {
+ '\u{1F37B}': String
+ }
+ }
+ `,
+ parserOptions
+ },
+ {
+ // #862
+ filename: 'test.vue',
+ code: `
+ export default {
+ props: {
+ $actionEl: String
+ }
+ }
+ `,
+ parserOptions
+ },
+ {
+ // #932
+ filename: 'test.vue',
+ code: `
+ export default {
+ props: {
+ $css: String
+ }
+ }
+ `,
+ parserOptions
+ },
+ {
+ filename: 'test.vue',
+ code: `
+ export default {
+ props: {
+ _item: String
+ }
+ }
+ `,
+ options: ['snake_case'],
+ parserOptions
}
],
@@ -441,35 +501,34 @@ ruleTester.run('prop-name-casing', rule, {
}]
},
{
- // emoji
filename: 'test.vue',
code: `
export default {
props: {
- '\u{1F37B}': String
+ 'abc-123-def': String
}
}
`,
parserOptions,
errors: [{
- message: 'Prop "\u{1F37B}" is not in camelCase.',
+ message: 'Prop "abc-123-def" is not in camelCase.',
type: 'Property',
line: 4
}]
},
{
- // Japanese characters
+ // Parentheses computed property name
filename: 'test.vue',
code: `
export default {
props: {
- '漢字': String
+ [('greeting-text')]: String
}
}
`,
parserOptions,
errors: [{
- message: 'Prop "漢字" is not in camelCase.',
+ message: 'Prop "greeting-text" is not in camelCase.',
type: 'Property',
line: 4
}]
@@ -479,33 +538,26 @@ ruleTester.run('prop-name-casing', rule, {
code: `
export default {
props: {
- 'abc-123-def': String
+ _item: String
}
}
`,
parserOptions,
- errors: [{
- message: 'Prop "abc-123-def" is not in camelCase.',
- type: 'Property',
- line: 4
- }]
+ errors: ['Prop "_item" is not in camelCase.']
},
{
- // Parentheses computed property name
filename: 'test.vue',
code: `
export default {
props: {
- [('greeting-text')]: String
+ _itemName: String
}
}
`,
+ options: ['snake_case'],
parserOptions,
- errors: [{
- message: 'Prop "greeting-text" is not in camelCase.',
- type: 'Property',
- line: 4
- }]
+ errors: ['Prop "_itemName" is not in snake_case.']
}
+
]
})
diff --git a/tests/lib/utils/casing.js b/tests/lib/utils/casing.js
index d72d186d5..28a71ce53 100644
--- a/tests/lib/utils/casing.js
+++ b/tests/lib/utils/casing.js
@@ -9,6 +9,7 @@ describe('getConverter()', () => {
it('should convert string to camelCase', () => {
const converter = casing.getConverter('camelCase')
+ assert.equal(converter('foo'), 'foo')
assert.equal(converter('fooBar'), 'fooBar')
assert.equal(converter('foo-bar'), 'fooBar')
assert.equal(converter('foo_bar'), 'fooBar')
@@ -17,11 +18,18 @@ describe('getConverter()', () => {
assert.equal(converter('FooBAR'), 'fooBAR')
assert.equal(converter('Foo1BAZ'), 'foo1BAZ')
assert.equal(converter('foo1b_a_z'), 'foo1bAZ')
+ assert.equal(converter('darИībaÊÊw'), 'darИībaÊÊw')
+ assert.equal(converter('klâwen-ûf'), 'klâwen-ûf')
+ assert.equal(converter('пустынныхИвдалП'), 'пустынныхИвдалП')
+ assert.equal(converter('kpłĄżć'), 'kpłĄżć')
+ assert.equal(converter('ÊtreSîne'), 'êtreSîne')
+ assert.equal(converter(' foo Bar '), ' foo Bar ')
})
it('should convert string to PascalCase', () => {
const converter = casing.getConverter('PascalCase')
+ assert.equal(converter('foo'), 'Foo')
assert.equal(converter('fooBar'), 'FooBar')
assert.equal(converter('foo-bar'), 'FooBar')
assert.equal(converter('foo_bar'), 'FooBar')
@@ -30,30 +38,184 @@ describe('getConverter()', () => {
assert.equal(converter('FooBAR'), 'FooBAR')
assert.equal(converter('Foo1BAZ'), 'Foo1BAZ')
assert.equal(converter('foo1b_a_z'), 'Foo1bAZ')
+ assert.equal(converter('darИībaÊÊw'), 'DarИībaÊÊw')
+ assert.equal(converter('klâwen-ûf'), 'Klâwen-ûf')
+ assert.equal(converter('пустынныхИвдалП'), 'ПустынныхИвдалП')
+ assert.equal(converter('kpłĄżć'), 'KpłĄżć')
+ assert.equal(converter('ÊtreSîne'), 'ÊtreSîne')
+ assert.equal(converter(' foo Bar '), ' foo Bar ')
})
it('should convert string to kebab-case', () => {
const converter = casing.getConverter('kebab-case')
+ assert.equal(converter('foo'), 'foo')
assert.equal(converter('fooBar'), 'foo-bar')
assert.equal(converter('foo-bar'), 'foo-bar')
assert.equal(converter('foo_bar'), 'foo-bar')
assert.equal(converter('FooBar'), 'foo-bar')
- assert.equal(converter('Foo1Bar'), 'foo1bar')
+ assert.equal(converter('Foo1Bar'), 'foo1-bar')
assert.equal(converter('FooBAR'), 'foo-b-a-r')
- assert.equal(converter('Foo1BAZ'), 'foo1b-a-z')
+ assert.equal(converter('Foo1BAZ'), 'foo1-b-a-z')
assert.equal(converter('foo1b_a_z'), 'foo1b-a-z')
+ assert.equal(converter('darИībaÊÊw'), 'darиībaêêw')
+ assert.equal(converter('klâwen-ûf'), 'klâwen-ûf')
+ assert.equal(converter('пустынныхИвдалП'), 'пустынныхивдалп')
+ assert.equal(converter('kpłĄżć'), 'kpłążć')
+ assert.equal(converter('ÊtreSîne'), 'être-sîne')
+ assert.equal(converter(' foo Bar '), ' foo bar ')
})
it('should convert string to snake_case', () => {
const converter = casing.getConverter('snake_case')
+ assert.equal(converter('a'), 'a')
assert.equal(converter('fooBar'), 'foo_bar')
assert.equal(converter('foo-bar'), 'foo_bar')
assert.equal(converter('FooBar'), 'foo_bar')
- assert.equal(converter('Foo1Bar'), 'foo1bar')
+ assert.equal(converter('Foo1Bar'), 'foo1_bar')
assert.equal(converter('FooBAR'), 'foo_b_a_r')
- assert.equal(converter('Foo1BAZ'), 'foo1b_a_z')
+ assert.equal(converter('Foo1BAZ'), 'foo1_b_a_z')
assert.equal(converter('foo1b_a_z'), 'foo1b_a_z')
+ assert.equal(converter('darИībaÊÊw'), 'darиībaêêw')
+ assert.equal(converter('klâwen-ûf'), 'klâwen_ûf')
+ assert.equal(converter('пустынныхИвдалП'), 'пустынныхивдалп')
+ assert.equal(converter('kpłĄżć'), 'kpłążć')
+ assert.equal(converter('ÊtreSîne'), 'être_sîne')
+ assert.equal(converter(' foo Bar '), ' foo bar ')
+ })
+})
+
+describe('getChecker()', () => {
+ it('should check string to camelCase', () => {
+ const checker = casing.getChecker('camelCase')
+
+ assert.equal(checker('foo'), true)
+ assert.equal(checker('fooBar'), true)
+ assert.equal(checker('fooBar'), true)
+ assert.equal(checker('fooBar'), true)
+ assert.equal(checker('fooBar'), true)
+ assert.equal(checker('foo1Bar'), true)
+ assert.equal(checker('fooBAR'), true)
+ assert.equal(checker('foo1BAZ'), true)
+ assert.equal(checker('foo1bAZ'), true)
+ assert.equal(checker('darИībaÊÊw'), true)
+ assert.equal(checker('klâwen-ûf'), false)
+ assert.equal(checker('пустынныхИвдалП'), true)
+ assert.equal(checker('kpłĄżć'), true)
+ assert.equal(checker('êtreSîne'), true)
+ assert.equal(checker(' foo Bar '), false)
+
+ assert.equal(checker('camelCase'), true)
+ assert.equal(checker('PascalCase'), false)
+ assert.equal(checker('kebab-case'), false)
+ assert.equal(checker('snake_case'), false)
+
+ assert.equal(checker('camel-Kebab-Case'), false)
+ assert.equal(checker('camel_Snake_Case'), false)
+ assert.equal(checker('Pascal-Kebab-Case'), false)
+ assert.equal(checker('Pascal_Snake_Case'), false)
+ assert.equal(checker('snake_kebab-case'), false)
+ })
+
+ it('should check string to PascalCase', () => {
+ const checker = casing.getChecker('PascalCase')
+
+ assert.equal(checker('Foo'), true)
+ assert.equal(checker('FooBar'), true)
+ assert.equal(checker('FooBar'), true)
+ assert.equal(checker('FooBar'), true)
+ assert.equal(checker('FooBar'), true)
+ assert.equal(checker('Foo1Bar'), true)
+ assert.equal(checker('FooBAR'), true)
+ assert.equal(checker('Foo1BAZ'), true)
+ assert.equal(checker('Foo1bAZ'), true)
+ assert.equal(checker('DarИībaÊÊw'), true)
+ assert.equal(checker('Klâwen-ûf'), false)
+ assert.equal(checker('ПустынныхИвдалП'), true)
+ assert.equal(checker('KpłĄżć'), true)
+ assert.equal(checker('ÊtreSîne'), true)
+ assert.equal(checker(' foo Bar '), false)
+
+ assert.equal(checker('DarbībaShow'), true)
+
+ assert.equal(checker('camelCase'), false)
+ assert.equal(checker('PascalCase'), true)
+ assert.equal(checker('kebab-case'), false)
+ assert.equal(checker('snake_case'), false)
+
+ assert.equal(checker('camel-Kebab-Case'), false)
+ assert.equal(checker('camel_Snake_Case'), false)
+ assert.equal(checker('Pascal-Kebab-Case'), false)
+ assert.equal(checker('Pascal_Snake_Case'), false)
+ assert.equal(checker('snake_kebab-case'), false)
+ })
+
+ it('should convert string to kebab-case', () => {
+ const checker = casing.getChecker('kebab-case')
+
+ assert.equal(checker('foo'), true)
+ assert.equal(checker('foo-bar'), true)
+ assert.equal(checker('foo-bar'), true)
+ assert.equal(checker('foo-bar'), true)
+ assert.equal(checker('foo-bar'), true)
+ assert.equal(checker('foo1-bar'), true)
+ assert.equal(checker('foo-b-a-r'), true)
+ assert.equal(checker('foo1-b-a-z'), true)
+ assert.equal(checker('foo1b-a-z'), true)
+ assert.equal(checker('darиībaêêw'), true)
+ assert.equal(checker('klâwen-ûf'), true)
+ assert.equal(checker('пустынныхивдалп'), true)
+ assert.equal(checker('kpłążć'), true)
+ assert.equal(checker('être-sîne'), true)
+ assert.equal(checker(' foo bar '), false)
+
+ assert.equal(checker('camelCase'), false)
+ assert.equal(checker('PascalCase'), false)
+ assert.equal(checker('kebab-case'), true)
+ assert.equal(checker('snake_case'), false)
+
+ assert.equal(checker('camel-Kebab-Case'), false)
+ assert.equal(checker('camel_Snake_Case'), false)
+ assert.equal(checker('Pascal-Kebab-Case'), false)
+ assert.equal(checker('Pascal_Snake_Case'), false)
+ assert.equal(checker('snake_kebab-case'), false)
+
+ assert.equal(checker('valid-kebab-case'), true)
+ assert.equal(checker('-invalid-kebab-case'), false)
+ assert.equal(checker('invalid--kebab-case'), false)
+ })
+
+ it('should check string to snake_case', () => {
+ const checker = casing.getChecker('snake_case')
+
+ assert.equal(checker('a'), true)
+ assert.equal(checker('foo_bar'), true)
+ assert.equal(checker('foo_bar'), true)
+ assert.equal(checker('foo_bar'), true)
+ assert.equal(checker('foo1_bar'), true)
+ assert.equal(checker('foo_b_a_r'), true)
+ assert.equal(checker('foo1_b_a_z'), true)
+ assert.equal(checker('foo1b_a_z'), true)
+ assert.equal(checker('darиībaêêw'), true)
+ assert.equal(checker('klâwen_ûf'), true)
+ assert.equal(checker('пустынныхивдалп'), true)
+ assert.equal(checker('kpłążć'), true)
+ assert.equal(checker('être_sîne'), true)
+ assert.equal(checker(' foo bar '), false)
+
+ assert.equal(checker('camelCase'), false)
+ assert.equal(checker('PascalCase'), false)
+ assert.equal(checker('kebab-case'), false)
+ assert.equal(checker('snake_case'), true)
+
+ assert.equal(checker('camel-Kebab-Case'), false)
+ assert.equal(checker('camel_Snake_Case'), false)
+ assert.equal(checker('Pascal-Kebab-Case'), false)
+ assert.equal(checker('Pascal_Snake_Case'), false)
+ assert.equal(checker('snake_kebab-case'), false)
+
+ assert.equal(checker('_valid_snake_case'), true)
+ assert.equal(checker('invalid__snake_case'), false)
})
})