729 lines
14 KiB
TypeScript
729 lines
14 KiB
TypeScript
import {
|
|
assert,
|
|
assertEquals,
|
|
} from "https://deno.land/std@0.106.0/testing/asserts.ts";
|
|
import * as mock from "./mock.ts";
|
|
|
|
import {
|
|
MatchResult,
|
|
toBe,
|
|
toBeDefined,
|
|
toBeFalsy,
|
|
toBeGreaterThan,
|
|
toBeInstanceOf,
|
|
toBeLessThan,
|
|
toBeLessThanOrEqual,
|
|
toBeNaN,
|
|
toBeNull,
|
|
toBeTruthy,
|
|
toBeUndefined,
|
|
toContain,
|
|
toEqual,
|
|
toHaveBeenCalled,
|
|
toHaveBeenCalledTimes,
|
|
toHaveBeenCalledWith,
|
|
toHaveBeenLastCalledWith,
|
|
toHaveBeenNthCalledWith,
|
|
toHaveLastReturnedWith,
|
|
toHaveLength,
|
|
toHaveNthReturnedWith,
|
|
toHaveProperty,
|
|
toHaveReturned,
|
|
toHaveReturnedTimes,
|
|
toHaveReturnedWith,
|
|
toMatch,
|
|
toThrow,
|
|
} from "./matchers.ts";
|
|
|
|
function assertResult(actual: MatchResult, expected: MatchResult) {
|
|
assertEquals(
|
|
actual.pass,
|
|
expected.pass,
|
|
`expected to be ${
|
|
expected.pass ? `pass but received: ${actual.message}` : "fail"
|
|
}`,
|
|
);
|
|
if (typeof expected.message !== "undefined") {
|
|
assert(!!actual.message, "no message given");
|
|
const colourless = actual.message.replace(
|
|
/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,
|
|
"",
|
|
);
|
|
const trim = (x: string) => x.trim().replace(/\s*\n\s+/g, "\n");
|
|
|
|
assertEquals(trim(colourless), trim(expected.message));
|
|
}
|
|
}
|
|
|
|
function assertResultPass(result: any) {
|
|
assertResult(result, { pass: true });
|
|
}
|
|
|
|
Deno.test({
|
|
name: "toBePass",
|
|
fn: () => {
|
|
assertResultPass(toBe(10, 10));
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toBeFail",
|
|
fn: () => {
|
|
assertResult(toBe(10, 20), {
|
|
pass: false,
|
|
message: `expect(actual).toBe(expected)
|
|
- 10
|
|
+ 20`,
|
|
});
|
|
|
|
assertResult(toBe({}, {}), {
|
|
pass: false,
|
|
message: `expect(actual).toBe(expected)
|
|
|
|
{}`,
|
|
});
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toEqualPass",
|
|
fn: () => {
|
|
assertResultPass(toEqual({ a: 1 }, { a: 1 }));
|
|
assertResultPass(toEqual(1, 1));
|
|
assertResultPass(toEqual([1], [1]));
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toEqualFail",
|
|
fn: () => {
|
|
assertResult(toEqual(10, 20), {
|
|
pass: false,
|
|
message: `expect(actual).toEqual(expected)\n\n- 10\n+ 20`,
|
|
});
|
|
|
|
assertResult(toEqual({ a: 1 }, { a: 2 }), {
|
|
pass: false,
|
|
message: `expect(actual).toEqual(expected)
|
|
- { a: 1 }
|
|
+ { a: 2 }`,
|
|
});
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toBeGreaterThanPass",
|
|
fn: () => {
|
|
assertResultPass(toBeGreaterThan(2, 1));
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toBeGreaterThanFail",
|
|
fn: () => {
|
|
assertResult(toBeGreaterThan(1, 2), {
|
|
pass: false,
|
|
message: `expect(actual).toBeGreaterThan(expected)
|
|
|
|
1 is not greater than 2`,
|
|
});
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toBeLessThanPass",
|
|
fn: () => {
|
|
assertResultPass(toBeLessThan(1, 2));
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toBeLessThanFail",
|
|
fn: () => {
|
|
assertResult(toBeLessThan(2, 1), {
|
|
pass: false,
|
|
message: `expect(actual).toBeLessThan(expected)
|
|
|
|
2 is not less than 1`,
|
|
});
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toBeLessThanOrEqualPass",
|
|
fn: () => {
|
|
assertResultPass(toBeLessThanOrEqual(1, 2));
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toBeLessThanOrEqualFail",
|
|
fn: () => {
|
|
assertResult(toBeLessThanOrEqual(2, 1), {
|
|
pass: false,
|
|
message: `expect(actual).toBeLessThanOrEqual(expected)
|
|
|
|
2 is not less than or equal to 1`,
|
|
});
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toBeTruthyPass",
|
|
fn: () => {
|
|
assertResultPass(toBeTruthy(1));
|
|
assertResultPass(toBeTruthy(true));
|
|
assertResultPass(toBeTruthy([]));
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toBeTruthyFail",
|
|
fn: () => {
|
|
assertResult(toBeTruthy(false), {
|
|
pass: false,
|
|
message: `expect(actual).toBeTruthy()
|
|
|
|
false is not truthy`,
|
|
});
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toBeFalsyPass",
|
|
fn: () => {
|
|
assertResultPass(toBeFalsy(0));
|
|
assertResultPass(toBeFalsy(false));
|
|
assertResultPass(toBeFalsy(null));
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toBeFalsyFail",
|
|
fn: () => {
|
|
assertResult(toBeFalsy(true), {
|
|
pass: false,
|
|
message: `expect(actual).toBeFalsy()
|
|
|
|
true is not falsy`,
|
|
});
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toBeDefinedPass",
|
|
fn: () => {
|
|
assertResultPass(toBeDefined(1));
|
|
assertResultPass(toBeDefined({}));
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toBeDefinedFail",
|
|
fn: () => {
|
|
assertResult(toBeDefined(undefined), {
|
|
pass: false,
|
|
message: `expect(actual).toBeDefined()
|
|
|
|
undefined is not defined`,
|
|
});
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toBeUndefinedPass",
|
|
fn: () => {
|
|
assertResultPass(toBeUndefined(undefined));
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toBeUndefinedFail",
|
|
fn: () => {
|
|
assertResult(toBeUndefined(null), {
|
|
pass: false,
|
|
message: `expect(actual).toBeUndefined()
|
|
|
|
null is defined but should be undefined`,
|
|
});
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toBeNullPass",
|
|
fn: () => {
|
|
assertResultPass(toBeNull(null));
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toBeNullFail",
|
|
fn: () => {
|
|
assertResult(toBeNull(10), {
|
|
pass: false,
|
|
message: `expect(actual).toBeNull()
|
|
|
|
10 should be null`,
|
|
});
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toBeNaNPass",
|
|
fn: () => {
|
|
assertResultPass(toBeNaN(NaN));
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toBeNaNFail",
|
|
fn: () => {
|
|
assertResult(toBeNaN(10), {
|
|
pass: false,
|
|
message: `expect(actual).toBeNaN()
|
|
|
|
10 should be NaN`,
|
|
});
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toBeInstanceOfPass",
|
|
fn: () => {
|
|
class A {}
|
|
const a = new A();
|
|
assertResultPass(toBeInstanceOf(a, A));
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toBeInstanceOfFail",
|
|
fn: () => {
|
|
class A {}
|
|
class B {}
|
|
|
|
const a = new A();
|
|
|
|
assertResult(toBeInstanceOf(a, B), {
|
|
pass: false,
|
|
message: `expect(actual).toBeInstanceOf(expected)
|
|
|
|
expected B but received A {}`,
|
|
});
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toBeMatchPass",
|
|
fn: () => {
|
|
assertResultPass(toMatch("hello", "hell"));
|
|
assertResultPass(toMatch("hello", /^hell/));
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toBeMatchFail",
|
|
fn: () => {
|
|
assertResult(toMatch("yo", "hell"), {
|
|
pass: false,
|
|
message: `expect(actual).toMatch(expected)
|
|
|
|
expected "yo" to contain "hell"`,
|
|
});
|
|
|
|
assertResult(toMatch("yo", /^hell/), {
|
|
pass: false,
|
|
message: `expect(actual).toMatch(expected)
|
|
|
|
"yo" did not match regex /^hell/`,
|
|
});
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toBeHavePropertyPass",
|
|
fn: () => {
|
|
assertResultPass(toHaveProperty({ a: 1 }, "a"));
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toBeHavePropertyFail",
|
|
fn: () => {
|
|
assertResult(toHaveProperty({ a: 1 }, "b"), {
|
|
pass: false,
|
|
message: `expect(actual).toHaveProperty(expected)
|
|
|
|
{ a: 1 } did not contain property "b"`,
|
|
});
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toHaveLengthPass",
|
|
fn: () => {
|
|
assertResultPass(toHaveLength([], 0));
|
|
assertResultPass(toHaveLength([1, 2], 2));
|
|
assertResultPass(toHaveLength({ length: 2 }, 2));
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toBeHaveLengthFail",
|
|
fn: () => {
|
|
assertResult(toHaveLength([], 1), {
|
|
pass: false,
|
|
message: `expect(actual).toHaveLength(expected)
|
|
|
|
expected array to have length 1 but was 0`,
|
|
});
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toContainPass",
|
|
fn: () => {
|
|
assertResultPass(toContain([1, 2], 2));
|
|
assertResultPass(toContain("Hello", "Hell"));
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toContainFail",
|
|
fn: () => {
|
|
assertResult(toContain([2, 3], 1), {
|
|
pass: false,
|
|
message: `expect(actual).toContain(expected)
|
|
|
|
[ 2, 3 ] did not contain 1`,
|
|
});
|
|
assertResult(toContain("Hello", "Good"), {
|
|
pass: false,
|
|
message: `expect(actual).toContain(expected)
|
|
|
|
"Hello" did not contain "Good"`,
|
|
});
|
|
assertResult(toContain(false, 1), {
|
|
pass: false,
|
|
message: `expect(actual).toContain(expected)
|
|
|
|
expected false to have an includes method but it is 1`,
|
|
});
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toThrowPass",
|
|
fn: () => {
|
|
assertResultPass(
|
|
toThrow(() => {
|
|
throw new Error("TEST");
|
|
}, "TEST"),
|
|
);
|
|
assertResultPass(
|
|
toThrow(() => {
|
|
throw new Error("TEST");
|
|
}, /^TEST/),
|
|
);
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toThrowFail",
|
|
fn: () => {
|
|
assertResult(
|
|
toThrow(() => {}, "TEST"),
|
|
{
|
|
pass: false,
|
|
message: `expect(actual).toThrow(expected)
|
|
|
|
expected [Function] to throw but it did not`,
|
|
},
|
|
);
|
|
|
|
assertResult(
|
|
toThrow(() => {
|
|
throw new Error("BLAH");
|
|
}, "TEST"),
|
|
{
|
|
pass: false,
|
|
message: `expect(actual).toThrow(expected)
|
|
|
|
expected [Function] to throw error matching "TEST" but it threw Error: BLAH`,
|
|
},
|
|
);
|
|
|
|
assertResult(
|
|
toThrow(() => {
|
|
throw new Error("BLAH");
|
|
}, /^TEST/),
|
|
{
|
|
pass: false,
|
|
message: `expect(actual).toThrow(expected)
|
|
|
|
expected [Function] to throw error matching /^TEST/ but it threw Error: BLAH`,
|
|
},
|
|
);
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toHaveBeenCalledPass",
|
|
fn: () => {
|
|
const m = mock.fn();
|
|
m(10);
|
|
assertResultPass(toHaveBeenCalled(m));
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toHaveBeenCalledFail",
|
|
fn: () => {
|
|
const m = mock.fn();
|
|
assertResult(toHaveBeenCalled(m), {
|
|
pass: false,
|
|
message: `expect(actual).toHaveBeenCalled()
|
|
|
|
[Function: f] was not called`,
|
|
});
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toHaveBeenCalledTimesPass",
|
|
fn: () => {
|
|
const m = mock.fn();
|
|
m(10);
|
|
m(12);
|
|
assertResultPass(toHaveBeenCalledTimes(m, 2));
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toHaveBeenCalledTimesFail",
|
|
fn: () => {
|
|
const m = mock.fn();
|
|
m(10);
|
|
assertResult(toHaveBeenCalledTimes(m, 2), {
|
|
pass: false,
|
|
message: `expect(actual).toHaveBeenCalledTimes(expected)
|
|
|
|
expected 2 calls but was called: 1`,
|
|
});
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toHaveBeenCalledWithPass",
|
|
fn: () => {
|
|
const m = mock.fn();
|
|
m(1, "a");
|
|
assertResultPass(toHaveBeenCalledWith(m, 1, "a"));
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toHaveBeenCalledWithFail",
|
|
fn: () => {
|
|
const m = mock.fn();
|
|
m(1, "a");
|
|
assertResult(toHaveBeenCalledWith(m, 2, "b"), {
|
|
pass: false,
|
|
message: `expect(actual).toHaveBeenCalledWith(expected)
|
|
|
|
function was not called with: [ 2, "b" ]`,
|
|
});
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toHaveBeenLastCalledWithPass",
|
|
fn: () => {
|
|
const m = mock.fn();
|
|
m(1, "a");
|
|
m(2, "b");
|
|
m(3, "c");
|
|
assertResultPass(toHaveBeenLastCalledWith(m, 3, "c"));
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toHaveBeenLastCalledWithPass",
|
|
fn: () => {
|
|
const m = mock.fn();
|
|
assertResult(toHaveBeenLastCalledWith(m, 2, "b"), {
|
|
pass: false,
|
|
message: `expect(actual).toHaveBeenLastCalledWith(...expected)
|
|
|
|
expect last call args to be 2,b but was not called`,
|
|
});
|
|
m(1, "a");
|
|
m(2, "b");
|
|
m(3, "c");
|
|
assertResult(toHaveBeenLastCalledWith(m, 2, "b"), {
|
|
pass: false,
|
|
message: `expect(actual).toHaveBeenLastCalledWith(...expected)
|
|
|
|
expect last call args to be 2,b but was: 3,c`,
|
|
});
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toHaveBeenNthCalledWithPass",
|
|
fn: () => {
|
|
const m = mock.fn();
|
|
m(1, "a");
|
|
m(2, "b");
|
|
m(3, "c");
|
|
const nthCall = 2;
|
|
assertResultPass(toHaveBeenNthCalledWith(m, nthCall, 2, "b"));
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toHaveBeenNthCalledWithFail",
|
|
fn: () => {
|
|
const m = mock.fn();
|
|
const nthCall = 3;
|
|
assertResult(toHaveBeenNthCalledWith(m, nthCall, 2, "b"), {
|
|
pass: false,
|
|
message: `expect(actual).toHaveBeenNthCalledWith(expected)
|
|
|
|
3th call was not made.`,
|
|
});
|
|
m(1, "a");
|
|
m(2, "b");
|
|
m(3, "c");
|
|
assertResult(toHaveBeenNthCalledWith(m, nthCall, 2, "b"), {
|
|
pass: false,
|
|
message: `expect(actual).toHaveBeenNthCalledWith(expected)
|
|
|
|
expect 3th call args to be 2,b but was: 3,c`,
|
|
});
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toHaveReturnedWithPass",
|
|
fn: () => {
|
|
const m = mock.fn(() => true);
|
|
m();
|
|
assertResultPass(toHaveReturnedWith(m, true));
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toHaveReturnedWithFail",
|
|
fn: () => {
|
|
const m = mock.fn(() => true);
|
|
m();
|
|
assertResult(toHaveReturnedWith(m, false), {
|
|
pass: false,
|
|
message: `expect(actual).toHaveReturnedWith(expected)
|
|
|
|
function did not return: false`,
|
|
});
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toHaveReturnedPass",
|
|
fn: () => {
|
|
const m = mock.fn(() => true);
|
|
m();
|
|
assertResultPass(toHaveReturned(m));
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toHaveReturnedFail",
|
|
fn: () => {
|
|
const m = mock.fn(() => true);
|
|
assertResult(toHaveReturned(m), {
|
|
pass: false,
|
|
message: `expected function to return but it never did`,
|
|
});
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toHaveLastReturnedWithPass",
|
|
fn: () => {
|
|
const m = mock.fn((arg: boolean) => arg);
|
|
m(false);
|
|
m(true);
|
|
assertResultPass(toHaveLastReturnedWith(m, true));
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toHaveLastReturnedWithFail",
|
|
fn: () => {
|
|
const m = mock.fn((arg: boolean) => arg);
|
|
assertResult(toHaveLastReturnedWith(m, true), {
|
|
pass: false,
|
|
message: `no calls made to function`,
|
|
});
|
|
m(true);
|
|
m(false);
|
|
assertResult(toHaveLastReturnedWith(m, true), {
|
|
pass: false,
|
|
message: `expected last call to return true but returned: false`,
|
|
});
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toHaveReturnedTimesPass",
|
|
fn: () => {
|
|
const m = mock.fn(() => true);
|
|
m();
|
|
m();
|
|
m();
|
|
assertResultPass(toHaveReturnedTimes(m, 3));
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toHaveReturnedTimesFail",
|
|
fn: () => {
|
|
const m = mock.fn(() => true);
|
|
m();
|
|
assertResult(toHaveReturnedTimes(m, 3), {
|
|
pass: false,
|
|
message: `expected 3 returned times but returned 1 times`,
|
|
});
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toHaveNthReturnedWithPass",
|
|
fn: () => {
|
|
const m = mock.fn((n: number) => n);
|
|
m(1);
|
|
m(2);
|
|
m(3);
|
|
const nthCall = 2;
|
|
assertResultPass(toHaveNthReturnedWith(m, nthCall, 2));
|
|
},
|
|
});
|
|
|
|
Deno.test({
|
|
name: "toHaveNthReturnedWithFail",
|
|
fn: () => {
|
|
const m = mock.fn((n: number) => n);
|
|
m(1);
|
|
m(2);
|
|
m(3);
|
|
assertResult(toHaveNthReturnedWith(m, 2, 1), {
|
|
pass: false,
|
|
message: `expected 2th call to return 1 but returned: 2`,
|
|
});
|
|
assertResult(toHaveNthReturnedWith(m, 9, 1), {
|
|
pass: false,
|
|
message: `9 calls were now made`,
|
|
});
|
|
},
|
|
});
|