Skip to content

Commit

Permalink
fix: split reform
Browse files Browse the repository at this point in the history
  • Loading branch information
erights committed Oct 20, 2022
1 parent 42fdddf commit ab70895
Show file tree
Hide file tree
Showing 28 changed files with 493 additions and 267 deletions.
11 changes: 6 additions & 5 deletions packages/ERTP/src/typeGuards.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,18 +124,19 @@ export const MAX_ABSOLUTE_DECIMAL_PLACES = 100;

export const AssetKindShape = M.or('nat', 'set', 'copySet', 'copyBag');

export const DisplayInfoShape = M.partial(
harden({
export const DisplayInfoShape = M.splitRecord(
{},
{
decimalPlaces: M.and(
M.gte(-MAX_ABSOLUTE_DECIMAL_PLACES),
M.lte(MAX_ABSOLUTE_DECIMAL_PLACES),
),
assetKind: AssetKindShape,
}),
harden({
},
{
// Including this empty `rest` ensures that there are no other
// properties beyond those in the `base` record.
}),
},
);

// //////////////////////// Interfaces /////////////////////////////////////////
Expand Down
19 changes: 8 additions & 11 deletions packages/ERTP/test/unitTests/test-inputValidation.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ test('makeIssuerKit bad displayInfo.decimalPlaces', async t => {
),
{
message:
'displayInfo: optional-parts: decimalPlaces: "hello" - Must be >= -100',
'displayInfo: optional: decimalPlaces: "hello" - Must be >= -100',
},
);

Expand Down Expand Up @@ -62,17 +62,15 @@ test('makeIssuerKit bad displayInfo.decimalPlaces', async t => {
() =>
makeIssuerKit('myTokens', AssetKind.NAT, harden({ decimalPlaces: 101 })),
{
message:
'displayInfo: optional-parts: decimalPlaces: 101 - Must be <= 100',
message: 'displayInfo: optional: decimalPlaces: 101 - Must be <= 100',
},
);

t.throws(
() =>
makeIssuerKit('myTokens', AssetKind.NAT, harden({ decimalPlaces: -101 })),
{
message:
'displayInfo: optional-parts: decimalPlaces: -101 - Must be >= -100',
message: 'displayInfo: optional: decimalPlaces: -101 - Must be >= -100',
},
);
});
Expand All @@ -90,7 +88,7 @@ test('makeIssuerKit bad displayInfo.assetKind', async t => {
),
{
message:
'displayInfo: optional-parts: assetKind: "something" - Must match one of ["nat","set","copySet","copyBag"]',
'displayInfo: optional: assetKind: "something" - Must match one of ["nat","set","copySet","copyBag"]',
},
);
});
Expand All @@ -107,8 +105,7 @@ test('makeIssuerKit bad displayInfo.whatever', async t => {
}),
),
{
message:
'displayInfo: rest-parts: {"whatever":"something"} - Must be: {}',
message: 'displayInfo: rest: {"whatever":"something"} - Must be: {}',
},
);
});
Expand Down Expand Up @@ -145,7 +142,7 @@ test('brand.isMyIssuer bad issuer', async t => {
// @ts-expect-error Intentional wrong type for testing
t.throwsAsync(() => brand.isMyIssuer('not an issuer'), {
message:
'In "isMyIssuer" method of (myTokens brand) arg 0: string "not an issuer" - Must be a remotable (Issuer)',
'In "isMyIssuer" method of (myTokens brand): args: [0]: string "not an issuer" - Must be a remotable (Issuer)',
});
const fakeIssuer = /** @type {Issuer} */ (
/** @type {unknown} */ (Far('myTokens issuer', {}))
Expand Down Expand Up @@ -188,7 +185,7 @@ test('issuer.combine bad payments array', async t => {
// @ts-expect-error Intentional wrong type for testing
await t.throwsAsync(() => E(issuer).combine(notAnArray), {
message:
'In "combine" method of (fungible issuer) arg 0: cannot serialize Remotables with non-methods like "length" in {"length":2,"split":"[Function split]"}',
'In "combine" method of (fungible issuer): cannot serialize Remotables with non-methods like "length" in {"length":2,"split":"[Function split]"}',
});

const notAnArray2 = Far('notAnArray2', {
Expand All @@ -198,7 +195,7 @@ test('issuer.combine bad payments array', async t => {
// @ts-expect-error Intentional wrong type for testing
await t.throwsAsync(() => E(issuer).combine(notAnArray2), {
message:
'In "combine" method of (fungible issuer) arg 0: remotable "[Alleged: notAnArray2]" - Must be a copyArray',
'In "combine" method of (fungible issuer): args: [0]: remotable "[Alleged: notAnArray2]" - Must be a copyArray',
});
});

Expand Down
6 changes: 3 additions & 3 deletions packages/ERTP/test/unitTests/test-issuerObj.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ test('bad display info', t => {
const displayInfo = harden({ somethingUnexpected: 3 });
// @ts-expect-error deliberate invalid arguments for testing
t.throws(() => makeIssuerKit('fungible', AssetKind.NAT, displayInfo), {
message: 'displayInfo: rest-parts: {"somethingUnexpected":3} - Must be: {}',
message: 'displayInfo: rest: {"somethingUnexpected":3} - Must be: {}',
});
});

Expand Down Expand Up @@ -200,7 +200,7 @@ test('purse.deposit promise', async t => {
() => E(purse).deposit(exclusivePaymentP, fungible25),
{
message:
'In "deposit" method of (fungible Purse purse) arg 0: promise "[Promise]" - Must be a remotable (Payment)',
'In "deposit" method of (fungible Purse purse): args: [0]: promise "[Promise]" - Must be a remotable (Payment)',
},
'failed to reject a promise for a payment',
);
Expand Down Expand Up @@ -335,7 +335,7 @@ test('issuer.split bad amount', async t => {
_ => E(issuer).split(payment, AmountMath.make(otherBrand, 10n)),
{
message:
'In "split" method of (fungible issuer) arg 1: brand: "[Alleged: other fungible brand]" - Must be: "[Alleged: fungible brand]"',
'In "split" method of (fungible issuer): args: [1]: brand: "[Alleged: other fungible brand]" - Must be: "[Alleged: fungible brand]"',
},
'throws for bad amount',
);
Expand Down
2 changes: 1 addition & 1 deletion packages/ERTP/test/unitTests/test-mintObj.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ test('mint.mintPayment set w strings AssetKind', async t => {
const badAmount = AmountMath.make(brand, harden([['badElement']]));
t.throws(() => mint.mintPayment(badAmount), {
message:
'In "mintPayment" method of (items mint) arg 0: value: [0]: copyArray ["badElement"] - Must be a string',
'In "mintPayment" method of (items mint): args: [0]: value: [0]: copyArray ["badElement"] - Must be a string',
});
});

Expand Down
31 changes: 16 additions & 15 deletions packages/SwingSet/src/typeGuards.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@ import { M } from '@agoric/store';

export const ManagerType = M.or('xs-worker', 'local'); // TODO: others

const Bundle = M.split({ moduleType: M.string() }, M.partial({}));
const Bundle = M.splitRecord({ moduleType: M.string() });

const partial1 = harden({
creationOptions: M.splitRecord({}, { critial: M.boolean() }),
parameters: M.recordOf(M.string(), M.any()),
});

const p1 = M.and(
M.partial({ creationOptions: M.partial({ critial: M.boolean() }) }),
M.partial({ parameters: M.recordOf(M.string(), M.any()) }),
);
const SwingSetConfigProperties = M.or(
M.split({ sourceSpec: M.string() }, p1),
M.split({ bundleSpec: M.string() }, p1),
M.split({ bundle: Bundle }, p1),
M.splitRecord({ sourceSpec: M.string() }, partial1),
M.splitRecord({ bundleSpec: M.string() }, partial1),
M.splitRecord({ bundle: Bundle }, partial1),
);
const SwingSetConfigDescriptor = M.recordOf(
M.string(),
Expand All @@ -31,11 +32,11 @@ const SwingSetConfigDescriptor = M.recordOf(
* in ./types-external.js
*/
export const SwingSetConfig = M.and(
M.partial({ defaultManagerType: ManagerType }),
M.partial({ includeDevDependencies: M.boolean() }),
M.partial({ defaultReapInterval: M.number() }), // not in type decl
M.partial({ snapshotInterval: M.number() }),
M.partial({ vats: SwingSetConfigDescriptor }),
M.partial({ bootstrap: M.string() }),
M.partial({ bundles: SwingSetConfigDescriptor }),
M.splitRecord({}, { defaultManagerType: ManagerType }),
M.splitRecord({}, { includeDevDependencies: M.boolean() }),
M.splitRecord({}, { defaultReapInterval: M.number() }), // not in type decl
M.splitRecord({}, { snapshotInterval: M.number() }),
M.splitRecord({}, { vats: SwingSetConfigDescriptor }),
M.splitRecord({}, { bootstrap: M.string() }),
M.splitRecord({}, { bundles: SwingSetConfigDescriptor }),
);
2 changes: 1 addition & 1 deletion packages/governance/test/unitTests/test-paramGovernance.js
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ test('multiple params bad change', async t => {
),
{
message:
'In "getAmountOf" method of (Zoe Invitation issuer) arg 0: bigint "[13n]" - Must be a remotable (Payment)',
'In "getAmountOf" method of (Zoe Invitation issuer): args: [0]: bigint "[13n]" - Must be a remotable (Payment)',
},
);
});
Expand Down
4 changes: 2 additions & 2 deletions packages/inter-protocol/src/psm/psm.js
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ export const start = async (zcf, privateArgs, baggage) => {
wantmintedHook,
'wantMinted',
undefined,
M.split({
M.splitRecord({
give: { In: anchorAmountShape },
want: M.or({ Out: stableAmountShape }, {}),
}),
Expand All @@ -286,7 +286,7 @@ export const start = async (zcf, privateArgs, baggage) => {
giveMintedHook,
'giveMinted',
undefined,
M.split({
M.splitRecord({
give: { In: stableAmountShape },
want: M.or({ Out: anchorAmountShape }, {}),
}),
Expand Down
20 changes: 9 additions & 11 deletions packages/inter-protocol/src/psm/psmCharter.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,15 @@ import { E } from '@endo/far';
* @property {Record<string, unknown>} params
* @property {{paramPath: { key: string }}} [path]
*/
const ParamChangesOfferArgsShape = harden(
M.split(
{
deadline: TimestampShape,
instance: InstanceHandleShape,
params: M.recordOf(M.string(), M.any()),
},
M.partial({
path: { paramPath: { key: M.string() } },
}),
),
const ParamChangesOfferArgsShape = M.splitRecord(
{
deadline: TimestampShape,
instance: InstanceHandleShape,
params: M.recordOf(M.string(), M.any()),
},
{
path: { paramPath: { key: M.string() } },
},
);

/**
Expand Down
17 changes: 7 additions & 10 deletions packages/inter-protocol/src/vaultFactory/params.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,16 +80,13 @@ const makeVaultParamManager = (publisherKit, initial) =>
});
/** @typedef {ReturnType<typeof makeVaultParamManager>} VaultParamManager */

export const vaultParamPattern = M.split(
{
liquidationMargin: ratioPattern,
liquidationPenalty: ratioPattern,
interestRate: ratioPattern,
loanFee: ratioPattern,
debtLimit: amountPattern,
},
M.any(),
);
export const vaultParamPattern = M.splitRecord({
liquidationMargin: ratioPattern,
liquidationPenalty: ratioPattern,
interestRate: ratioPattern,
loanFee: ratioPattern,
debtLimit: amountPattern,
});

/**
* @param {import('@agoric/notifier').StoredPublisherKit<GovernanceSubscriptionState>} publisherKit
Expand Down
6 changes: 3 additions & 3 deletions packages/inter-protocol/test/psm/test-psm.js
Original file line number Diff line number Diff line change
Expand Up @@ -624,7 +624,7 @@ test('wrong give giveMintedInvitation', async t => {
),
{
message:
'"giveMinted" proposal: required-parts: give: In: brand: "[Alleged: aUSD brand]" - Must be: "[Alleged: IST brand]"',
'"giveMinted" proposal: give: In: brand: "[Alleged: aUSD brand]" - Must be: "[Alleged: IST brand]"',
},
);
});
Expand Down Expand Up @@ -654,7 +654,7 @@ test('wrong give wantMintedInvitation', async t => {
),
{
message:
'"wantMinted" proposal: required-parts: give: In: brand: "[Alleged: IST brand]" - Must be: "[Alleged: aUSD brand]"',
'"wantMinted" proposal: give: In: brand: "[Alleged: IST brand]" - Must be: "[Alleged: aUSD brand]"',
},
);
});
Expand All @@ -676,7 +676,7 @@ test('extra give wantMintedInvitation', async t => {
),
{
message:
'"wantMinted" proposal: required-parts: give: {"Extra":{"brand":"[Alleged: aUSD brand]","value":"[200000000n]"},"In":{"brand":"[Seen]","value":"[200000000n]"}} - Must not have unexpected properties: ["Extra"]',
'"wantMinted" proposal: give: {"Extra":{"brand":"[Alleged: aUSD brand]","value":"[200000000n]"},"In":{"brand":"[Seen]","value":"[200000000n]"}} - Must not have unexpected properties: ["Extra"]',
},
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -2518,7 +2518,7 @@ test('addVaultType: extra, unexpected params', async t => {
E(vaultFactory).addVaultType(chit.issuer, 'Chit', missingParams),
{
message:
/initialParamValues: required-parts: .* - Must have missing properties \["interestRate"\]/,
/initialParamValues: .* - Must have missing properties \["interestRate"\]/,
},
);

Expand Down
6 changes: 3 additions & 3 deletions packages/internal/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ const { details: X, quote: q } = assert;

/**
* Throws if multiple entries use the same property name. Otherwise acts
* like `Object.fromEntries`. Use it to protect from property names
* computed from user-provided data.
* like `Object.fromEntries` but hardens the result.
* Use it to protect from property names computed from user-provided data.
*
* @template K,V
* @param {Iterable<[K,V]>} allEntries
* @returns {{[k: K]: V}}
*/
export const fromUniqueEntries = allEntries => {
const entriesArray = [...allEntries];
const result = fromEntries(entriesArray);
const result = harden(fromEntries(entriesArray));
if (ownKeys(result).length === entriesArray.length) {
return result;
}
Expand Down
19 changes: 10 additions & 9 deletions packages/smart-wallet/src/typeGuards.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,25 @@ export const shape = {
},

// invitations
ContractInvitationSpec: M.split(
ContractInvitationSpec: M.splitRecord(
{
source: 'contract',
instance: InstanceHandleShape,
publicInvitationMaker: M.string(),
},
M.partial({
{
invitationArgs: M.array(),
}),
},
),
ContinuingInvitationSpec: M.split(
ContinuingInvitationSpec: M.splitRecord(
{
source: 'continuing',
previousOffer: M.number(),
invitationMakerName: M.string(),
},
M.partial({
{
invitationArgs: M.array(),
}),
},
),
PurseInvitationSpec: {
source: 'purse',
Expand All @@ -41,24 +41,25 @@ export const shape = {
},

// offers
OfferSpec: M.split(
OfferSpec: M.splitRecord(
{
id: M.number(),
// TODO M.unknown() to defer validation
invitationSpec: M.any(),
proposal: ProposalShape,
},
M.partial({ offerArgs: M.any() }),
{ offerArgs: M.any() },
),

// walletFactory
WalletBridgeMsg: M.split(
WalletBridgeMsg: M.splitRecord(
{
owner: M.string(),
type: M.string(),
blockHeight: M.number(),
blockTime: M.number(),
},
{},
M.or({ action: M.string() }, { spendAction: M.string() }),
),
};
Expand Down
4 changes: 2 additions & 2 deletions packages/smart-wallet/src/walletFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ import { makeSmartWallet } from './smartWallet.js';
import { shape } from './typeGuards.js';

const PrivateArgsShape = harden(
M.split(
M.splitRecord(
{ storageNode: M.eref(M.any()) },
M.partial({ bridgeManager: M.eref(M.any()) }),
{ bridgeManager: M.eref(M.any()) },
),
);

Expand Down
Loading

0 comments on commit ab70895

Please sign in to comment.