Skip to content

test(exchange): bring src/api/exchange to 100% offline line coverage - #73

Merged
joeblau merged 1 commit into
mainfrom
test/coverage-cov-exchange
Jul 27, 2026
Merged

test(exchange): bring src/api/exchange to 100% offline line coverage#73
joeblau merged 1 commit into
mainfrom
test/coverage-cov-exchange

Conversation

@joeblau

@joeblau joeblau commented Jul 27, 2026

Copy link
Copy Markdown

What

Tests-only PR — no src/ changes. Brings src/api/exchange to 100% line coverage under the offline CI gate (HL_OFFLINE=1 bun test tests/ --coverage --coverage-reporter=lcov). Previously the method/client bodies were only exercised by the live tests, which are skipped offline.

  • tests/api/exchange/_mockTransport.ts (new): shared offline harness — recording/failing mock transports, deterministic local viem wallets, and prebuilt single-wallet & multi-sig configs with a fixed nonce and signature chain ID, so signed payloads are deterministic and no test touches the network.
  • tests/api/exchange/_client.test.ts (new): 139 offline tests —
    • Every ExchangeClient method path: valid params → exact wire payload (action fields deep-equal, envelope nonce, signature shape); invalid params → ValidationError with zero requests sent.
    • Multi-sig wrapper paths (L1 + user-signed): wrapper shape, per-signer inner signatures, userSetAbstraction payload-action mappings (disabled/unifiedAccount/portfolioMargini/u/p + the skipValidation passthrough), and the signature-chain-ID fallback to the leader wallet.
    • Options plumbing: vaultAddress/expiresAfter options vs config defaults, function-valued defaultExpiresAfter (sync/async/throwing), AbortSignal passthrough, nonceManager (receives the wallet address; sync and promise-returning).
    • skipValidation on both L1 and user-signed paths (no default-filling, invalid values posted as-is).
    • Error passthrough: transport rejections propagate unchanged; all error-envelope shapes (ApiRequestError), including the single-status envelope and the getter-flip fallthrough in getErrorMessage (duck-typed detection is not idempotent).
    • prepareRequest/submitPrepared client wrappers: capture posts nothing, submission posts the prepared payload byte-for-byte, zero-request callbacks fail the prepare.
    • executeUserSignedAction contract: EIP-712 types without a nonce/time field are rejected.

Coverage

Measured with HL_OFFLINE=1 bun test tests/ --coverage --coverage-reporter=lcov (DA lines). Denominators shift slightly because Bun's lcov only emits DA entries for some closing lines of a function once the function has executed.

