Утилита слежения за вызовом функций и методов для JavaScript
|
|
7 months ago | |
|---|---|---|
| .husky | 7 months ago | |
| dist | 7 months ago | |
| src | 7 months ago | |
| .c8rc | 7 months ago | |
| .commitlintrc | 7 months ago | |
| .editorconfig | 7 months ago | |
| .gitignore | 7 months ago | |
| .mocharc.cjs | 7 months ago | |
| .prettierrc | 7 months ago | |
| LICENSE | 7 months ago | |
| README.md | 7 months ago | |
| build-cjs.js | 7 months ago | |
| eslint.config.js | 7 months ago | |
| package.json | 7 months ago | |
| tsconfig.json | 7 months ago |
Утилита слежения за вызовом функций и методов для JavaScript.
npm install @e22m4u/js-spy
Поддержка ESM и CommonJS стандартов.
ESM
import {createSpy} from '@e22m4u/js-spy';
CommonJS
const {createSpy} = require('@e22m4u/js-spy');
Отслеживание вызова функции.
import {createSpy} from '@e22m4u/js-spy';
function greet(name) {
return `Hello, ${name}!`;
}
const greetSpy = createSpy(greet);
greetSpy('World');
greetSpy('JavaScript');
console.log(greetSpy.called); // true
console.log(greetSpy.callCount); // 2
console.log(greetSpy.getCall(0).args); // ['World']
console.log(greetSpy.getCall(0).returnValue); // 'Hello, World!'
console.log(greetSpy.calledWith('JavaScript')); // true
try {
greetSpy.getCall(5); // Попытка получить несуществующий вызов
} catch (e) {
// Ожидаемая ошибка, например:
// "Invalid call index 5. Spy has 2 call(s)."
console.error(e.message);
}
Отслеживание вызова метода.
import {createSpy} from '@e22m4u/js-spy';
const calculator = {
value: 0,
add(a, b) {
this.value = a + b;
return this.value;
},
};
const addSpy = createSpy(calculator, 'add');
calculator.add(5, 3);
console.log(addSpy.called); // true
console.log(calculator.value); // 8
console.log(addSpy.getCall(0).thisArg === calculator); // true
console.log(addSpy.getCall(0).returnValue); // 8
// восстановление оригинального метода
addSpy.restore();
// calculator.add теперь снова оригинальный метод
Основная функция для создания шпиона.
Сигнатуры вызова и аргументы:
Отслеживание отдельной функции:
createSpy(targetFn, [customImplementation])
targetFn: Функция, которую требуется отслеживать.customImplementation (необязательно): Пользовательская
функция, которая будет вызываться вместо targetFn. Должна
иметь ту же сигнатуру.Отслеживание метода объекта:
createSpy(targetObject, methodName, [customImplementation])
targetObject: Объект, метод которого будет
отслеживаться.methodName: Имя метода в targetObject,
который требуется отслеживать.customImplementation (необязательно): Пользовательская
функция, которая будет вызываться вместо оригинального метода. Должна
иметь ту же сигнатуру.Возвращает:
Каждая функция-шпион, возвращаемая createSpy, обладает
следующими свойствами и методами:
Сам шпион является функцией. При вызове он выполняет либо оригинальную функцию/метод (или пользовательскую реализацию, если предоставлена), записывает информацию о вызове и возвращает результат (или пробрасывает ошибку).
const fn = (x) => x * 2;
const spy = createSpy(fn);
const result = spy(5); // result будет 10
console.log(spy.callCount); // 1
boolean (только для чтения)const spy = createSpy(() => {});
console.log(spy.called); // false
spy();
console.log(spy.called); // true
number (только для чтения)const spy = createSpy(() => {});
console.log(spy.callCount); // 0
spy();
spy();
console.log(spy.callCount); // 2
Аргументы:
n: Число, индекс вызова (начиная с 0).Возвращает: Объект CallInfo со свойствами:
args: Массив аргументов, с которыми был совершен
вызов.thisArg: Контекст this вызова.returnValue: Значение, возвращенное функцией (или
undefined, если функция бросила ошибку).error: Ошибка, выброшенная функцией (или
undefined, если ошибки не было).Выбрасывает:
RangeError: Если n не является допустимым
индексом вызова.Пример:
const spy = createSpy((a, b) => a + b);
spy.call({ id: 1 }, 10, 20); // 0-й вызов
const firstCall = spy.getCall(0);
console.log(firstCall.args); // [10, 20]
try {
spy.getCall(1); // Попытка получить несуществующий вызов
} catch (e) {
// Ожидаемая ошибка, например:
// "Invalid call index 1. Spy has 1 call(s)."
console.error(e.message);
}
Аргументы:
...expectedArgs: Аргументы, с которыми, как ожидается,
был вызван шпион.Возвращает: boolean
true, если шпион был хотя бы раз вызван с точно таким
же набором аргументов (сравнение с использованием
Object.is).false в противном случае.Пример:
const spy = createSpy(() => {});
spy(1, 'a', true);
spy(2, 'b');
console.log(spy.calledWith(1, 'a', true)); // true
console.log(spy.calledWith(1, 'a')); // false
console.log(spy.calledWith(2, 'c')); // false
Аргументы:
n: Число, индекс вызова (начиная с 0)....expectedArgs: Аргументы, с которыми, как ожидается,
был совершен n-ый вызов.Возвращает: boolean
true, если n-ый вызов шпиона был совершен с точно таким
же набором аргументов.false в противном случае.Выбрасывает:
RangeError: Если n не является допустимым
индексом вызова (унаследовано от getCall).Пример:
const spy = createSpy(() => {});
spy('first call');
spy('second call', 123);
console.log(spy.nthCalledWith(0, 'first call')); // true
console.log(spy.nthCalledWith(1, 'second call', 123)); // true
console.log(spy.nthCalledWith(0, 'another')); // false
try {
spy.nthCalledWith(2, 'anything'); // Несуществующий вызов
} catch (e) {
// Ожидаемая ошибка, например:
// "Invalid call index 2. Spy has 2 call(s)."
console.error(e.message);
}
Аргументы:
n: Число, индекс вызова (начиная с 0).expectedReturnValue: Ожидаемое возвращаемое значение
для n-го вызова.Возвращает: boolean
true, если n-ый вызов шпиона вернул
expectedReturnValue (сравнение с помощью
Object.is).false, если значение не совпало или вызов выбросил
ошибку.Выбрасывает:
RangeError: Если n не является допустимым
индексом вызова (унаследовано от getCall).Пример:
const spy = createSpy(val => {
if (val === 0) throw new Error('zero');
return val * 10;
});
spy(5); // 0-й вызов, возвращает 50
try { spy(0); } catch(e) {} // 1-й вызов, бросает ошибку
spy(2); // 2-й вызов, возвращает 20
console.log(spy.nthCallReturned(0, 50)); // true
console.log(spy.nthCallReturned(1, 10)); // false (вызов 1 бросил ошибку)
console.log(spy.nthCallReturned(2, 20)); // true
try {
spy.nthCallReturned(3, 30); // Несуществующий вызов
} catch (e) {
// Ожидаемая ошибка, например:
// "Invalid call index 3. Spy has 3 call(s)."
console.error(e.message);
}
Аргументы:
n: Число, индекс вызова (начиная с 0).expectedError (необязательно): Матчер для ошибки.
Возможные варианты:
undefined: Проверяет, что n-ый вызов просто выбросил
любую ошибку.error.message) совпадает со строкой.Error,
TypeError): Проверяет, что выброшенная ошибка является
экземпляром (instanceof) этого конструктора.error.name) и
сообщение (error.message) выброшенной ошибки совпадают с
полями expectedError.expectedError через Object.is.Возвращает: boolean
true, если n-ый вызов шпиона выбросил ошибку или ошибка
соответствует expectedError.false, если вызов не выбросил ошибку (или выбросил не
ту ошибку).Выбрасывает:
RangeError: Если n не является допустимым
индексом вызова (унаследовано от getCall).Пример:
const mightThrow = (val) => {
if (val === 0) throw new TypeError('Zero is not allowed');
if (val < 0) throw new Error('Negative value');
return val;
};
const spy = createSpy(mightThrow);
try { spy(0); } catch (e) {} // 0-й вызов
try { spy(-5); } catch (e) {} // 1-й вызов
spy(10); // 2-й вызов
console.log(spy.nthCallThrew(0)); // true
console.log(spy.nthCallThrew(0, 'Zero is not allowed')); // true
console.log(spy.nthCallThrew(2)); // false (2-й вызов не бросил ошибку)
try {
spy.nthCallThrew(3); // Несуществующий вызов
} catch (e) {
// Ожидаемая ошибка, например:
// "Invalid call index 3. Spy has 3 call(s)."
console.error(e.message);
}
Описание:
const myObject = {
doSomething() {
return 'original';
}
};
const spy = createSpy(myObject, 'doSomething');
// myObject.doSomething(); // может быть вызван шпион
spy.restore();
console.log(myObject.doSomething()); // 'original'
npm run test
MIT