fix: Ponder: fix mintNextHourProjected divisor, dead param, dead code (#308)
This commit is contained in:
parent
c540d56d08
commit
a4a3a85fdc
6 changed files with 31 additions and 32 deletions
17
kraiken-lib/package-lock.json
generated
17
kraiken-lib/package-lock.json
generated
|
|
@ -226,6 +226,7 @@
|
||||||
"integrity": "sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ==",
|
"integrity": "sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ampproject/remapping": "^2.2.0",
|
"@ampproject/remapping": "^2.2.0",
|
||||||
"@babel/code-frame": "^7.24.2",
|
"@babel/code-frame": "^7.24.2",
|
||||||
|
|
@ -2742,6 +2743,7 @@
|
||||||
"integrity": "sha512-F1CBxgqwOMc4GKJ7eY22hWhBVQuMYTtqI8L0FcszYcpYX0fzfDGpez22Xau8Mgm7O9fI+zA/TYIdq3tGWfweBA==",
|
"integrity": "sha512-F1CBxgqwOMc4GKJ7eY22hWhBVQuMYTtqI8L0FcszYcpYX0fzfDGpez22Xau8Mgm7O9fI+zA/TYIdq3tGWfweBA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~7.13.0"
|
"undici-types": "~7.13.0"
|
||||||
}
|
}
|
||||||
|
|
@ -2802,6 +2804,7 @@
|
||||||
"integrity": "sha512-TGf22kon8KW+DeKaUmOibKWktRY8b2NSAZNdtWh798COm1NWx8+xJ6iFBtk3IvLdv6+LGLJLRlyhrhEDZWargQ==",
|
"integrity": "sha512-TGf22kon8KW+DeKaUmOibKWktRY8b2NSAZNdtWh798COm1NWx8+xJ6iFBtk3IvLdv6+LGLJLRlyhrhEDZWargQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/scope-manager": "8.45.0",
|
"@typescript-eslint/scope-manager": "8.45.0",
|
||||||
"@typescript-eslint/types": "8.45.0",
|
"@typescript-eslint/types": "8.45.0",
|
||||||
|
|
@ -3413,6 +3416,7 @@
|
||||||
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"acorn": "bin/acorn"
|
"acorn": "bin/acorn"
|
||||||
},
|
},
|
||||||
|
|
@ -3737,6 +3741,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"caniuse-lite": "^1.0.30001587",
|
"caniuse-lite": "^1.0.30001587",
|
||||||
"electron-to-chromium": "^1.4.668",
|
"electron-to-chromium": "^1.4.668",
|
||||||
|
|
@ -4525,6 +4530,7 @@
|
||||||
"integrity": "sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ==",
|
"integrity": "sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/eslint-utils": "^4.8.0",
|
"@eslint-community/eslint-utils": "^4.8.0",
|
||||||
"@eslint-community/regexpp": "^4.12.1",
|
"@eslint-community/regexpp": "^4.12.1",
|
||||||
|
|
@ -5222,6 +5228,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/graphql/-/graphql-16.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/graphql/-/graphql-16.8.1.tgz",
|
||||||
"integrity": "sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==",
|
"integrity": "sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0"
|
"node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0"
|
||||||
}
|
}
|
||||||
|
|
@ -5304,8 +5311,9 @@
|
||||||
"version": "5.16.0",
|
"version": "5.16.0",
|
||||||
"resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-5.16.0.tgz",
|
"resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-5.16.0.tgz",
|
||||||
"integrity": "sha512-Ju2RCU2dQMgSKtArPbEtsK5gNLnsQyTNIo/T7cZNp96niC1x0KdJNZV0TIoilceBPQwfb5itrGl8pkFeOUMl4A==",
|
"integrity": "sha512-Ju2RCU2dQMgSKtArPbEtsK5gNLnsQyTNIo/T7cZNp96niC1x0KdJNZV0TIoilceBPQwfb5itrGl8pkFeOUMl4A==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
},
|
},
|
||||||
|
|
@ -7212,6 +7220,7 @@
|
||||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
},
|
},
|
||||||
|
|
@ -8146,8 +8155,9 @@
|
||||||
"version": "5.4.3",
|
"version": "5.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz",
|
||||||
"integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==",
|
"integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc",
|
||||||
"tsserver": "bin/tsserver"
|
"tsserver": "bin/tsserver"
|
||||||
|
|
@ -8354,6 +8364,7 @@
|
||||||
"integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==",
|
"integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "^0.27.0",
|
"esbuild": "^0.27.0",
|
||||||
"fdir": "^6.5.0",
|
"fdir": "^6.5.0",
|
||||||
|
|
@ -8452,6 +8463,7 @@
|
||||||
"integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==",
|
"integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/chai": "^5.2.2",
|
"@types/chai": "^5.2.2",
|
||||||
"@vitest/expect": "3.2.4",
|
"@vitest/expect": "3.2.4",
|
||||||
|
|
@ -8667,6 +8679,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
|
||||||
"integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
|
"integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10.0.0"
|
"node": ">=10.0.0"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,4 @@
|
||||||
export function bytesToUint256LittleEndian(bytes: Uint8Array): bigint {
|
export function bytesToUint256LittleEndian(bytes: Uint8Array): bigint {
|
||||||
// console.log(hexString);
|
|
||||||
// const cleanHexString = hexString.startsWith('0x') ? hexString.substring(2) : hexString;
|
|
||||||
// const bytes = new Uint8Array(Math.ceil(cleanHexString.length / 2));
|
|
||||||
// for (let i = 0, j = 0; i < cleanHexString.length; i += 2, j++) {
|
|
||||||
// bytes[j] = parseInt(cleanHexString.slice(i, i + 2), 16);
|
|
||||||
// }
|
|
||||||
let value: bigint = 0n;
|
let value: bigint = 0n;
|
||||||
|
|
||||||
for (let i = bytes.length - 1; i >= 0; i--) {
|
for (let i = bytes.length - 1; i >= 0; i--) {
|
||||||
|
|
@ -20,12 +14,4 @@ export function uint256ToBytesLittleEndian(value: bigint): Uint8Array {
|
||||||
bytes[i] = Number((value >> (8n * BigInt(i))) & 0xffn);
|
bytes[i] = Number((value >> (8n * BigInt(i))) & 0xffn);
|
||||||
}
|
}
|
||||||
return bytes;
|
return bytes;
|
||||||
// let hexString = '0x';
|
|
||||||
|
|
||||||
// for (let i = 0; i < bytes.length; i++) {
|
|
||||||
// // Convert each byte to a hexadecimal string and pad with zero if needed
|
|
||||||
// hexString += bytes[i].toString(16).padStart(2, '0');
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return hexString;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
8
services/ponder/package-lock.json
generated
8
services/ponder/package-lock.json
generated
|
|
@ -45,17 +45,17 @@
|
||||||
"@graphql-codegen/typescript": "^4.0.6",
|
"@graphql-codegen/typescript": "^4.0.6",
|
||||||
"@graphql-codegen/typescript-operations": "^4.2.0",
|
"@graphql-codegen/typescript-operations": "^4.2.0",
|
||||||
"@graphql-typed-document-node/core": "^3.2.0",
|
"@graphql-typed-document-node/core": "^3.2.0",
|
||||||
"@types/jest": "^29.5.12",
|
|
||||||
"@types/node": "^24.6.0",
|
"@types/node": "^24.6.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.45.0",
|
"@typescript-eslint/eslint-plugin": "^8.45.0",
|
||||||
"@typescript-eslint/parser": "^8.45.0",
|
"@typescript-eslint/parser": "^8.45.0",
|
||||||
|
"@vitest/coverage-v8": "^3.0.0",
|
||||||
"eslint": "^9.36.0",
|
"eslint": "^9.36.0",
|
||||||
"husky": "^9.1.7",
|
"husky": "^9.1.7",
|
||||||
"jest": "^29.7.0",
|
|
||||||
"lint-staged": "^16.2.3",
|
"lint-staged": "^16.2.3",
|
||||||
|
"picomatch": "^4.0.3",
|
||||||
"prettier": "^3.6.2",
|
"prettier": "^3.6.2",
|
||||||
"ts-jest": "^29.1.2",
|
"typescript": "^5.4.3",
|
||||||
"typescript": "^5.4.3"
|
"vitest": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@adraffy/ens-normalize": {
|
"node_modules/@adraffy/ens-normalize": {
|
||||||
|
|
|
||||||
|
|
@ -92,11 +92,11 @@ function computeProjections(ringBuffer: bigint[], pointer: number, timestamp: bi
|
||||||
|
|
||||||
const project = (current: bigint, previous: bigint, weekly: bigint) => {
|
const project = (current: bigint, previous: bigint, weekly: bigint) => {
|
||||||
if (elapsedSeconds === 0n) {
|
if (elapsedSeconds === 0n) {
|
||||||
return weekly / 7n;
|
return weekly / 168n;
|
||||||
}
|
}
|
||||||
const projectedTotal = (current * BigInt(SECONDS_IN_HOUR)) / elapsedSeconds;
|
const projectedTotal = (current * BigInt(SECONDS_IN_HOUR)) / elapsedSeconds;
|
||||||
const medium = (previous + projectedTotal) / 2n;
|
const medium = (previous + projectedTotal) / 2n;
|
||||||
return medium > 0n ? medium : weekly / 7n;
|
return medium > 0n ? medium : weekly / 168n;
|
||||||
};
|
};
|
||||||
|
|
||||||
const mintProjection = project(ringBuffer[currentBase + 1], ringBuffer[previousBase + 1], metrics.mintedWeek);
|
const mintProjection = project(ringBuffer[currentBase + 1], ringBuffer[previousBase + 1], metrics.mintedWeek);
|
||||||
|
|
@ -259,8 +259,8 @@ export async function updateHourlyData(context: StatsContext, timestamp: bigint)
|
||||||
ethReserveLastWeek: metrics.ethReserveLatest > 0n ? metrics.ethReserveLatest - metrics.ethReserve7dAgo : 0n,
|
ethReserveLastWeek: metrics.ethReserveLatest > 0n ? metrics.ethReserveLatest - metrics.ethReserve7dAgo : 0n,
|
||||||
netSupplyChangeDay: metrics.mintedDay - metrics.burnedDay,
|
netSupplyChangeDay: metrics.mintedDay - metrics.burnedDay,
|
||||||
netSupplyChangeWeek: metrics.mintedWeek - metrics.burnedWeek,
|
netSupplyChangeWeek: metrics.mintedWeek - metrics.burnedWeek,
|
||||||
mintNextHourProjected: metrics.mintedWeek / 7n,
|
mintNextHourProjected: metrics.mintedWeek / 168n,
|
||||||
burnNextHourProjected: metrics.burnedWeek / 7n,
|
burnNextHourProjected: metrics.burnedWeek / 168n,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const metrics = computeMetrics(ringBuffer, pointer);
|
const metrics = computeMetrics(ringBuffer, pointer);
|
||||||
|
|
@ -325,7 +325,7 @@ export async function refreshOutstandingStake(context: StatsContext) {
|
||||||
* Record ETH reserve snapshot in ring buffer slot 0.
|
* Record ETH reserve snapshot in ring buffer slot 0.
|
||||||
* Called from lm.ts on Recentered events (where we know the pool's ETH balance).
|
* Called from lm.ts on Recentered events (where we know the pool's ETH balance).
|
||||||
*/
|
*/
|
||||||
export async function recordEthReserveSnapshot(context: StatsContext, timestamp: bigint, ethBalance: bigint) {
|
export async function recordEthReserveSnapshot(context: StatsContext, ethBalance: bigint) {
|
||||||
const statsData = await context.db.find(stats, { id: STATS_ID });
|
const statsData = await context.db.find(stats, { id: STATS_ID });
|
||||||
if (!statsData) return;
|
if (!statsData) return;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -189,7 +189,7 @@ async function updateReserveStats(
|
||||||
vwapTick: number | bigint
|
vwapTick: number | bigint
|
||||||
) {
|
) {
|
||||||
// Record ETH reserve in ring buffer for hourly time-series
|
// Record ETH reserve in ring buffer for hourly time-series
|
||||||
await recordEthReserveSnapshot(context, event.block.timestamp, ethBalance);
|
await recordEthReserveSnapshot(context, ethBalance);
|
||||||
|
|
||||||
// Compute 7d growth from ring buffer (slot 0 = ethReserve snapshots)
|
// Compute 7d growth from ring buffer (slot 0 = ethReserve snapshots)
|
||||||
const statsData = await context.db.find(stats, { id: STATS_ID });
|
const statsData = await context.db.find(stats, { id: STATS_ID });
|
||||||
|
|
|
||||||
|
|
@ -291,14 +291,14 @@ describe('updateHourlyData', () => {
|
||||||
// Filled slots: i=2..49 from pointer=7 (48 slots × 10n minted / 5n burned).
|
// Filled slots: i=2..49 from pointer=7 (48 slots × 10n minted / 5n burned).
|
||||||
// mintedLastDay: i<24 → i=2..23 = 22 slots × 10n = 220n
|
// mintedLastDay: i<24 → i=2..23 = 22 slots × 10n = 220n
|
||||||
// mintedLastWeek: 48 × 10n = 480n
|
// mintedLastWeek: 48 × 10n = 480n
|
||||||
// mintNextHourProjected = mintedWeek / 7n = 480n / 7n = 68n (BigInt truncation)
|
// mintNextHourProjected = mintedWeek / 168n = 480n / 168n = 2n (BigInt truncation)
|
||||||
// burnNextHourProjected = burnedWeek / 7n = 240n / 7n = 34n
|
// burnNextHourProjected = burnedWeek / 168n = 240n / 168n = 1n
|
||||||
expect(setArg.mintedLastWeek).toBe(480n);
|
expect(setArg.mintedLastWeek).toBe(480n);
|
||||||
expect(setArg.mintedLastDay).toBe(220n);
|
expect(setArg.mintedLastDay).toBe(220n);
|
||||||
expect(setArg.burnedLastWeek).toBe(240n);
|
expect(setArg.burnedLastWeek).toBe(240n);
|
||||||
expect(setArg.burnedLastDay).toBe(110n);
|
expect(setArg.burnedLastDay).toBe(110n);
|
||||||
expect(setArg.mintNextHourProjected).toBe(68n);
|
expect(setArg.mintNextHourProjected).toBe(2n);
|
||||||
expect(setArg.burnNextHourProjected).toBe(34n);
|
expect(setArg.burnNextHourProjected).toBe(1n);
|
||||||
expect(setArg.netSupplyChangeDay).toBe(110n);
|
expect(setArg.netSupplyChangeDay).toBe(110n);
|
||||||
expect(setArg.netSupplyChangeWeek).toBe(240n);
|
expect(setArg.netSupplyChangeWeek).toBe(240n);
|
||||||
});
|
});
|
||||||
|
|
@ -399,7 +399,7 @@ describe('updateHourlyData', () => {
|
||||||
describe('recordEthReserveSnapshot', () => {
|
describe('recordEthReserveSnapshot', () => {
|
||||||
it('returns early when no stats row exists', async () => {
|
it('returns early when no stats row exists', async () => {
|
||||||
const ctx = createMockContext(null);
|
const ctx = createMockContext(null);
|
||||||
await recordEthReserveSnapshot(ctx, 1000n, 500n);
|
await recordEthReserveSnapshot(ctx, 500n);
|
||||||
expect((ctx as unknown as { db: { update: ReturnType<typeof vi.fn> } }).db.update).not.toHaveBeenCalled();
|
expect((ctx as unknown as { db: { update: ReturnType<typeof vi.fn> } }).db.update).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -409,7 +409,7 @@ describe('recordEthReserveSnapshot', () => {
|
||||||
const ctx = createMockContext(row);
|
const ctx = createMockContext(row);
|
||||||
const ethBalance = 12345678n;
|
const ethBalance = 12345678n;
|
||||||
|
|
||||||
await recordEthReserveSnapshot(ctx, 1000n, ethBalance);
|
await recordEthReserveSnapshot(ctx, ethBalance);
|
||||||
|
|
||||||
const dbMock = ctx as unknown as { db: { update: ReturnType<typeof vi.fn> } };
|
const dbMock = ctx as unknown as { db: { update: ReturnType<typeof vi.fn> } };
|
||||||
const setArg = (dbMock.db.update as ReturnType<typeof vi.fn>).mock.results[0].value.set.mock.calls[0][0];
|
const setArg = (dbMock.db.update as ReturnType<typeof vi.fn>).mock.results[0].value.set.mock.calls[0][0];
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue