diff --git a/README.md b/README.md
index 5df2d95..731292a 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
# Mock
-[![release](https://img.shields.io/badge/release-0.12.0-success)](https://github.com/udibo/mock/releases/tag/0.12.0)
-[![deno doc](https://doc.deno.land/badge.svg)](https://doc.deno.land/https/deno.land/x/mock@0.12.0/mod.ts)
+[![release](https://img.shields.io/badge/release-0.12.1-success)](https://github.com/udibo/mock/releases/tag/0.12.1)
+[![deno doc](https://doc.deno.land/badge.svg)](https://doc.deno.land/https/deno.land/x/mock@0.12.1/mod.ts)
[![CI](https://github.com/udibo/mock/workflows/CI/badge.svg)](https://github.com/udibo/mock/actions?query=workflow%3ACI)
[![codecov](https://codecov.io/gh/udibo/mock/branch/master/graph/badge.svg?token=TXORMSEHM7)](https://codecov.io/gh/udibo/mock)
[![license](https://img.shields.io/github/license/udibo/mock)](https://github.com/udibo/mock/blob/master/LICENSE)
@@ -30,9 +30,9 @@ imported directly from GitHub using raw content URLs.
```ts
// Import from Deno's third party module registry
-import { spy, Spy } from "https://deno.land/x/mock@0.12.0/mod.ts";
+import { spy, Spy } from "https://deno.land/x/mock@0.12.1/mod.ts";
// Import from GitHub
-import { spy, Spy } "https://raw.githubusercontent.com/udibo/mock/0.12.0/mod.ts";
+import { spy, Spy } "https://raw.githubusercontent.com/udibo/mock/0.12.1/mod.ts";
```
If you do not need all of the sub-modules, you can choose to just import the
@@ -40,12 +40,12 @@ sub-modules you need.
```ts
// Import from Deno's third party module registry
-import { Spy, spy } from "https://deno.land/x/mock@0.12.0/spy.ts";
+import { Spy, spy } from "https://deno.land/x/mock@0.12.1/spy.ts";
// Import from GitHub
import {
Spy,
spy,
-} from "https://raw.githubusercontent.com/udibo/mock/0.12.0/spy.ts";
+} from "https://raw.githubusercontent.com/udibo/mock/0.12.1/spy.ts";
```
#### Sub-modules
@@ -69,7 +69,7 @@ If a Node.js package has the type "module" specified in its package.json file,
the JavaScript bundle can be imported as a `.js` file.
```js
-import { Spy, spy } from "./mock_0.12.0.js";
+import { Spy, spy } from "./mock_0.12.1.js";
```
The default type for Node.js packages is "commonjs". To import the bundle into a
@@ -77,7 +77,7 @@ commonjs package, the file extension of the JavaScript bundle must be changed
from `.js` to `.mjs`.
```js
-import { Spy, spy } from "./mock_0.12.0.mjs";
+import { Spy, spy } from "./mock_0.12.1.mjs";
```
See [Node.js Documentation](https://nodejs.org/api/esm.html) for more
@@ -96,7 +96,7 @@ modules must have the type attribute set to "module".
```js
// main.js
-import { Spy, spy } from "./mock_0.12.0.js";
+import { Spy, spy } from "./mock_0.12.1.js";
```
You can also embed a module script directly into an HTML file by placing the
@@ -104,7 +104,7 @@ JavaScript code within the body of the script tag.
```html
```
@@ -120,7 +120,7 @@ a try block then restore the function in a finally block to ensure the original
instance method is restored before continuing to other tests. The same applies
when using fake time.
-See [deno docs](https://doc.deno.land/https/deno.land/x/mock@0.12.0/mod.ts) for
+See [deno docs](https://doc.deno.land/https/deno.land/x/mock@0.12.1/mod.ts) for
more information.
### Spy
@@ -135,9 +135,12 @@ anything, you can create an empty spy. An empty spy will just return undefined
for any calls made to it.
```ts
-import { assertEquals } from "https://deno.land/std@0.114.0/testing/asserts.ts";
-import { assertSpyCall } from "https://deno.land/x/mock@0.12.0/asserts.ts";
-import { Spy, spy } from "https://deno.land/x/mock@0.12.0/spy.ts";
+import { assertEquals } from "https://deno.land/std@0.115.1/testing/asserts.ts";
+import {
+ assertSpyCall,
+ Spy,
+ spy,
+} from "https://deno.land/x/mock@0.12.1/mod.ts";
function add(
a: number,
@@ -163,8 +166,13 @@ If you have a function that takes a callback that needs to still behave
normally, you can wrap it with a spy.
```ts
-import { assertEquals } from "https://deno.land/std@0.114.0/testing/asserts.ts";
-import { Spy, spy } from "https://deno.land/x/mock@0.12.0/spy.ts";
+import { assertEquals } from "https://deno.land/std@0.115.1/testing/asserts.ts";
+import {
+ assertSpyCall,
+ assertSpyCalls,
+ Spy,
+ spy,
+} from "https://deno.land/x/mock@0.12.1/mod.ts";
function filter(values: T[], callback: (value: T) => boolean): any[] {
return values.filter(callback);
@@ -179,12 +187,11 @@ Deno.test("calls real callback", () => {
const values: number[] = [5, 6, 7, 8];
assertEquals(filter(values, callback), [6, 8]);
- assertEquals(callback.calls, [
- { args: [5, 0, values], returned: false },
- { args: [6, 1, values], returned: true },
- { args: [7, 2, values], returned: false },
- { args: [8, 3, values], returned: true },
- ]);
+ assertSpyCall(callback, 0, { args: [5, 0, values], returned: false });
+ assertSpyCall(callback, 1, { args: [6, 1, values], returned: true });
+ assertSpyCall(callback, 2, { args: [7, 2, values], returned: false });
+ assertSpyCall(callback, 3, { args: [8, 3, values], returned: true });
+ assertSpyCalls(callback, 4);
});
```
@@ -195,10 +202,16 @@ method. If it is not restored and you attempt to wrap it again, it will throw a
spy error saying "already spying on function".
```ts
-import { assertEquals } from "https://deno.land/std@0.114.0/testing/asserts.ts";
-import { Spy, spy } from "https://deno.land/x/mock@0.12.0/spy.ts";
+import { assertEquals } from "https://deno.land/std@0.115.1/testing/asserts.ts";
+import {
+ assertSpyCall,
+ assertSpyCalls,
+ Spy,
+ spy,
+} from "https://deno.land/x/mock@0.12.1/mod.ts";
class Database {
+ // deno-lint-ignore no-explicit-any
private queries: any;
constructor() {
this.queries = {
@@ -212,12 +225,14 @@ class Database {
},
};
}
+
+ // deno-lint-ignore no-explicit-any
query(query: string, params: any[]): any[][] {
return this.queries[query][params[0]]; // implementation not important for example
}
}
-function getNamesByFirstName(db: Database, firstName: string) {
+function getNamesByFirstName(db: Database, firstName: string): string[] {
return db
.query(
"select id, last_name from USERS where first_name=?",
@@ -226,7 +241,7 @@ function getNamesByFirstName(db: Database, firstName: string) {
.map((row) => `${firstName} ${row[1]}`);
}
-function getNamesByLastName(db: Database, lastName: string) {
+function getNamesByLastName(db: Database, lastName: string): string[] {
return db
.query(
"select id, first_name from USERS where last_name=?",
@@ -241,31 +256,30 @@ Deno.test("functions call db.query", () => {
try {
assertEquals(getNamesByFirstName(db, "Jane"), ["Jane Doe", "Jane Smith"]);
+ assertSpyCall(query, 0, {
+ args: ["select id, last_name from USERS where first_name=?", ["Jane"]],
+ self: db,
+ returned: [[1, "Doe"], [3, "Smith"]],
+ });
assertEquals(getNamesByLastName(db, "Doe"), ["Jane Doe", "John Doe"]);
+ assertSpyCall(query, 1, {
+ args: ["select id, first_name from USERS where last_name=?", ["Doe"]],
+ self: db,
+ returned: [[1, "Jane"], [2, "John"]],
+ });
assertEquals(getNamesByFirstName(db, "John"), ["John Doe"]);
+ assertSpyCall(query, 2, {
+ args: ["select id, last_name from USERS where first_name=?", ["John"]],
+ self: db,
+ returned: [[2, "Doe"]],
+ });
assertEquals(getNamesByLastName(db, "Smith"), ["Jane Smith"]);
- assertEquals(query.calls, [
- {
- args: ["select id, last_name from USERS where first_name=?", ["Jane"]],
- self: db,
- returned: [[1, "Doe"], [3, "Smith"]],
- },
- {
- args: ["select id, first_name from USERS where last_name=?", ["Doe"]],
- self: db,
- returned: [[1, "Jane"], [2, "John"]],
- },
- {
- args: ["select id, last_name from USERS where first_name=?", ["John"]],
- self: db,
- returned: [[2, "Doe"]],
- },
- {
- args: ["select id, first_name from USERS where last_name=?", ["Smith"]],
- self: db,
- returned: [[3, "Jane"]],
- },
- ]);
+ assertSpyCall(query, 3, {
+ args: ["select id, first_name from USERS where last_name=?", ["Smith"]],
+ self: db,
+ returned: [[3, "Jane"]],
+ });
+ assertSpyCalls(query, 4);
} finally {
query.restore();
}
@@ -284,8 +298,8 @@ you can create an empty stub. An empty stub will just return undefined for any
calls made to it.
```ts
-import { assertEquals } from "https://deno.land/std@0.114.0/testing/asserts.ts";
-import { Stub, stub } from "https://deno.land/x/mock@0.12.0/stub.ts";
+import { assertEquals } from "https://deno.land/std@0.115.1/testing/asserts.ts";
+import { Stub, stub } from "https://deno.land/x/mock@0.12.1/stub.ts";
class Cat {
action(name: string): any {
@@ -311,152 +325,89 @@ Deno.test("doAction", () => {
```
If you have an instance method but need it to return specific values for each
-call, you can create a stub with a function that returns those values. A
-callback helper is provided for converting an iterable into a callback for your
-stub function. You can add more return values after initialization by pushing
-onto the array as long as the iterator has not completed. An iterator is
+call, you can create a stub with a function that returns those values. The stub
+function will have all the same arguments available to it if you would like to
+generate return values based on the arguments.
+
+A callback helper is provided for converting an iterable into a callback for
+your stub function. You can add more return values after initialization by
+pushing onto the array as long as the iterator has not completed. An iterator is
considered complete if called after all values have been returned. The callback
will return undefined to each call after the iterator is done.
```ts
-import { assertEquals } from "https://deno.land/std@0.114.0/testing/asserts.ts";
-import { Stub, stub } from "https://deno.land/x/mock@0.12.0/stub.ts";
-
-class Database {
- query(query: string, params: any[]): any[][] {
- throw new Error("unimplemented");
- }
-}
-
-function getUsers(
- db: Database,
- lastName: string,
- firstName?: string,
-): string[] {
- return db
- .query(
- "SELECT id, username FROM users WHERE last_name=?" +
- (firstName ? " and first_name=?" : ""),
- firstName ? [lastName, firstName] : [lastName],
- )
- .map((row) => `${row[0]} ${row[1]}`);
-}
-
-Deno.test("getUsers", () => {
- const db: Database = new Database();
- const returns: [number, string][][] = [
- [[1, "jd"], [2, "johnd"], [3, "janedoe"]],
- [[2, "johnd"]],
- ];
- const query: Stub = stub(db, "query", returnsNext(returns));
-
- try {
- assertEquals(getUsers(db, "doe"), ["1 jd", "2 johnd", "3 janedoe"]);
- assertEquals(getUsers(db, "doe", "john"), ["2 johnd"]);
-
- returns.push([[3, "janedoe"]]);
- assertEquals(getUsers(db, "doe"), ["3 janedoe"]);
-
- assertEquals(query.calls, [
- {
- args: [
- "SELECT id, username FROM users WHERE last_name=?",
- ["doe"],
- ],
- self: db,
- returned: [[1, "jd"], [2, "johnd"], [3, "janedoe"]],
- },
- {
- args: [
- "SELECT id, username FROM users WHERE last_name=? and first_name=?",
- ["doe", "john"],
- ],
- self: db,
- returned: [[2, "johnd"]],
- },
- {
- args: [
- "SELECT id, username FROM users WHERE last_name=?",
- ["doe"],
- ],
- self: db,
- returned: [[3, "janedoe"]],
- },
- ]);
- } finally {
- query.restore();
- }
-});
-```
-
-If you have an instance method but need it to call a replacement function
-instead of the original, you can create a stub with a replacement function.
-
-```ts
-import { assertEquals } from "https://deno.land/std@0.114.0/testing/asserts.ts";
-import { Stub, stub } from "https://deno.land/x/mock@0.12.0/stub.ts";
+import { assertEquals } from "https://deno.land/std@0.115.1/testing/asserts.ts";
+import {
+ assertSpyCallAsync,
+ assertSpyCalls,
+ resolvesNext,
+ Stub,
+ stub,
+} from "https://deno.land/x/mock@0.12.1/mod.ts";
class Database {
- query(query: string, params: any[]): any[][] {
+ query(_query: string, _params: unknown[]): Promise {
throw new Error("unimplemented");
}
}
-function getUsers(
+async function getUsers(
db: Database,
lastName: string,
firstName?: string,
-): string[] {
- return db
+): Promise {
+ return (await db
.query(
"SELECT id, username FROM users WHERE last_name=?" +
(firstName ? " and first_name=?" : ""),
firstName ? [lastName, firstName] : [lastName],
- )
+ ))
.map((row) => `${row[0]} ${row[1]}`);
}
-Deno.test("getUsers", () => {
+Deno.test("getUsers", async () => {
const db: Database = new Database();
- const returns: [number, string][][] = [
+ const resolves: [number, string][][] = [
[[1, "jd"], [2, "johnd"], [3, "janedoe"]],
[[2, "johnd"]],
];
- const query: Stub = stub(db, "query", () => returns.shift());
+ const query: Stub = stub(db, "query", resolvesNext(resolves));
try {
- assertEquals(getUsers(db, "doe"), ["1 jd", "2 johnd", "3 janedoe"]);
- assertEquals(getUsers(db, "doe", "john"), ["2 johnd"]);
-
- returns.push([[3, "janedoe"]]);
- assertEquals(getUsers(db, "doe"), ["3 janedoe"]);
-
- assertEquals(query.calls, [
- {
- args: [
- "SELECT id, username FROM users WHERE last_name=?",
- ["doe"],
- ],
- self: db,
- returned: [[1, "jd"], [2, "johnd"], [3, "janedoe"]],
- },
- {
- args: [
- "SELECT id, username FROM users WHERE last_name=? and first_name=?",
- ["doe", "john"],
- ],
- self: db,
- returned: [[2, "johnd"]],
- },
- {
- args: [
- "SELECT id, username FROM users WHERE last_name=?",
- ["doe"],
- ],
- self: db,
- returned: [[3, "janedoe"]],
- },
- ]);
+ assertEquals(await getUsers(db, "doe"), ["1 jd", "2 johnd", "3 janedoe"]);
+ assertEquals(await getUsers(db, "doe", "john"), ["2 johnd"]);
+
+ resolves.push([[3, "janedoe"]]);
+ assertEquals(await getUsers(db, "doe"), ["3 janedoe"]);
+
+ await assertSpyCallAsync(query, 0, {
+ args: [
+ "SELECT id, username FROM users WHERE last_name=?",
+ ["doe"],
+ ],
+ self: db,
+ returned: [[1, "jd"], [2, "johnd"], [3, "janedoe"]],
+ });
+
+ await assertSpyCallAsync(query, 1, {
+ args: [
+ "SELECT id, username FROM users WHERE last_name=? and first_name=?",
+ ["doe", "john"],
+ ],
+ self: db,
+ returned: [[2, "johnd"]],
+ });
+
+ await assertSpyCallAsync(query, 2, {
+ args: [
+ "SELECT id, username FROM users WHERE last_name=?",
+ ["doe"],
+ ],
+ self: db,
+ returned: [[3, "janedoe"]],
+ });
+
+ assertSpyCalls(query, 3);
} finally {
query.restore();
}
@@ -469,9 +420,7 @@ Overrides the real Date object and timer functions with fake ones that can be
controlled through the fake time instance.
```ts
-import { assertEquals } from "https://deno.land/std@0.114.0/testing/asserts.ts";
-import { Spy, spy } from "https://deno.land/x/mock@0.12.0/spy.ts";
-import { FakeTime } from "https://deno.land/x/mock@0.12.0/time.ts";
+import { FakeTime, Spy, spy } from "https://deno.land/x/mock@0.12.1/mod.ts";
function secondInterval(cb: () => void): void {
setInterval(cb, 1000);
@@ -483,13 +432,13 @@ Deno.test("calls callback every second", () => {
try {
secondInterval(cb);
- assertEquals(cb.calls.length, 0);
+ assertSpyCalls(cb, 0);
time.tick(500);
- assertEquals(cb.calls.length, 0);
+ assertSpyCalls(cb, 0);
time.tick(500);
- assertEquals(cb.calls.length, 1);
+ assertSpyCalls(cb, 1);
time.tick(3500);
- assertEquals(cb.calls.length, 4);
+ assertSpyCalls(cb, 4);
} finally {
time.restore();
}
diff --git a/callbacks.ts b/callbacks.ts
index 5293524..baadad3 100644
--- a/callbacks.ts
+++ b/callbacks.ts
@@ -40,7 +40,7 @@ export function returnsNext(
}
export function resolvesNext(
- iterable: AsyncIterable,
+ iterable: Iterable | AsyncIterable,
// deno-lint-ignore no-explicit-any
): (...args: any[]) => Promise {
const gen = (async function* returnsValue() {
diff --git a/callbacks_test.ts b/callbacks_test.ts
index c3063e0..27d0b7e 100644
--- a/callbacks_test.ts
+++ b/callbacks_test.ts
@@ -45,7 +45,7 @@ Deno.test("returnsArgs", () => {
assertEquals(callback("d", "e", "f", "g"), ["e", "f"]);
});
-Deno.test("returnsNext array", () => {
+Deno.test("returnsNext with array", () => {
let results: number[] = [1, 2, 3];
let callback = returnsNext(results);
assertEquals(callback(), 1);
@@ -66,20 +66,113 @@ Deno.test("returnsNext array", () => {
assertEquals(callback(), undefined);
});
-Deno.test("resolvesNext array", async () => {
+Deno.test("returnsNext with iterator", () => {
let results: number[] = [1, 2, 3];
- const asyncIterator = async function* () {
- await delay(0);
+ let callback = returnsNext(results.values());
+ assertEquals(callback(), 1);
+ assertEquals(callback(), 2);
+ assertEquals(callback(), 3);
+ assertEquals(callback(), undefined);
+
+ results = [];
+ callback = returnsNext(results.values());
+ results.push(1, 2, 3);
+ assertEquals(callback(), 1);
+ assertEquals(callback(), 2);
+ assertEquals(callback(), 3);
+ results.push(4);
+ assertEquals(callback(), 4);
+ assertEquals(callback(), undefined);
+ results.push(5);
+ assertEquals(callback(), undefined);
+});
+
+Deno.test("returnsNext with generator", () => {
+ let results: number[] = [1, 2, 3];
+ const generator = function* () {
yield* results;
};
- let callback = resolvesNext(asyncIterator());
+ let callback = returnsNext(generator());
+ assertEquals(callback(), 1);
+ assertEquals(callback(), 2);
+ assertEquals(callback(), 3);
+ assertEquals(callback(), undefined);
+
+ results = [];
+ callback = returnsNext(generator());
+ results.push(1, 2, 3);
+ assertEquals(callback(), 1);
+ assertEquals(callback(), 2);
+ assertEquals(callback(), 3);
+ results.push(4);
+ assertEquals(callback(), 4);
+ assertEquals(callback(), undefined);
+ results.push(5);
+ assertEquals(callback(), undefined);
+});
+
+Deno.test("resolvesNext with array", async () => {
+ let results: number[] = [1, 2, 3];
+ let callback = resolvesNext(results);
+ const value = callback();
+ assertEquals(Promise.resolve(value), value);
+ assertEquals(await value, 1);
+ assertEquals(await callback(), 2);
+ assertEquals(await callback(), 3);
+ assertEquals(await callback(), undefined);
+
+ results = [];
+ callback = resolvesNext(results);
+ results.push(1, 2, 3);
+ assertEquals(await callback(), 1);
+ assertEquals(await callback(), 2);
+ assertEquals(await callback(), 3);
+ results.push(4);
+ assertEquals(await callback(), 4);
+ assertEquals(await callback(), undefined);
+ results.push(5);
+ assertEquals(await callback(), undefined);
+});
+
+Deno.test("resolvesNext with iterator", async () => {
+ let results: number[] = [1, 2, 3];
+ let callback = resolvesNext(results.values());
+ const value = callback();
+ assertEquals(Promise.resolve(value), value);
+ assertEquals(await value, 1);
+ assertEquals(await callback(), 2);
+ assertEquals(await callback(), 3);
+ assertEquals(await callback(), undefined);
+
+ results = [];
+ callback = resolvesNext(results.values());
+ results.push(1, 2, 3);
assertEquals(await callback(), 1);
assertEquals(await callback(), 2);
assertEquals(await callback(), 3);
+ results.push(4);
+ assertEquals(await callback(), 4);
+ assertEquals(await callback(), undefined);
+ results.push(5);
+ assertEquals(await callback(), undefined);
+});
+
+Deno.test("resolvesNext with async generator", async () => {
+ let results: number[] = [1, 2, 3];
+ const asyncGenerator = async function* () {
+ await delay(0);
+ yield* results;
+ };
+ let callback = resolvesNext(asyncGenerator());
+ const value = callback();
+ assertEquals(Promise.resolve(value), value);
+ assertEquals(await value, 1);
+ assertEquals(await callback(), 2);
+ assertEquals(await callback(), 3);
assertEquals(await callback(), undefined);
results = [];
- callback = resolvesNext(asyncIterator());
+ callback = resolvesNext(asyncGenerator());
results.push(1, 2, 3);
assertEquals(await callback(), 1);
assertEquals(await callback(), 2);
diff --git a/deps.ts b/deps.ts
index f71365e..6c98f3a 100644
--- a/deps.ts
+++ b/deps.ts
@@ -1,5 +1,5 @@
-export { delay } from "https://deno.land/std@0.114.0/async/delay.ts";
-export type { DelayOptions } from "https://deno.land/std@0.114.0/async/delay.ts";
+export { delay } from "https://deno.land/std@0.115.1/async/delay.ts";
+export type { DelayOptions } from "https://deno.land/std@0.115.1/async/delay.ts";
export {
assert,
@@ -10,7 +10,7 @@ export {
assertRejects,
assertStrictEquals,
assertThrows,
-} from "https://deno.land/std@0.114.0/testing/asserts.ts";
+} from "https://deno.land/std@0.115.1/testing/asserts.ts";
export { RBTree } from "https://deno.land/x/collections@0.11.2/trees/rb_tree.ts";
export { ascend } from "https://deno.land/x/collections@0.11.2/comparators.ts";
diff --git a/examples/spy_default_test.ts b/examples/spy_default_test.ts
index b90dc97..dfd43bb 100644
--- a/examples/spy_default_test.ts
+++ b/examples/spy_default_test.ts
@@ -1,6 +1,5 @@
import { assertEquals } from "../deps.ts";
-import { assertSpyCall } from "../asserts.ts";
-import { Spy, spy } from "../spy.ts";
+import { assertSpyCall, Spy, spy } from "../mod.ts";
function add(
a: number,
diff --git a/examples/spy_function_test.ts b/examples/spy_function_test.ts
index 7763553..0bda549 100644
--- a/examples/spy_function_test.ts
+++ b/examples/spy_function_test.ts
@@ -1,5 +1,5 @@
import { assertEquals } from "../deps.ts";
-import { Spy, spy } from "../spy.ts";
+import { assertSpyCall, assertSpyCalls, Spy, spy } from "../mod.ts";
function filter(values: T[], callback: (value: T) => boolean): T[] {
return values.filter(callback);
@@ -14,10 +14,9 @@ Deno.test("calls real callback", () => {
const values: number[] = [5, 6, 7, 8];
assertEquals(filter(values, callback), [6, 8]);
- assertEquals(callback.calls, [
- { args: [5, 0, values], returned: false },
- { args: [6, 1, values], returned: true },
- { args: [7, 2, values], returned: false },
- { args: [8, 3, values], returned: true },
- ]);
+ assertSpyCall(callback, 0, { args: [5, 0, values], returned: false });
+ assertSpyCall(callback, 1, { args: [6, 1, values], returned: true });
+ assertSpyCall(callback, 2, { args: [7, 2, values], returned: false });
+ assertSpyCall(callback, 3, { args: [8, 3, values], returned: true });
+ assertSpyCalls(callback, 4);
});
diff --git a/examples/spy_instance_method_test.ts b/examples/spy_instance_method_test.ts
index 7af52d2..2c6100c 100644
--- a/examples/spy_instance_method_test.ts
+++ b/examples/spy_instance_method_test.ts
@@ -1,5 +1,5 @@
import { assertEquals } from "../deps.ts";
-import { Spy, spy } from "../spy.ts";
+import { assertSpyCall, assertSpyCalls, Spy, spy } from "../mod.ts";
class Database {
// deno-lint-ignore no-explicit-any
@@ -16,6 +16,7 @@ class Database {
},
};
}
+
// deno-lint-ignore no-explicit-any
query(query: string, params: any[]): any[][] {
return this.queries[query][params[0]]; // implementation not important for example
@@ -46,31 +47,30 @@ Deno.test("functions call db.query", () => {
try {
assertEquals(getNamesByFirstName(db, "Jane"), ["Jane Doe", "Jane Smith"]);
+ assertSpyCall(query, 0, {
+ args: ["select id, last_name from USERS where first_name=?", ["Jane"]],
+ self: db,
+ returned: [[1, "Doe"], [3, "Smith"]],
+ });
assertEquals(getNamesByLastName(db, "Doe"), ["Jane Doe", "John Doe"]);
+ assertSpyCall(query, 1, {
+ args: ["select id, first_name from USERS where last_name=?", ["Doe"]],
+ self: db,
+ returned: [[1, "Jane"], [2, "John"]],
+ });
assertEquals(getNamesByFirstName(db, "John"), ["John Doe"]);
+ assertSpyCall(query, 2, {
+ args: ["select id, last_name from USERS where first_name=?", ["John"]],
+ self: db,
+ returned: [[2, "Doe"]],
+ });
assertEquals(getNamesByLastName(db, "Smith"), ["Jane Smith"]);
- assertEquals(query.calls, [
- {
- args: ["select id, last_name from USERS where first_name=?", ["Jane"]],
- self: db,
- returned: [[1, "Doe"], [3, "Smith"]],
- },
- {
- args: ["select id, first_name from USERS where last_name=?", ["Doe"]],
- self: db,
- returned: [[1, "Jane"], [2, "John"]],
- },
- {
- args: ["select id, last_name from USERS where first_name=?", ["John"]],
- self: db,
- returned: [[2, "Doe"]],
- },
- {
- args: ["select id, first_name from USERS where last_name=?", ["Smith"]],
- self: db,
- returned: [[3, "Jane"]],
- },
- ]);
+ assertSpyCall(query, 3, {
+ args: ["select id, first_name from USERS where last_name=?", ["Smith"]],
+ self: db,
+ returned: [[3, "Jane"]],
+ });
+ assertSpyCalls(query, 4);
} finally {
query.restore();
}
diff --git a/examples/stub_function_test.ts b/examples/stub_function_test.ts
deleted file mode 100644
index 2b089f7..0000000
--- a/examples/stub_function_test.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-import { assertEquals } from "../deps.ts";
-import { Stub, stub } from "../stub.ts";
-
-class Database {
- // deno-lint-ignore no-explicit-any
- query(_query: string, _params: any[]): any[][] {
- throw new Error("unimplemented");
- }
-}
-
-function getUsers(
- db: Database,
- lastName: string,
- firstName?: string,
-): string[] {
- return db
- .query(
- "SELECT id, username FROM users WHERE last_name=?" +
- (firstName ? " and first_name=?" : ""),
- firstName ? [lastName, firstName] : [lastName],
- )
- .map((row) => `${row[0]} ${row[1]}`);
-}
-
-Deno.test("getUsers", () => {
- const db: Database = new Database();
- const returns: [number, string][][] = [
- [[1, "jd"], [2, "johnd"], [3, "janedoe"]],
- [[2, "johnd"]],
- ];
- const query: Stub = stub(db, "query", () => returns.shift());
-
- try {
- assertEquals(getUsers(db, "doe"), ["1 jd", "2 johnd", "3 janedoe"]);
- assertEquals(getUsers(db, "doe", "john"), ["2 johnd"]);
-
- returns.push([[3, "janedoe"]]);
- assertEquals(getUsers(db, "doe"), ["3 janedoe"]);
-
- assertEquals(query.calls, [
- {
- args: [
- "SELECT id, username FROM users WHERE last_name=?",
- ["doe"],
- ],
- self: db,
- returned: [[1, "jd"], [2, "johnd"], [3, "janedoe"]],
- },
- {
- args: [
- "SELECT id, username FROM users WHERE last_name=? and first_name=?",
- ["doe", "john"],
- ],
- self: db,
- returned: [[2, "johnd"]],
- },
- {
- args: [
- "SELECT id, username FROM users WHERE last_name=?",
- ["doe"],
- ],
- self: db,
- returned: [[3, "janedoe"]],
- },
- ]);
- } finally {
- query.restore();
- }
-});
diff --git a/examples/stub_instance_method_test.ts b/examples/stub_instance_method_test.ts
new file mode 100644
index 0000000..eecc227
--- /dev/null
+++ b/examples/stub_instance_method_test.ts
@@ -0,0 +1,76 @@
+import { assertEquals } from "../deps.ts";
+import {
+ assertSpyCallAsync,
+ assertSpyCalls,
+ resolvesNext,
+ Stub,
+ stub,
+} from "../mod.ts";
+
+class Database {
+ query(_query: string, _params: unknown[]): Promise {
+ throw new Error("unimplemented");
+ }
+}
+
+async function getUsers(
+ db: Database,
+ lastName: string,
+ firstName?: string,
+): Promise {
+ return (await db
+ .query(
+ "SELECT id, username FROM users WHERE last_name=?" +
+ (firstName ? " and first_name=?" : ""),
+ firstName ? [lastName, firstName] : [lastName],
+ ))
+ .map((row) => `${row[0]} ${row[1]}`);
+}
+
+Deno.test("getUsers", async () => {
+ const db: Database = new Database();
+ const resolves: [number, string][][] = [
+ [[1, "jd"], [2, "johnd"], [3, "janedoe"]],
+ [[2, "johnd"]],
+ ];
+ const query: Stub = stub(db, "query", resolvesNext(resolves));
+
+ try {
+ assertEquals(await getUsers(db, "doe"), ["1 jd", "2 johnd", "3 janedoe"]);
+ assertEquals(await getUsers(db, "doe", "john"), ["2 johnd"]);
+
+ resolves.push([[3, "janedoe"]]);
+ assertEquals(await getUsers(db, "doe"), ["3 janedoe"]);
+
+ await assertSpyCallAsync(query, 0, {
+ args: [
+ "SELECT id, username FROM users WHERE last_name=?",
+ ["doe"],
+ ],
+ self: db,
+ returned: [[1, "jd"], [2, "johnd"], [3, "janedoe"]],
+ });
+
+ await assertSpyCallAsync(query, 1, {
+ args: [
+ "SELECT id, username FROM users WHERE last_name=? and first_name=?",
+ ["doe", "john"],
+ ],
+ self: db,
+ returned: [[2, "johnd"]],
+ });
+
+ await assertSpyCallAsync(query, 2, {
+ args: [
+ "SELECT id, username FROM users WHERE last_name=?",
+ ["doe"],
+ ],
+ self: db,
+ returned: [[3, "janedoe"]],
+ });
+
+ assertSpyCalls(query, 3);
+ } finally {
+ query.restore();
+ }
+});
diff --git a/examples/stub_returns_next_test.ts b/examples/stub_returns_next_test.ts
deleted file mode 100644
index 989fba4..0000000
--- a/examples/stub_returns_next_test.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-import { returnsNext } from "../callbacks.ts";
-import { assertEquals } from "../deps.ts";
-import { Stub, stub } from "../stub.ts";
-
-class Database {
- query(_query: string, _params: unknown[]): unknown[][] {
- throw new Error("unimplemented");
- }
-}
-
-function getUsers(
- db: Database,
- lastName: string,
- firstName?: string,
-): string[] {
- return db
- .query(
- "SELECT id, username FROM users WHERE last_name=?" +
- (firstName ? " and first_name=?" : ""),
- firstName ? [lastName, firstName] : [lastName],
- )
- .map((row) => `${row[0]} ${row[1]}`);
-}
-
-Deno.test("getUsers", () => {
- const db: Database = new Database();
- const returns: [number, string][][] = [
- [[1, "jd"], [2, "johnd"], [3, "janedoe"]],
- [[2, "johnd"]],
- ];
- const query: Stub = stub(db, "query", returnsNext(returns));
-
- try {
- assertEquals(getUsers(db, "doe"), ["1 jd", "2 johnd", "3 janedoe"]);
- assertEquals(getUsers(db, "doe", "john"), ["2 johnd"]);
-
- returns.push([[3, "janedoe"]]);
- assertEquals(getUsers(db, "doe"), ["3 janedoe"]);
-
- assertEquals(query.calls, [
- {
- args: [
- "SELECT id, username FROM users WHERE last_name=?",
- ["doe"],
- ],
- self: db,
- returned: [[1, "jd"], [2, "johnd"], [3, "janedoe"]],
- },
- {
- args: [
- "SELECT id, username FROM users WHERE last_name=? and first_name=?",
- ["doe", "john"],
- ],
- self: db,
- returned: [[2, "johnd"]],
- },
- {
- args: [
- "SELECT id, username FROM users WHERE last_name=?",
- ["doe"],
- ],
- self: db,
- returned: [[3, "janedoe"]],
- },
- ]);
- } finally {
- query.restore();
- }
-});
diff --git a/examples/time_test.ts b/examples/time_test.ts
index fcd72d4..7a9c8d7 100644
--- a/examples/time_test.ts
+++ b/examples/time_test.ts
@@ -1,6 +1,4 @@
-import { assertEquals } from "../deps.ts";
-import { Spy, spy } from "../spy.ts";
-import { FakeTime } from "../time.ts";
+import { assertSpyCalls, FakeTime, Spy, spy } from "../mod.ts";
function secondInterval(cb: () => void): void {
setInterval(cb, 1000);
@@ -12,13 +10,13 @@ Deno.test("calls callback every second", () => {
try {
secondInterval(cb);
- assertEquals(cb.calls.length, 0);
+ assertSpyCalls(cb, 0);
time.tick(500);
- assertEquals(cb.calls.length, 0);
+ assertSpyCalls(cb, 0);
time.tick(500);
- assertEquals(cb.calls.length, 1);
+ assertSpyCalls(cb, 1);
time.tick(3500);
- assertEquals(cb.calls.length, 4);
+ assertSpyCalls(cb, 4);
} finally {
time.restore();
}