diff --git a/index.js b/index.js index 3204526..b983a17 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,7 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.random = +exports.table = + exports.random = exports.min = exports.max = exports.divide = @@ -11,12 +12,13 @@ exports.random = exports.fromRoman = exports.toRoman = exports.isRoman = + exports.validateGeneral = exports.getCount = void 0; /** * Returns the number of times an element occurs in an array * @param { string[] } array Array to be checked - * @param { string | number } value string or number to be counted + * @param { string } value string to be counted * @return { number } Count of value in an array */ function getCount(array, value) { @@ -29,6 +31,29 @@ function getCount(array, value) { return count; } exports.getCount = getCount; +/** + * Centralized validation for general inputs + * @param input { general } Input to be validated + * @returns { number } Validated number + * @throws { Error } When the input is invalid or out of range + */ +function validateGeneral(input) { + let result = 0; + if (typeof input === "string") { + if (isRoman(input)) { + result = fromRoman(input); + } + } else if (typeof input === "number") { + result = input; + } else { + throw new Error("Input must be a string or number"); + } + if (result > 3999 || result <= 0) { + throw new Error("Value must be between 1 and 3999"); + } + return result; +} +exports.validateGeneral = validateGeneral; /** * Confirm that string is a valid roman numeral * @param { string } value String to be tested @@ -243,6 +268,9 @@ function sum(expected, ...args) { if (isRoman(numeral) === true) { sum += fromRoman(numeral); } + if (sum > 3999) { + throw new Error("Result exceeds maximum value of 3999"); + } }); return expected === "number" ? sum : toRoman(sum); } @@ -262,6 +290,9 @@ function diff(expected, numerals) { if (isRoman(numerals[0]) && isRoman(numerals[1])) { sum = Math.abs(fromRoman(numerals[0]) - fromRoman(numerals[1])); } + if (sum < 1) { + throw new Error("Result is less than minimum value of 1"); + } return expected === "number" ? sum : toRoman(sum); } exports.diff = diff; @@ -278,45 +309,9 @@ function range(end, start = "I", intervals = "I") { let startNum = 1; let diffNum = 1; let ranged = []; - // Validate end value - if (typeof end === "string") { - if (isRoman(end)) { - endNum = fromRoman(end); - } - } else if (typeof end === "number") { - if (end >= 4000 || end <= 0) { - throw new Error("Range has to be between 1 and 3999"); - } - endNum = end; - } else { - throw new Error("End value must be a string or number"); - } - // Validate start value - if (start && typeof start === "string") { - if (isRoman(start)) { - startNum = fromRoman(start); - } - } else if (start && typeof start === "number") { - if (start >= 4000 || start <= 0) { - throw new Error("Range has to be between 1 and 3999"); - } - startNum = start; - } else { - throw new Error("Start value must be a string or number"); - } - // Validate interval value - if (intervals && typeof intervals === "string") { - if (isRoman(intervals)) { - diffNum = fromRoman(intervals); - } - } else if (intervals && typeof intervals === "number") { - if (intervals >= 4000 || intervals <= 0) { - throw new Error("Range has to be between 1 and 3999"); - } - diffNum = intervals; - } else { - throw new Error("Start value must be a string or number"); - } + endNum = validateGeneral(end); + startNum = validateGeneral(start); + diffNum = validateGeneral(intervals); for (let i = startNum; i < endNum + 1; i += diffNum) { ranged.push(toRoman(i)); } @@ -333,10 +328,9 @@ exports.range = range; function multiply(expected, ...args) { let product = 1; for (let i = 0; i < args.length; i++) { - if (isRoman(args[i]) !== true) { - throw new Error(`Invalid Roman numeral: ${args[i]}`); + if (isRoman(args[i])) { + product *= fromRoman(args[i]); } - product *= fromRoman(args[i]); if (product > 3999) { throw new Error("Result exceeds maximum value of 3999"); } @@ -362,31 +356,41 @@ function divide(expected, numerals) { return expected === "number" ? quotient : toRoman(quotient); } exports.divide = divide; +/** + * Get maximum roman numeral from a list + * @param args { string[] } Roman numerals to compare + * @returns { string } Maximum roman numeral + * @throws { Error } When an invalid numeral is provided + */ function max(...args) { let maxNum = 0; for (let i = 0; i < args.length; i++) { let currentNum = args[i]; - if (isRoman(currentNum) !== true) { - throw new Error(`Invalid Roman numeral: ${args[i]}`); - } - let currentRomanNum = fromRoman(currentNum); - if (currentRomanNum > maxNum) { - maxNum = currentRomanNum; + if (isRoman(currentNum)) { + let currentRomanNum = fromRoman(currentNum); + if (currentRomanNum > maxNum) { + maxNum = currentRomanNum; + } } } return toRoman(maxNum); } exports.max = max; +/** + * Get minimum roman numeral from a list + * @param args { string[] } Roman numerals to compare + * @returns { string } Minimum roman numeral + * @throws { Error } When an invalid numeral is provided + */ function min(...args) { let minNum = 4000; for (let i = 0; i < args.length; i++) { let currentNum = args[i]; - if (isRoman(currentNum) !== true) { - throw new Error(`Invalid Roman numeral: ${args[i]}`); - } - let currentRomanNum = fromRoman(currentNum); - if (currentRomanNum < minNum) { - minNum = currentRomanNum; + if (isRoman(currentNum)) { + let currentRomanNum = fromRoman(currentNum); + if (currentRomanNum < minNum) { + minNum = currentRomanNum; + } } } return toRoman(minNum); @@ -402,41 +406,28 @@ exports.min = min; function random(max = 3999, min = 1) { let maxNum = 3999; let minNum = 1; - if (typeof max === "number") { - maxNum = max; - if (maxNum > 3999 || maxNum <= 0) { - throw new Error("Max value must be between 1 and 3999"); - } - } else if (typeof max === "string") { - if (isRoman(max)) { - maxNum = fromRoman(max); - if (maxNum > 3999 || maxNum <= 0) { - throw new Error("Max value must be between 1 and 3999"); - } - } - } else { - throw new Error("Max value must be a number or string"); - } - if (typeof min === "number") { - minNum = min; - if (minNum >= maxNum || minNum <= 0) { - throw new Error( - "Min value must be less than max value and greater than 0" - ); - } - } else if (typeof min === "string") { - if (isRoman(min)) { - minNum = fromRoman(min); - if (minNum >= maxNum || minNum <= 0) { - throw new Error( - "Min value must be less than max value and greater than 0" - ); - } - } - } else { - throw new Error("Min value must be a number or string"); - } + maxNum = validateGeneral(max); + minNum = validateGeneral(min); const randomNum = Math.floor(Math.random() * (maxNum - minNum + 1)) + minNum; return toRoman(randomNum); } exports.random = random; +/** + * Generate a table of Roman numerals within a specified range + * @param start Starting point for table + * @param end Stopping point for table + * @returns { number: number; roman: string }[] Array of objects containing number and its Roman numeral representation + * @throws { Error } When the inputs are invalid or out of range + */ +function table(start, end) { + const result = []; + let startNum = 1; + let endNum = 1; + startNum = validateGeneral(start); + endNum = validateGeneral(end); + for (let i = startNum; i <= endNum; i++) { + result.push({ number: i, roman: toRoman(i) }); + } + return result; +} +exports.table = table; diff --git a/src/index.ts b/src/index.ts index 9281c73..d348852 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,12 +3,12 @@ type general = string | number; /** * Returns the number of times an element occurs in an array * @param { string[] } array Array to be checked - * @param { string | number } value string or number to be counted + * @param { string } value string to be counted * @return { number } Count of value in an array */ export function getCount( array: string[], - value: general + value: string ): number { let count: number = 0; @@ -21,6 +21,32 @@ export function getCount( return count; } +/** + * Centralized validation for general inputs + * @param input { general } Input to be validated + * @returns { number } Validated number + * @throws { Error } When the input is invalid or out of range + */ +export function validateGeneral(input: general): number { + let result: number = 0; + + if (typeof input === "string") { + if (isRoman(input)) { + result = fromRoman(input) as number; + } + } else if (typeof input === "number") { + result = input; + } else { + throw new Error("Input must be a string or number"); + } + + if (result > 3999 || result <= 0) { + throw new Error("Value must be between 1 and 3999"); + } + + return result; +} + /** * Confirm that string is a valid roman numeral * @param { string } value String to be tested @@ -40,7 +66,7 @@ export function isRoman(value: string): true { value = value.toUpperCase(); const letters: string[] = value.split(""); - const romans = [ + const romans: [string, number][] = [ ["M", 4], ["D", 1], ["C", 4], @@ -267,6 +293,10 @@ export function sum( if (isRoman(numeral) === true) { sum += fromRoman(numeral) as number; } + + if (sum > 3999) { + throw new Error("Result exceeds maximum value of 3999"); + } }); return expected === "number" ? sum : toRoman(sum); @@ -295,6 +325,10 @@ export function diff( ); } + if (sum < 1) { + throw new Error("Result is less than minimum value of 1"); + } + return expected === "number" ? sum : toRoman(sum); } @@ -316,50 +350,9 @@ export function range( let diffNum: number = 1; let ranged: string[] = []; - // Validate end value - if (typeof end === "string") { - if (isRoman(end)) { - endNum = fromRoman(end) as number; - } - } else if (typeof end === "number") { - if (end >= 4000 || end <= 0) { - throw new Error("Range has to be between 1 and 3999"); - } - - endNum = end; - } else { - throw new Error("End value must be a string or number"); - } - - // Validate start value - if (start && typeof start === "string") { - if (isRoman(start)) { - startNum = fromRoman(start) as number; - } - } else if (start && typeof start === "number") { - if (start >= 4000 || start <= 0) { - throw new Error("Range has to be between 1 and 3999"); - } - - startNum = start; - } else { - throw new Error("Start value must be a string or number"); - } - - // Validate interval value - if (intervals && typeof intervals === "string") { - if (isRoman(intervals)) { - diffNum = fromRoman(intervals) as number; - } - } else if (intervals && typeof intervals === "number") { - if (intervals >= 4000 || intervals <= 0) { - throw new Error("Range has to be between 1 and 3999"); - } - - diffNum = intervals; - } else { - throw new Error("Start value must be a string or number"); - } + endNum = validateGeneral(end); + startNum = validateGeneral(start); + diffNum = validateGeneral(intervals); for (let i = startNum; i < endNum + 1; i += diffNum) { ranged.push(toRoman(i) as string); @@ -382,12 +375,10 @@ export function multiply( let product = 1; for (let i = 0; i < args.length; i++) { - if (isRoman(args[i]) !== true) { - throw new Error(`Invalid Roman numeral: ${args[i]}`); + if (isRoman(args[i])) { + product *= fromRoman(args[i]) as number; } - product *= fromRoman(args[i]) as number; - if (product > 3999) { throw new Error("Result exceeds maximum value of 3999"); } @@ -422,40 +413,48 @@ export function divide( return expected === "number" ? quotient : toRoman(quotient); } +/** + * Get maximum roman numeral from a list + * @param args { string[] } Roman numerals to compare + * @returns { string } Maximum roman numeral + * @throws { Error } When an invalid numeral is provided + */ export function max(...args: string[]): string { let maxNum: number = 0; for (let i = 0; i < args.length; i++) { let currentNum = args[i]; - if (isRoman(currentNum) !== true) { - throw new Error(`Invalid Roman numeral: ${args[i]}`); - } + if (isRoman(currentNum)) { + let currentRomanNum = fromRoman(currentNum) as number; - let currentRomanNum = fromRoman(currentNum) as number; - - if (currentRomanNum > maxNum) { - maxNum = currentRomanNum; + if (currentRomanNum > maxNum) { + maxNum = currentRomanNum; + } } } return toRoman(maxNum); } +/** + * Get minimum roman numeral from a list + * @param args { string[] } Roman numerals to compare + * @returns { string } Minimum roman numeral + * @throws { Error } When an invalid numeral is provided + */ export function min(...args: string[]): string { let minNum: number = 4000; for (let i = 0; i < args.length; i++) { let currentNum = args[i]; - if (isRoman(currentNum) !== true) { - throw new Error(`Invalid Roman numeral: ${args[i]}`); - } - - let currentRomanNum = fromRoman(currentNum) as number; + if (isRoman(currentNum)) { + let currentRomanNum = fromRoman(currentNum) as number; - if (currentRomanNum < minNum) { - minNum = currentRomanNum; + if (currentRomanNum < minNum) { + minNum = currentRomanNum; + } } } @@ -476,43 +475,35 @@ export function random( let maxNum: number = 3999; let minNum: number = 1; - if (typeof max === "number") { - maxNum = max; + maxNum = validateGeneral(max); + minNum = validateGeneral(min); - if (maxNum > 3999 || maxNum <= 0) { - throw new Error("Max value must be between 1 and 3999"); - } - } else if (typeof max === "string") { - if (isRoman(max)) { - maxNum = fromRoman(max) as number; + const randomNum = Math.floor(Math.random() * (maxNum - minNum + 1)) + minNum; - if (maxNum > 3999 || maxNum <= 0) { - throw new Error("Max value must be between 1 and 3999"); - } - } - } else { - throw new Error("Max value must be a number or string"); - } + return toRoman(randomNum); +} - if (typeof min === "number") { - minNum = min; +/** + * Generate a table of Roman numerals within a specified range + * @param start Starting point for table + * @param end Stopping point for table + * @returns { number: number; roman: string }[] Array of objects containing number and its Roman numeral representation + * @throws { Error } When the inputs are invalid or out of range + */ +export function table( + start: general, + end: general +): { number: number; roman: string }[] { + const result: { number: number; roman: string }[] = []; + let startNum: number = 1; + let endNum: number = 1; - if (minNum >= maxNum || minNum <= 0) { - throw new Error("Min value must be less than max value and greater than 0"); - } - } else if (typeof min === "string") { - if (isRoman(min)) { - minNum = fromRoman(min) as number; + startNum = validateGeneral(start); + endNum = validateGeneral(end); - if (minNum >= maxNum || minNum <= 0) { - throw new Error("Min value must be less than max value and greater than 0"); - } - } - } else { - throw new Error("Min value must be a number or string"); + for (let i = startNum; i <= endNum; i++) { + result.push({number: i, roman: toRoman(i) as string}); } - const randomNum = Math.floor(Math.random() * (maxNum - minNum + 1)) + minNum; - - return toRoman(randomNum); + return result; } diff --git a/src/tests/index.test.ts b/src/tests/index.test.ts index f33d376..da4ab7c 100644 --- a/src/tests/index.test.ts +++ b/src/tests/index.test.ts @@ -9,7 +9,7 @@ import { sum, toRoman, max, - min, random + min, random, table, validateGeneral } from "../index"; describe("getCount", () => { @@ -205,7 +205,7 @@ describe("fromRoman", () => { ); }); -describe("diff", () => { +describe("sum", () => { test("should return X when called with XVIII and VIII", () => { expect(sum("roman", "II", "VIII")).toBe("X"); }); @@ -213,9 +213,18 @@ describe("diff", () => { test("should return 98 when called with III, XXII, LXV and VIII", () => { expect(sum("number", "III", "XXII", "LXV", "VIII")).toBe(98); }); + + test("should throw error when sum exceeds 3999", () => { + try { + sum("roman", "MM", "MM"); + } catch (error) { + // @ts-ignore + expect(error.message).toBe("Result exceeds maximum value of 3999"); + } + }); }); -describe("sum", () => { +describe("diff", () => { test("should return X when called with XVII and VIII", () => { expect(diff("roman", ["XVIII", "VIII"])).toBe("X"); }); @@ -223,6 +232,15 @@ describe("sum", () => { test("should return 98 when called with CXVI and XVIII", () => { expect(diff("number", ["CXVI", "XVIII"])).toBe(98); }); + + test("should throw error when difference is less than 1", () => { + try { + diff("roman", ["X", "X"]); + } catch (error) { + // @ts-ignore + expect(error.message).toBe("Result is less than minimum value of 1"); + } + }); }); describe("range", () => { @@ -259,7 +277,7 @@ describe("multiply", () => { test("should error on any invalid input", () => { try { // @ts-ignore - sum("number", "X", 5); + multiply("number", "X", 5); } catch (error) { // @ts-ignore expect(error.message).toBe( @@ -312,7 +330,7 @@ describe("divide", () => { test("should error on any invalid input", () => { try { // @ts-ignore - sum("number", "X", 5); + divide("number", ["X", 5]); } catch (error) { // @ts-ignore expect(error.message).toBe( @@ -397,7 +415,7 @@ describe("min", () => { ]; test.each(testCases)( - "should return the maximum value from %s", + "should return the minimum value of %s", (expected, inputs) => { expect(min(...inputs)).toBe(expected); } @@ -411,7 +429,7 @@ describe("random", () => { random([43]); } catch (error) { // @ts-ignore - expect(error.message).toBe("Max value must be a number or string"); + expect(error.message).toBe("Input must be a string or number"); } }); @@ -421,7 +439,7 @@ describe("random", () => { random(4897); } catch (error) { // @ts-ignore - expect(error.message).toBe("Max value must be between 1 and 3999"); + expect(error.message).toBe("Value must be between 1 and 3999"); } }); @@ -431,7 +449,7 @@ describe("random", () => { random("MMMM"); } catch (error) { // @ts-ignore - expect(error.message).toBe("Max value must be between 1 and 3999"); + expect(error.message).toBe("Value must be between 1 and 3999"); } }); @@ -451,7 +469,7 @@ describe("random", () => { random(100, {}); } catch (error) { // @ts-ignore - expect(error.message).toBe("Min value must be a number or string"); + expect(error.message).toBe("Input must be a string or number"); } }); @@ -461,7 +479,7 @@ describe("random", () => { random(300, -23); } catch (error) { // @ts-ignore - expect(error.message).toBe("Min value must be less than max value and greater than 0"); + expect(error.message).toBe("Value must be between 1 and 3999"); } }); @@ -471,7 +489,7 @@ describe("random", () => { random(300, "MMMM"); } catch (error) { // @ts-ignore - expect(error.message).toBe("Min value must be less than max value and greater than 0"); + expect(error.message).toBe("Value must be between 1 and 3999"); } }); @@ -503,3 +521,175 @@ describe("random", () => { expect(fromRoman(result)).toBeLessThanOrEqual(3999); }); }); + +describe("table", () => { + test("should throw error on invalid start", () => { + try { + // @ts-ignore + table([43]); + } catch (error) { + // @ts-ignore + expect(error.message).toBe("Input must be a string or number"); + } + }); + + test("should throw error on invalid start (number)", () => { + try { + // @ts-ignore + table(4897); + } catch (error) { + // @ts-ignore + expect(error.message).toBe("Value must be between 1 and 3999"); + } + }); + + test("should throw error on invalid start (roman)", () => { + try { + // @ts-ignore + table("MMMM"); + } catch (error) { + // @ts-ignore + expect(error.message).toBe("Value must be between 1 and 3999"); + } + }); + + test("should throw error on invalid start (roman) II", () => { + try { + // @ts-ignore + table("VIJ"); + } catch (error) { + // @ts-ignore + expect(error.message).toBe("Unexpected token J, expected either X, V or I"); + } + }); + + test("should throw error on invalid end", () => { + try { + // @ts-ignore + table(100, {}); + } catch (error) { + // @ts-ignore + expect(error.message).toBe("Input must be a string or number"); + } + }); + + test("should throw error on invalid end (number)", () => { + try { + // @ts-ignore + table(300, -23); + } catch (error) { + // @ts-ignore + expect(error.message).toBe("Value must be between 1 and 3999"); + } + }); + + test("should throw error on invalid end (roman)", () => { + try { + // @ts-ignore + table(300, "MMMM"); + } catch (error) { + // @ts-ignore + expect(error.message).toBe("Value must be between 1 and 3999"); + } + }); + + test("should throw error on invalid end (roman) II", () => { + try { + // @ts-ignore + table(230, "VIJ"); + } catch (error) { + // @ts-ignore + expect(error.message).toBe("Unexpected token J, expected either X, V or I"); + } + }); + + test("should throw error when start is greater than end", () => { + try { + table("X", "V"); + } catch (error) { + // @ts-ignore + expect(error.message).toBe("Start value must be less than or equal to end value"); + } + }); + + test("should return a table from I to X", () => { + const result = table("I", "x"); + expect(result).toEqual([ + {number: 1, roman: "I"}, + {number: 2, roman: "II"}, + {number: 3, roman: "III"}, + {number: 4, roman: "IV"}, + {number: 5, roman: "V"}, + {number: 6, roman: "VI"}, + {number: 7, roman: "VII"}, + {number: 8, roman: "VIII"}, + {number: 9, roman: "IX"}, + {number: 10, roman: "X"}, + ]); + }); + + test("should return a table from 98 to 114", () => { + const result = table(98, 114); + expect(result).toEqual([ + {number: 98, roman: "XCVIII"}, + {number: 99, roman: "XCIX"}, + {number: 100, roman: "C"}, + {number: 101, roman: "CI"}, + {number: 102, roman: "CII"}, + {number: 103, roman: "CIII"}, + {number: 104, roman: "CIV"}, + {number: 105, roman: "CV"}, + {number: 106, roman: "CVI"}, + {number: 107, roman: "CVII"}, + {number: 108, roman: "CVIII"}, + {number: 109, roman: "CIX"}, + {number: 110, roman: "CX"}, + {number: 111, roman: "CXI"}, + {number: 112, roman: "CXII"}, + {number: 113, roman: "CXIII"}, + {number: 114, roman: "CXIV"}, + ]); + }) +}) + +describe("validateGeneral", () => { + test("should throw error on invalid input", () => { + try { + // @ts-ignore + validateGeneral({}); + } catch (error) { + // @ts-ignore + expect(error.message).toBe("Input must be a string or number"); + } + }); + + test("should throw error on invalid input (number)", () => { + try { + // @ts-ignore + validateGeneral(-23); + } catch (error) { + // @ts-ignore + expect(error.message).toBe("Value must be between 1 and 3999"); + } + }); + + test("should throw error on invalid input (roman)", () => { + try { + // @ts-ignore + validateGeneral("MMMM"); + } catch (error) { + // @ts-ignore + expect(error.message).toBe("Value must be between 1 and 3999"); + } + }); + + test("should throw error on invalid input (roman) II", () => { + try { + // @ts-ignore + validateGeneral("VIJ"); + } catch (error) { + // @ts-ignore + expect(error.message).toBe("Unexpected token J, expected either X, V or I"); + } + }); +}); diff --git a/tests/index.test.js b/tests/index.test.js index fd21976..bd114ea 100644 --- a/tests/index.test.js +++ b/tests/index.test.js @@ -174,21 +174,37 @@ describe("fromRoman", () => { } ); }); -describe("diff", () => { +describe("sum", () => { test("should return X when called with XVIII and VIII", () => { expect((0, index_1.sum)("roman", "II", "VIII")).toBe("X"); }); test("should return 98 when called with III, XXII, LXV and VIII", () => { expect((0, index_1.sum)("number", "III", "XXII", "LXV", "VIII")).toBe(98); }); + test("should throw error when sum exceeds 3999", () => { + try { + (0, index_1.sum)("roman", "MM", "MM"); + } catch (error) { + // @ts-ignore + expect(error.message).toBe("Result exceeds maximum value of 3999"); + } + }); }); -describe("sum", () => { +describe("diff", () => { test("should return X when called with XVII and VIII", () => { expect((0, index_1.diff)("roman", ["XVIII", "VIII"])).toBe("X"); }); test("should return 98 when called with CXVI and XVIII", () => { expect((0, index_1.diff)("number", ["CXVI", "XVIII"])).toBe(98); }); + test("should throw error when difference is less than 1", () => { + try { + (0, index_1.diff)("roman", ["X", "X"]); + } catch (error) { + // @ts-ignore + expect(error.message).toBe("Result is less than minimum value of 1"); + } + }); }); describe("range", () => { test("should return an array of 100 elements when called with C and I", () => { @@ -218,7 +234,7 @@ describe("multiply", () => { test("should error on any invalid input", () => { try { // @ts-ignore - (0, index_1.sum)("number", "X", 5); + (0, index_1.multiply)("number", "X", 5); } catch (error) { // @ts-ignore expect(error.message).toBe("Roman numeral must be of type string"); @@ -261,7 +277,7 @@ describe("divide", () => { test("should error on any invalid input", () => { try { // @ts-ignore - (0, index_1.sum)("number", "X", 5); + (0, index_1.divide)("number", ["X", 5]); } catch (error) { // @ts-ignore expect(error.message).toBe("Roman numeral must be of type string"); @@ -330,7 +346,7 @@ describe("min", () => { ["CCCXL", ["CDXLIV", "CCCXL", "CCCLX", "CDXX"]], ]; test.each(testCases)( - "should return the maximum value from %s", + "should return the minimum value of %s", (expected, inputs) => { expect((0, index_1.min)(...inputs)).toBe(expected); } @@ -343,7 +359,7 @@ describe("random", () => { (0, index_1.random)([43]); } catch (error) { // @ts-ignore - expect(error.message).toBe("Max value must be a number or string"); + expect(error.message).toBe("Input must be a string or number"); } }); test("should throw error on invalid max (number)", () => { @@ -352,7 +368,7 @@ describe("random", () => { (0, index_1.random)(4897); } catch (error) { // @ts-ignore - expect(error.message).toBe("Max value must be between 1 and 3999"); + expect(error.message).toBe("Value must be between 1 and 3999"); } }); test("should throw error on invalid max (roman)", () => { @@ -361,7 +377,7 @@ describe("random", () => { (0, index_1.random)("MMMM"); } catch (error) { // @ts-ignore - expect(error.message).toBe("Max value must be between 1 and 3999"); + expect(error.message).toBe("Value must be between 1 and 3999"); } }); test("should throw error on invalid max (roman) II", () => { @@ -381,7 +397,7 @@ describe("random", () => { (0, index_1.random)(100, {}); } catch (error) { // @ts-ignore - expect(error.message).toBe("Min value must be a number or string"); + expect(error.message).toBe("Input must be a string or number"); } }); test("should throw error on invalid min (number)", () => { @@ -390,9 +406,7 @@ describe("random", () => { (0, index_1.random)(300, -23); } catch (error) { // @ts-ignore - expect(error.message).toBe( - "Min value must be less than max value and greater than 0" - ); + expect(error.message).toBe("Value must be between 1 and 3999"); } }); test("should throw error on invalid min (roman)", () => { @@ -401,9 +415,7 @@ describe("random", () => { (0, index_1.random)(300, "MMMM"); } catch (error) { // @ts-ignore - expect(error.message).toBe( - "Min value must be less than max value and greater than 0" - ); + expect(error.message).toBe("Value must be between 1 and 3999"); } }); test("should throw error on invalid min (roman) II", () => { @@ -433,3 +445,168 @@ describe("random", () => { expect((0, index_1.fromRoman)(result)).toBeLessThanOrEqual(3999); }); }); +describe("table", () => { + test("should throw error on invalid start", () => { + try { + // @ts-ignore + (0, index_1.table)([43]); + } catch (error) { + // @ts-ignore + expect(error.message).toBe("Input must be a string or number"); + } + }); + test("should throw error on invalid start (number)", () => { + try { + // @ts-ignore + (0, index_1.table)(4897); + } catch (error) { + // @ts-ignore + expect(error.message).toBe("Value must be between 1 and 3999"); + } + }); + test("should throw error on invalid start (roman)", () => { + try { + // @ts-ignore + (0, index_1.table)("MMMM"); + } catch (error) { + // @ts-ignore + expect(error.message).toBe("Value must be between 1 and 3999"); + } + }); + test("should throw error on invalid start (roman) II", () => { + try { + // @ts-ignore + (0, index_1.table)("VIJ"); + } catch (error) { + // @ts-ignore + expect(error.message).toBe( + "Unexpected token J, expected either X, V or I" + ); + } + }); + test("should throw error on invalid end", () => { + try { + // @ts-ignore + (0, index_1.table)(100, {}); + } catch (error) { + // @ts-ignore + expect(error.message).toBe("Input must be a string or number"); + } + }); + test("should throw error on invalid end (number)", () => { + try { + // @ts-ignore + (0, index_1.table)(300, -23); + } catch (error) { + // @ts-ignore + expect(error.message).toBe("Value must be between 1 and 3999"); + } + }); + test("should throw error on invalid end (roman)", () => { + try { + // @ts-ignore + (0, index_1.table)(300, "MMMM"); + } catch (error) { + // @ts-ignore + expect(error.message).toBe("Value must be between 1 and 3999"); + } + }); + test("should throw error on invalid end (roman) II", () => { + try { + // @ts-ignore + (0, index_1.table)(230, "VIJ"); + } catch (error) { + // @ts-ignore + expect(error.message).toBe( + "Unexpected token J, expected either X, V or I" + ); + } + }); + test("should throw error when start is greater than end", () => { + try { + (0, index_1.table)("X", "V"); + } catch (error) { + // @ts-ignore + expect(error.message).toBe( + "Start value must be less than or equal to end value" + ); + } + }); + test("should return a table from I to X", () => { + const result = (0, index_1.table)("I", "x"); + expect(result).toEqual([ + { number: 1, roman: "I" }, + { number: 2, roman: "II" }, + { number: 3, roman: "III" }, + { number: 4, roman: "IV" }, + { number: 5, roman: "V" }, + { number: 6, roman: "VI" }, + { number: 7, roman: "VII" }, + { number: 8, roman: "VIII" }, + { number: 9, roman: "IX" }, + { number: 10, roman: "X" }, + ]); + }); + test("should return a table from 98 to 114", () => { + const result = (0, index_1.table)(98, 114); + expect(result).toEqual([ + { number: 98, roman: "XCVIII" }, + { number: 99, roman: "XCIX" }, + { number: 100, roman: "C" }, + { number: 101, roman: "CI" }, + { number: 102, roman: "CII" }, + { number: 103, roman: "CIII" }, + { number: 104, roman: "CIV" }, + { number: 105, roman: "CV" }, + { number: 106, roman: "CVI" }, + { number: 107, roman: "CVII" }, + { number: 108, roman: "CVIII" }, + { number: 109, roman: "CIX" }, + { number: 110, roman: "CX" }, + { number: 111, roman: "CXI" }, + { number: 112, roman: "CXII" }, + { number: 113, roman: "CXIII" }, + { number: 114, roman: "CXIV" }, + ]); + }); +}); +describe("validateGeneral", () => { + test("should throw error on invalid input", () => { + try { + // @ts-ignore + (0, index_1.validateGeneral)({}); + } catch (error) { + // @ts-ignore + expect(error.message).toBe("Input must be a string or number"); + } + }); + test("should throw error on invalid input (number)", () => { + try { + // @ts-ignore + (0, index_1.validateGeneral)(-23); + } catch (error) { + // @ts-ignore + expect(error.message).toBe("Value must be between 1 and 3999"); + } + }); + test("should throw error on invalid input (roman)", () => { + try { + // @ts-ignore + (0, index_1.validateGeneral)("MMMM"); + } catch (error) { + // @ts-ignore + expect(error.message).toBe("Value must be between 1 and 3999"); + } + }); + test("should throw error on invalid input (roman) II", () => { + try { + // @ts-ignore + (0, index_1.validateGeneral)("VIJ"); + } catch (error) { + // @ts-ignore + expect(error.message).toBe( + "Unexpected token J, expected either X, V or I" + ); + } + }); +});