Skip to content

Commit

Permalink
Merge pull request #4 from ValeriaVG/fix/expect-match-object
Browse files Browse the repository at this point in the history
fix: expect toMatchObject should properly handle arrays
  • Loading branch information
ValeriaVG authored Oct 28, 2021
2 parents a8612fb + 7d4d4ec commit c789755
Show file tree
Hide file tree
Showing 9 changed files with 129 additions and 81 deletions.
2 changes: 1 addition & 1 deletion dist/Test.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export declare type TestResult = {
};
export declare type FixtureFn = () => Promise<void> | void;
export default class Test {
title?: string;
title: string;
suite: {
title: string;
fn?: Function;
Expand Down
2 changes: 1 addition & 1 deletion dist/Test.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class Test {
this.after = (fn) => {
this._after.push(fn);
};
this.title = title;
this.title = title !== null && title !== void 0 ? title : "";
}
}
exports.default = Test;
2 changes: 1 addition & 1 deletion dist/bundle.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion dist/expect.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,13 @@ const matchers = {
return actual ? `Expected ${JSON.stringify(actual)} to be falsy` : false;
},
toMatchObject: (actual, expected) => {
const error = `${JSON.stringify(actual)} does not match ${JSON.stringify(expected)}`;
if (typeof actual !== typeof expected ||
Array.isArray(actual) !== Array.isArray(expected))
return error;
for (let key in expected) {
if (typeof actual[key] !== typeof expected[key])
return `Types mismatch for ${key}: ${typeof actual[key]} != ${typeof expected[key]}`;
return `${error}:\nTypes mismatch for ${key}: ${typeof actual[key]} != ${typeof expected[key]}`;
if (typeof expected[key] !== "object") {
const res = matchers.toBe(actual[key], expected[key]);
if (res)
Expand Down
155 changes: 82 additions & 73 deletions dist/mod.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,76 @@
export type TestResult = {
title: string;
skipped?: boolean;
passed?: boolean;
error?: Error;
};

export type FixtureFn = () => Promise<void> | void;
export class Test {
title: string;
suite: { title: string; fn?: Function }[] = [];
// Stores last results
results: TestResult[] = [];
private _before: FixtureFn[] = [];
private _after: FixtureFn[] = [];
constructor(title?: string) {
this.title = title ?? "";
}
it = (title: string, fn?: Function) => {
this.suite.push({ title, fn });
};
xit = (title: string, _fn?: Function) => {
this.suite.push({ title });
};
run = async () => {
this.results = [];
try {
await Promise.all(this._before.map((fn) => fn()));
} catch (error) {
return [{ title: this.title, error, passed: false }];
}
for (let test of this.suite) {
if (!test.fn) {
this.results.push({ title: test.title, skipped: true });
continue;
}
try {
await test.fn();
this.results.push({ title: test.title, passed: true });
} catch (error) {
this.results.push({ title: test.title, error, passed: false });
}
}
try {
await Promise.all(this._after.map((fn) => fn()));
} catch (error) {
console.error(error);
}
return this.results;
};
before = (fn: FixtureFn) => {
this._before.push(fn);
};
after = (fn: FixtureFn) => {
this._after.push(fn);
};
}

export function prettify(testResults: TestResult[]) {
testResults.forEach(({ title, passed, skipped, error }) => {
if (passed) return console.info("\x1b[32m", `✓ ${title}`);
if (skipped) return console.info("\x1b[33m", `□ ${title}`);
if (!passed)
return console.error(
"\x1b[31m",
`𐄂 ${title}`,
"\n Failed:",
error!.message
);
});
console.log("\x1b[0m");
}

export class ExpectationError extends Error {
extensions: { matcher: string; expected: any; actual: any };
constructor(matcher: string, expected: any, actual: any, diff: string) {
Expand Down Expand Up @@ -39,9 +112,17 @@ const matchers: Record<keyof Expectations, Matcher> = {
return actual ? `Expected ${JSON.stringify(actual)} to be falsy` : false;
},
toMatchObject: (actual: any, expected: any): string | false => {
const error = `${JSON.stringify(actual)} does not match ${JSON.stringify(
expected
)}`;
if (
typeof actual !== typeof expected ||
Array.isArray(actual) !== Array.isArray(expected)
)
return error;
for (let key in expected) {
if (typeof actual[key] !== typeof expected[key])
return `Types mismatch for ${key}: ${typeof actual[
return `${error}:\nTypes mismatch for ${key}: ${typeof actual[
key
]} != ${typeof expected[key]}`;
if (typeof expected[key] !== "object") {
Expand Down Expand Up @@ -102,75 +183,3 @@ export function expect(actual: any): Expectations & { not: Expectations } {
});
return expectation;
}

export function prettify(testResults: TestResult[]) {
testResults.forEach(({ title, passed, skipped, error }) => {
if (passed) return console.info("\x1b[32m", `✓ ${title}`);
if (skipped) return console.info("\x1b[33m", `□ ${title}`);
if (!passed)
return console.error(
"\x1b[31m",
`𐄂 ${title}`,
"\n Failed:",
error!.message
);
});
console.log("\x1b[0m");
}

export type TestResult = {
title: string;
skipped?: boolean;
passed?: boolean;
error?: Error;
};
export type FixtureFn = () => Promise<void> | void;
export class Test {
title: string;
suite: { title: string; fn?: Function }[] = [];
// Stores last results
results: TestResult[] = [];
private _before: FixtureFn[] = [];
private _after: FixtureFn[] = [];
constructor(title?: string) {
this.title = title ?? "";
}
it = (title: string, fn?: Function) => {
this.suite.push({ title, fn });
};
xit = (title: string, _fn?: Function) => {
this.suite.push({ title });
};
run = async () => {
this.results = [];
try {
await Promise.all(this._before.map((fn) => fn()));
} catch (error) {
return [{ title: this.title, error, passed: false }];
}
for (let test of this.suite) {
if (!test.fn) {
this.results.push({ title: test.title, skipped: true });
continue;
}
try {
await test.fn();
this.results.push({ title: test.title, passed: true });
} catch (error) {
this.results.push({ title: test.title, error, passed: false });
}
}
try {
await Promise.all(this._after.map((fn) => fn()));
} catch (error) {
console.error(error);
}
return this.results;
};
before = (fn: FixtureFn) => {
this._before.push(fn);
};
after = (fn: FixtureFn) => {
this._after.push(fn);
};
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "tiny-jest",
"version": "1.1.0",
"version": "1.1.1",
"description": "Minimalistic zero dependency Jest-like test library to run tests in browser, nodejs or deno.",
"keywords": [
"jest",
Expand Down
4 changes: 2 additions & 2 deletions src/Test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ export type TestResult = {

export type FixtureFn = () => Promise<void> | void;
export default class Test {
title?: string;
title: string;
suite: { title: string; fn?: Function }[] = [];
// Stores last results
results: TestResult[] = [];
private _before: FixtureFn[] = [];
private _after: FixtureFn[] = [];
constructor(title?: string) {
this.title = title;
this.title = title ?? "";
}
it = (title: string, fn?: Function) => {
this.suite.push({ title, fn });
Expand Down
10 changes: 9 additions & 1 deletion src/expect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,17 @@ const matchers: Record<keyof Expectations, Matcher> = {
return actual ? `Expected ${JSON.stringify(actual)} to be falsy` : false;
},
toMatchObject: (actual: any, expected: any): string | false => {
const error = `${JSON.stringify(actual)} does not match ${JSON.stringify(
expected
)}`;
if (
typeof actual !== typeof expected ||
Array.isArray(actual) !== Array.isArray(expected)
)
return error;
for (let key in expected) {
if (typeof actual[key] !== typeof expected[key])
return `Types mismatch for ${key}: ${typeof actual[
return `${error}:\nTypes mismatch for ${key}: ${typeof actual[
key
]} != ${typeof expected[key]}`;
if (typeof expected[key] !== "object") {
Expand Down
27 changes: 27 additions & 0 deletions tests/expect.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,31 @@ it("expect.not", async () => {
expect(error.message).toBe("Expected 2 not to be truthy");
}
});

it("toMatchObject", () => {
const more = { a: 1, b: 2, c: 3 };
const less = { a: 1, b: 2 };
expect(more).toMatchObject(more);
expect(less).toMatchObject(less);

expect(more).toMatchObject(less);
expect(less).not.toMatchObject(more);
});

it("toMatchObject/arrays", () => {
expect([]).toMatchObject([]);
expect([]).not.toMatchObject({});
expect([1, 2, 3]).toMatchObject([1, 2]);
expect([2, 3]).not.toMatchObject([1, 2, 3]);
expect([{ id: 1, name: "1" }, { id: 2, name: "2" }, { id: 3 }]).toMatchObject(
[{ id: 1 }, { id: 2 }, { id: 3 }]
);
expect([{ id: 1 }, { id: 2 }, { id: 3 }]).not.toMatchObject([
{ id: 1, name: "1" },
{ id: 2, name: "2" },
{ id: 3 },
]);
expect({ a: [1, 2, 3] }).toMatchObject({ a: [1, 2, 3] });
expect({ a: [1, 2] }).not.toMatchObject({ a: [1, 2, 3] });
});
module.exports = test;

0 comments on commit c789755

Please sign in to comment.