Skip to content
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

feat: implement spell check in separated by underscore words #83

Merged
merged 2 commits into from
Nov 22, 2022
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
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ Check Spelling inside identifiers
"ignoreRequire": <<Boolean>>, default: false
Exclude `require()` imports from spell-checking. Useful for excluding NPM package name false-positives.

"enableUpperCaseUnderscoreCheck": <<Boolean>>, default: false
Exclude checking uppercase words separated by an underscore. e.g., `SEARCH_CONDITIONS_LIMIT`

"templates": <<Boolean>>, default: true
Check Spelling inside ES6 templates you should enable parser options for ES6 features for this to work
Refer to: [specifying-parser-options](http://eslint.org/docs/user-guide/configuring#specifying-parser-options)
Expand Down
57 changes: 36 additions & 21 deletions rules/spell-checker.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ module.exports = {
type: 'boolean',
default: false
},
enableUpperCaseUnderscoreCheck: {
type: 'boolean',
default: false
stu01509 marked this conversation as resolved.
Show resolved Hide resolved
},
templates: {
type: 'boolean',
default: true
Expand Down Expand Up @@ -111,7 +115,6 @@ module.exports = {
additionalProperties: false
}
]

},

// create (function) returns an object with methods that ESLint calls to “visit” nodes while traversing the abstract syntax tree (AST as defined by ESTree) of JavaScript code:
Expand Down Expand Up @@ -164,31 +167,31 @@ module.exports = {
}

function checkSpelling(aNode, value, spellingType) {
if(!hasToSkip(value)) {
if (!hasToSkip(value)) {
// Regular expression matches regexp metacharacters, and any special char
var regexp = /(\\[sSwdDB0nfrtv])|\\[0-7][0-7][0-7]|\\x[0-9A-F][0-9A-F]|\\u[0-9A-F][0-9A-F][0-9A-F][0-9A-F]|[^0-9a-zA-Z '’]/g,
nodeWords = value.replace(regexp, ' ')
.replace(/([A-Z])/g, ' $1').split(' '),
.replace(/([A-Z])/g, ' $1').split(' '),
errors;
errors = nodeWords
.filter(hasToSkipWord)
.filter(isSpellingError)
.filter(function(aWord) {
// Split words by numbers for special cases such as test12anything78variable and to include 2nd and 3rd ordinals
// also for Proper names we convert to lower case in second pass.
.filter(function (aWord) {
// Split words by numbers for special cases such as test12anything78variable and to include 2nd and 3rd ordinals
// also for Proper names we convert to lower case in second pass.
var splitByNumberWords = aWord.replace(/[0-9']/g, ' ').replace(/([A-Z])/g, ' $1').toLowerCase().split(' ');
return splitByNumberWords.some(isSpellingError);
})
.forEach(function(aWord) {
.forEach(function (aWord) {
context.report(
aNode,
'You have a misspelled word: {{word}} on {{spellingType}}', {
word: aWord,
spellingType: spellingType
});
word: aWord,
spellingType: spellingType
});
});
}
}
}

function isInImportDeclaration(aNode) {
// @see https://buildmedia.readthedocs.org/media/pdf/esprima/latest/esprima.pdf
Expand All @@ -198,26 +201,38 @@ module.exports = {
);
}

function underscoreParser(aNode, value, spellingType) {
if (!options.enableUpperCaseUnderscoreCheck) {
checkSpelling(aNode, value, spellingType);
} else {
const splitValues = value.split('_');
splitValues.forEach((word) => {
checkSpelling(aNode, word.toLowerCase(), spellingType);
})
}
}

function checkComment(aNode) {
if(options.comments) {
checkSpelling(aNode, aNode.value, 'Comment');
if (options.comments) {
underscoreParser(aNode, aNode.value, 'Comment');
}
}

function checkLiteral(aNode){
if(options.strings && typeof aNode.value === 'string' && !isInImportDeclaration(aNode)) {
checkSpelling(aNode, aNode.value, 'String');
function checkLiteral(aNode) {
if (options.strings && typeof aNode.value === 'string' && !isInImportDeclaration(aNode)) {
underscoreParser(aNode, aNode.value, 'String');
}
}
function checkTemplateElement(aNode){
if(options.templates && typeof aNode.value.raw === 'string' && !isInImportDeclaration(aNode)) {
checkSpelling(aNode, aNode.value.raw, 'Template');

function checkTemplateElement(aNode) {
if (options.templates && typeof aNode.value.raw === 'string' && !isInImportDeclaration(aNode)) {
underscoreParser(aNode, aNode.value.raw, 'Template');
}
}

function checkIdentifier(aNode) {
if(options.identifiers) {
checkSpelling(aNode, aNode.name, 'Identifier');
if (options.identifiers) {
underscoreParser(aNode, aNode.name, 'Identifier');
}
}
/* Returns true if the string in value has to be skipped for spell checking */
Expand Down
40 changes: 35 additions & 5 deletions test/spell-checker.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ var ruleTester = new RuleTester({
},

parserOptions: {
"ecmaVersion": 2018,
"sourceType": "module",
'ecmaVersion': 2018,
'sourceType': 'module',
ecmaFeatures: {
"modules": true
'modules': true
}
}
});
Expand All @@ -44,6 +44,14 @@ ruleTester.run('spellcheck/spell-checker', rule, {
'var url = "http://examplus.com"',
'var a = Math.trunc(-0.1)',
'var a = "test", test = `${a}`;',
'var a = "ADD_SUM";',
'var a = "ADD_SMU";',
'const SEARCH_CONDITIONS_LIMIT = 9;',
stu01509 marked this conversation as resolved.
Show resolved Hide resolved
'const SEACH_CONDITIONS_LIMIT = 9;',
'const KEY = "HELLO_WORLD";',
'const KEY = "HELLO_WORDL";',
'const PASSWORD = "123456";',
'const PASSWROD = "123456";',
{
code: 'var a = 1 // This is a comment',
options: [{lang: 'sym', langDir: __dirname}]
Expand Down Expand Up @@ -183,7 +191,29 @@ ruleTester.run('spellcheck/spell-checker', rule, {
errors: [
{ message: 'You have a misspelled word: noooot on Template'}]
},


{
code: 'var a = "ADD_SMU"',
options:[{ enableUpperCaseUnderscoreCheck: true }],
errors: [
{ message: 'You have a misspelled word: smu on String'}]
},
{
code: 'const SEACH_CONDITIONS_LIMIT = 9;',
options:[{ enableUpperCaseUnderscoreCheck: true }],
errors: [
{ message: 'You have a misspelled word: seach on Identifier'}]
},
{
code: 'const KEY = "HELLO_WORDL";',
options:[{ enableUpperCaseUnderscoreCheck: true }],
errors: [
{ message: 'You have a misspelled word: wordl on String'}]
},
{
code: 'const PASSWROD = "123456";',
options:[{ enableUpperCaseUnderscoreCheck: true }],
errors: [
{ message: 'You have a misspelled word: passwrod on Identifier'}]
},
]
});