fully working functions and tests

This commit is contained in:
ak 2023-07-20 15:19:36 -07:00
parent 4f780ecdb1
commit 7dbec26588
14 changed files with 5983 additions and 0 deletions

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
node_modules
.eslint*
.prettier*

3
babel.config.js Normal file
View file

@ -0,0 +1,3 @@
module.exports = {
presets: [['@babel/preset-env', {targets: {node: 'current'}}]],
};

5698
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

22
package.json Normal file
View file

@ -0,0 +1,22 @@
{
"name": "js-testing-practice",
"version": "1.0.0",
"description": "",
"main": "src/main.js",
"scripts": {
"test": "jest",
"watch": "jest --watch src/*.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.22.9",
"@babel/preset-env": "^7.22.9",
"babel-jest": "^29.6.1",
"eslint": "^8.45.0",
"eslint-config-prettier": "^8.8.0",
"jest": "^29.6.1",
"prettier": "^3.0.0"
}
}

17
src/analyzeArray.js Normal file
View file

@ -0,0 +1,17 @@
// function that takes an array of numbers and returns an object with the following properties: average, min, max, and length
export const analyzeArray = (input) => {
// throws error if not passed an array
if (!Array.isArray(input)) throw new Error ('Input is not an array!');
// returns object containing
const output = {
// minimum value in array
min: Math.min(...input),
// maximum value in array
max: Math.max(...input),
// length of the array
length: input.length,
// mean value of the array - computed by getting sum of array values and dividing by number of indexes
average: (input.reduce((sum, curr) => sum + curr, 0)) / input.length
}
return output;
}

23
src/analyzeArray.test.js Normal file
View file

@ -0,0 +1,23 @@
import { analyzeArray } from "./analyzeArray";
// function that takes an array of numbers and returns an object with the following properties: average, min, max, and length
test ('Function throws error on non-array input', () => {
expect(() => analyzeArray('string')).toThrow('Input is not an array!');
expect(() => analyzeArray(8)).toThrow('Input is not an array!');
expect(() => analyzeArray({})).toThrow('Input is not an array!');
});
test ('Function returns object when passed array', () => {
expect(analyzeArray([1, 2, 3])).toEqual(expect.any(Object));
});
test ('Function returns object containing variable min as the smallest number in passed array', () => {
expect(analyzeArray([1, 2, 3]).min).toBe(1);
});
test ('Function returns object containing variable max as the largest number in passed array', () => {
expect(analyzeArray([1, 2, 3]).max).toBe(3);
});
test ('Function returns object containing variable length as the length of passed array', () => {
expect(analyzeArray([1, 2, 3]).length).toBe(3);
});
test ('Function returns object containing variable average as the mean value of passed array', () => {
expect(analyzeArray([1, 2, 3]).average).toBe(2);
});

55
src/caesarCipher.js Normal file
View file

@ -0,0 +1,55 @@
// function that takes a string and a shift factor and returns it with each character “shifted”
export const caesarCipher = (string, factor) => {
// define ASCII values for operations
const UPPERSTART = 65;
const UPPEREND = 90;
const LOWERSTART = 97;
const LOWEREND = 122;
// if either of the arguments are invalid, throw error
if (!string || !factor || typeof string != 'string' || typeof factor != 'number') throw new Error ('Invalid inputs!');
if (string === '') throw new Error ('Blank string entered!');
// create output string
let output = '';
// for each character in string
for (let i = 0; i < string.length; i++) {
// get charcode
const curr = string.charCodeAt(i);
// if uppercase
if (curr >= UPPERSTART && curr <= UPPEREND) {
// define modified charcode
let modified = curr + factor;
// if greater than 90 (Z)
if (modified > UPPEREND) {
// "loop around" and append to the first value, subtracting one digit for the "loop"
modified = modified - UPPEREND + UPPERSTART - 1;
}
// if less than 65 (A)
if (modified < UPPERSTART) {
// get the "negative" difference and "loop around" to apply it to the end, adding one digit for the "loop"
modified = modified - UPPERSTART + UPPEREND + 1;
}
// set the current character index in string to be the new character
output += String.fromCharCode(modified);
// iterate the for loop
continue;
}
// if lowercase
if (curr >= LOWERSTART && curr <= LOWEREND) {
// define modified charcode
let modified = curr + factor;
// if greater than 122 (z)
if (modified > LOWEREND) {
// "loop around" and append to the first value, subtracting one digit for the "loop"
modified = modified - LOWEREND + LOWERSTART - 1;
}
// if less than 97 (a)
if (modified < LOWERSTART) {
// get the "negative" difference and "loop around" to apply it to the end, adding one digit for the "loop"
modified = modified - LOWERSTART + LOWEREND + 1;
}
// set the current character index in string to be the new character
output += String.fromCharCode(modified);
}
}
return output;
}

