using QuantEngine.Core.Domain; using Xunit; namespace QuantEngine.Core.Tests; public sealed class FormulaCanonicalCoverageTests { [Fact] public void ActiveFormulaImplementationsReturnTheirCanonicalIds() { var input = new Dictionary { ["velocity_1d"] = 0.01d, ["velocity_threshold"] = 0.02d, ["cash_shortfall_krw"] = 100d, ["recovered_krw"] = 100d, ["proposal_gate"] = "PASS", ["cycle_detected"] = false, ["intraday_restriction_gate"] = "PASS", ["portfolio_health_label"] = "HEALTHY", ["rs_v2_score"] = 1d, ["technical_score"] = 1d, ["current_price"] = 90d, ["stop_loss_price"] = 100d, ["gap_threshold"] = 0.05d, ["price"] = 10_000d, }; var results = new[] { FormulaCanonicalCoverage.AntiChaseV1(input), FormulaCanonicalCoverage.CashRecoveryV1(input), FormulaCanonicalCoverage.ComprehensiveProposalV1(input), FormulaCanonicalCoverage.DfgV1(input), FormulaCanonicalCoverage.IntradayV1(input), FormulaCanonicalCoverage.PortfolioHealthV1(input), FormulaCanonicalCoverage.RsV2Fusion(input), FormulaCanonicalCoverage.StopBreachV1(input), FormulaCanonicalCoverage.TickNormV1(input), }; Assert.Equal(9, results.Length); Assert.All(results, result => Assert.NotEqual("DATA_MISSING — 하네스 업데이트 필요", result["gate"])); Assert.Equal(9, results.Select(result => result["formula_id"]).Distinct().Count()); } }