test(assert): improve test coverage (#4679)

* test(assert): improve test coverage

* chore: format

* chore: lint

* nits

---------

Co-authored-by: Asher Gomez <ashersaupingomez@gmail.com>
This commit is contained in:
Michael Herzner 2024-05-07 02:08:16 +02:00 committed by GitHub
parent 5e99c21210
commit b649680328
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 394 additions and 174 deletions

View File

@ -51,3 +51,11 @@ Deno.test("assertAlmostEquals() throws when special numbers do not match", () =>
'Expected actual: "Infinity" to be close to "NaN"',
);
});
Deno.test("assertAlmostEquals() throws with custom message", () => {
assertThrows(
() => assertAlmostEquals(-Infinity, +Infinity, 1e-17, "CUSTOM MESSAGE"),
AssertionError,
`Expected actual: "-Infinity" to be close to "Infinity": delta "Infinity" is greater than "1e-17": CUSTOM MESSAGE`,
);
});

View File

@ -56,6 +56,23 @@ missing: [
);
});
Deno.test("assertArrayIncludes() throws with custom message", () => {
assertThrows(
() => assertArrayIncludes(["a"], ["b"], "CUSTOM MESSAGE"),
AssertionError,
`
Expected actual: "[
"a",
]" to include: "[
"b",
]": CUSTOM MESSAGE
missing: [
"b",
]
`.trim(),
);
});
// https://github.com/denoland/deno_std/issues/3372
Deno.test("assertArrayIncludes() type-checks failing cases", () => {
// @ts-expect-error 2nd arg - 'string' is not assignable to 'ArrayLikeArg<string>'.

View File

@ -1,6 +1,8 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
import { assertEquals, AssertionError, assertThrows } from "./mod.ts";
import { bold, gray, green, red, stripAnsiCode, yellow } from "@std/fmt/colors";
import { _internals } from "@std/internal";
import { stub } from "@std/testing/mock";
const createHeader = (): string[] => [
"",
@ -151,9 +153,27 @@ Deno.test({
},
});
Deno.test(
"assertEquals() compares objects structurally if one object's constructor is undefined and the other is Object",
() => {
Deno.test({
name: "assertEquals() throws with [Cannot display] if diffing fails",
fn() {
using _ = stub(_internals, "diff", () => {
throw new Error();
});
assertThrows(
() => assertEquals("1", "2"),
AssertionError,
[
"Values are not equal.",
"[Cannot display]",
].join("\n"),
);
},
});
Deno.test({
name:
"assertEquals() compares objects structurally if one object's constructor is undefined and the other is Object",
fn() {
const a = Object.create(null);
a.prop = "test";
const b = {
@ -163,50 +183,56 @@ Deno.test(
assertEquals(a, b);
assertEquals(b, a);
},
);
});
Deno.test("assertEquals() orders diff for differently ordered objects", () => {
assertThrows(
() => {
assertEquals(
{
aaaaaaaaaaaaaaaaaaaaaaaa: 0,
bbbbbbbbbbbbbbbbbbbbbbbb: 0,
ccccccccccccccccccccccc: 0,
},
{
ccccccccccccccccccccccc: 1,
aaaaaaaaaaaaaaaaaaaaaaaa: 0,
bbbbbbbbbbbbbbbbbbbbbbbb: 0,
},
);
},
AssertionError,
`
Deno.test({
name: "assertEquals() orders diff for differently ordered objects",
fn() {
assertThrows(
() => {
assertEquals(
{
aaaaaaaaaaaaaaaaaaaaaaaa: 0,
bbbbbbbbbbbbbbbbbbbbbbbb: 0,
ccccccccccccccccccccccc: 0,
},
{
ccccccccccccccccccccccc: 1,
aaaaaaaaaaaaaaaaaaaaaaaa: 0,
bbbbbbbbbbbbbbbbbbbbbbbb: 0,
},
);
},
AssertionError,
`
{
aaaaaaaaaaaaaaaaaaaaaaaa: 0,
bbbbbbbbbbbbbbbbbbbbbbbb: 0,
- ccccccccccccccccccccccc: 0,
+ ccccccccccccccccccccccc: 1,
}`,
);
);
},
});
Deno.test("assertEquals() matches same Set with object keys", () => {
const data = [
{
id: "_1p7ZED73OF98VbT1SzSkjn",
type: { id: "_ETGENUS" },
name: "Thuja",
friendlyId: "g-thuja",
},
{
id: "_567qzghxZmeQ9pw3q09bd3",
type: { id: "_ETGENUS" },
name: "Pinus",
friendlyId: "g-pinus",
},
];
assertEquals(data, data);
assertEquals(new Set(data), new Set(data));
Deno.test({
name: "assertEquals() matches same Set with object keys",
fn() {
const data = [
{
id: "_1p7ZED73OF98VbT1SzSkjn",
type: { id: "_ETGENUS" },
name: "Thuja",
friendlyId: "g-thuja",
},
{
id: "_567qzghxZmeQ9pw3q09bd3",
type: { id: "_ETGENUS" },
name: "Pinus",
friendlyId: "g-pinus",
},
];
assertEquals(data, data);
assertEquals(new Set(data), new Set(data));
},
});

View File

@ -32,3 +32,11 @@ Deno.test("assertExists() throws when value is null or undefined", () => {
'Expected actual: "null" to not be null or undefined.',
);
});
Deno.test("assertExists() throws with custom message", () => {
assertThrows(
() => assertExists(undefined, "CUSTOM MESSAGE"),
AssertionError,
'Expected actual: "undefined" to not be null or undefined: CUSTOM MESSAGE',
);
});

View File

@ -33,9 +33,9 @@ Deno.test({
// Custom message
assertThrows(
() => assertInstanceOf(new Date(), RegExp, "Custom message"),
() => assertInstanceOf(new Date(), RegExp, "CUSTOM MESSAGE"),
AssertionError,
"Custom message",
"CUSTOM MESSAGE",
);
// Edge cases

View File

@ -34,9 +34,8 @@ export function assertIsError<E extends Error = Error>(
);
}
if (ErrorClass && !(error instanceof ErrorClass)) {
msg = `Expected error to be instance of "${ErrorClass.name}", but was "${
typeof error === "object" ? error?.constructor?.name : "[not an object]"
}"${msgSuffix}`;
msg =
`Expected error to be instance of "${ErrorClass.name}", but was "${error?.constructor?.name}"${msgSuffix}`;
throw new AssertionError(msg);
}
let msgCheck;
@ -54,11 +53,7 @@ export function assertIsError<E extends Error = Error>(
msgMatches instanceof RegExp
? msgMatches.toString()
: JSON.stringify(msgMatches)
}, but got ${
error instanceof Error
? JSON.stringify(error.message)
: '"[not an Error]"' // TODO(kt3k): show more useful information
}${msgSuffix}`;
}, but got ${JSON.stringify(error?.message)}${msgSuffix}`;
throw new AssertionError(msg);
}
}

View File

@ -58,3 +58,17 @@ Deno.test("assertIsError() throws when given value doesn't match regex ", () =>
`Expected error message to include /egg/, but got "Regex test"`,
);
});
Deno.test("assertIsError() throws with custom message", () => {
assertThrows(
() =>
assertIsError(
new CustomError("failed"),
AnotherCustomError,
"fail",
"CUSTOM MESSAGE",
),
AssertionError,
'Expected error to be instance of "AnotherCustomError", but was "CustomError": CUSTOM MESSAGE',
);
});

View File

@ -1,21 +1,28 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
import { assert, AssertionError, assertMatch } from "./mod.ts";
import { assertThrows } from "./assert_throws.ts";
import { AssertionError, assertMatch } from "./mod.ts";
Deno.test("AssertStringMatching", function () {
Deno.test("assertMatch()", () => {
assertMatch("foobar@deno.com", RegExp(/[a-zA-Z]+@[a-zA-Z]+.com/));
});
Deno.test("AssertStringMatchingThrows", function () {
let didThrow = false;
try {
assertMatch("Denosaurus from Jurassic", RegExp(/Raptor/));
} catch (e) {
assert(e instanceof AssertionError);
assert(
e.message ===
`Expected actual: "Denosaurus from Jurassic" to match: "/Raptor/".`,
);
didThrow = true;
}
assert(didThrow);
Deno.test("assertMatch() throws", () => {
assertThrows(
() => assertMatch("Denosaurus from Jurassic", RegExp(/Raptor/)),
AssertionError,
`Expected actual: "Denosaurus from Jurassic" to match: "/Raptor/".`,
);
});
Deno.test("assertMatch() throws with custom message", () => {
assertThrows(
() =>
assertMatch(
"Denosaurus from Jurassic",
RegExp(/Raptor/),
"CUSTOM MESSAGE",
),
AssertionError,
`Expected actual: "Denosaurus from Jurassic" to match: "/Raptor/": CUSTOM MESSAGE`,
);
});

View File

@ -1,28 +1,46 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
import {
assert,
assertEquals,
AssertionError,
assertNotEquals,
} from "./mod.ts";
import { AssertionError, assertNotEquals, assertThrows } from "./mod.ts";
import { stub } from "@std/testing/mock";
Deno.test("NotEquals", function () {
const a = { foo: "bar" };
const b = { bar: "foo" };
assertNotEquals<unknown>(a, b);
Deno.test("assertNotEquals()", () => {
assertNotEquals<unknown>({ foo: "bar" }, { bar: "foo" });
assertNotEquals("Denosaurus", "Tyrannosaurus");
assertNotEquals(
new Date(2019, 0, 3, 4, 20, 1, 10),
new Date(2019, 0, 3, 4, 20, 1, 20),
);
assertNotEquals(new Date("invalid"), new Date(2019, 0, 3, 4, 20, 1, 20));
let didThrow;
try {
assertNotEquals("Raptor", "Raptor");
didThrow = false;
} catch (e) {
assert(e instanceof AssertionError);
didThrow = true;
}
assertEquals(didThrow, true);
});
Deno.test("assertNotEquals() throws", () => {
assertThrows(
() => {
assertNotEquals("foo", "foo");
},
AssertionError,
"Expected actual: foo not to be: foo.",
);
});
Deno.test("assertNotEquals() throws with custom message", () => {
assertThrows(
() => {
assertNotEquals("foo", "foo", "CUSTOM MESSAGE");
},
AssertionError,
"Expected actual: foo not to be: foo: CUSTOM MESSAGE",
);
});
Deno.test("assertNotEquals() throws with [Cannot display]", () => {
using _ = stub(globalThis, "String", () => {
throw new Error();
});
assertThrows(
() => {
assertNotEquals("a", "a");
},
AssertionError,
`Expected actual: [Cannot display] not to be: [Cannot display].`,
);
});

View File

@ -1,11 +1,33 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
import { assertNotInstanceOf } from "./mod.ts";
import { AssertionError, assertNotInstanceOf, assertThrows } from "./mod.ts";
Deno.test({
name: "assertNotInstanceOf",
name: "assertNotInstanceOf()",
fn() {
assertNotInstanceOf("not a number", Number);
assertNotInstanceOf(42, String);
assertNotInstanceOf(new URL("http://example.com"), Boolean);
},
});
Deno.test({
name: "assertNotInstanceOf() throws",
fn() {
assertThrows(
() => assertNotInstanceOf(new Date(), Date),
AssertionError,
'Expected object to not be an instance of "function".',
);
},
});
Deno.test({
name: "assertNotInstanceOf() throws with custom message",
fn() {
assertThrows(
() => assertNotInstanceOf(new Date(), Date, "CUSTOM MESSAGE"),
AssertionError,
'Expected object to not be an instance of "function": CUSTOM MESSAGE',
);
},
});

View File

@ -1,21 +1,27 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
import { assert, AssertionError, assertNotMatch } from "./mod.ts";
import { AssertionError, assertNotMatch, assertThrows } from "./mod.ts";
Deno.test("AssertStringNotMatching", function () {
Deno.test("assertNotMatch()", () => {
assertNotMatch("foobar.deno.com", RegExp(/[a-zA-Z]+@[a-zA-Z]+.com/));
});
Deno.test("AssertStringNotMatchingThrows", function () {
let didThrow = false;
try {
assertNotMatch("Denosaurus from Jurassic", RegExp(/from/));
} catch (e) {
assert(e instanceof AssertionError);
assert(
e.message ===
`Expected actual: "Denosaurus from Jurassic" to not match: "/from/".`,
);
didThrow = true;
}
assert(didThrow);
Deno.test("assertNotMatch() throws", () => {
assertThrows(
() => assertNotMatch("Denosaurus from Jurassic", RegExp(/from/)),
AssertionError,
`Expected actual: "Denosaurus from Jurassic" to not match: "/from/".`,
);
});
Deno.test("assertNotMatch() throws with custom message", () => {
assertThrows(
() =>
assertNotMatch(
"Denosaurus from Jurassic",
RegExp(/from/),
"CUSTOM MESSAGE",
),
AssertionError,
`Expected actual: "Denosaurus from Jurassic" to not match: "/from/": CUSTOM MESSAGE`,
);
});

View File

@ -40,7 +40,7 @@ export function assertObjectMatch(
a === null ? null : `type ${typeof a}`
}`,
);
} else throw err;
}
}
// Filter keys and symbols which are present in both actual and expected
const filtered = {} as loose;

View File

@ -295,7 +295,7 @@ Deno.test("assertObjectMatch() throws assertion error when in the first argument
);
});
Deno.test("assertObjectMatch() throws readable type error for non mapable primative types", () => {
Deno.test("assertObjectMatch() throws readable type error for non mappable primitive types", () => {
assertThrows(
// @ts-expect-error Argument of type 'null' is not assignable to parameter of type 'Record<PropertyKey, any>'
() => assertObjectMatch(null, { foo: 42 }),

View File

@ -81,6 +81,8 @@ export async function assertRejects<E extends Error = Error>(
) {
isPromiseReturned = true;
await possiblePromise;
} else {
throw Error();
}
} catch (error) {
if (!isPromiseReturned) {
@ -89,7 +91,7 @@ export async function assertRejects<E extends Error = Error>(
);
}
if (ErrorClass) {
if (error instanceof Error === false) {
if (!(error instanceof Error)) {
throw new AssertionError(`A non-Error object was rejected${msgSuffix}`);
}
assertIsError(

View File

@ -1,13 +1,13 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
import { assert, assertEquals, AssertionError, assertRejects } from "./mod.ts";
Deno.test("assertRejects with return type", async () => {
Deno.test("assertRejects() with return type", async () => {
await assertRejects(() => {
return Promise.reject(new Error());
});
});
Deno.test("assertRejects with synchronous function that throws", async () => {
Deno.test("assertRejects() with synchronous function that throws", async () => {
await assertRejects(() =>
assertRejects(() => {
throw new Error();
@ -23,7 +23,7 @@ Deno.test("assertRejects with synchronous function that throws", async () => {
);
});
Deno.test("assertRejects with PromiseLike", async () => {
Deno.test("assertRejects() with PromiseLike", async () => {
await assertRejects(
() => ({
then() {
@ -35,7 +35,7 @@ Deno.test("assertRejects with PromiseLike", async () => {
);
});
Deno.test("assertRejects with non-error value rejected and error class", async () => {
Deno.test("assertRejects() with non-error value rejected and error class", async () => {
await assertRejects(
() => {
return assertRejects(
@ -51,7 +51,7 @@ Deno.test("assertRejects with non-error value rejected and error class", async (
);
});
Deno.test("assertRejects with non-error value rejected", async () => {
Deno.test("assertRejects() with non-error value rejected", async () => {
await assertRejects(() => {
return Promise.reject(null);
});
@ -60,7 +60,7 @@ Deno.test("assertRejects with non-error value rejected", async () => {
});
});
Deno.test("assertRejects with error class", async () => {
Deno.test("assertRejects() with error class", async () => {
await assertRejects(
() => {
return Promise.reject(new Error("foo"));
@ -70,7 +70,7 @@ Deno.test("assertRejects with error class", async () => {
);
});
Deno.test("assertRejects resolves with caught error", async () => {
Deno.test("assertRejects() resolves with caught error", async () => {
const error = await assertRejects(
() => {
return Promise.reject(new Error("foo"));
@ -80,7 +80,7 @@ Deno.test("assertRejects resolves with caught error", async () => {
assertEquals(error.message, "foo");
});
Deno.test("Assert Throws Async Parent Error", async () => {
Deno.test("assertRejects() throws async parent error ", async () => {
await assertRejects(
() => {
return Promise.reject(new AssertionError("Fail!"));
@ -91,7 +91,7 @@ Deno.test("Assert Throws Async Parent Error", async () => {
});
Deno.test(
"Assert Throws Async promise rejected with custom Error",
"assertRejects() throws with custom Error",
async () => {
class CustomError extends Error {}
class AnotherCustomError extends Error {}
@ -107,3 +107,32 @@ Deno.test(
);
},
);
Deno.test("assertRejects() throws when no promise is returned", async () => {
await assertRejects(
// @ts-expect-error - testing invalid input
async () => await assertRejects(() => {}),
AssertionError,
"Function throws when expected to reject.",
);
});
Deno.test("assertRejects() throws when the promise doesn't reject", async () => {
await assertRejects(
async () => await assertRejects(async () => await Promise.resolve(42)),
AssertionError,
"Expected function to reject.",
);
});
Deno.test("assertRejects() throws with custom message", async () => {
await assertRejects(
async () =>
await assertRejects(
async () => await Promise.resolve(42),
"CUSTOM MESSAGE",
),
AssertionError,
"Expected function to reject: CUSTOM MESSAGE",
);
});

View File

@ -1,8 +1,28 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
import { AssertionError, assertStrictEquals, assertThrows } from "./mod.ts";
import { _internals } from "@std/internal";
import { stub } from "@std/testing/mock";
Deno.test({
name: "strict types test",
name: "assertStrictEquals()",
fn() {
assertStrictEquals(true, true);
assertStrictEquals(10, 10);
assertStrictEquals("abc", "abc");
assertStrictEquals(NaN, NaN);
const xs = [1, false, "foo"];
const ys = xs;
assertStrictEquals(xs, ys);
const x = { a: 1 };
const y = x;
assertStrictEquals(x, y);
},
});
Deno.test({
name: "assertStrictEquals() types test",
fn() {
const x = { number: 2 };
@ -26,25 +46,7 @@ Deno.test({
});
Deno.test({
name: "strict pass case",
fn() {
assertStrictEquals(true, true);
assertStrictEquals(10, 10);
assertStrictEquals("abc", "abc");
assertStrictEquals(NaN, NaN);
const xs = [1, false, "foo"];
const ys = xs;
assertStrictEquals(xs, ys);
const x = { a: 1 };
const y = x;
assertStrictEquals(x, y);
},
});
Deno.test({
name: "strict failed with structure diff",
name: "assertStrictEquals() throws with structure diff",
fn() {
assertThrows(
() => assertStrictEquals({ a: 1, b: 2 }, { a: 1, c: [3] }),
@ -62,7 +64,7 @@ Deno.test({
});
Deno.test({
name: "strict failed with reference diff",
name: "assertStrictEquals() throws with reference diff",
fn() {
assertThrows(
() => assertStrictEquals({ a: 1, b: 2 }, { a: 1, b: 2 }),
@ -78,7 +80,7 @@ Deno.test({
});
Deno.test({
name: "strict failed with custom msg",
name: "assertStrictEquals() throws with custom message",
fn() {
assertThrows(
() => assertStrictEquals({ a: 1 }, { a: 1 }, "CUSTOM MESSAGE"),
@ -91,3 +93,17 @@ Deno.test({
);
},
});
Deno.test({
name: "assertStrictEquals() throws with [Cannot display] if diffing fails",
fn() {
using _ = stub(_internals, "diff", () => {
throw new Error();
});
assertThrows(
() => assertStrictEquals("1", "2"),
AssertionError,
"\n[Cannot display] + \n\n",
);
},
});

View File

@ -4,9 +4,10 @@ import {
assertEquals,
AssertionError,
assertStringIncludes,
assertThrows,
} from "./mod.ts";
Deno.test("AssertStringIncludes", function () {
Deno.test("assertStringIncludes()", () => {
assertStringIncludes("Denosaurus", "saur");
assertStringIncludes("Denosaurus", "Deno");
assertStringIncludes("Denosaurus", "rus");
@ -21,17 +22,23 @@ Deno.test("AssertStringIncludes", function () {
assertEquals(didThrow, true);
});
Deno.test("AssertStringContainsThrow", function () {
let didThrow = false;
try {
assertStringIncludes("Denosaurus from Jurassic", "Raptor");
} catch (e) {
assert(e instanceof AssertionError);
assert(
e.message ===
`Expected actual: "Denosaurus from Jurassic" to contain: "Raptor".`,
);
didThrow = true;
}
assert(didThrow);
Deno.test("assertStringIncludes() throws", () => {
assertThrows(
() => assertStringIncludes("Denosaurus from Jurassic", "Raptor"),
AssertionError,
`Expected actual: "Denosaurus from Jurassic" to contain: "Raptor".`,
);
});
Deno.test("assertStringIncludes() with custom message", () => {
assertThrows(
() =>
assertStringIncludes(
"Denosaurus from Jurassic",
"Raptor",
"CUSTOM MESSAGE",
),
AssertionError,
`Expected actual: "Denosaurus from Jurassic" to contain: "Raptor": CUSTOM MESSAGE`,
);
});

View File

@ -62,8 +62,8 @@ export function assertThrows<E extends Error = Error>(
if (typeof errorClassOrMsg !== "string") {
if (
errorClassOrMsg === undefined ||
errorClassOrMsg.prototype instanceof Error ||
errorClassOrMsg.prototype === Error.prototype
errorClassOrMsg?.prototype instanceof Error ||
errorClassOrMsg?.prototype === Error.prototype
) {
// deno-lint-ignore no-explicit-any
ErrorClass = errorClassOrMsg as new (...args: any[]) => E;

View File

@ -127,3 +127,34 @@ Deno.test("assertThrows() matches subclass of expected error", () => {
"Fail!",
);
});
Deno.test("assertThrows() throws when input function does not throw", () => {
assertThrows(
() => {
assertThrows(() => {});
},
AssertionError,
"Expected function to throw.",
);
});
Deno.test("assertThrows() throws with custom message", () => {
assertThrows(
() => {
assertThrows(() => {}, "CUSTOM MESSAGE");
},
AssertionError,
"Expected function to throw: CUSTOM MESSAGE",
);
});
Deno.test("assertThrows() throws with custom message and no error class", () => {
assertThrows(
() => {
// @ts-expect-error testing invalid input
assertThrows(() => {}, null, "CUSTOM MESSAGE");
},
AssertionError,
"Expected function to throw: CUSTOM MESSAGE",
);
});

View File

@ -64,10 +64,14 @@ export function equal(c: unknown, d: unknown): boolean {
if (!(a instanceof WeakSet && b instanceof WeakSet)) return false;
throw new TypeError("cannot compare WeakSet instances");
}
if (a instanceof WeakRef || b instanceof WeakRef) {
if (!(a instanceof WeakRef && b instanceof WeakRef)) return false;
return compare(a.deref(), b.deref());
}
if (seen.get(a) === b) {
return true;
}
if (Object.keys(a || {}).length !== Object.keys(b || {}).length) {
if (Object.keys(a).length !== Object.keys(b).length) {
return false;
}
seen.set(a, b);
@ -109,10 +113,6 @@ export function equal(c: unknown, d: unknown): boolean {
return false;
}
}
if (a instanceof WeakRef || b instanceof WeakRef) {
if (!(a instanceof WeakRef && b instanceof WeakRef)) return false;
return compare(a.deref(), b.deref());
}
return true;
}
return false;

View File

@ -1,7 +1,7 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
import { assert, assertFalse, assertThrows, equal } from "./mod.ts";
Deno.test("EqualDifferentZero", () => {
Deno.test("equal() different zero", () => {
assert(equal(0, -0));
assert(equal(0, +0));
assert(equal(+0, -0));
@ -13,7 +13,7 @@ Deno.test("EqualDifferentZero", () => {
assert(equal({ msg: "hello", array: [0] }, { msg: "hello", array: [-0] }));
});
Deno.test("Equal", function () {
Deno.test("equal()", () => {
assert(equal("world", "world"));
assert(!equal("hello", "world"));
assertFalse(equal("hello", "world"));
@ -21,9 +21,13 @@ Deno.test("Equal", function () {
assert(!equal(5, 6));
assertFalse(equal(5, 6));
assert(equal(NaN, NaN));
assert(equal(null, null));
assertFalse(equal(null, undefined));
assert(equal({ hello: "world" }, { hello: "world" }));
assert(!equal({ world: "hello" }, { hello: "world" }));
assertFalse(equal({}, { hello: "world" }));
assertFalse(equal({ world: "hello" }, { hello: "world" }));
assertFalse(equal({ hello: "world", world: "hello" }, { world: "hello" }));
assert(
equal(
{ hello: "world", hi: { there: "everyone" } },
@ -251,7 +255,7 @@ Deno.test("Equal", function () {
);
});
Deno.test("EqualCircular", () => {
Deno.test("equal() circular", () => {
const objA: { prop?: unknown } = {};
objA.prop = objA;
const objB: { prop?: unknown } = {};
@ -264,3 +268,11 @@ Deno.test("EqualCircular", () => {
mapB.set("prop", mapB);
assert(equal(mapA, mapB));
});
Deno.test("equal() WeakMap, WeakRef and WeakSet", () => {
assertThrows(() => equal(new WeakMap(), new WeakMap()));
assertThrows(() => equal(new WeakSet(), new WeakSet()));
assertFalse(equal(new WeakMap(), { constructor: WeakMap }));
assertFalse(equal(new WeakSet(), { constructor: WeakSet }));
assertFalse(equal(new WeakRef({}), { constructor: WeakRef }));
});

View File

@ -1,14 +1,14 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
import { assert, AssertionError, unimplemented } from "./mod.ts";
import { AssertionError, assertThrows, unimplemented } from "./mod.ts";
Deno.test("AssertsUnimplemented", function () {
let didThrow = false;
try {
unimplemented();
} catch (e) {
assert(e instanceof AssertionError);
assert(e.message === "Unimplemented.");
didThrow = true;
}
assert(didThrow);
Deno.test("unimplemented() throws", function () {
assertThrows(() => unimplemented(), AssertionError, "Unimplemented.");
});
Deno.test("unimplemented() throws with custom message", function () {
assertThrows(
() => unimplemented("CUSTOM MESSAGE"),
AssertionError,
"Unimplemented: CUSTOM MESSAGE",
);
});

View File

@ -139,7 +139,7 @@ Deno.test({
});
Deno.test({
name: "assertEquals() throws with given custom messages",
name: "assertEquals() throws with custom message",
fn() {
assertThrows(
() => assertEquals(1, 2, { msg: "CUSTOM MESSAGE" }),

View File

@ -136,7 +136,7 @@ Deno.test({
});
Deno.test({
name: "expect().toEqual() throws with a custom message",
name: "expect().toEqual() throws with custom message",
fn() {
assertThrows(
() => expect(1, "CUSTOM MESSAGE").toEqual(2),

View File

@ -338,7 +338,7 @@ export function diffstr(A: string, B: string): DiffResult<string>[] {
}
// Compute multi-line diff
const diffResult = diff(
const diffResult = _internals.diff(
tokenize(`${unescape(A)}\n`),
tokenize(`${unescape(B)}\n`),
);
@ -369,7 +369,7 @@ export function diffstr(A: string, B: string): DiffResult<string>[] {
tokenize(b?.value ?? "", { wordDiff: true }),
] as [string[], string[]];
if (hasMoreRemovedLines) tokenized.reverse();
tokens = diff(tokenized[0], tokenized[1]);
tokens = _internals.diff(tokenized[0], tokenized[1]);
if (
tokens.some(({ type, value }) =>
type === DiffType.common && value.trim().length
@ -455,3 +455,5 @@ export function buildMessage(
return messages;
}
export const _internals = { diff, diffstr };