Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions packages/core/src/lib/ArrayAssertion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import isDeepEqual from "fast-deep-equal/es6";
import { Assertion } from "./Assertion";
import { UnsupportedOperationError } from "./errors/UnsupportedOperationError";
import { prettify } from "./helpers/messages";
import { deepEquals } from "./helpers/predicates";

import type { Expect } from "./expect";
import type { TypeFactory } from "./helpers/TypeFactories";
Expand Down Expand Up @@ -233,7 +234,7 @@ export class ArrayAssertion<T> extends Assertion<T[]> {
return this.execute({
assertWhen:
this.actual.length === expected.length
&& this.actual.every(value => expected.includes(value)),
&& this.actual.every(item => expected.some(deepEquals(item))),
error,
invertedError,
});
Expand Down Expand Up @@ -262,7 +263,7 @@ export class ArrayAssertion<T> extends Assertion<T[]> {
});

return this.execute({
assertWhen: values.every(value => this.actual.includes(value)),
assertWhen: values.every(value => this.actual.some(deepEquals(value))),
error,
invertedError,
});
Expand Down Expand Up @@ -291,7 +292,7 @@ export class ArrayAssertion<T> extends Assertion<T[]> {
});

return this.execute({
assertWhen: values.some(value => this.actual.includes(value)),
assertWhen: values.some(value => this.actual.some(deepEquals(value))),
error,
invertedError,
});
Expand Down
27 changes: 27 additions & 0 deletions packages/core/src/lib/helpers/predicates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import isDeepEqual from "fast-deep-equal/es6";

import type { Predicate } from "./types";

/**
* Creates a predicate function that checks if a given value is deeply equal
* to the provided `second` value.
*
* @param second - the value to compare against
* @returns a predicate function that takes a `first` value and returns `true`
* if it's deeply equal to `second`, `false` otherwise
*/
export function deepEquals<A, B>(second: B): Predicate<A> {
return first => isDeepEqual(first, second);
}

/**
* Creates a predicate function that checks if a given value is NOT deeply
* equal to the provided `second` value.
*
* @param second - the value to compare against
* @returns a predicate function that takes a `first` value and returns `true`
* if it's NOT deeply equal to `second`, `false` otherwise
*/
export function notDeepEquals<A, B>(second: B): Predicate<A> {
return first => !isDeepEqual(first, second);
}
8 changes: 8 additions & 0 deletions packages/core/src/lib/helpers/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,11 @@ export type Struct = Record<keyof unknown, unknown>;
* @param T an structured object which extends {@link Struct}
*/
export type Entry<T extends Struct> = { [K in keyof T]: [K, T[K]]; }[keyof T];

/**
* Utility type that represents a predicate function, i.e. a function that
* takes a value of type `<T>` and returns a boolean.
*
* @param T the type of the value to be evaluated by the predicate
*/
export type Predicate<T> = (value: T) => boolean;
24 changes: 12 additions & 12 deletions packages/core/test/lib/ArrayAssertion.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,11 @@ describe("[Unit] ArrayAssertion.test.ts", () => {
describe(".toHaveSameMembers", () => {
context("when the array has the same members as the passed array", () => {
it("returns the assertion instance", () => {
const test = new ArrayAssertion([1, 2, 3]);
const test = new ArrayAssertion([1, { x: 2 }, "3"]);

assert.deepStrictEqual(test.toHaveSameMembers([2, 3, 1]), test);
assert.throws(() => test.not.toHaveSameMembers([2, 3, 1]), {
message: "Expected array NOT to have the same members as <[2,3,1]>",
assert.deepStrictEqual(test.toHaveSameMembers([{ x: 2 }, "3", 1]), test);
assert.throws(() => test.not.toHaveSameMembers([{ x: 2 }, "3", 1]), {
message: 'Expected array NOT to have the same members as <[{"x":2},"3",1]>',
name: AssertionError.name,
});
});
Expand Down Expand Up @@ -215,11 +215,11 @@ describe("[Unit] ArrayAssertion.test.ts", () => {
describe(".toContainAll", () => {
context("when the array contains the expected values", () => {
it("returns the assertion instance", () => {
const test = new ArrayAssertion([1, 2, 3, 4, 5]);
const test = new ArrayAssertion([1, 2, { x: 3 }, 4, "5"]);

assert.deepStrictEqual(test.toContainAll(1, 3, 5), test);
assert.throws(() => test.not.toContainAll(1, 3, 5), {
message: "Expected array NOT to contain all the values <1, 3, 5>",
assert.deepStrictEqual(test.toContainAll(1, { x: 3 }, "5"), test);
assert.throws(() => test.not.toContainAll(1, { x: 3 }, "5"), {
message: 'Expected array NOT to contain all the values <1, {"x":3}, "5">',
name: AssertionError.name,
});
});
Expand All @@ -241,11 +241,11 @@ describe("[Unit] ArrayAssertion.test.ts", () => {
describe(".toContainAny", () => {
context("when the array contains one of the expected values", () => {
it("returns the assertion instance", () => {
const test = new ArrayAssertion([1, 2, 3, 4, 5]);
const test = new ArrayAssertion([1, 2, { x: 3 }, 4, 5]);

assert.deepStrictEqual(test.toContainAny(7, 3, 8), test);
assert.throws(() => test.not.toContainAny(7, 3, 8), {
message: "Expected array NOT to contain any of the values <7, 3, 8>",
assert.deepStrictEqual(test.toContainAny(2, 7, { x: 3 }, 8), test);
assert.throws(() => test.not.toContainAny(2, 7, { x: 3 }, 8), {
message: 'Expected array NOT to contain any of the values <2, 7, {"x":3}, 8>',
name: AssertionError.name,
});
});
Expand Down
Loading