typemoq
Version:
A simple mocking library for TypeScript
89 lines (72 loc) • 2.9 kB
text/typescript
import * as _ from "lodash";
import * as common from "../Common/_all";
import * as error from "../Error/_all";
import * as proxy from "../Proxy/_all";
export class Times {
private static NO_MATCHING_CALLS_EXACTLY_N_TIMES = "expected invocation of <%= i %> exactly <%= min %> times, invoked <%= c %> times";
private static NO_MATCHING_CALLS_AT_LEAST_N_TIMES = "expected invocation of <%= i %> at least <%= min %> times, invoked <%= c %> times";
private static NO_MATCHING_CALLS_AT_MOST_N_TIMES = "expected invocation of <%= i %> at most <%= max %> times, invoked <%= c %> times";
private _lastCallCount: number;
private _failMessage: (...data: any[]) => string;
private constructor(
private _condition: common.IFunc2<number, boolean>,
public readonly min: number,
public readonly max: number,
failMessage: string) {
this._failMessage = _.template(failMessage);
}
failMessage(call: proxy.ICallContext) {
return this._failMessage({ i: call, min: this.min, max: this.max, c: this._lastCallCount });
}
verify(callCount: number): boolean {
this._lastCallCount = callCount;
return this._condition(callCount);
}
private static checkArg(n: number, target: string) {
if (n < 0)
throw new error.MockException(error.MockExceptionReason.InvalidArg,
undefined, `${target} argument cannot be a negative number`);
}
static exactly(n: number): Times {
Times.checkArg(n, "'Times.exactly'");
return new Times(c => c === n, n, n, Times.NO_MATCHING_CALLS_EXACTLY_N_TIMES);
}
static atLeast(n: number): Times {
Times.checkArg(n, "'Times.atLeast'");
return new Times(c => c >= n, n, 255, Times.NO_MATCHING_CALLS_AT_LEAST_N_TIMES);
}
static atMost(n: number): Times {
Times.checkArg(n, "'Times.atMost'");
return new Times(c => c >= 0 && c <= n, 0, n, Times.NO_MATCHING_CALLS_AT_MOST_N_TIMES);
}
static never(): Times {
return Times.exactly(0);
}
static once(): Times {
return Times.exactly(1);
}
static atLeastOnce(): Times {
return Times.atLeast(1);
}
static atMostOnce(): Times {
return Times.atMost(1);
}
toString(): string {
let res = "";
if (this.min === this.max) {
if (this.min === 0) {
res = "never";
} else if (this.min === 1) {
res = "once";
} else {
res = `${this.min} times`;
}
} else {
if (this.min === 0 && this.max !== 255)
res = `at most ${this.max} times`;
else
res = `at least ${this.min} times`;
}
return res;
}
}