Task: Write round-trip tests for instrument parse dispatch
Table of Contents
This page documents a task in the Fix rfl complexity failure (Windows + macOS CI) story. It captures the goal, current status, acceptance, and any notes or results.
Goal
Validate the new instrument parse dispatch with round-trip tests that exercise the full
server → client JSON path. Tests must compile and pass on Linux, Windows (MSVC), and macOS
(Clang) — their compilation on MSVC/Clang is itself evidence that AddTagsToVariants has
been successfully eliminated from the client parse path.
Status
| Field | Value |
|---|---|
| State | DONE |
| Parent story | Fix rfl complexity failure (Windows + macOS CI) |
| Now | Nothing. |
| Waiting on | Nothing. |
| Next | N/A. |
| Last touched | 2026-05-31 |
Acceptance
- At least one test per instrument family: bond, credit, commodity, scripted, composite, FX (at least 2 leaf types: forward + one option), rates/swap (at least 2 leaf types: FRA + vanilla swap), equity (at least 2 leaf types: option + forward).
- Each test serializes a fully-populated response struct using
rfl::json::write<rfl::AddTagsToVariants>(matching server behaviour), then calls the new client parse function, and asserts:trade_export_item.instrumentholds the expectedstd::variantalternative.- Key instrument fields round-trip correctly (instrument_id, a family-specific field).
trade_export_item.trade.classification.product_typematches.
- A test for an unknown
(product_type, trade_type)combination asserts the instrument isstd::monostateand that awarnlog was emitted. - A test for a malformed instrument JSON asserts the call returns
std::nulloptand that anerrorlog was emitted. - All tests compile with MSVC (no
C1202) and Clang (no fold-expression error).
Plan
(Transient.)
Test structure
One test fixture (or test file) per family is sufficient. Tests live in the
ores.qt.api test target alongside existing tests.
Pattern per test:
// 1. Build a response the way the server does messaging::get_trade_instrument_response resp{ .success = true, .trade = make_test_trade(product_type::fx, "FxForward"), .instrument = fx_instrument_variant{make_fx_forward()} }; // 2. Serialize as the server does const auto json = rfl::json::write<rfl::AddTagsToVariants>(resp); // 3. Run client parse auto result = parse_trade_instrument(json); // the new function under test // 4. Assert ASSERT_TRUE(result.has_value()); auto* fx_fwd = std::get_if<fx_instrument_variant>(&result->instrument); ASSERT_NE(fx_fwd, nullptr); auto* fwd = std::get_if<fx_forward_instrument>(fx_fwd); ASSERT_NE(fwd, nullptr); EXPECT_EQ(fwd->currency_pair, "EURUSD");
Leaf types to cover
| Family | Leaf types to test |
|---|---|
| Bond | bond_instrument |
| Credit | credit_instrument |
| Commodity | commodity_instrument |
| Scripted | scripted_instrument |
| Composite | composite_instrument_data (with legs) |
| FX | fx_forward_instrument, fx_vanilla_option_instrument |
| Rates | fra_instrument, vanilla_swap_instrument (with legs) |
| Equity | equity_option_instrument, equity_forward_instrument |
Notes
PRs
| PR | Title |
|---|---|
| 941 | [ores.qt.api] Task 3: extract parse_trade_instrument + tests |
Review
| # | Comment summary | File | Decision | Notes |
|---|---|---|---|---|
| 1 | READ_FLAT/READ_LEGS identical; unhygienic | parse_trade_instrument.cpp | Applied | Replaced both macros with try_parse<T>() template (8c9cad6b); thread resolved |