feat: Test running overhaul, switch to Prettier & reformat everything (#1407)

* chore: Switch to Node 20 + Vitest

* chore: migrate to vitest mock functions

* chore: code style (switch to prettier)

* test: re-enable long-running test

Seems the switch to Node 20 and Vitest has vastly improved the code's and / or the test's runtime!

see #1193

* chore: code style

* chore: fix failing tests

* Updated Documentation in README.md

* Update contribution guidelines to state usage of Prettier

* fix: set prettier printWidth back to 80

* chore: apply updated code style automatically

* fix: set prettier line endings to lf again

* chore: apply updated code style automatically

---------

Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
Co-authored-by: Lars Müller <34514239+appgurueu@users.noreply.github.com>
This commit is contained in:
Roland Hummel
2023-10-03 23:08:19 +02:00
committed by GitHub
parent 0ca18c2b2c
commit 86d333ee94
392 changed files with 5849 additions and 16622 deletions

View File

@@ -13,7 +13,7 @@ const key = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
* @param {Number} m - Modulos value
* @return {Number} Return n mod m
*/
function mod (n, m) {
function mod(n, m) {
return ((n % m) + m) % m
}
@@ -23,7 +23,7 @@ function mod (n, m) {
* @param {Number} m - Modulos value
* @return {Number} Return modular multiplicative inverse of coefficient a and modulos m
*/
function inverseMod (a, m) {
function inverseMod(a, m) {
for (let x = 1; x < m; x++) {
if (mod(a * x, m) === 1) return x
}
@@ -36,7 +36,7 @@ function inverseMod (a, m) {
* @param {Number} b - B coefficient to be checked
* @return {Boolean} Result of the checking
*/
function isCorrectFormat (str, a, b) {
function isCorrectFormat(str, a, b) {
if (typeof a !== 'number' || typeof b !== 'number') {
throw new TypeError('Coefficient a, b should be number')
}
@@ -57,8 +57,8 @@ function isCorrectFormat (str, a, b) {
* @param {String} char - Character index to be found
* @return {Boolean} Character index
*/
function findCharIndex (char) {
return char.toUpperCase().charCodeAt(0) - ('A').charCodeAt(0)
function findCharIndex(char) {
return char.toUpperCase().charCodeAt(0) - 'A'.charCodeAt(0)
}
/**
@@ -69,7 +69,7 @@ function findCharIndex (char) {
* @return {String} result - Encrypted string
*/
function encrypt (str, a, b) {
function encrypt(str, a, b) {
let result = ''
if (isCorrectFormat(str, a, b)) {
for (let x = 0; x < str.length; x++) {
@@ -88,7 +88,7 @@ function encrypt (str, a, b) {
* @param {Number} b - B coefficient
* @return {String} result - Decrypted string
*/
function decrypt (str, a, b) {
function decrypt(str, a, b) {
let result = ''
if (isCorrectFormat(str, a, b)) {
str = str.split(' ')

View File

@@ -2,7 +2,8 @@
Find and retrieve the encryption key automatically
Note: This is a draft version, please help to modify, Thanks!
******************************************************/
function keyFinder (str) { // str is used to get the input of encrypted string
function keyFinder(str) {
// str is used to get the input of encrypted string
const wordBank = [
'I ',
'You ',
@@ -27,13 +28,15 @@ function keyFinder (str) { // str is used to get the input of encrypted string
' may ',
'May ',
' be ',
'Be ']
'Be '
]
// let wordbankelementCounter = 0;
// let key = 0; // return zero means the key can not be found
const inStr = str.toString() // convert the input to String
let outStr = '' // store the output value
let outStrElement = '' // temporary store the word inside the outStr, it is used for comparison
for (let k = 0; k < 26; k++) { // try the number of key shifted, the sum of character from a-z or A-Z is 26
for (let k = 0; k < 26; k++) {
// try the number of key shifted, the sum of character from a-z or A-Z is 26
outStr = caesarCipherEncodeAndDecodeEngine(inStr, k) // use the encryption engine to decrypt the input string
// loop through the whole input string
@@ -57,7 +60,7 @@ function keyFinder (str) { // str is used to get the input of encrypted string
}
/* this sub-function is used to assist the keyFinder to find the key */
function caesarCipherEncodeAndDecodeEngine (inStr, numShifted) {
function caesarCipherEncodeAndDecodeEngine(inStr, numShifted) {
const shiftNum = numShifted
let charCode = 0
let outStr = ''
@@ -69,7 +72,7 @@ function caesarCipherEncodeAndDecodeEngine (inStr, numShifted) {
shiftedCharCode = charCode + shiftNum
result = charCode
if ((charCode >= 48 && charCode <= 57)) {
if (charCode >= 48 && charCode <= 57) {
if (shiftedCharCode < 48) {
let diff = Math.abs(48 - 1 - shiftedCharCode) % 10
@@ -95,11 +98,11 @@ function caesarCipherEncodeAndDecodeEngine (inStr, numShifted) {
result = shiftedCharCode
}
} else if ((charCode >= 65 && charCode <= 90)) {
} else if (charCode >= 65 && charCode <= 90) {
if (shiftedCharCode <= 64) {
let diff = Math.abs(65 - 1 - shiftedCharCode) % 26
while ((diff % 26) >= 26) {
while (diff % 26 >= 26) {
diff = diff % 26
}
shiftedCharCode = 90 - diff
@@ -109,17 +112,17 @@ function caesarCipherEncodeAndDecodeEngine (inStr, numShifted) {
} else if (shiftedCharCode > 90) {
let diff = Math.abs(shiftedCharCode - 1 - 90) % 26
while ((diff % 26) >= 26) {
while (diff % 26 >= 26) {
diff = diff % 26
}
shiftedCharCode = 65 + diff
result = shiftedCharCode
}
} else if ((charCode >= 97 && charCode <= 122)) {
} else if (charCode >= 97 && charCode <= 122) {
if (shiftedCharCode <= 96) {
let diff = Math.abs(97 - 1 - shiftedCharCode) % 26
while ((diff % 26) >= 26) {
while (diff % 26 >= 26) {
diff = diff % 26
}
shiftedCharCode = 122 - diff
@@ -129,7 +132,7 @@ function caesarCipherEncodeAndDecodeEngine (inStr, numShifted) {
} else if (shiftedCharCode > 122) {
let diff = Math.abs(shiftedCharCode - 1 - 122) % 26
while ((diff % 26) >= 26) {
while (diff % 26 >= 26) {
diff = diff % 26
}
shiftedCharCode = 97 + diff

View File

@@ -16,9 +16,36 @@
* Non alphabetical characters (space, exclamation mark, ...) are kept as they are
*/
const alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
const alphabet = [
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
'w',
'x',
'y',
'z'
]
function checkKeywordValidity (keyword) {
function checkKeywordValidity(keyword) {
keyword.split('').forEach((char, index) => {
const rest = keyword.slice(0, index) + keyword.slice(index + 1)
if (rest.indexOf(char) !== -1) {
@@ -28,7 +55,7 @@ function checkKeywordValidity (keyword) {
return true
}
function getEncryptedAlphabet (keyword) {
function getEncryptedAlphabet(keyword) {
const encryptedAlphabet = keyword.split('')
alphabet.forEach((char) => {
if (encryptedAlphabet.indexOf(char) === -1) {
@@ -38,17 +65,20 @@ function getEncryptedAlphabet (keyword) {
return encryptedAlphabet
}
function translate (sourceAlphabet, targetAlphabet, message) {
function translate(sourceAlphabet, targetAlphabet, message) {
return message.split('').reduce((encryptedMessage, char) => {
const isUpperCase = char === char.toUpperCase()
const encryptedCharIndex = sourceAlphabet.indexOf(char.toLowerCase())
const encryptedChar = encryptedCharIndex !== -1 ? targetAlphabet[encryptedCharIndex] : char
encryptedMessage += isUpperCase ? encryptedChar.toUpperCase() : encryptedChar
const encryptedChar =
encryptedCharIndex !== -1 ? targetAlphabet[encryptedCharIndex] : char
encryptedMessage += isUpperCase
? encryptedChar.toUpperCase()
: encryptedChar
return encryptedMessage
}, '')
}
function checkInputs (keyword, message) {
function checkInputs(keyword, message) {
if (!keyword || !message) {
throw new Error('Both keyword and message must be specified')
}
@@ -58,14 +88,22 @@ function checkInputs (keyword, message) {
}
}
function encrypt (keyword, message) {
function encrypt(keyword, message) {
checkInputs(keyword, message)
return translate(alphabet, getEncryptedAlphabet(keyword.toLowerCase()), message)
return translate(
alphabet,
getEncryptedAlphabet(keyword.toLowerCase()),
message
)
}
function decrypt (keyword, message) {
function decrypt(keyword, message) {
checkInputs(keyword, message)
return translate(getEncryptedAlphabet(keyword.toLowerCase()), alphabet, message)
return translate(
getEncryptedAlphabet(keyword.toLowerCase()),
alphabet,
message
)
}
export { encrypt, decrypt }

View File

@@ -50,7 +50,7 @@ const morse = (msg, dot = '*', dash = '-') => {
',': '--**--',
'?': '**--**',
'!': '-*-*--',
'\'': '*----*',
"'": '*----*',
'"': '*-**-*',
'(': '-*--*',
')': '-*--*-',
@@ -68,16 +68,21 @@ const morse = (msg, dot = '*', dash = '-') => {
let newMsg = ''
msg.toString().split('').forEach((e) => {
if (/[a-zA-Z]/.test(e)) {
newMsg += key[e.toUpperCase()].replaceAll('*', dot).replaceAll('-', dash)
} else if (Object.keys(key).includes(e)) {
newMsg += key[e].replaceAll('*', dot).replaceAll('-', dash)
} else {
newMsg += e
}
newMsg += ' '
})
msg
.toString()
.split('')
.forEach((e) => {
if (/[a-zA-Z]/.test(e)) {
newMsg += key[e.toUpperCase()]
.replaceAll('*', dot)
.replaceAll('-', dash)
} else if (Object.keys(key).includes(e)) {
newMsg += key[e].replaceAll('*', dot).replaceAll('-', dash)
} else {
newMsg += e
}
newMsg += ' '
})
return newMsg.trim()
}

View File

@@ -5,7 +5,7 @@
* @param {String} str - string to be decrypted
* @return {String} decrypted string
*/
function ROT13 (str) {
function ROT13(str) {
if (typeof str !== 'string') {
throw new TypeError('Argument should be string')
}

View File

@@ -3,7 +3,7 @@
* @param {String} str - character to check
* @return {object} An array with the character or null if isn't a letter
*/
function isLetter (str) {
function isLetter(str) {
return str.length === 1 && str.match(/[a-zA-Z]/i)
}
@@ -12,7 +12,7 @@ function isLetter (str) {
* @param {String} character - character to check
* @return {Boolean} result of the checking
*/
function isUpperCase (character) {
function isUpperCase(character) {
if (character === character.toUpperCase()) {
return true
}
@@ -27,16 +27,22 @@ function isUpperCase (character) {
* @param {String} key - key for encrypt
* @return {String} result - encrypted string
*/
function encrypt (message, key) {
function encrypt(message, key) {
let result = ''
for (let i = 0, j = 0; i < message.length; i++) {
const c = message.charAt(i)
if (isLetter(c)) {
if (isUpperCase(c)) {
result += String.fromCharCode((c.charCodeAt(0) + key.toUpperCase().charCodeAt(j) - 2 * 65) % 26 + 65) // A: 65
result += String.fromCharCode(
((c.charCodeAt(0) + key.toUpperCase().charCodeAt(j) - 2 * 65) % 26) +
65
) // A: 65
} else {
result += String.fromCharCode((c.charCodeAt(0) + key.toLowerCase().charCodeAt(j) - 2 * 97) % 26 + 97) // a: 97
result += String.fromCharCode(
((c.charCodeAt(0) + key.toLowerCase().charCodeAt(j) - 2 * 97) % 26) +
97
) // a: 97
}
} else {
result += c
@@ -52,16 +58,21 @@ function encrypt (message, key) {
* @param {String} key - key for decrypt
* @return {String} result - decrypted string
*/
function decrypt (message, key) {
function decrypt(message, key) {
let result = ''
for (let i = 0, j = 0; i < message.length; i++) {
const c = message.charAt(i)
if (isLetter(c)) {
if (isUpperCase(c)) {
result += String.fromCharCode(90 - (25 - (c.charCodeAt(0) - key.toUpperCase().charCodeAt(j))) % 26)
result += String.fromCharCode(
90 - ((25 - (c.charCodeAt(0) - key.toUpperCase().charCodeAt(j))) % 26)
)
} else {
result += String.fromCharCode(122 - (25 - (c.charCodeAt(0) - key.toLowerCase().charCodeAt(j))) % 26)
result += String.fromCharCode(
122 -
((25 - (c.charCodeAt(0) - key.toLowerCase().charCodeAt(j))) % 26)
)
}
} else {
result += c

View File

@@ -14,8 +14,8 @@ const XORCipher = (str, key) => {
throw new TypeError('Arguments type are invalid')
}
return str.replace(
/./g, (char) => String.fromCharCode(char.charCodeAt() ^ key)
return str.replace(/./g, (char) =>
String.fromCharCode(char.charCodeAt() ^ key)
)
}

View File

@@ -9,8 +9,14 @@ describe('Testing the caesarsCipher function', () => {
it('Test - 2, Testing for valid string and rotation', () => {
expect(caesarCipher('middle-Outz', 2)).toBe('okffng-Qwvb')
expect(caesarCipher('abcdefghijklmnopqrstuvwxyz', 3)).toBe('defghijklmnopqrstuvwxyzabc')
expect(caesarCipher('Always-Look-on-the-Bright-Side-of-Life', 5)).toBe('Fqbfdx-Qttp-ts-ymj-Gwnlmy-Xnij-tk-Qnkj')
expect(caesarCipher('THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG', 23)).toBe('QEB NRFZH YOLTK CLU GRJMP LSBO QEB IXWV ALD')
expect(caesarCipher('abcdefghijklmnopqrstuvwxyz', 3)).toBe(
'defghijklmnopqrstuvwxyzabc'
)
expect(caesarCipher('Always-Look-on-the-Bright-Side-of-Life', 5)).toBe(
'Fqbfdx-Qttp-ts-ymj-Gwnlmy-Xnij-tk-Qnkj'
)
expect(
caesarCipher('THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG', 23)
).toBe('QEB NRFZH YOLTK CLU GRJMP LSBO QEB IXWV ALD')
})
})

View File

@@ -1,13 +1,13 @@
import { encrypt, decrypt } from '../KeywordShiftedAlphabet'
test('Hello world! === decrypt(encrypt(Hello world!))', () => {
const word = 'Hello world!'
const result = decrypt('keyword', encrypt('keyword', word))
expect(result).toMatch(word)
})
test('The Algorithms === decrypt(encrypt(The Algorithms))', () => {
const word = 'The Algorithms'
const result = decrypt('keyword', encrypt('keyword', word))
expect(result).toMatch(word)
})
import { encrypt, decrypt } from '../KeywordShiftedAlphabet'
test('Hello world! === decrypt(encrypt(Hello world!))', () => {
const word = 'Hello world!'
const result = decrypt('keyword', encrypt('keyword', word))
expect(result).toMatch(word)
})
test('The Algorithms === decrypt(encrypt(The Algorithms))', () => {
const word = 'The Algorithms'
const result = decrypt('keyword', encrypt('keyword', word))
expect(result).toMatch(word)
})

View File

@@ -2,12 +2,16 @@ import { morse } from '../MorseCode'
describe('Testing morse function', () => {
it('should return an enciphered string with a given input string', () => {
expect(morse('Hello World!')).toBe('**** * *-** *-** --- *-- --- *-* *-** -** -*-*--')
expect(morse('Hello World!')).toBe(
'**** * *-** *-** --- *-- --- *-* *-** -** -*-*--'
)
expect(morse('1+1=2')).toBe('*---- *-*-* *---- -***- **---')
})
it('should leave symbols that does not have its corresponding morse representation', () => {
expect(morse('© 2023 GitHub, Inc.')).toBe('© **--- ----- **--- ***-- --* ** - **** **- -*** --**-- ** -* -*-* *-*-*-')
expect(morse('© 2023 GitHub, Inc.')).toBe(
'© **--- ----- **--- ***-- --* ** - **** **- -*** --**-- ** -* -*-* *-*-*-'
)
})
it('should be able to accept custom morse code symbols', () => {

View File

@@ -12,7 +12,11 @@ describe('Testing ROT13 function', () => {
it('Test - 2, passing a string as an argument', () => {
expect(ROT13('Uryyb Jbeyq')).toBe('Hello World')
expect(ROT13('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz')).toBe('NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm')
expect(ROT13('The quick brown fox jumps over the lazy dog')).toBe('Gur dhvpx oebja sbk whzcf bire gur ynml qbt')
expect(ROT13('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz')).toBe(
'NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm'
)
expect(ROT13('The quick brown fox jumps over the lazy dog')).toBe(
'Gur dhvpx oebja sbk whzcf bire gur ynml qbt'
)
})
})

View File

@@ -1,13 +1,13 @@
import { encrypt, decrypt } from '../VigenereCipher'
test('Hello world! === decrypt(encrypt(Hello world!))', () => {
const word = 'Hello world!'
const result = decrypt(encrypt(word, 'code'), 'code')
expect(result).toMatch(word)
})
test('The Algorithms === decrypt(encrypt(The Algorithms))', () => {
const word = 'The Algorithms'
const result = decrypt(encrypt(word, 'code'), 'code')
expect(result).toMatch(word)
})
import { encrypt, decrypt } from '../VigenereCipher'
test('Hello world! === decrypt(encrypt(Hello world!))', () => {
const word = 'Hello world!'
const result = decrypt(encrypt(word, 'code'), 'code')
expect(result).toMatch(word)
})
test('The Algorithms === decrypt(encrypt(The Algorithms))', () => {
const word = 'The Algorithms'
const result = decrypt(encrypt(word, 'code'), 'code')
expect(result).toMatch(word)
})