tinyspy
Advanced tools
Comparing version 1.1.1 to 2.0.0
@@ -0,14 +1,20 @@ | ||
declare const S: unique symbol; | ||
declare let spies: Set<SpyImpl<any[], any>>; | ||
declare let getInternalState: <A extends any[], R>(spy: SpyInternal<A, R>) => SpyInternalState<A, R>; | ||
declare type ReturnError = ['error', any]; | ||
declare type ReturnOk<R> = ['ok', R]; | ||
declare type ResultFn<R> = ReturnError | ReturnOk<R>; | ||
interface Spy<A extends any[] = any[], R = any> { | ||
interface SpyInternal<A extends any[] = any[], R = any> { | ||
(this: any, ...args: A): R; | ||
[S]: SpyInternalState<A, R>; | ||
} | ||
interface SpyInternalImpl<A extends any[] = any[], R = any> extends SpyInternal<A, R> { | ||
[S]: SpyInternalImplState<A, R>; | ||
} | ||
interface SpyInternalState<A extends any[] = any[], R = any> { | ||
called: boolean; | ||
callCount: number; | ||
calls: A[]; | ||
length: number; | ||
results: ResultFn<R>[]; | ||
returns: R[]; | ||
nextError(error: any): this; | ||
nextResult(result: R): this; | ||
reset(): void; | ||
@@ -18,2 +24,13 @@ impl: ((...args: A) => R) | undefined; | ||
} | ||
interface SpyInternalImplState<A extends any[] = any[], R = any> extends SpyInternalState<A, R> { | ||
getOriginal(): (...args: A) => R; | ||
willCall(cb: (...args: A) => R): this; | ||
restore(): void; | ||
} | ||
interface Spy<A extends any[] = any[], R = any> extends SpyInternalState<A, R> { | ||
returns: R[]; | ||
length: number; | ||
nextError(error: any): this; | ||
nextResult(result: R): this; | ||
} | ||
interface SpyImpl<A extends any[] = any[], R = any> extends Spy<A, R> { | ||
@@ -24,5 +41,9 @@ getOriginal(): (...args: A) => R; | ||
} | ||
declare function createInternalSpy<A extends any[], R>(cb?: ((...args: A) => R) | { | ||
new (...args: A): R; | ||
}): SpyInternal<A, R>; | ||
interface SpyFn<A extends any[] = any[], R = any> extends Spy<A, R> { | ||
new (...args: A): R extends void ? any : R; | ||
(...args: A): R; | ||
new (...args: A): R; | ||
} | ||
@@ -40,5 +61,10 @@ declare function spy<A extends any[], R>(cb?: ((...args: A) => R) | { | ||
}[keyof T]; | ||
declare type Classes<T> = { | ||
declare type Constructors<T> = { | ||
[K in keyof T]: T[K] extends new (...args: any[]) => any ? K : never; | ||
}[keyof T]; | ||
declare function internalSpyOn<T extends object, K extends string & keyof T>(obj: T, methodName: K | { | ||
getter: K; | ||
} | { | ||
setter: K; | ||
}, mock?: Procedure): SpyInternalImpl<any[], any>; | ||
declare function spyOn<T, S extends Getters<Required<T>>>(obj: T, methodName: { | ||
@@ -50,3 +76,3 @@ setter: S; | ||
}, mock?: () => T[G]): SpyImpl<[], T[G]>; | ||
declare function spyOn<T, M extends Classes<Required<T>>>(object: T, method: M): Required<T>[M] extends new (...args: infer A) => infer R ? SpyImpl<A, R> : never; | ||
declare function spyOn<T, M extends Constructors<Required<T>>>(object: T, method: M): Required<T>[M] extends new (...args: infer A) => infer R ? SpyImpl<A, R> : never; | ||
declare function spyOn<T, M extends Methods<Required<T>>>(obj: T, methodName: M, mock?: T[M]): Required<T>[M] extends (...args: infer A) => infer R ? SpyImpl<A, R> : never; | ||
@@ -56,2 +82,2 @@ | ||
export { Spy, SpyFn, SpyImpl, restoreAll, spies, spy, spyOn }; | ||
export { Spy, SpyFn, SpyImpl, createInternalSpy, getInternalState, internalSpyOn, restoreAll, spies, spy, spyOn }; |
// src/utils.ts | ||
function d(t, e) { | ||
if (!t) | ||
throw new Error(e); | ||
function S(e, t) { | ||
if (!e) | ||
throw new Error(t); | ||
} | ||
function y(t, e) { | ||
return typeof e === t; | ||
function p(e, t) { | ||
return typeof t === e; | ||
} | ||
function w(t) { | ||
return t instanceof Promise; | ||
function O(e) { | ||
return e instanceof Promise; | ||
} | ||
function f(t, e, i) { | ||
Object.defineProperty(t, e, i); | ||
function g(e, t, n) { | ||
Object.defineProperty(e, t, n); | ||
} | ||
function l(e, t, n) { | ||
Object.defineProperty(e, t, { value: n }); | ||
} | ||
// src/spy.ts | ||
var g = /* @__PURE__ */ new Set(); | ||
function S(t) { | ||
d(y("function", t) || y("undefined", t), "cannot spy on a non-function value"); | ||
let e = function(...o) { | ||
if (e.called = !0, e.callCount++, e.calls.push(o), e.next) { | ||
let [s, l] = e.next; | ||
if (e.results.push(e.next), e.next = null, s === "ok") | ||
return l; | ||
throw l; | ||
// src/constants.ts | ||
var y = Symbol.for("tinyspy:spy"); | ||
// src/internal.ts | ||
var m = /* @__PURE__ */ new Set(), M = (e) => { | ||
e.called = !1, e.callCount = 0, e.calls = [], e.results = []; | ||
}, C = (e) => (g(e, y, { value: { reset: () => M(e[y]) } }), e[y]), I = (e) => e[y] || C(e); | ||
function T(e) { | ||
S(p("function", e) || p("undefined", e), "cannot spy on a non-function value"); | ||
let t = function(...a) { | ||
let r = I(t); | ||
if (r.called = !0, r.callCount++, r.calls.push(a), r.next) { | ||
let [i, s] = r.next; | ||
if (r.results.push(r.next), r.next = null, i === "ok") | ||
return s; | ||
throw s; | ||
} | ||
let r, n = "ok"; | ||
if (e.impl) | ||
let o, f = "ok"; | ||
if (r.impl) | ||
try { | ||
r = e.impl.apply(this, o), n = "ok"; | ||
} catch (s) { | ||
throw r = s, n = "error", e.results.push([n, s]), s; | ||
o = r.impl.apply(this, a), f = "ok"; | ||
} catch (i) { | ||
throw o = i, f = "error", r.results.push([f, i]), i; | ||
} | ||
let c = [n, r]; | ||
if (w(r)) { | ||
let s = r.then((l) => c[1] = l).catch((l) => { | ||
throw c[0] = "error", c[1] = l, l; | ||
let u = [f, o]; | ||
if (O(o)) { | ||
let i = o.then((s) => u[1] = s).catch((s) => { | ||
throw u[0] = "error", u[1] = s, s; | ||
}); | ||
Object.assign(s, r), r = s; | ||
Object.assign(i, o), o = i; | ||
} | ||
return e.results.push(c), r; | ||
return r.results.push(u), o; | ||
}; | ||
f(e, "_isMockFunction", { get: () => !0 }), f(e, "length", { value: t ? t.length : 0 }), f(e, "returns", { | ||
get() { | ||
return this.results.map(([, o]) => o); | ||
} | ||
}), f(e, "name", { value: t && t.name || "spy" }); | ||
let i = () => { | ||
e.called = !1, e.callCount = 0, e.results = [], e.calls = []; | ||
}; | ||
return i(), e.impl = t, e.reset = i, e.nextError = (o) => (e.next = ["error", o], e), e.nextResult = (o) => (e.next = ["ok", o], e), e; | ||
l(t, "_isMockFunction", !0), l(t, "length", e ? e.length : 0), l(t, "name", e && e.name || "spy"); | ||
let n = I(t); | ||
return n.reset(), n.impl = e, t; | ||
} | ||
function v(e) { | ||
let t = I(e); | ||
g(e, "returns", { | ||
get: () => t.results.map(([, n]) => n) | ||
}), ["called", "callCount", "results", "calls", "reset", "impl"].forEach((n) => g(e, n, { get: () => t[n], set: (a) => t[n] = a })), l(e, "nextError", (n) => (t.next = ["error", n], t)), l(e, "nextResult", (n) => (t.next = ["ok", n], t)); | ||
} | ||
// src/spy.ts | ||
function z(e) { | ||
let t = T(e); | ||
return v(t), t; | ||
} | ||
// src/spyOn.ts | ||
var v = (t, e) => Object.getOwnPropertyDescriptor(t, e); | ||
function C(t, e, i) { | ||
d(!y("undefined", t), "spyOn could not find an object to spy upon"), d(y("object", t) || y("function", t), "cannot spyOn on a primitive value"); | ||
let o = () => { | ||
if (typeof e != "object") | ||
return [e, "value"]; | ||
if ("getter" in e && "setter" in e) | ||
var P = (e, t) => Object.getOwnPropertyDescriptor(e, t); | ||
function j(e, t, n) { | ||
S(!p("undefined", e), "spyOn could not find an object to spy upon"), S(p("object", e) || p("function", e), "cannot spyOn on a primitive value"); | ||
let a = () => { | ||
if (!p("object", t)) | ||
return [t, "value"]; | ||
if ("getter" in t && "setter" in t) | ||
throw new Error("cannot spy on both getter and setter"); | ||
if ("getter" in e) | ||
return [e.getter, "get"]; | ||
if ("setter" in e) | ||
return [e.setter, "set"]; | ||
if ("getter" in t) | ||
return [t.getter, "get"]; | ||
if ("setter" in t) | ||
return [t.setter, "set"]; | ||
throw new Error("specify getter or setter to spy on"); | ||
}, [r, n] = o(), c = v(t, r), s = Object.getPrototypeOf(t), l = s && v(s, r), a = c || l; | ||
d(a || r in t, `${String(r)} does not exist`); | ||
let T = !1; | ||
n === "value" && a && !a.value && a.get && (n = "get", T = !0, i = a.get()); | ||
let u; | ||
a ? u = a[n] : n !== "value" ? u = () => t[r] : u = t[r], i || (i = u); | ||
let p = S(i), A = (m) => { | ||
let { value: O, ...h } = a || { | ||
}, [r, o] = a(), f = P(e, r), u = Object.getPrototypeOf(e), i = u && P(u, r), s = f || i; | ||
S(s || r in e, `${String(r)} does not exist`); | ||
let w = !1; | ||
o === "value" && s && !s.value && s.get && (o = "get", w = !0, n = s.get()); | ||
let c; | ||
s ? c = s[o] : o !== "value" ? c = () => e[r] : c = e[r], n || (n = c); | ||
let d = T(n), k = (h) => { | ||
let { value: E, ...b } = s || { | ||
configurable: !0, | ||
writable: !0 | ||
}; | ||
n !== "value" && delete h.writable, h[n] = m, f(t, r, h); | ||
}, k = () => A(u); | ||
return p.restore = k, p.getOriginal = () => T ? u() : u, p.willCall = (m) => (p.impl = m, p), A(T ? () => p : p), g.add(p), p; | ||
o !== "value" && delete b.writable, b[o] = h, g(e, r, b); | ||
}, K = () => k(c), A = d[y]; | ||
return l(A, "restore", K), l(A, "getOriginal", () => w ? c() : c), l(A, "willCall", (h) => (A.impl = h, d)), k(w ? () => d : d), m.add(d), d; | ||
} | ||
function W(e, t, n) { | ||
let a = j(e, t, n); | ||
return v(a), ["restore", "getOriginal", "willCall"].forEach((r) => { | ||
l(a, r, a[y][r]); | ||
}), a; | ||
} | ||
// src/restoreAll.ts | ||
function q() { | ||
for (let t of g) | ||
t.restore(); | ||
g.clear(); | ||
function Z() { | ||
for (let e of m) | ||
e.restore(); | ||
m.clear(); | ||
} | ||
export { | ||
q as restoreAll, | ||
g as spies, | ||
S as spy, | ||
C as spyOn | ||
T as createInternalSpy, | ||
I as getInternalState, | ||
j as internalSpyOn, | ||
Z as restoreAll, | ||
m as spies, | ||
z as spy, | ||
W as spyOn | ||
}; |
{ | ||
"name": "tinyspy", | ||
"version": "1.1.1", | ||
"version": "2.0.0", | ||
"type": "module", | ||
@@ -36,4 +36,4 @@ "main": "./dist/index.cjs", | ||
"scripts": { | ||
"publish": "npm run build && clean-publish" | ||
"publish": "pnpm run build && clean-publish" | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
13263
329