fully working functions and tests
This commit is contained in:
parent
4f780ecdb1
commit
7dbec26588
14 changed files with 5983 additions and 0 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
node_modules
|
||||||
|
.eslint*
|
||||||
|
.prettier*
|
||||||
3
babel.config.js
Normal file
3
babel.config.js
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = {
|
||||||
|
presets: [['@babel/preset-env', {targets: {node: 'current'}}]],
|
||||||
|
};
|
||||||
5698
package-lock.json
generated
Normal file
5698
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
22
package.json
Normal file
22
package.json
Normal 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
17
src/analyzeArray.js
Normal 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
23
src/analyzeArray.test.js
Normal 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
55
src/caesarCipher.js
Normal 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
31
src/caesarCipher.test.js
Normal 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
31
src/calculator.js
Normal 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
42
src/calculator.test.js
Normal 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
10
src/capitalize.js
Normal 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
15
src/capitalize.test.js
Normal 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
14
src/reverseString.js
Normal 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
19
src/reverseString.test.js
Normal 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');
|
||||||
|
});
|
||||||
Loading…
Add table
Reference in a new issue