31
src/caesarCipher.test.js Normal file
View file

@ -0,0 +1,31 @@
import { caesarCipher } from "./caesarCipher.js";
// function that takes a string and a shift factor and returns it with each character “shifted”
test ('Function throws error if either argument is missing', () => {
expect(() => caesarCipher()).toThrow('Invalid inputs!');
expect(() => caesarCipher(null, 8)).toThrow('Invalid inputs!');
expect(() => caesarCipher('fish')).toThrow('Invalid inputs!');
});
test ('Function throws error if shift factor is not a number', () => {
expect(() => caesarCipher('string', {})).toThrow('Invalid inputs!');
});
test ('Function throws error on non-String input', () => {
expect(() => caesarCipher([8], 8)).toThrow('Invalid inputs!');
});
test ('Function throws error on blank String input', () => {
expect(() => caesarCipher('', 8)).toThrow('Invalid inputs!');
});
test ('Function returns String when passed valid input String', () => {
const tester = caesarCipher('string', 8);
expect(tester).toEqual(expect.any(String));
});
test ('Function returns factor-shifted String', () => {
const tester = caesarCipher('string', 13);
const tester2 = caesarCipher('string', 2);
expect(tester).toBe('fgevat');
expect(tester2).toBe('uvtkpi');
});
test ('Function returns factor-shifted String when given negative factor', () => {
const tester = caesarCipher('abba', -15);
expect(tester).toBe('lmml');
});

31
src/calculator.js Normal file
View file

@ -0,0 +1,31 @@
// calculator object that contains functions for the basic operations: add, subtract, divide, and multiply
// Each of these functions should take two numbers and return the correct calculation.
export const calculator = () => {
// validator function for operations arguments
const valid = (first, second) => {
// checks if both values exist and are numbers, if not returns false
return (!first || !second || typeof first != 'number' || typeof second != 'number') ? false : true;
}
const add = (num1, num2) => {
if (!valid(num1, num2)) throw new Error('Invalid inputs!');
return num1 + num2;
}
const subtract = (num1, num2) => {
if (!valid(num1, num2)) throw new Error('Invalid inputs!');
return num1 - num2;
}
const divide = (num1, num2) => {
if (!valid(num1, num2)) throw new Error('Invalid inputs!');
return num1 / num2;
}
const multiply = (num1, num2) => {
if (!valid(num1, num2)) throw new Error('Invalid inputs!');
return num1 * num2;
}
return {
add,
subtract,
divide,
multiply
}
}

42
src/calculator.test.js Normal file
View file

