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.
1. 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.
2. 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 |
3. 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).
4. Plan
(Transient.)
4.1. 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");
4.2. 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 |
5. Notes
6. PRs
| PR | Title |
|---|---|
| 941 | [ores.qt.api] Task 3: extract parse_trade_instrument + tests |
7. 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 |