Area Before After
src/api/exchange/_methods 2435/2785 (87.4%) 2836/2836 (100%)
src/api/exchange/client.ts 127/277 (45.8%) 277/277 (100%)
src/api/exchange/mod.ts 62/62 (100%) 62/62 (100%)
Total 2624/3124 (84.0%) 3175/3175 (100%)
Per-file before → after
File Before After
src/api/exchange/_methods/_base/_action.ts 9/9 (100.0%) 9/9 (100%)
src/api/exchange/_methods/_base/_nonce.ts 23/23 (100.0%) 23/23 (100%)
src/api/exchange/_methods/_base/_semaphore.ts 43/43 (100.0%) 43/43 (100%)
src/api/exchange/_methods/_base/_shell.ts 53/53 (100.0%) 53/53 (100%)
src/api/exchange/_methods/_base/errors.ts 31/35 (88.6%) 35/35 (100%)
src/api/exchange/_methods/_base/execute.ts 105/124 (84.7%) 125/125 (100%)
src/api/exchange/_methods/_base/mod.ts 3/3 (100.0%) 3/3 (100%)
src/api/exchange/_methods/agentEnableDexAbstraction.ts 20/25 (80.0%) 26/26 (100%)
src/api/exchange/_methods/agentSendAsset.ts 28/44 (63.6%) 44/44 (100%)
src/api/exchange/_methods/agentSetAbstraction.ts 21/27 (77.8%) 28/28 (100%)
src/api/exchange/_methods/approveAgent.ts 90/92 (97.8%) 93/93 (100%)
src/api/exchange/_methods/approveBuilderFee.ts 36/42 (85.7%) 43/43 (100%)
src/api/exchange/_methods/authorizeAqav2Role.ts 22/28 (78.6%) 29/29 (100%)
src/api/exchange/_methods/batchModify.ts 55/61 (90.2%) 62/62 (100%)
src/api/exchange/_methods/borrowLend.ts 24/30 (80.0%) 31/31 (100%)
src/api/exchange/_methods/cDeposit.ts 30/36 (83.3%) 37/37 (100%)
src/api/exchange/_methods/cSignerAction.ts 27/33 (81.8%) 34/34 (100%)
src/api/exchange/_methods/cValidatorAction.ts 56/62 (90.3%) 63/63 (100%)
src/api/exchange/_methods/cWithdraw.ts 30/36 (83.3%) 37/37 (100%)
src/api/exchange/_methods/cancel.ts 38/38 (100.0%) 38/38 (100%)
src/api/exchange/_methods/cancelByCloid.ts 28/34 (82.4%) 35/35 (100%)
src/api/exchange/_methods/claimRewards.ts 20/22 (90.9%) 23/23 (100%)
src/api/exchange/_methods/convertToMultiSigUser.ts 55/55 (100.0%) 55/55 (100%)
src/api/exchange/_methods/createSubAccount.ts 21/27 (77.8%) 28/28 (100%)
src/api/exchange/_methods/createVault.ts 25/41 (61.0%) 41/41 (100%)
src/api/exchange/_methods/evmUserModify.ts 21/27 (77.8%) 28/28 (100%)
src/api/exchange/_methods/finalizeEvmContract.ts 30/36 (83.3%) 37/37 (100%)
src/api/exchange/_methods/gossipPriorityBid.ts 23/29 (79.3%) 30/30 (100%)
src/api/exchange/_methods/hip3LiquidatorTransfer.ts 23/29 (79.3%) 30/30 (100%)
src/api/exchange/_methods/linkStakingUser.ts 36/42 (85.7%) 43/43 (100%)
src/api/exchange/_methods/modify.ts 51/57 (89.5%) 58/58 (100%)
src/api/exchange/_methods/noop.ts 20/22 (90.9%) 23/23 (100%)
src/api/exchange/_methods/order.ts 76/76 (100.0%) 76/76 (100%)
src/api/exchange/_methods/perpDeploy.ts 160/166 (96.4%) 167/167 (100%)
src/api/exchange/_methods/prepareRequest.ts 80/80 (100.0%) 80/80 (100%)
src/api/exchange/_methods/registerReferrer.ts 21/27 (77.8%) 28/28 (100%)
src/api/exchange/_methods/reserveRequestWeight.ts 21/27 (77.8%) 28/28 (100%)
src/api/exchange/_methods/scheduleCancel.ts 46/46 (100.0%) 46/46 (100%)
src/api/exchange/_methods/sendAsset.ts 40/46 (87.0%) 47/47 (100%)
src/api/exchange/_methods/sendToEvmWithData.ts 55/55 (100.0%) 55/55 (100%)
src/api/exchange/_methods/setDisplayName.ts 21/27 (77.8%) 28/28 (100%)
src/api/exchange/_methods/setReferrer.ts 21/27 (77.8%) 28/28 (100%)
src/api/exchange/_methods/spotDeploy.ts 110/110 (100.0%) 110/110 (100%)
src/api/exchange/_methods/spotSend.ts 34/40 (85.0%) 41/41 (100%)
src/api/exchange/_methods/spotUser.ts 23/29 (79.3%) 30/30 (100%)
src/api/exchange/_methods/stakingLinkDisableTradingUser.ts 34/44 (77.3%) 45/45 (100%)
src/api/exchange/_methods/subAccountModify.ts 22/28 (78.6%) 29/29 (100%)
src/api/exchange/_methods/subAccountSpotTransfer.ts 24/30 (80.0%) 31/31 (100%)
src/api/exchange/_methods/subAccountTransfer.ts 23/29 (79.3%) 30/30 (100%)
src/api/exchange/_methods/submitPrepared.ts 17/17 (100.0%) 17/17 (100%)
src/api/exchange/_methods/tokenDelegate.ts 38/44 (86.4%) 45/45 (100%)
src/api/exchange/_methods/topUpIsolatedOnlyMargin.ts 23/29 (79.3%) 30/30 (100%)
src/api/exchange/_methods/twapCancel.ts 23/29 (79.3%) 30/30 (100%)
src/api/exchange/_methods/twapOrder.ts 29/35 (82.9%) 36/36 (100%)
src/api/exchange/_methods/updateIsolatedMargin.ts 24/30 (80.0%) 31/31 (100%)
src/api/exchange/_methods/updateLeverage.ts 24/30 (80.0%) 31/31 (100%)
src/api/exchange/_methods/usdClassTransfer.ts 39/45 (86.7%) 46/46 (100%)
src/api/exchange/_methods/usdSend.ts 32/38 (84.2%) 39/39 (100%)
src/api/exchange/_methods/userDexAbstraction.ts 36/42 (85.7%) 43/43 (100%)
src/api/exchange/_methods/userOutcome.ts 48/54 (88.9%) 55/55 (100%)
src/api/exchange/_methods/userPortfolioMargin.ts 36/42 (85.7%) 43/43 (100%)
src/api/exchange/_methods/userSetAbstraction.ts 37/47 (78.7%) 48/48 (100%)
src/api/exchange/_methods/validatorL1Stream.ts 21/27 (77.8%) 28/28 (100%)
src/api/exchange/_methods/vaultDistribute.ts 22/28 (78.6%) 29/29 (100%)
src/api/exchange/_methods/vaultModify.ts 23/29 (79.3%) 30/30 (100%)
src/api/exchange/_methods/vaultTransfer.ts 23/29 (79.3%) 30/30 (100%)
src/api/exchange/_methods/withdraw3.ts 32/38 (84.2%) 39/39 (100%)
src/api/exchange/client.ts 127/277 (45.8%) 277/277 (100%)
src/api/exchange/mod.ts 62/62 (100.0%) 62/62 (100%)

Verification

  • bun run check — all steps pass (format, lint, docs, types, ts7, jsdoc, export).
  • HL_OFFLINE=1 bun test tests/ — 1159 pass, 0 fail, 236 skip (live-endpoint tests).

…ine coverage

Add a mock-transport harness (recording/failing transports, deterministic
local wallets, fixed-nonce single-wallet and multi-sig configs) and 139
offline tests covering every ExchangeClient method path: exact wire
payloads for valid params, ValidationError with zero requests for invalid
params, multi-sig wrappers (L1 + user-signed, userSetAbstraction payload
mappings), options plumbing (vault/expiresAfter/signal/nonceManager,
function-valued defaultExpiresAfter), skipValidation, transport and API
error passthrough, prepareRequest/submitPrepared wrappers, and the
executeUserSignedAction nonce/time-field contract.

src/api/exchange: 2624/3124 (84.0%) -> 3175/3175 (100%) DA lines offline.
@joeblau
joeblau merged commit 8948869 into main Jul 27, 2026
4 of 5 checks passed
@joeblau
joeblau deleted the test/coverage-cov-exchange branch July 27, 2026 05:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant