Skip to content

Commit

Permalink
squash branch
Browse files Browse the repository at this point in the history
  • Loading branch information
kcinay055679 committed Dec 24, 2024
1 parent 385a02b commit 9979100
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 11 deletions.
26 changes: 16 additions & 10 deletions frontend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ https://eslint.org/
We use **prettier** to format scss json and yaml files:
https://prettier.io/

We use **prettier** to format scss json and yaml files:
https://prettier.io/

If you get a does not match pattern error, it is likely because of the custom words for the OKR tool
here is a regex101 project that showcases how the regex works:
https://regex101.com/r/VUyAt6/1
## Test Coverage

For generating the coverage of our frontend specs (jest), you can use following command:
Expand All @@ -47,16 +53,16 @@ Open the html file in browser and you get a beautiful overview
## Cypress Tests

- local setup
- start local Docker `docker-compose up`
- start local Server: `OkrApplication-E2E`
- start local Client: `npm run start`
- start local Docker `docker-compose up`
- start local Server: `OkrApplication-E2E`
- start local Client: `npm run start`
- run selected Tests
- npm run `npm run cypress:open`
- in Cypress App, select `E2E Testing` and `Chrome` as Browser
- npm run `npm run cypress:open`
- in Cypress App, select `E2E Testing` and `Chrome` as Browser
- run all tests
- npm run `npm run cypress:run`
- in Cypress App, select `E2E Testing` and `Chrome` as Browser
- npm run `npm run cypress:run`
- in Cypress App, select `E2E Testing` and `Chrome` as Browser
- in case of failing Tests:
- stop and restart local Server
- stop and restart local Client
- re-run Cypress Tests
- stop and restart local Server
- stop and restart local Client
- re-run Cypress Tests
43 changes: 43 additions & 0 deletions frontend/eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import stylistic from '@stylistic/eslint-plugin'
import html from '@html-eslint/eslint-plugin'
import angular from 'angular-eslint'
import htmlParser from '@html-eslint/parser'
import { createRegexForWords } from './eslintHelper.mjs'

export default tsEslint.config(
{
Expand All @@ -15,6 +16,11 @@ export default tsEslint.config(
...tsEslint.configs.stylistic,
...angular.configs.tsRecommended,
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.json', './tsconfig.spec.json'],
},
},
processor: angular.processInlineTemplates,
rules: {
...stylistic.configs['all-flat'].rules,
Expand Down Expand Up @@ -76,8 +82,38 @@ export default tsEslint.config(
style: 'kebab-case',
},
],
'@typescript-eslint/naming-convention': [
'error',
{
selector: ['class', 'interface'],
format: ['PascalCase'],
},
{
selector: 'variable',
modifiers: [],
format: ['camelCase', 'UPPER_CASE'],
},
{
selector: 'enum',
format: ['PascalCase'],
},
{
selector: 'enumMember',
format: ['UPPER_CASE'],
},
{
selector: ['method', 'function'],
format: ['camelCase'],
},
{
selector: 'typeParameter',
format: ['PascalCase'],
},
],
'id-match': ['error', createRegexForWords(['KeyResult', 'CheckIn', 'TeamManagement', 'StretchGoal'])],
},
},

{
files: ['**/*.spec.ts'],
rules: {
Expand All @@ -101,6 +137,13 @@ export default tsEslint.config(
'@html-eslint/require-img-alt': 'off',
'@html-eslint/element-newline': 'off',
'@html-eslint/require-closing-tags': ['error', { selfClosing: 'always' }],
'@html-eslint/id-naming-convention': [
'error',
'regex',
{
pattern: `(?=(^[a-z]+(-[a-z]+)*$))(?=(${createRegexForWords(['KeyResult', 'CheckIn', 'TeamManagement', 'StretchGoal'])}))`,
},
],
},
},
{
Expand Down
59 changes: 59 additions & 0 deletions frontend/eslintHelper.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
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 transformToHyphenLowercase(word) {
return word
.split(/(?=[A-Z])/) // Split at uppercase letters without removing them
.join('-')
.toLowerCase()
}

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)
const wordInLowerCase = transformToHyphenLowercase(word)
return `(?=.*${wordLooksLikeRegex}.*)(.*${wordCorrectRegex}.*|[A-Z_]*${wordInUpperCase}[A-Z_]*|[a-z-]*${wordInLowerCase}[a-z-]*)`
}

function createFallbackRegex(word) {
const caseInsensitiveWordRegex = createCaseInsensitiveRegexForWord(word)
return `(?=^(?!.*${caseInsensitiveWordRegex}).*)`
}
31 changes: 31 additions & 0 deletions frontend/eslintHelper.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import * as eslintHelper from "./eslintHelper.mjs"
import { $locationShim } from "@angular/common/upgrade";

describe("eslintHelper", () => {
const combinedRegex:string = "((?=.*[Kk]?[Ee]?[Yy].?[Rr]?[Ee]?[Ss]?[Uu]?[Ll]?[Tt]?.*)(.*[Kk]eyResult.*|[A-Z_]*KEY_RESULT[A-Z_]*|[a-z-]*key-result[a-z-]*)|(?=.*[Cc]?[Hh]?[Ee]?[Cc]?[Kk].?[Ii]?[Nn]?.*)(.*[Cc]heckIn.*|[A-Z_]*CHECK_IN[A-Z_]*|[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_]*|[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_]*|[a-z-]*check-in[a-z-]*))|((?=^(?!.*[Cc][Hh][Ee][Cc][Kk].?[Ii][Nn]).*))"

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

it.each([
[["KeyResult"], ["KeyResult", "CurrentKeyResult", "keyResult", "keyResultId", "key-result", "test-key-result-test"],["Keyresult", "CurrentKeyresult", "keyresult", "keyresultId", "KEyResult", "KeyResUlt", "test-keyresult-test"]],
[["CheckIn"], ["CheckIn", "CurrentCheckIn", "checkIn", "checkInId", "check-in", "test-check-in-test"],["Checkin", "CurrentCheckin", "checkin", "checkinId", "cHeckIn", "checkIN", "test-checkin-test"]],
[["KeyResult", "CheckIn"], ["KeyResult", "CurrentKeyResult", "keyResult", "keyResultId", "key-result", "test-key-result-test", "CheckIn", "CurrentCheckIn", "checkIn", "checkInId", "check-in", "test-check-in-test"],["Keyresult", "CurrentKeyresult", "keyresult", "keyresultId", "KEyResult", "KeyResUlt", "test-keyresult-test", "Checkin", "CurrentCheckin", "checkin", "checkinId", "cHeckIn", "checkIN", "test-checkin-test"]],
])("should run regex %p threw the matching and not matching list", (wordToRegex:string[], matchingListToRegex:string[], notMatchingListToRegex:string[]) => {
const regexOfCustomWord = new RegExp(eslintHelper.createRegexForWords(wordToRegex));
matchingListToRegex = matchingListToRegex.filter(word => regexOfCustomWord.test(word));
notMatchingListToRegex = notMatchingListToRegex.filter(word => regexOfCustomWord.test(word));

expect(matchingListToRegex.length).toBe(matchingListToRegex.length);
expect(notMatchingListToRegex.length).toBe(0)
});

})

3 changes: 2 additions & 1 deletion frontend/tsconfig.spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
"module": "CommonJs",
"types": ["jest"]
},
"include": ["src/**/*.spec.ts", "src/**/*.d.ts"]
"include": ["src/**/*.spec.ts", "src/**/*.d.ts"],
"exclude": []
}

0 comments on commit 9979100

Please sign in to comment.