diff --git a/LICENSE b/LICENSE index 034ee1f..9a746c7 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,21 @@ -MIT License - -Copyright (c) 2020 Rob Waller - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +MIT License + +Copyright (c) 2020 Rob Waller + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index 9347a5b..6c37b77 100644 --- a/README.md +++ b/README.md @@ -1,192 +1,233 @@ -[![Actions Status](https://github.com/robdwaller/explicitly/workflows/ci/badge.svg)](https://github.com/robdwaller/explicitly/actions) ![GitHub release (latest by date)](https://img.shields.io/github/v/release/robdwaller/explicitly) ![GitHub](https://img.shields.io/github/license/robdwaller/explicitly) - -# Explicitly - -This library extends the [Deno asserts module](https://github.com/denoland/deno/blob/master/std/testing/asserts.ts) with additional assertions so developers can write more explicit unit tests if they choose to. It works with [Deno Test Tools](https://deno.land/manual/testing) in the same way the built in assertions do. - -The principle behind this library is unit tests should focus on small units of business logic. Assertions should therefore focus on the assertion of basic types in an explicit manner. This library provides assertions which fulfill this requirement and all the assertions are simple and specific which makes the intent of a unit test clearer. - -For more generalised equality checks, better suited to integration or functional tests, please use the built in [Deno assertions module](https://github.com/denoland/deno/blob/master/std/testing/asserts.ts). - -## Installation - -Before you use this library make sure you have read and understood how to set up [Deno Tests](https://deno.land/manual/testing). - -To install this library and make use of the assertions in your test suite simply add the following import to the test modules which require it. - -```js -import { - assertTrue, - assertFalse, - assertSame, - assertGreater, - assertGreaterOrEqual, - assertLess, - assertLessOrEqual, - assertInstanceOf, - assertTypeOf, - assertDate, - assertDateTime, - assertFloat, - Round -} from "https://deno.land/x/explicitly/mod.ts"; -``` - -## Basic Usage - -This assertion library makes 11 assertion methods available: - -- `assertTrue(actual: unknown): void` -- `assertFalse(actual: unknown): void` -- `assertSame(actual: unknown, expected: unknown): void` -- `assertGreater(actual: unknown, expected: unknown): void` -- `assertGreaterOrEqual(actual: unknown, expected: unknown): void` -- `assertLess(actual: unknown, expected: unknown): void` -- `assertLessOrEqual(actual: unknown, expected: unknown): void` -- `assertInstanceOf(actual: unknown, expected: any): void` -- `assertTypeOf(actual: unknown, expected: string): void` -- `assertDateTime(actual: Date, expected: Date | string): void` -- `assertDate(actual: Date, expected: Date | string): void` -- `assertFloat(actual: number, expected: number, decimals?: number, round?: Round): void` - -Each of these assertions aims to test a single thing. This means unit tests are explicit and clearer to read. - -### Assert True / Assert False Example - -A basic example of when you may wish to assert true or assert false. - -```js -Deno.test("Assert True Example", () => { - function isOlderThanFive(age: number): boolean { - return age >= 5; - } - - assertTrue(isOlderThanFive(6)); - - assertFalse(isOlderThanFive(4)); -}); -``` - -### Assert Same Example - -Provide a simple, strict equality check based on `===`. Will not match two instances of identical objects. - -```js -Deno.test("Assert Same Example", () => { - assertSame(3, 3); - - assertSame("Hello World", "Hello World"); -}); -``` - -### Assert Greater or Less Example - -Assert whether a value is greater, less, greater or equal, less or equal than another value. - -```js -Deno.test("Assert Greater or Less Example", () => { - assertGreater(4, 3); - - assertLess(5, 6); - - assertGreaterOrEqual(11, 10); - - assertGreaterOrEqual(10, 10); - - assertLessOrEqual(20, 21); - - assertLessOrEqual(21, 21); -}); -``` - -### Assert Date and Time Example - -Assert whether a date or date time match. Can assert based on two Date objects or a Date object and a string. - -```js -Deno.test("Assert Date Time Example", () => { - assertDate(new Date("2020/06/15"), new Date("2020/06/15")); - - assertDate(new Date("2020/06/15"), "2020/06/15"); - - assertDateTime(new Date("2020/06/15 08:16:15"), new Date("2020/06/15 08:16:15")); - - assertDateTime(new Date("2020/06/15 08:16:15"), "2020/06/15 08:16:15"); -}); -``` - -### Assert Float - -Assert whether two floats match. You can optionally define how many decimal places the assertion should be made to, along with defining if the check should be to the floor or ceiling. This is done by passing in the `Round` enum, either `Round.Floor` or `Round.Ceiling`. The assertion defaults to floor. - -```js -Deno.test("Assert Float Example", () => { - assertFloat(0.23, 0.23); - - assertFloat(3.46, 3.42, 1); - - assertFloat(11.732, 11.739, 2, Round.Ceiling); -}); -``` - -### Assert Type Of Example - -Assert whether a value is of a particular type. Useful when it's not clear what type a function returns. - -```js -Deno.test("Assert Type Of Example", () => { - assertTypeOf("Hello World", "string"); - - assertTypeOf(4, "number"); -}); -``` - -### Assert Instance Of Example - -A more advanced example of when you may wish to assert an instance of. This is useful when there is a polymorphic relationship between objects. Or if you are following Test Driven Development principles and are creating a new class. - -```js -Deno.test("Assert Instance Of Example", () => { - interface Person { - name: string; - age: number; - location: string; - } - - class Adult implements Person { - name: string; - age: number; - location: string; - - constructor(name: string, age: number, location: string) { - this.name = name; - this.age = age; - this.location = location; - } - } - - class Child implements Person { - name: string; - age: number; - location: string; - - constructor(name: string, age: number, location: string) { - this.name = name; - this.age = age; - this.location = location; - } - } - - function createPerson(name: string, age: number, location: string): Person { - if (age < 18) { - return new Child(name, age, location); - } - - return new Adult(name, age, location); - } - - const jenny = createPerson("Jenny Brown", 12, "US"); - - assertInstanceOf(jenny, Child); -}); +[![Actions Status](https://github.com/robdwaller/explicitly/workflows/ci/badge.svg)](https://github.com/robdwaller/explicitly/actions) ![GitHub release (latest by date)](https://img.shields.io/github/v/release/robdwaller/explicitly) ![GitHub](https://img.shields.io/github/license/robdwaller/explicitly) [![deno doc](https://doc.deno.land/badge.svg)](https://doc.deno.land/https/deno.land/x/explicitly/mod.ts) + +# Explicitly + +This library extends the [Deno asserts module](https://github.com/denoland/deno/blob/master/std/testing/asserts.ts) with additional assertions so developers can write more explicit unit tests if they choose to. It works with [Deno Test Tools](https://deno.land/manual/testing) in the same way the built in assertions do. + +The principle behind this library is unit tests should focus on small units of business logic. Assertions should therefore focus on the assertion of basic types in an explicit manner. This library provides assertions which fulfill this requirement and all the assertions are simple and specific which makes the intent of a unit test clearer. + +For more generalised equality checks, better suited to integration or functional tests, please use the built in [Deno assertions module](https://github.com/denoland/deno/blob/master/std/testing/asserts.ts). + +## Installation + +Before you use this library make sure you have read and understood how to set up [Deno Tests](https://deno.land/manual/testing). + +To install this library and make use of the assertions in your test suite simply add the following import to the test modules which require it. + +```js +import { + assertTrue, + assertFalse, + assertSame, + assertGreater, + assertGreaterOrEqual, + assertLess, + assertLessOrEqual, + assertInstanceOf, + assertTypeOf, + assertDate, + assertDateTime, + assertFloat, + Round +} from "https://deno.land/x/explicitly@0.4.0/mod.ts"; +``` + +## Basic Usage + +This assertion library makes 14 assertion methods available: + +- `assertTrue(actual: unknown): void` +- `assertFalse(actual: unknown): void` +- `assertSame(actual: unknown, expected: unknown): void` +- `assertGreater(actual: unknown, expected: unknown): void` +- `assertGreaterOrEqual(actual: unknown, expected: unknown): void` +- `assertLess(actual: unknown, expected: unknown): void` +- `assertLessOrEqual(actual: unknown, expected: unknown): void` +- `assertInstanceOf(actual: unknown, expected: any): void` +- `assertTypeOf(actual: unknown, expected: string): void` +- `assertDateTime(actual: Date, expected: Date | string): void` +- `assertDate(actual: Date, expected: Date | string): void` +- `assertFloat(actual: number, expected: number, decimals?: number, round?: Round): void` +- `assertNotThrows(actual: Function): void` +- `assertCount(actual: Array, expected: number): void` + +Each of these assertions aims to test a single thing. This means unit tests are explicit and clearer to read. + +### Assert True / Assert False Example + +A basic example of when you may wish to assert true or assert false. + +```js +Deno.test("Assert True Example", () => { + function isOlderThanFive(age: number): boolean { + return age >= 5; + } + + assertTrue(isOlderThanFive(6)); + + assertFalse(isOlderThanFive(4)); +}); +``` + +### Assert Same Example + +Provide a simple, strict equality check based on `===`. Will not match two instances of identical objects. + +```js +Deno.test("Assert Same Example", () => { + assertSame(3, 3); + + assertSame("Hello World", "Hello World"); +}); +``` + +### Assert Greater or Less Example + +Assert whether a value is greater, less, greater or equal, less or equal than another value. + +```js +Deno.test("Assert Greater or Less Example", () => { + assertGreater(4, 3); + + assertLess(5, 6); + + assertGreaterOrEqual(11, 10); + + assertGreaterOrEqual(10, 10); + + assertLessOrEqual(20, 21); + + assertLessOrEqual(21, 21); +}); +``` + +### Assert Date and Time Example + +Assert whether a date or date time match. Can assert based on two Date objects or a Date object and a string. + +```js +Deno.test("Assert Date Time Example", () => { + assertDate(new Date("2020/06/15"), new Date("2020/06/15")); + + assertDate(new Date("2020/06/15"), "2020/06/15"); + + assertDateTime(new Date("2020/06/15 08:16:15"), new Date("2020/06/15 08:16:15")); + + assertDateTime(new Date("2020/06/15 08:16:15"), "2020/06/15 08:16:15"); +}); +``` + +### Assert Float + +Assert whether two floats match. You can optionally define how many decimal places the assertion should be made to, along with defining if the check should be to the floor or ceiling. This is done by passing in the `Round` enum, either `Round.Floor` or `Round.Ceiling`. The assertion defaults to floor. + +```js +Deno.test("Assert Float Example", () => { + assertFloat(0.23, 0.23); + + assertFloat(3.46, 3.42, 1); + + assertFloat(11.732, 11.739, 2, Round.Ceiling); +}); +``` + +### Assert Count + +Assert whether an array has an expected number of elements. Will only count top level elements +will count nested elements as a single element. + +```js +Deno.test("Assert Count Example", () => { + const strings = ["Hello", "World"] + + assertCount(strings, 2); + + const numbers = [1, 2, [4, 5], 6]; + + assertCount(numbers, 4); +}); +``` + +### Assert Not Throws + +Assert a function does not throw an Error. This assertion may be of use when testing complicated legacy code when you want to ensure no errors occur. + +```js +Deno.test("Assert Not Throws Example", () => { + const myFunc = () => true; + + assertNotThrows(myFunc); + + function canThrow(count: number): string { + if (count > 5) { + throw new Error("Oh No!"); + } + + return "Ok"; + } + + assertNotThrows(() => canThrow(4)); +}); +``` + +### Assert Type Of Example + +Assert whether a value is of a particular type. Useful when it's not clear what type a function returns. + +```js +Deno.test("Assert Type Of Example", () => { + assertTypeOf("Hello World", "string"); + + assertTypeOf(4, "number"); +}); +``` + +### Assert Instance Of Example + +A more advanced example of when you may wish to assert an instance of. This is useful when there is a polymorphic relationship between objects. Or if you are following Test Driven Development principles and are creating a new class. + +```js +Deno.test("Assert Instance Of Example", () => { + interface Person { + name: string; + age: number; + location: string; + } + + class Adult implements Person { + name: string; + age: number; + location: string; + + constructor(name: string, age: number, location: string) { + this.name = name; + this.age = age; + this.location = location; + } + } + + class Child implements Person { + name: string; + age: number; + location: string; + + constructor(name: string, age: number, location: string) { + this.name = name; + this.age = age; + this.location = location; + } + } + + function createPerson(name: string, age: number, location: string): Person { + if (age < 18) { + return new Child(name, age, location); + } + + return new Adult(name, age, location); + } + + const jenny = createPerson("Jenny Brown", 12, "US"); + + assertInstanceOf(jenny, Child); +}); ``` \ No newline at end of file diff --git a/deps.ts b/deps.ts index 8ccacdb..53f6593 100644 --- a/deps.ts +++ b/deps.ts @@ -5,4 +5,4 @@ export { red, green, } from "https://deno.land/std@0.59.0/fmt/colors.ts"; -export { Result, ok, err } from "https://deno.land/x/resulty@0.2.0/mod.ts"; +export { Result, ok, err } from "https://deno.land/x/resulty@0.3.1/mod.ts"; diff --git a/dev_deps.ts b/dev_deps.ts index c8239c3..3ee5872 100644 --- a/dev_deps.ts +++ b/dev_deps.ts @@ -6,4 +6,4 @@ export { red, green, } from "https://deno.land/std@0.59.0/fmt/colors.ts"; -export { Result } from "https://deno.land/x/resulty@0.2.0/mod.ts"; +export { Result } from "https://deno.land/x/resulty@0.3.1/mod.ts"; diff --git a/egg.json b/egg.json new file mode 100644 index 0000000..92702db --- /dev/null +++ b/egg.json @@ -0,0 +1,14 @@ +{ + "name": "explicitly", + "description": "Additional assertions for Deno so developers can write more explicit unit tests.", + "stable": false, + "version": "0.4.0", + "entry": "./mod.ts", + "repository": "https://github.com/robdwaller/explicitly", + "files": [ + "./mod.ts", + "README.md", + "./src/**/*", + "./LICENSE.md" + ] +} \ No newline at end of file diff --git a/mod.ts b/mod.ts index e4e06a4..276dbf4 100644 --- a/mod.ts +++ b/mod.ts @@ -6,6 +6,7 @@ import { lessOrEqual, instanceOf, typeOf, + count, } from "./src/equality.ts"; import { dateTime, @@ -18,51 +19,94 @@ import { ceiling, Round, } from "./src/float.ts"; +import { notThrows } from "./src/throws.ts"; export { Round } from "./src/float.ts"; import { Result, AssertionError } from "./deps.ts"; +/** + * Deno test tools require an AssertionError to be thrown on error. If the + * result of the equality check is false throw an error with the unwrapped error + * message included. + */ function handleError(result: Result): void { if (result.isError()) { - throw new AssertionError(result.unwrap()); + throw new AssertionError(result.unwrapErr()); } } +/** + * Assert the provided value is equal to true. + */ export function assertTrue(actual: unknown): void { handleError(equals(actual, true)); } +/** + * Assert the provided value is equal to false. + */ export function assertFalse(actual: unknown): void { handleError(equals(actual, false)); } +/** + * Assert the provided values have the same value and type. + */ export function assertSame(actual: unknown, expected: unknown): void { handleError(equals(actual, expected)); } +/** + * Assert the actual value is greater in value or length than the + * expected value. + */ export function assertGreater(actual: unknown, expected: unknown): void { handleError(greater(actual, expected)); } +/** + * Assert the actual value is greater or equal in value or length to the + * expected value. + */ export function assertGreaterOrEqual(actual: unknown, expected: unknown): void { handleError(greaterOrEqual(actual, expected)); } +/** + * Assert the actual value is less in value or length than the + * expected value. + */ export function assertLess(actual: unknown, expected: unknown): void { handleError(less(actual, expected)); } +/** + * Assert the actual value is less or equal in value or length to the + * expected value. + */ export function assertLessOrEqual(actual: unknown, expected: unknown): void { handleError(lessOrEqual(actual, expected)); } +/** + * Assert the actual value is an instance of the expected type. Useful when + * checking polymorphic relationships. + */ export function assertInstanceOf(actual: unknown, expected: any): void { handleError(instanceOf(actual, expected)); } +/** + * Assert the actual value is of a specific type. Useful when a method returns + * a value of any or unknown. + */ export function assertTypeOf(actual: unknown, expected: string): void { handleError(typeOf(actual, expected)); } +/** + * Assert a date object has the same date time as another date object or a + * date time string. + */ export function assertDateTime(actual: Date, expected: Date | string): void { if (typeof expected === "string") { handleError(dateTimeString(actual, expected)); @@ -71,6 +115,10 @@ export function assertDateTime(actual: Date, expected: Date | string): void { } } +/** + * Assert a date object has the same date as another date object or a + * date string. + */ export function assertDate(actual: Date, expected: Date | string): void { if (typeof expected === "string") { handleError(dateString(actual, expected)); @@ -79,6 +127,11 @@ export function assertDate(actual: Date, expected: Date | string): void { } } +/** + * Assert whether an actual float equals an expected float. Can define the + * equality accuracy to a number of decimal places and whether it should be + * based on rounding to the floor or ceiling. + */ export function assertFloat( actual: number, expected: number, @@ -93,3 +146,18 @@ export function assertFloat( handleError(equals(actual, expected)); } } + +/** + * Assert whether a function does not throw an error. May be a useful when + * refactoring a codebase. + */ +export function assertNotThrows(actual: Function): void { + handleError(notThrows(actual)); +} + +/** + * Assert an array has a expected number of elements. + */ +export function assertCount(actual: Array, expected: number): void { + handleError(count(actual, expected)); +} diff --git a/src/equality.ts b/src/equality.ts index 8293329..592c567 100644 --- a/src/equality.ts +++ b/src/equality.ts @@ -66,3 +66,11 @@ export function typeOf( return err(errorSimple(actual, expected, "is not a type of")); } + +export function count(actual: Array, expected: number): Result { + if (actual.length === expected) { + return ok(`${actual} has a count of ${expected}`); + } + + return err(errorSimple(actual, expected, "does not have a count of")); +} diff --git a/src/message.ts b/src/message.ts index f2beb6f..9d28d22 100644 --- a/src/message.ts +++ b/src/message.ts @@ -9,7 +9,11 @@ function getValueOrName(value: unknown): string { } if (typeof value === "function") { - return String(value?.name); + if (value.name === undefined || value.name === "") { + return "Function"; + } + + return String(value.name); } return String(value); @@ -42,3 +46,7 @@ export function errorSimple( green(`"${getValueOrName(expected)}".`), ); } + +export function errorMessage(actual: unknown, text: string): string { + return red(`"${getValueOrName(actual)}" ${text}.`); +} diff --git a/src/throws.ts b/src/throws.ts new file mode 100644 index 0000000..1ebb9a9 --- /dev/null +++ b/src/throws.ts @@ -0,0 +1,11 @@ +import { Result, ok, err } from "../deps.ts"; +import { errorMessage } from "./message.ts"; + +export function notThrows(actual: Function): Result { + try { + actual(); + return ok("Function did not throw."); + } catch (e) { + return err(errorMessage(actual, "threw an unexpected Error")); + } +} diff --git a/tests/equality.test.ts b/tests/equality.test.ts index 880fe22..968d4d6 100644 --- a/tests/equality.test.ts +++ b/tests/equality.test.ts @@ -1,5 +1,5 @@ import { Result } from "../dev_deps.ts"; -import { assertTrue } from "../mod.ts"; +import { assertTrue, assertFalse } from "../mod.ts"; import { equals, greater, @@ -8,6 +8,7 @@ import { lessOrEqual, instanceOf, typeOf, + count, } from "../src/equality.ts"; Deno.test("Equals Boolean", () => { @@ -106,3 +107,36 @@ Deno.test("Type Of Fail", () => { assertTrue(result.isError()); }); + +Deno.test("Count", () => { + const result: Result = count(["Hello", "World"], 2); + + assertTrue(result.isOk()); +}); + +Deno.test("Count Fail", () => { + const result: Result = count(["Hello", "World", "Foo"], 2); + + assertFalse(result.isOk()); +}); + +Deno.test("Count Mixed Types", () => { + const result: Result = count(["Hello", 4, "Foo"], 3); + + assertTrue(result.isOk()); +}); + +Deno.test("Count Nested Elements", () => { + const myArray = [ + "Hello", + "World", + ["Foo", "Bar"], + "How", + "Are", + "You", + ]; + + const result: Result = count(myArray, 6); + + assertTrue(result.isOk()); +}); diff --git a/tests/examples.test.ts b/tests/examples.test.ts index 4f8bfd7..8831a04 100644 --- a/tests/examples.test.ts +++ b/tests/examples.test.ts @@ -12,6 +12,8 @@ import { assertInstanceOf, assertFloat, Round, + assertCount, + assertNotThrows, } from "../mod.ts"; Deno.test("Assert True Example", () => { @@ -65,6 +67,32 @@ Deno.test("Assert Float Example", () => { assertFloat(11.732, 11.739, 2, Round.Ceiling); }); +Deno.test("Assert Count Example", () => { + const strings = ["Hello", "World"]; + + assertCount(strings, 2); + + const numbers = [1, 2, [4, 5], 6]; + + assertCount(numbers, 4); +}); + +Deno.test("Assert Not Throws Example", () => { + const myFunc = () => true; + + assertNotThrows(myFunc); + + function canThrow(count: number): string { + if (count > 5) { + throw new Error("Oh No!"); + } + + return "Ok"; + } + + assertNotThrows(() => canThrow(4)); +}); + Deno.test("Assert Type Of Example", () => { assertTypeOf("Hello World", "string"); diff --git a/tests/message.test.ts b/tests/message.test.ts index a38dc34..f81e334 100644 --- a/tests/message.test.ts +++ b/tests/message.test.ts @@ -3,7 +3,7 @@ import { green, } from "../dev_deps.ts"; import { assertSame } from "../mod.ts"; -import { error, errorSimple } from "../src/message.ts"; +import { error, errorSimple, errorMessage } from "../src/message.ts"; Deno.test("Create Message", () => { const actual = error(true, true, "equals"); @@ -50,3 +50,17 @@ Deno.test("Create Simple Message", () => { assertSame(actual, expected); }); + +Deno.test("Create Error Message", () => { + const actual = errorMessage("Hello", "is not a word"); + const expected = red(`"Hello" is not a word.`); + + assertSame(actual, expected); +}); + +Deno.test("Create Error Message With Callback", () => { + const actual = errorMessage(() => {}, "throws an error"); + const expected = red(`"Function" throws an error.`); + + assertSame(actual, expected); +}); diff --git a/tests/mod.test.ts b/tests/mod.test.ts index c875884..9be8954 100644 --- a/tests/mod.test.ts +++ b/tests/mod.test.ts @@ -20,6 +20,8 @@ import { assertDate, assertFloat, Round, + assertNotThrows, + assertCount, } from "../mod.ts"; Deno.test("Assert True", () => { @@ -368,3 +370,39 @@ Deno.test("Assert Float Fail Three Decimals Ceiling", () => { green(`"1.473" type of number`), ); }); + +Deno.test("Assert Not Throws", () => { + assertNotThrows(() => { + return true; + }); +}); + +Deno.test("Assert Not Throws Fail", () => { + assertThrows( + (): void => { + assertNotThrows(() => { + throw new Error("Fail!"); + }); + }, + AssertionError, + red(`"Function" threw an unexpected Error.`), + ); +}); + +Deno.test("Assert Count", () => { + const toCount = ["Hello", "World"]; + + assertCount(toCount, 2); +}); + +Deno.test("Assert Not Throws Fail", () => { + const toCount = ["Hello", "World"]; + + assertThrows( + (): void => { + assertCount(toCount, 3); + }, + AssertionError, + red(`"Array"`) + " does not have a count of " + green(`"3".`), + ); +}); diff --git a/tests/throws.test.ts b/tests/throws.test.ts new file mode 100644 index 0000000..51eb7d1 --- /dev/null +++ b/tests/throws.test.ts @@ -0,0 +1,55 @@ +import { Result } from "../dev_deps.ts"; +import { assertTrue, assertFalse } from "../mod.ts"; +import { notThrows } from "../src/throws.ts"; + +Deno.test("Not Throws", () => { + const toNotThrow = () => { + return "Hello World"; + }; + + const result: Result = notThrows(toNotThrow); + + assertTrue(result.isOk()); +}); + +Deno.test("Not Throws Fail", () => { + const toThrow = () => { + throw new Error("Error!"); + }; + + const result: Result = notThrows(toThrow); + + assertFalse(result.isOk()); +}); + +Deno.test("Not Throws Class", () => { + class AllOk { + ok(): string { + return "Ok"; + } + } + + const allOk = new AllOk(); + + const result: Result = notThrows(() => { + allOk.ok(); + }); + + assertTrue(result.isOk()); +}); + +Deno.test("Not Throws Class Fail", () => { + class NotOk { + notOk(): string { + throw new Error(); + } + } + + const notOk = new NotOk(); + + const result: Result = notThrows(() => { + notOk.notOk(); + }); + + assertFalse(result.isOk()); +});