diff --git a/packages/boot/test/fast-usdc/fast-usdc.test.ts b/packages/boot/test/fast-usdc/fast-usdc.test.ts index 73d8b4e6baf..e13f95849e7 100644 --- a/packages/boot/test/fast-usdc/fast-usdc.test.ts +++ b/packages/boot/test/fast-usdc/fast-usdc.test.ts @@ -8,6 +8,7 @@ import { documentStorageSchema } from '@agoric/governance/tools/storageDoc.js'; import { Fail } from '@endo/errors'; import { unmarshalFromVstorage } from '@agoric/internal/src/marshal.js'; import { makeMarshal } from '@endo/marshal'; +import { defaultMarshaller } from '@agoric/internal/src/storage-test-utils.js'; import { makeWalletFactoryContext, type WalletFactoryTestContext, @@ -110,11 +111,12 @@ test.serial( test.serial('writes feed policy to vstorage', async t => { const { storage } = t.context; - const doc = { + const opts = { node: 'fastUsdc.feedPolicy', owner: 'the general and chain-specific policies for the Fast USDC feed', + showValue: JSON.parse, }; - await documentStorageSchema(t, storage, doc); + await documentStorageSchema(t, storage, opts); }); test.serial('writes fee config to vstorage', async t => { @@ -122,6 +124,7 @@ test.serial('writes fee config to vstorage', async t => { const doc = { node: 'fastUsdc.feeConfig', owner: 'the fee configuration for Fast USDC', + showValue: v => defaultMarshaller.fromCapData(JSON.parse(v)), }; await documentStorageSchema(t, storage, doc); }); diff --git a/packages/boot/test/fast-usdc/snapshots/fast-usdc.test.ts.md b/packages/boot/test/fast-usdc/snapshots/fast-usdc.test.ts.md index 08400eda5f5..f953f9ea514 100644 --- a/packages/boot/test/fast-usdc/snapshots/fast-usdc.test.ts.md +++ b/packages/boot/test/fast-usdc/snapshots/fast-usdc.test.ts.md @@ -14,7 +14,18 @@ Generated by [AVA](https://avajs.dev). [ [ 'published.fastUsdc.feedPolicy', - '{"blockHeight":"0","values":["{\\"chainPolicies\\":{\\"Arbitrum\\":{\\"cctpTokenMessengerAddress\\":\\"0x19330d10D9Cc8751218eaf51E8885D058642E08A\\",\\"chainId\\":42161,\\"confirmations\\":2,\\"nobleContractAddress\\":\\"0x19330d10D9Cc8751218eaf51E8885D058642E08A\\"}},\\"nobleAgoricChannelId\\":\\"channel-21\\",\\"nobleDomainId\\":4}"]}', + { + chainPolicies: { + Arbitrum: { + cctpTokenMessengerAddress: '0x19330d10D9Cc8751218eaf51E8885D058642E08A', + chainId: 42161, + confirmations: 2, + nobleContractAddress: '0x19330d10D9Cc8751218eaf51E8885D058642E08A', + }, + }, + nobleAgoricChannelId: 'channel-21', + nobleDomainId: 4, + }, ], ] @@ -28,7 +39,36 @@ Generated by [AVA](https://avajs.dev). [ [ 'published.fastUsdc.feeConfig', - '{"blockHeight":"0","values":["{\\"body\\":\\"#{\\\\\\"contractRate\\\\\\":{\\\\\\"denominator\\\\\\":{\\\\\\"brand\\\\\\":\\\\\\"$0.Alleged: USDC brand\\\\\\",\\\\\\"value\\\\\\":\\\\\\"+10\\\\\\"},\\\\\\"numerator\\\\\\":{\\\\\\"brand\\\\\\":\\\\\\"$0\\\\\\",\\\\\\"value\\\\\\":\\\\\\"+2\\\\\\"}},\\\\\\"flat\\\\\\":{\\\\\\"brand\\\\\\":\\\\\\"$0\\\\\\",\\\\\\"value\\\\\\":\\\\\\"+10000\\\\\\"},\\\\\\"maxVariable\\\\\\":{\\\\\\"brand\\\\\\":\\\\\\"$0\\\\\\",\\\\\\"value\\\\\\":\\\\\\"+5000000\\\\\\"},\\\\\\"variableRate\\\\\\":{\\\\\\"denominator\\\\\\":{\\\\\\"brand\\\\\\":\\\\\\"$0\\\\\\",\\\\\\"value\\\\\\":\\\\\\"+100\\\\\\"},\\\\\\"numerator\\\\\\":{\\\\\\"brand\\\\\\":\\\\\\"$0\\\\\\",\\\\\\"value\\\\\\":\\\\\\"+1\\\\\\"}}}\\",\\"slots\\":[\\"board01029\\"]}"]}', + { + contractRate: { + denominator: { + brand: Object @Alleged: USDC brand {}, + value: 10n, + }, + numerator: { + brand: Object @Alleged: USDC brand {}, + value: 2n, + }, + }, + flat: { + brand: Object @Alleged: USDC brand {}, + value: 10000n, + }, + maxVariable: { + brand: Object @Alleged: USDC brand {}, + value: 5000000n, + }, + variableRate: { + denominator: { + brand: Object @Alleged: USDC brand {}, + value: 100n, + }, + numerator: { + brand: Object @Alleged: USDC brand {}, + value: 1n, + }, + }, + }, ], ] @@ -42,10 +82,10 @@ Generated by [AVA](https://avajs.dev). [ [ 'published.fastUsdc.status.0xc81bc6105b60a234c7c50ac17816ebcd5561d366df8bf3be59ff387552761702', - '{"blockHeight":"0","values":["OBSERVED"]}', + 'OBSERVED', ], [ 'published.fastUsdc.status.0xd81bc6105b60a234c7c50ac17816ebcd5561d366df8bf3be59ff387552761799', - '{"blockHeight":"0","values":["OBSERVED"]}', + 'OBSERVED', ], ] diff --git a/packages/boot/test/fast-usdc/snapshots/fast-usdc.test.ts.snap b/packages/boot/test/fast-usdc/snapshots/fast-usdc.test.ts.snap index 2a1d52ca9c2..9489b8bc7ff 100644 Binary files a/packages/boot/test/fast-usdc/snapshots/fast-usdc.test.ts.snap and b/packages/boot/test/fast-usdc/snapshots/fast-usdc.test.ts.snap differ diff --git a/packages/internal/src/storage-test-utils.js b/packages/internal/src/storage-test-utils.js index f224c47ad93..143a6bbd444 100644 --- a/packages/internal/src/storage-test-utils.js +++ b/packages/internal/src/storage-test-utils.js @@ -7,6 +7,7 @@ import { makeTracer } from './debug.js'; import { isStreamCell, makeChainStorageRoot } from './lib-chainStorage.js'; import { bindAllMethods } from './method-tools.js'; import { eventLoopIteration } from './testing-utils.js'; +import { NonNullish } from './errors.js'; /** * @import {TotalMap} from './types.js'; @@ -250,30 +251,48 @@ export const makeMockChainStorageRoot = () => { * @param {import('ava').ExecutionContext} t * @param {MockChainStorageRoot | FakeStorageKit} storage * @param {({ note: string } | { node: string; owner: string }) & - * ({ pattern: string; replacement: string } | {})} opts + * ({ pattern: string; replacement: string } | {}) & { + * showValue?: (v: string) => unknown; + * }} opts */ export const documentStorageSchema = async (t, storage, opts) => { // chainStorage publication is unsynchronized await eventLoopIteration(); + const getLast = (/** @type {string} */ cell) => + JSON.parse(cell).values.at(-1) || assert.fail(); + const { showValue = s => s } = opts; + /** @type {(d: Map, k: string) => unknown} */ + const getBodyDefault = (d, k) => showValue(getLast(NonNullish(d.get(k)))); + const [keys, getBody] = 'keys' in storage ? [storage.keys(), (/** @type {string} */ k) => storage.getBody(k)] - : [storage.data.keys(), (/** @type {string} */ k) => storage.data.get(k)]; + : [ + storage.data.keys(), + (/** @type {string} */ k) => getBodyDefault(storage.data, k), + ]; const { pattern, replacement } = 'pattern' in opts ? opts : { pattern: 'mockChainStorageRoot.', replacement: 'published.' }; - const illustration = [...keys].sort().map( + + const pruned = [...keys] + .sort() + .filter( + 'node' in opts + ? key => + key + .replace(pattern, replacement) + .startsWith(`published.${opts.node}`) + : _entry => true, + ); + + const illustration = pruned.map( /** @type {(k: string) => [string, unknown]} */ key => [key.replace(pattern, replacement), getBody(key)], ); - const pruned = illustration.filter( - 'node' in opts - ? ([key, _]) => key.startsWith(`published.${opts.node}`) - : _entry => true, - ); const note = 'note' in opts @@ -283,5 +302,5 @@ export const documentStorageSchema = async (t, storage, opts) => { The example below illustrates the schema of the data published there. See also board marshalling conventions (_to appear_).`; - t.snapshot(pruned, note + boilerplate); + t.snapshot(illustration, note + boilerplate); };