| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465 |
- "use strict";
- var __defProp = Object.defineProperty;
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
- var __getOwnPropNames = Object.getOwnPropertyNames;
- var __hasOwnProp = Object.prototype.hasOwnProperty;
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
- var __export = (target, all) => {
- for (var name in all)
- __defProp(target, name, { get: all[name], enumerable: true });
- };
- var __copyProps = (to, from, except, desc) => {
- if (from && typeof from === "object" || typeof from === "function") {
- for (let key of __getOwnPropNames(from))
- if (!__hasOwnProp.call(to, key) && key !== except)
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
- }
- return to;
- };
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
- // src/index.js
- var index_exports = {};
- __export(index_exports, {
- SpiesGroup: () => SpiesGroup,
- chaiSpies: () => chaiSpies,
- createSpiesGroup: () => createSpiesGroup,
- createSpy: () => createSpy
- });
- module.exports = __toCommonJS(index_exports);
- // src/chai/chai-spies.js
- function chaiSpies(chai, _) {
- const Assertion = chai.Assertion;
- Assertion.addProperty("spy", function() {
- this.assert(
- this._obj.__isSpy === true,
- "expected " + this._obj + " to be a spy",
- "expected " + this._obj + " to not be a spy"
- );
- return this;
- });
- function assertCalled(n) {
- new Assertion(this._obj).to.be.spy;
- const spy = this._obj;
- if (n != void 0) {
- this.assert(
- spy.calls.length === n,
- "expected " + this._obj + " to have been called #{exp} but got #{act}",
- "expected " + this._obj + " to have not been called #{exp}",
- n,
- spy.calls.length
- );
- } else {
- this.assert(
- spy.called === true,
- "expected " + this._obj + " to have been called",
- "expected " + this._obj + " to not have been called"
- );
- }
- }
- __name(assertCalled, "assertCalled");
- function assertCalledChain() {
- new Assertion(this._obj).to.be.spy;
- }
- __name(assertCalledChain, "assertCalledChain");
- Assertion.addChainableMethod("called", assertCalled, assertCalledChain);
- Assertion.addProperty("once", function() {
- new Assertion(this._obj).to.be.spy;
- this.assert(
- this._obj.calls.length === 1,
- "expected " + this._obj + " to have been called once but got #{act}",
- "expected " + this._obj + " to not have been called once",
- 1,
- this._obj.calls.length
- );
- });
- Assertion.addProperty("twice", function() {
- new Assertion(this._obj).to.be.spy;
- this.assert(
- this._obj.calls.length === 2,
- "expected " + this._obj + " to have been called twice but got #{act}",
- "expected " + this._obj + " to not have been called twice",
- 2,
- this._obj.calls.length
- );
- });
- function nthCallWith(spy, n, expArgs) {
- if (spy.calls.length <= n) return false;
- const actArgs = spy.calls[n].args;
- if (actArgs.length !== expArgs.length) return false;
- for (let i = 0; i < expArgs.length; i++) {
- if (!_.eql(actArgs[i], expArgs[i])) {
- return false;
- }
- }
- return true;
- }
- __name(nthCallWith, "nthCallWith");
- function numberOfCallsWith(spy, expArgs) {
- let found = 0;
- const calls = spy.calls;
- for (let i = 0; i < calls.length; i++) {
- if (nthCallWith(spy, i, expArgs)) {
- found++;
- }
- }
- return found;
- }
- __name(numberOfCallsWith, "numberOfCallsWith");
- Assertion.addProperty("first", function() {
- if (this._obj.__isSpy) {
- _.flag(this, "spy nth call with", 1);
- }
- });
- Assertion.addProperty("second", function() {
- if (this._obj.__isSpy) {
- _.flag(this, "spy nth call with", 2);
- }
- });
- Assertion.addProperty("third", function() {
- if (this._obj.__isSpy) {
- _.flag(this, "spy nth call with", 3);
- }
- });
- Assertion.addProperty("on");
- Assertion.addChainableMethod("nth", function(n) {
- if (this._obj.__isSpy) {
- _.flag(this, "spy nth call with", n);
- }
- });
- function generateOrdinalNumber(n) {
- if (n === 1) return "first";
- if (n === 2) return "second";
- if (n === 3) return "third";
- return n + "th";
- }
- __name(generateOrdinalNumber, "generateOrdinalNumber");
- function assertWith() {
- new Assertion(this._obj).to.be.spy;
- const expArgs = [].slice.call(arguments, 0), spy = this._obj, calls = spy.calls, always = _.flag(this, "spy always"), nthCall = _.flag(this, "spy nth call with");
- if (always) {
- const passed = numberOfCallsWith(spy, expArgs);
- this.assert(
- arguments.length ? calls.length && passed === calls.length : calls.length === 0,
- "expected " + this._obj + " to have been always called with #{exp} but got " + passed + " out of " + calls.length,
- "expected " + this._obj + " to have not always been called with #{exp}",
- expArgs
- );
- } else if (nthCall) {
- const ordinalNumber = generateOrdinalNumber(nthCall), actArgs = calls[nthCall - 1];
- new Assertion(this._obj).to.be.have.been.called.min(nthCall);
- this.assert(
- nthCallWith(spy, nthCall - 1, expArgs),
- "expected " + this._obj + " to have been called at the " + ordinalNumber + " time with #{exp} but got #{act}",
- "expected " + this._obj + " to have not been called at the " + ordinalNumber + " time with #{exp}",
- expArgs,
- actArgs
- );
- } else {
- const passed = numberOfCallsWith(spy, expArgs);
- this.assert(
- passed > 0,
- "expected " + this._obj + " to have been called with #{exp}",
- "expected " + this._obj + " to have not been called with #{exp} but got " + passed + " times",
- expArgs
- );
- }
- }
- __name(assertWith, "assertWith");
- function assertWithChain() {
- if (this._obj.__isSpy) {
- _.flag(this, "spy with", true);
- }
- }
- __name(assertWithChain, "assertWithChain");
- Assertion.addChainableMethod("with", assertWith, assertWithChain);
- Assertion.addProperty("always", function() {
- if (this._obj.__isSpy) {
- _.flag(this, "spy always", true);
- }
- });
- Assertion.addMethod("exactly", function() {
- new Assertion(this._obj).to.be.spy;
- const args = [].slice.call(arguments, 0);
- this.assert(
- this._obj.calls.length === args[0],
- "expected " + this._obj + " to have been called #{exp} times but got #{act}",
- "expected " + this._obj + " to not have been called #{exp} times",
- args[0],
- this._obj.calls.length
- );
- });
- function above(_super) {
- return function(n) {
- if (this._obj.__isSpy) {
- new Assertion(this._obj).to.be.spy;
- this.assert(
- this._obj.calls.length > n,
- "expected " + this._obj + " to have been called more than #{exp} times but got #{act}",
- "expected " + this._obj + " to have been called at most #{exp} times but got #{act}",
- n,
- this._obj.calls.length
- );
- } else {
- _super.apply(this, arguments);
- }
- };
- }
- __name(above, "above");
- Assertion.overwriteMethod("above", above);
- Assertion.overwriteMethod("gt", above);
- function below(_super) {
- return function(n) {
- if (this._obj.__isSpy) {
- new Assertion(this._obj).to.be.spy;
- this.assert(
- this._obj.calls.length < n,
- "expected " + this._obj + " to have been called fewer than #{exp} times but got #{act}",
- "expected " + this._obj + " to have been called at least #{exp} times but got #{act}",
- n,
- this._obj.calls.length
- );
- } else {
- _super.apply(this, arguments);
- }
- };
- }
- __name(below, "below");
- Assertion.overwriteMethod("below", below);
- Assertion.overwriteMethod("lt", below);
- function min(_super) {
- return function(n) {
- if (this._obj.__isSpy) {
- new Assertion(this._obj).to.be.spy;
- this.assert(
- this._obj.calls.length >= n,
- "expected " + this._obj + " to have been called at least #{exp} times but got #{act}",
- "expected " + this._obj + " to have been called fewer than #{exp} times but got #{act}",
- n,
- this._obj.calls.length
- );
- } else {
- _super.apply(this, arguments);
- }
- };
- }
- __name(min, "min");
- Assertion.overwriteMethod("min", min);
- Assertion.overwriteMethod("least", min);
- function max(_super) {
- return function(n) {
- if (this._obj.__isSpy) {
- new Assertion(this._obj).to.be.spy;
- this.assert(
- this._obj.calls.length <= n,
- "expected " + this._obj + " to have been called at most #{exp} times but got #{act}",
- "expected " + this._obj + " to have been called more than #{exp} times but got #{act}",
- n,
- this._obj.calls.length
- );
- } else {
- _super.apply(this, arguments);
- }
- };
- }
- __name(max, "max");
- Assertion.overwriteMethod("max", max);
- Assertion.overwriteMethod("most", max);
- }
- __name(chaiSpies, "chaiSpies");
- // src/create-spy.js
- function _parseSpyArgs(target, methodNameOrImpl, customImplForMethod) {
- let originalFn;
- let customImplementation;
- let isMethodSpy = false;
- let objToSpyOn;
- let methodName;
- let hasOwnMethod = false;
- const isLikelyFunctionSpy = typeof target === "function" && customImplForMethod === void 0;
- const isLikelyMethodSpy = typeof target === "object" && target !== null && typeof methodNameOrImpl === "string";
- if (isLikelyFunctionSpy) {
- originalFn = target;
- if (methodNameOrImpl !== void 0) {
- if (typeof methodNameOrImpl !== "function") {
- throw new TypeError(
- "When spying on a function, the second argument (custom implementation) must be a function if provided."
- );
- }
- customImplementation = methodNameOrImpl;
- }
- } else if (isLikelyMethodSpy) {
- methodName = methodNameOrImpl;
- objToSpyOn = target;
- isMethodSpy = true;
- hasOwnMethod = Object.prototype.hasOwnProperty.call(objToSpyOn, methodName);
- if (!(methodName in target)) {
- throw new TypeError(
- `Attempted to spy on a non-existent property: "${methodName}"`
- );
- }
- const propertyToSpyOn = target[methodName];
- if (typeof propertyToSpyOn !== "function") {
- throw new TypeError(
- `Attempted to spy on "${methodName}" which is not a function. It is a "${typeof propertyToSpyOn}".`
- );
- }
- originalFn = propertyToSpyOn;
- if (customImplForMethod !== void 0) {
- if (typeof customImplForMethod !== "function") {
- throw new TypeError(
- "When spying on a method, the third argument (custom implementation) must be a function if provided."
- );
- }
- customImplementation = customImplForMethod;
- }
- } else {
- if (target === null && methodNameOrImpl === void 0 && customImplForMethod === void 0) {
- throw new TypeError("Attempted to spy on null.");
- }
- if (methodNameOrImpl === void 0 && typeof target !== "function") {
- throw new TypeError(
- "Attempted to spy on a non-function value. To spy on an object method, you must provide the method name as the second argument."
- );
- }
- throw new Error(
- "Invalid arguments. Valid signatures:\n createSpy(function, [customImplementationFunction])\n createSpy(object, methodNameString, [customImplementationFunction])"
- );
- }
- return {
- originalFn,
- // определение функции для выполнения шпионом: либо
- // пользовательская реализация, либо оригинальная функция
- fnToExecute: customImplementation || originalFn,
- isMethodSpy,
- objToSpyOn,
- methodName,
- hasOwnMethod
- };
- }
- __name(_parseSpyArgs, "_parseSpyArgs");
- function createSpy(target = void 0, methodNameOrImpl = void 0, customImplForMethod = void 0) {
- if (typeof target === "undefined" && typeof methodNameOrImpl === "undefined" && typeof customImplForMethod === "undefined") {
- target = /* @__PURE__ */ __name(function() {
- }, "target");
- }
- const {
- originalFn,
- fnToExecute,
- isMethodSpy,
- objToSpyOn,
- methodName,
- hasOwnMethod
- } = _parseSpyArgs(target, methodNameOrImpl, customImplForMethod);
- const callLog = {
- count: 0,
- calls: []
- };
- const spy = /* @__PURE__ */ __name(function(...args) {
- callLog.count++;
- const callInfo = {
- // сохранение аргументов, с которыми
- // был вызван шпион
- args: [...args],
- // сохранение контекста (this)
- // вызова шпиона
- thisArg: this,
- returnValue: void 0,
- error: void 0
- };
- try {
- callInfo.returnValue = fnToExecute.apply(this, args);
- callLog.calls.push(callInfo);
- return callInfo.returnValue;
- } catch (e) {
- callInfo.error = e;
- callLog.calls.push(callInfo);
- throw e;
- }
- }, "spy");
- Object.defineProperty(spy, "calls", {
- get: /* @__PURE__ */ __name(() => callLog.calls, "get"),
- enumerable: true,
- configurable: false
- });
- Object.defineProperty(spy, "callCount", {
- get: /* @__PURE__ */ __name(() => callLog.count, "get"),
- enumerable: true,
- configurable: false
- });
- Object.defineProperty(spy, "called", {
- get: /* @__PURE__ */ __name(() => callLog.count > 0, "get"),
- enumerable: true,
- configurable: false
- });
- spy.restore = () => {
- if (isMethodSpy && objToSpyOn) {
- if (originalFn !== void 0) {
- if (hasOwnMethod) {
- objToSpyOn[methodName] = originalFn;
- } else {
- delete objToSpyOn[methodName];
- }
- }
- }
- callLog.count = 0;
- callLog.calls = [];
- };
- if (isMethodSpy && objToSpyOn) {
- objToSpyOn[methodName] = spy;
- }
- spy.__isSpy = true;
- return spy;
- }
- __name(createSpy, "createSpy");
- // src/create-spies-group.js
- var _SpiesGroup = class _SpiesGroup {
- /**
- * Constructor.
- */
- constructor() {
- this.spies = [];
- }
- /**
- * Создает шпиона для отдельной функции
- * или метода объекта и добавляет его в группу.
- *
- * @param {Function|object} [target]
- * @param {Function|string} [methodNameOrImpl]
- * @param {Function} [customImplForMethod]
- * @returns {Function}
- */
- on(target, methodNameOrImpl, customImplForMethod) {
- const spy = createSpy(target, methodNameOrImpl, customImplForMethod);
- this.spies.push(spy);
- return spy;
- }
- /**
- * Восстановление всех оригинальных методов объектов,
- * для которых были созданы шпионы в этой группе,
- * и сброс истории вызовов для всех шпионов в группе.
- * Очищает внутренний список шпионов.
- *
- * @returns {this}
- */
- restore() {
- this.spies.forEach((spy) => spy.restore());
- this.spies = [];
- return this;
- }
- };
- __name(_SpiesGroup, "SpiesGroup");
- var SpiesGroup = _SpiesGroup;
- function createSpiesGroup() {
- return new SpiesGroup();
- }
- __name(createSpiesGroup, "createSpiesGroup");
- // Annotate the CommonJS export names for ESM import in node:
- 0 && (module.exports = {
- SpiesGroup,
- chaiSpies,
- createSpiesGroup,
- createSpy
- });
|