@ -0,0 +1,42 @@
import { calculator } from "./calculator.js";
// calculator object that contains functions for the basic operations: add, subtract, divide, and multiply
// Each of these functions should take two numbers and return the correct calculation.
const calc = calculator();
test ('Function throws error if either argument is missing', () => {
expect(() => calc.add(8)).toThrow('Invalid inputs!');
expect(() => calc.add(null, 8)).toThrow('Invalid inputs!');
expect(() => calc.subtract(8)).toThrow('Invalid inputs!');
expect(() => calc.subtract(null, 8)).toThrow('Invalid inputs!');
expect(() => calc.divide(8)).toThrow('Invalid inputs!');
expect(() => calc.divide(null, 8)).toThrow('Invalid inputs!');
expect(() => calc.multiply(8)).toThrow('Invalid inputs!');
expect(() => calc.multiply(null, 8)).toThrow('Invalid inputs!');
});
test ('Function throws error on non-Number input', () => {
expect(() => calc.add('string', [8])).toThrow('Invalid inputs!');
expect(() => calc.subtract('string', [8])).toThrow('Invalid inputs!');
expect(() => calc.divide('string', [8])).toThrow('Invalid inputs!');
expect(() => calc.multiply('string', [8])).toThrow('Invalid inputs!');
});
test ('Function returns numeric value', () => {
expect(calc.add(1, 2)).toEqual(expect.any(Number));
expect(calc.subtract(1, 2)).toEqual(expect.any(Number));
expect(calc.divide(1, 2)).toEqual(expect.any(Number));
expect(calc.multiply(1, 2)).toEqual(expect.any(Number));
});
test ('Add function returns sum of values', () => {
expect(calc.add(2, 2)).toBe(4);
expect(calc.add(1315201, 5352396)).toBe(1315201 + 5352396);
});
test ('Subtract function returns difference of values', () => {
expect(calc.subtract(30, 5)).toBe(25);
expect(calc.subtract(1415153, 241512)).toBe(1415153 - 241512);
});
test ('Divide function returns quotient of values', () => {
expect(calc.divide(6, 3)).toBe(2);
expect(calc.divide(25, 5)).toBe(5);
});
test ('Multiplication function returns product of values', () => {
expect(calc.multiply(4, 4)).toBe(16);
expect(calc.multiply(2251825, 55125)).toBe(2251825 * 55125);
});

10
src/capitalize.js Normal file
View file

@ -0,0 +1,10 @@
// capitalize function that takes a string and returns it with the first character capitalized
export const capitalize = (input) => {
// if the input type is not a string, throw error
if (typeof input != 'string') throw new Error('Input is not a string!');
// if the input is an empty string, throw error
if (input === '') throw new Error('Input string is empty!');
// regex for lowercase first character and replace if so with upper case equivalent then return output string
const output = input.replace(/^[a-z]/i, input.at(0).toUpperCase());
return output;
}

15
src/capitalize.test.js Normal file
View file

@ -0,0 +1,15 @@
import { capitalize } from "./capitalize.js";
// capitalize function that takes a string and returns it with the first character capitalized
test ('Function throws error on non-String input', () => {
expect(() => capitalize([8])).toThrow('Input is not a string!');
});
test ('Function throws error on invalid String input', () => {
expect(() => capitalize('')).toThrow('Input string is empty!');
});
test ('Function returns String when passed valid input String', () => {
expect(capitalize('string')).toEqual(expect.any(String));
});
test ('Function capitalizes first character of passed String', () => {
expect(capitalize('test')).toBe('Test');
});

14
src/reverseString.js Normal file
View file

@ -0,0 +1,14 @@
// reverseString function that takes a string and returns it reversed
export const reverseString = (input) => {
// if the input type is not a string, throw error
if (typeof input != 'string') throw new Error('Input is not a string!');
// if the input is an empty string, throw error
if (input === '') throw new Error('Input string is empty!');
// loop through string and output value
let output = '';
// start at the end and append each char to new string, then return
for (let i = input.length - 1; i >= 0; i--) {
output += input.at(i);
}
return output;
}

19
src/reverseString.test.js Normal file
View file

@ -0,0 +1,19 @@
import { reverseString } from "./reverseString.js";
// reverseString function that takes a string and returns it reversed
test ('Function throws error on non-String input', () => {
expect(() => reverseString([8])).toThrow('Input is not a string!');
});
test ('Function throws error on invalid String input', () => {
expect(() => reverseString('')).toThrow('Input string is empty!');
});
test ('Function returns String when passed valid input String', () => {
expect(reverseString('string')).toEqual(expect.any(String));
});
test ('Function modifies input String', () => {
expect(reverseString('string')).not.toBe('string');
});
test ('Function returns reverse value of current String', () => {
expect(reverseString('string')).toBe('gnirts');
expect(reverseString('backWards')).toBe('sdraWkcab');
});