test(trading): stop mocking suggestSlippageBps out of its own test - #982
test(trading): stop mocking suggestSlippageBps out of its own test#982gomesalexandre wants to merge 1 commit into
Conversation
The test suite mocked @cowprotocol/sdk-order-book's getQuoteAmountsWithCosts, which does not exist anywhere in this codebase — the real export is getQuoteAmountsAndCosts. That mock never connected to the code under test. It also mocked percentageToBps as `percent * 100`, where the real function multiplies by 10_000 (it treats its input as a portion of 1, not an already-scaled percentage) — every bps assertion was checked against a conversion factor that doesn't exist in production. With getSlippagePercent, suggestSlippageFromFee and suggestSlippageFromVolume also fully mocked, the only logic any of the 7 existing tests actually exercised was the final Math.max/Math.min clamp. Proven with a mutation check: inverting suggestSlippageBps.ts's `isSell` computation left all 7 tests green. Production code is unaffected — both mocked-vs-real discrepancies happened to cancel out in the old tests' hardcoded expectations, and getSlippagePercent's real portion-of-1 convention paired with the real percentageToBps already produces correct bps values. Rewrites the suite to run getQuoteAmountsAndCosts, suggestSlippageFromFee, suggestSlippageFromVolume, getSlippagePercent and percentageToBps for real in new SELL and BUY end-to-end cases (expected values hand-derived from source and confirmed by execution: 100 and 150 bps respectively) — the BUY case specifically closes the isSell blind spot, since no existing test exercised the buy branch at all. Keeps a legitimate jest.spyOn(slippageUtils, 'getSlippagePercent') for the clamp-boundary tests, now using the correct portion-of-1 convention instead of the old percent-unit mock. Re-ran the same mutation check against the new suite: inverting `isSell` now fails the BUY test (150 -> 148), proving the tests are no longer blind to it.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (1)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthroughThe slippage tests now run real calculation paths for SELL and BUY quotes. They add a quote factory and use targeted spies for clamping tests. The suite verifies lower bounds, EthFlow defaults, upper bounds, and distinct results for both order kinds. ChangesSlippage calculation test coverage
Estimated code review effort: 3 (Moderate) | ~20 minutes Merge Risk: ⚪ Minimal · up to This test-only change exercises real SELL and BUY slippage calculations and preserves clamp coverage without changing production behavior. No actionable merge-blocking risk remains after normal checks and review. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Does what it says on the box, mostly test-only, production code is unchanged.
What's wrong
suggestSlippageBps.test.tsmocked@cowprotocol/sdk-order-book'sgetQuoteAmountsWithCosts— that export doesn't exist anywhere in this codebase. The real function isgetQuoteAmountsAndCosts(called atsuggestSlippageBps.ts:35). The mock never connected to the code under test.It also mocked
percentageToBpsaspercent * 100, where the real function (packages/common/src/utils/math.ts:13) multiplies by10_000n— it treats its input as a portion of 1, not an already-scaled percentage.With
getSlippagePercent,suggestSlippageFromFeeandsuggestSlippageFromVolumealso fully mocked, the only logic any of the 7 existing tests actually exercised was the finalMath.max(Math.min(...), lowerCap)clamp insuggestSlippageBps.ts:76. TheisSellcomputation (suggestSlippageBps.ts:30) — which every one of those mocked functions consumes — was never actually tested.Proof, mutation-check style: inverting
isSelltoquote.quote.kind !== OrderKind.SELLand running the existing suite: all 7 tests still passed.Is this masking a real bug?
No — checked explicitly.
getSlippagePercent's docstring states it "Returns a percentage as a portion of 1", and the realpercentageToBpsmultiplies by10_000, so0.005(0.5%) correctly becomes50bps. Production is self-consistent and correct; the two test mocks' errors (wrong function name, wrong scale) happened to cancel out in the old hardcoded expectations without ever touching real code.Fix
Stops mocking the functions actually under test.
getQuoteAmountsAndCosts,suggestSlippageFromFee,suggestSlippageFromVolume,getSlippagePercentandpercentageToBpsare all pure, deterministic, I/O-free — they now run for real.Adds two end-to-end cases (SELL and BUY) with expected bps values hand-derived from source and confirmed by execution:
isSellblind spot)Keeps the clamp-boundary tests (Lower/Upper bound clamping) using a
jest.spyOn(slippageUtils, 'getSlippagePercent')— legitimate isolation for testingMath.max/Math.minbehavior specifically — now using the real portion-of-1 convention (0.01for 1%, not1) so expected bps values actually match what the realpercentageToBpswould produce.Receipts
Mutation check re-run against the new suite:
The BUY case now genuinely catches it, where none of the old 7 caught it at all.
suggestSlippageBps.tsitself is untouched —git diff --statshows only the test file changed.Codex review
Attempted a synchronous adversarial Codex pass; it hit a transient "model at capacity" error twice in a row (not a stall — exited cleanly both times, first attempt had already done real investigation confirming module resolution and compiled dist output before erroring). Falling back to self-review, backed by the empirical evidence above rather than just reasoning:
jest.spyOnmodule-resolution concern is directly proven, not assumed: all 7 clamp tests pass with results matching the specific mocked values (-0.01,0.0001,0.01,0.02,1.5,2,1) — if the spy weren't intercepting the callsuggestSlippageBps.tsmakes, those tests would get the real computed slippage instead and almost certainly fail on the hardcoded expectations.Summary by CodeRabbit