test(lp): unit tests for lp positions subcommand (offline mocked) - #19
Merged
Conversation
lp.ts is 1803 LOC — the largest still-untested CLI handler at the
start of this PR stack. The full surface (add/remove/farm/claim/
discover/pipeline/compound/autopilot/positions) needs to be split
across multiple PRs. This commit covers only the smallest leaf
(`lp positions`) so the basic --chain / --protocol / --address
routing has shape-pinning regression coverage; other subcommands
will follow in their own PRs.
4 new tests in lp-positions.test.ts:
- errors when --chain is missing (no protocol enumeration)
Asserts the standard "--chain is required" error envelope.
- returns an empty array when balanceOf returns 0n across every
protocol on the chain
The viem.readContract mock returns 0n for every NPM contract;
every protocol's NFT enumeration short-circuits and the output
is the canonical empty array.
- --protocol filter narrows enumeration to a single protocol
Pins that --protocol controls the loop scope.
- --address parameter overrides DEFI_WALLET_ADDRESS without throwing
Pins the resolveAccount priority and ensures opts.address wins.
Mock strategy:
- vi.mock("viem"): createPublicClient.readContract returns 0n,
so every NPM balanceOf reports zero NFTs and the loop is
skipped. http() is a no-op factory.
- vi.mock("@hypurrquant/defi-protocols"): createMerchantMoeLB
returns an adapter whose discoverRewardedPools / etc. return [],
so the LB scan path doesn't reach the network either.
- All other adapter constructors fall through to the real
implementations because the test protocols (uniswap-v2-monad,
uniswap-v3-monad) don't trigger them in the empty-positions
branch.
Verified:
- pnpm -C ts -r build — clean.
- pnpm -C ts -r lint — 3 packages, tsc --noEmit clean.
- pnpm -C ts -r test — defi-core 32/32, defi-protocols 43/43,
defi-cli 98/98 (+4 lp-positions tests on
a baseline of 94 swap tests; the merged
main after PR #18 will be 102 once both
land).
Hiksang
added a commit
that referenced
this pull request
May 16, 2026
Closes 5 Dependabot alerts on ts/pnpm-lock.yaml: high fast-uri 3.1.0 -> 3.1.2 (#19 path traversal, #23 host confusion) medium hono 4.12.16 -> 4.12.19 (#22 CSS injection in JSX SSR) medium hono 4.12.16 -> 4.12.19 (#20 cache leak: Vary ignored) low hono 4.12.16 -> 4.12.19 (#21 JWT NumericDate validation) Both are transitive via @modelcontextprotocol/sdk: fast-uri : @modelcontextprotocol/sdk -> ajv -> fast-uri hono : @modelcontextprotocol/sdk -> {hono, @hono/node-server -> hono} Existing hono override (>=4.12.12) was below the fix line; bumped to >=4.12.18. fast-uri had no override; added >=3.1.2. Verified: pnpm install + pnpm -r build + pnpm -r test all green (defi-core 49 / defi-protocols 147 / defi-cli 235 = 431 passed).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
lp.tsis 1803 LOC — the largest still-untested CLI handler at the start of this PR stack. The full surface (add/remove/farm/claim/discover/pipeline/compound/autopilot/positions) needs to be split across multiple PRs. This PR covers only the smallest leaf,lp positions, so the basic--chain/--protocol/--addressrouting has shape-pinning regression coverage; other subcommands follow in their own PRs.What's added
ts/packages/defi-cli/src/commands/lp-positions.test.ts— 4 tests:--chainmissing--chain.*requiredbalanceOf=0n--protocol uniswap-v3-monadfilter--address 0x…BEEFoverrideDEFI_WALLET_ADDRESSset inbeforeEach; call completes without throwingMock strategy
vi.mock("viem"):createPublicClient.readContractreturns0nfor every call. Every NPMbalanceOfreports zero NFTs and the per-protocol enumeration short-circuits.http()is a no-op factory.vi.mock("@hypurrquant/defi-protocols"):createMerchantMoeLBreturns an adapter whosediscoverRewardedPools/findUserBinsWithBalance/ etc. return[], so the LB scan path doesn't reach the network either.uniswap-v2-monad,uniswap-v3-monad) don't trigger them in the empty-positions branch.Tests run offline and deterministically.
Test plan
pnpm -C ts -r build— clean.pnpm -C ts -r lint— 3 packages,tsc --noEmitclean.pnpm -C ts -r test— defi-core 32/32, defi-protocols 43/43, defi-cli 98/98 (+4 lp-positions on a baseline of 94 swap tests; with PR test(swap): add happy-path coverage for openocean/lifi/relay/liquid providers #18's 4 swap happy-paths already merged, post-merge main is 102).lp positionszero-result shape — it returns[]directly viaprintOutput(results, getOpts())in lp.ts.Sibling PR / next stack
PR #18 (
test/swap-all-providers-coverage) was merged just before this PR was opened. The next stack items forlp(add/remove/farm/claim) need viem mocking that goes deeper than0n— separate PRs.🤖 Generated with Claude Code