package calculation_validation import ( "math/big" "testing" ) func TestValidateThresholdCheck(t *testing.T) { validator := NewProfitValidator(1.0) tests := []struct { name string check *ThresholdCheck wantValid bool }{ { name: "valid executable - profit above threshold", check: &ThresholdCheck{ NetProfit: big.NewFloat(834.210302), MinThreshold: big.NewFloat(0.0001), Passed: true, }, wantValid: true, }, { name: "valid rejection - profit below threshold", check: &ThresholdCheck{ NetProfit: big.NewFloat(0.00001), MinThreshold: big.NewFloat(0.0001), Passed: false, }, wantValid: true, }, { name: "invalid - should pass but marked failed", check: &ThresholdCheck{ NetProfit: big.NewFloat(1.0), MinThreshold: big.NewFloat(0.0001), Passed: false, // Wrong! }, wantValid: false, }, { name: "edge case - profit equals threshold", check: &ThresholdCheck{ NetProfit: big.NewFloat(0.0001), MinThreshold: big.NewFloat(0.0001), Passed: true, }, wantValid: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { valid := validator.validateThresholdCheck(tt.check) if valid != tt.wantValid { t.Errorf("validateThresholdCheck() = %v, want %v", valid, tt.wantValid) } }) } } func TestValidateThresholdComparison(t *testing.T) { validator := NewProfitValidator(1.0) minThresholdWei := big.NewInt(100000000000000) // 0.0001 ETH tests := []struct { name string netProfit *big.Float shouldExecute bool wantValid bool wantExecutable bool }{ { name: "bug fix scenario - 834 ETH", netProfit: big.NewFloat(834.210302), shouldExecute: true, wantValid: true, wantExecutable: true, }, { name: "below threshold", netProfit: big.NewFloat(0.00001), shouldExecute: false, wantValid: true, wantExecutable: false, }, { name: "exactly at threshold", netProfit: big.NewFloat(0.0001), shouldExecute: true, wantValid: true, wantExecutable: true, }, { name: "large profit", netProfit: big.NewFloat(1249.324868), shouldExecute: true, wantValid: true, wantExecutable: true, }, { name: "buggy comparison - should reject but marked executable", netProfit: big.NewFloat(0.00001), shouldExecute: true, // Wrong! wantValid: false, wantExecutable: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result := validator.ValidateThresholdComparison(tt.netProfit, minThresholdWei, tt.shouldExecute) if result.IsValid != tt.wantValid { t.Errorf("ValidateThresholdComparison() valid = %v, want %v", result.IsValid, tt.wantValid) if len(result.Errors) > 0 { t.Logf("Errors: %v", result.Errors) } } }) } } func TestValidateV3Calculation(t *testing.T) { validator := NewProfitValidator(1.0) tests := []struct { name string calc SwapCalculation wantValid bool wantWarns bool }{ { name: "valid calculation with 0.3% fee", calc: SwapCalculation{ AmountIn: big.NewInt(1000000), AmountOut: big.NewInt(995000), Fee: 3000, FinalOut: big.NewInt(992015), // ~0.3% less }, wantValid: true, wantWarns: false, }, { name: "zero output", calc: SwapCalculation{ AmountIn: big.NewInt(1000000), AmountOut: big.NewInt(0), Fee: 3000, FinalOut: big.NewInt(0), }, wantValid: true, wantWarns: true, }, { name: "invalid - finalOut > amountOut", calc: SwapCalculation{ AmountIn: big.NewInt(1000000), AmountOut: big.NewInt(1000000), Fee: 3000, FinalOut: big.NewInt(1100000), // Impossible! }, wantValid: false, wantWarns: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result := validator.ValidateV3Calculation(tt.calc) if result.IsValid != tt.wantValid { t.Errorf("ValidateV3Calculation() valid = %v, want %v", result.IsValid, tt.wantValid) if len(result.Errors) > 0 { t.Logf("Errors: %v", result.Errors) } } hasWarnings := len(result.Warnings) > 0 if hasWarnings != tt.wantWarns { t.Errorf("ValidateV3Calculation() warnings = %v, want %v", hasWarnings, tt.wantWarns) } }) } } func TestCompareETHtoWei(t *testing.T) { validator := NewProfitValidator(1.0) tests := []struct { name string ethValue *big.Float weiValue *big.Int wantValid bool }{ { name: "correct conversion - 1 ETH", ethValue: big.NewFloat(1.0), weiValue: big.NewInt(1e18), wantValid: true, }, { name: "correct conversion - 0.0001 ETH", ethValue: big.NewFloat(0.0001), weiValue: big.NewInt(1e14), wantValid: true, }, { name: "incorrect conversion - off by factor of 1000", ethValue: big.NewFloat(1.0), weiValue: big.NewInt(1e15), // Wrong! wantValid: false, }, { name: "bug scenario - using Int(nil) without scaling", ethValue: big.NewFloat(834.210302), weiValue: big.NewInt(834), // Buggy conversion! wantValid: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result := validator.CompareETHtoWei(tt.ethValue, tt.weiValue) if result.IsValid != tt.wantValid { t.Errorf("CompareETHtoWei() valid = %v, want %v", result.IsValid, tt.wantValid) if len(result.Errors) > 0 { t.Logf("Errors: %v", result.Errors) } } }) } } func TestCalculateStatistics(t *testing.T) { profits := []*big.Float{ big.NewFloat(0.311819), big.NewFloat(1249.324868), big.NewFloat(2.166576), big.NewFloat(1363.860509), big.NewFloat(83.981698), } total, average, max, min := CalculateStatistics(profits) // Verify total expectedTotal := 2699.645470 // Sum of all values totalFloat, _ := total.Float64() if diff := totalFloat - expectedTotal; diff > 0.0001 || diff < -0.0001 { t.Errorf("Total = %.6f, want %.6f", totalFloat, expectedTotal) } // Verify average expectedAvg := expectedTotal / 5.0 avgFloat, _ := average.Float64() if diff := avgFloat - expectedAvg; diff > 0.0001 || diff < -0.0001 { t.Errorf("Average = %.6f, want %.6f", avgFloat, expectedAvg) } // Verify max maxFloat, _ := max.Float64() if maxFloat != 1363.860509 { t.Errorf("Max = %.6f, want 1363.860509", maxFloat) } // Verify min minFloat, _ := min.Float64() if minFloat != 0.311819 { t.Errorf("Min = %.6f, want 0.311819", minFloat) } } func TestValidateOpportunity(t *testing.T) { validator := NewProfitValidator(1.0) tests := []struct { name string opp *OpportunityTestData wantValid bool wantErrs int wantWarns int }{ { name: "valid executable opportunity", opp: &OpportunityTestData{ ID: "test_1", NetProfitETH: big.NewFloat(1.0), IsExecutable: true, RejectReason: "", ThresholdCheck: &ThresholdCheck{ NetProfit: big.NewFloat(1.0), MinThreshold: big.NewFloat(0.0001), Passed: true, }, }, wantValid: true, wantErrs: 0, wantWarns: 0, }, { name: "invalid - executable but zero profit", opp: &OpportunityTestData{ ID: "test_2", NetProfitETH: big.NewFloat(0.0), IsExecutable: true, RejectReason: "", }, wantValid: false, wantErrs: 1, wantWarns: 0, }, { name: "warning - executable but has reject reason", opp: &OpportunityTestData{ ID: "test_3", NetProfitETH: big.NewFloat(1.0), IsExecutable: true, RejectReason: "some reason", }, wantValid: true, wantErrs: 0, wantWarns: 1, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result := validator.ValidateOpportunity(tt.opp) if result.IsValid != tt.wantValid { t.Errorf("ValidateOpportunity() valid = %v, want %v", result.IsValid, tt.wantValid) } if len(result.Errors) != tt.wantErrs { t.Errorf("ValidateOpportunity() errors = %d, want %d: %v", len(result.Errors), tt.wantErrs, result.Errors) } if len(result.Warnings) != tt.wantWarns { t.Errorf("ValidateOpportunity() warnings = %d, want %d: %v", len(result.Warnings), tt.wantWarns, result.Warnings) } }) } }