Skip to content

Commit

Permalink
add helper class and write test for regex creator
Browse files Browse the repository at this point in the history
  • Loading branch information
Miguel7373 committed Dec 17, 2024
1 parent 7e9fcce commit 988b5f5
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 47 deletions.
49 changes: 2 additions & 47 deletions frontend/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import tsEslint from "typescript-eslint";
import html from "@html-eslint/eslint-plugin";
import { createRegexForWords } from "./eslintHelper.mjs"


export default tsEslint.config(
{
Expand Down Expand Up @@ -62,50 +64,3 @@ export default tsEslint.config(
);


//Creates a big regex to check the right spelling on Words in the List
function createRegexForWords(wordList) {
// This function builds a case-insensitive regex pattern for a given word.
function makeRegexForWord(word, ignoreQuestionMark = false) {
return word
.split('')
.map((char, index) => {
const regex = `[${char.toUpperCase()}${char.toLowerCase()}]`;

if (index === 0) return regex;
if (index === word.length - 1) return ignoreQuestionMark ? regex : `?${regex}?`;
if (char.match(/[A-Z]/)) return `.?${regex}`;

return ignoreQuestionMark ? regex : `?${regex}`;
})
.join('');
}

function transformToUnderscoreUppercase(word) {
return word
.split(/(?=[A-Z])/) // Split at uppercase letters without removing them
.join('_')
.toUpperCase();
}

function buildPart2(word) {
const flexibleWord = makeRegexForWord(word, true);
return `(?=^(?!.*${flexibleWord}).*)`;
}

function buildPart1(word) {
const flexibleWord = makeRegexForWord(word, false);
const wordPart = `[${word[0]}${word[0].toLowerCase()}]${word.slice(1)}`; // Make the first character case-insensitive
return `(?=.*${flexibleWord}.*)(.*${wordPart}.*|[A-Z_]*${transformToUnderscoreUppercase(word)}[A-Z_]*)`;
}
const part1List = [];
const part2List = [];

wordList.forEach(word => {
const part1 = buildPart1(word);
const part2 = buildPart2(word);
part1List.push(part1);
part2List.push(part2);
});

return `(${part1List.join('|')})|(${part2List.join('')})`;
}
56 changes: 56 additions & 0 deletions frontend/eslintHelper.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@

export function createRegexForWords(wordList) {

// This function builds a case-insensitive regex pattern for a given word.


const part1List = [];
const part2List = [];

wordList.forEach(word => {
const part1 = createRegexToCheckIfWordLookAlike(word);
const part2 = createFallbackRegex(word);
part1List.push(part1);
part2List.push(part2);
});

return `(${part1List.join('|')})|(${part2List.join('')})`;
}

function getCaseInsensitiveRegexForChar(c){
return `[${c.toUpperCase()}${c.toLowerCase()}]`
}

function createCaseInsensitiveRegexForWord(word) {
return word
.match(/[A-Z][a-z]+/g)
.join(".?")
.split("")
.map(c => /[a-zA-Z]/g.test(c) ?getCaseInsensitiveRegexForChar(c) : c)
.join('');
}

function transformToUnderscoreUppercase(word) {
return word
.split(/(?=[A-Z])/) // Split at uppercase letters without removing them
.join('_')
.toUpperCase();
}

function getWordRegexWithOptionalLetters(word) {
return word.replace(/(\[[^\[\]]+\])(?![.?])/g, "$1?"); // Puts a "?" between the case-insensitive braces if there is no "?" or "." already
}

function createRegexToCheckIfWordLookAlike(word) {
let wordLooksLikeRegex = createCaseInsensitiveRegexForWord(word);
wordLooksLikeRegex = getWordRegexWithOptionalLetters(wordLooksLikeRegex)
const wordCorrectRegex = getCaseInsensitiveRegexForChar(word[0]) + word.slice(1);
const wordInUpperCase = transformToUnderscoreUppercase(word)
return `(?=.*${wordLooksLikeRegex}.*)(.*${wordCorrectRegex}.*|[A-Z_]*${wordInUpperCase}[A-Z_]*)`;
}

function createFallbackRegex(word) {
const caseInsensitiveWordRegex = createCaseInsensitiveRegexForWord(word);
return `(?=^(?!.*${caseInsensitiveWordRegex}).*)`;
}

18 changes: 18 additions & 0 deletions frontend/eslintHelper.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import * as eslintHelper from "./eslintHelper.mjs"

describe("eslintHelper", () => {
const combinedRegex:string = "((?=.*[Kk]?[Ee]?[Yy].?[Rr]?[Ee]?[Ss]?[Uu]?[Ll]?[Tt]?.*)(.*[Kk]eyResult.*|[A-Z_]*KEY_RESULT[A-Z_]*)|(?=.*[Cc]?[Hh]?[Ee]?[Cc]?[Kk].?[Ii]?[Nn]?.*)(.*[Cc]heckIn.*|[A-Z_]*CHECK_IN[A-Z_]*))|((?=^(?!.*[Kk][Ee][Yy].?[Rr][Ee][Ss][Uu][Ll][Tt]).*)(?=^(?!.*[Cc][Hh][Ee][Cc][Kk].?[Ii][Nn]).*))"
const keyResultRegex:string = "((?=.*[Kk]?[Ee]?[Yy]?[Rr]?[Ee]?[Ss]?[Uu]?[Ll]?[Tt]?.*)(.*[Kk]eyResult.*|[A-Z_]*KEY_RESULT[A-Z_]*))|((?=^(?!.*[Kk][Ee][Yy][Rr][Ee][Ss][Uu][Ll][Tt]).*))"
const CheckInRegex:string = "((?=.*[Cc]?[Hh]?[Ee]?[Cc]?[Kk]?[Ii]?[Nn]?.*)(.*[Cc]heckIn.*|[A-Z_]*CHECK_IN[A-Z_]*))|((?=^(?!.*[Cc][Hh][Ee][Cc][Kk][Ii][Nn]).*))"


it.each([
// [["KeyResult"], /KeyResult/],
// [["CheckIn"], /CheckIn/],
[["KeyResult", "CheckIn"], /KeyResult|CheckIn/],
])("should return regex %p", (wordToRegex) => {
expect(eslintHelper.createRegexForWords(wordToRegex)).toEqual(combinedRegex);

});
})

0 comments on commit 988b5f5

Please sign in to comment.