mirror of
https://github.com/SamyRai/turash.git
synced 2025-12-26 23:01:33 +00:00
- Initialize git repository - Add comprehensive .gitignore for Go projects - Install golangci-lint v2.6.0 (latest v2) globally - Configure .golangci.yml with appropriate linters and formatters - Fix all formatting issues (gofmt) - Fix all errcheck issues (unchecked errors) - Adjust complexity threshold for validation functions - All checks passing: build, test, vet, lint
321 lines
8.6 KiB
Go
321 lines
8.6 KiB
Go
package match
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/damirmukimov/city_resource_graph/models/transport"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestCalculateMatchEconomics(t *testing.T) {
|
|
params := MatchEconomicsParams{
|
|
SourceResource: ResourceFlowSummary{
|
|
ID: "source_001",
|
|
Type: "waste_heat",
|
|
Direction: "output",
|
|
Quantity: 1000,
|
|
Unit: "MWh",
|
|
CostPerUnit: 20, // €20/MWh disposal cost avoided
|
|
},
|
|
TargetResource: ResourceFlowSummary{
|
|
ID: "target_001",
|
|
Type: "process_heat",
|
|
Direction: "input",
|
|
Quantity: 1000,
|
|
Unit: "MWh",
|
|
CostPerUnit: 50, // €50/MWh value to target
|
|
},
|
|
DistanceKm: 5.0,
|
|
InitialInvestment: 25000, // €25k setup cost
|
|
SymbiosisType: transport.SymbiosisEnergyCascading,
|
|
Complexity: "medium",
|
|
RiskLevel: "low",
|
|
AnnualQuantity: 8000, // 8000 MWh/year
|
|
UnitValue: 35, // €35/MWh exchange value
|
|
CO2ReductionFactor: 0.0005, // 0.0005 tonnes CO2/MWh
|
|
}
|
|
|
|
assumptions := DefaultCalculationAssumptions()
|
|
|
|
result, err := CalculateMatchEconomics(params, assumptions)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, result)
|
|
|
|
// Validate basic structure
|
|
assert.Equal(t, "match_source_001_target_001", result.MatchID)
|
|
assert.Equal(t, params.SourceResource, result.SourceResource)
|
|
assert.Equal(t, params.TargetResource, result.TargetResource)
|
|
|
|
// Validate calculations are reasonable
|
|
assert.Greater(t, result.Calculations.AnnualSavings, 0.0)
|
|
assert.Greater(t, result.Calculations.NPV10Years, -params.InitialInvestment)
|
|
assert.LessOrEqual(t, result.Calculations.PaybackPeriodYears, 10.0)
|
|
assert.GreaterOrEqual(t, result.Calculations.IRRPercent, -100.0)
|
|
assert.LessOrEqual(t, result.Calculations.IRRPercent, 3000.0) // Allow higher IRR for good investments
|
|
assert.Greater(t, result.Calculations.CO2ReductionTonnes, 0.0)
|
|
|
|
// Validate transportation costs
|
|
assert.Greater(t, result.Calculations.TransportationCosts.AnnualCost, 0.0)
|
|
assert.Equal(t, 5.0, result.Calculations.TransportationCosts.DistanceKm)
|
|
assert.Equal(t, "heat_pipe", result.Calculations.TransportationCosts.Method)
|
|
|
|
// Validate implementation complexity
|
|
assert.Contains(t, []string{"low", "medium", "high"}, result.Calculations.ImplementationComplexity)
|
|
|
|
// Validate regulatory requirements
|
|
assert.Contains(t, result.Calculations.RegulatoryRequirements, "energy_distribution_license")
|
|
}
|
|
|
|
func TestCalculateAnnualSavings(t *testing.T) {
|
|
params := MatchEconomicsParams{
|
|
SourceResource: ResourceFlowSummary{
|
|
CostPerUnit: 20, // €20/unit disposal cost
|
|
},
|
|
TargetResource: ResourceFlowSummary{
|
|
CostPerUnit: 50, // €50/unit value
|
|
},
|
|
AnnualQuantity: 1000, // 1000 units/year
|
|
}
|
|
|
|
savings := calculateAnnualSavings(params)
|
|
expected := float64((20 + 50) * 1000) // €70,000
|
|
assert.Equal(t, expected, savings)
|
|
}
|
|
|
|
func TestCalculatePaybackPeriod(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
initialInvestment float64
|
|
annualNetCashFlow float64
|
|
expected float64
|
|
}{
|
|
{
|
|
name: "normal payback",
|
|
initialInvestment: 25000,
|
|
annualNetCashFlow: 12500,
|
|
expected: 2.0,
|
|
},
|
|
{
|
|
name: "never pays back",
|
|
initialInvestment: 25000,
|
|
annualNetCashFlow: 0,
|
|
expected: 999,
|
|
},
|
|
{
|
|
name: "pays back in first year",
|
|
initialInvestment: 5000,
|
|
annualNetCashFlow: 10000,
|
|
expected: 0.5,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := calculatePaybackPeriod(tt.initialInvestment, tt.annualNetCashFlow)
|
|
assert.Equal(t, tt.expected, result)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestAssessImplementationComplexity(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
params MatchEconomicsParams
|
|
expected string
|
|
}{
|
|
{
|
|
name: "low complexity",
|
|
params: MatchEconomicsParams{
|
|
DistanceKm: 1.0,
|
|
InitialInvestment: 10000,
|
|
SymbiosisType: transport.SymbiosisDataSharing,
|
|
},
|
|
expected: "low",
|
|
},
|
|
{
|
|
name: "medium complexity",
|
|
params: MatchEconomicsParams{
|
|
DistanceKm: 10.0,
|
|
InitialInvestment: 30000,
|
|
SymbiosisType: transport.SymbiosisEnergyCascading,
|
|
},
|
|
expected: "medium",
|
|
},
|
|
{
|
|
name: "high complexity",
|
|
params: MatchEconomicsParams{
|
|
DistanceKm: 50.0,
|
|
InitialInvestment: 100000,
|
|
SymbiosisType: transport.SymbiosisWasteToResource,
|
|
},
|
|
expected: "high",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := assessImplementationComplexity(tt.params)
|
|
assert.Equal(t, tt.expected, result)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestIdentifyRegulatoryRequirements(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
params MatchEconomicsParams
|
|
expected []string
|
|
}{
|
|
{
|
|
name: "waste handling requires permits",
|
|
params: MatchEconomicsParams{
|
|
SymbiosisType: transport.SymbiosisWasteToResource,
|
|
},
|
|
expected: []string{"waste_disposal_permit", "environmental_impact_assessment"},
|
|
},
|
|
{
|
|
name: "energy transfer requires license",
|
|
params: MatchEconomicsParams{
|
|
SymbiosisType: transport.SymbiosisEnergyCascading,
|
|
},
|
|
expected: []string{"energy_distribution_license"},
|
|
},
|
|
{
|
|
name: "long distance requires transport license",
|
|
params: MatchEconomicsParams{
|
|
DistanceKm: 60.0,
|
|
SymbiosisType: transport.SymbiosisDataSharing,
|
|
},
|
|
expected: []string{"transport_license"},
|
|
},
|
|
{
|
|
name: "high value requires insurance",
|
|
params: MatchEconomicsParams{
|
|
UnitValue: 100,
|
|
AnnualQuantity: 2000, // €200k annual value
|
|
SymbiosisType: transport.SymbiosisDataSharing,
|
|
},
|
|
expected: []string{"liability_insurance"},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := identifyRegulatoryRequirements(tt.params)
|
|
for _, expectedReq := range tt.expected {
|
|
assert.Contains(t, result, expectedReq)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDetermineTransportMethod(t *testing.T) {
|
|
tests := []struct {
|
|
symbiosisType transport.SymbiosisType
|
|
expected string
|
|
}{
|
|
{transport.SymbiosisWasteToResource, "truck"},
|
|
{transport.SymbiosisEnergyCascading, "heat_pipe"},
|
|
{transport.SymbiosisUtilitySharing, "pipeline"},
|
|
{transport.SymbiosisDataSharing, "network"},
|
|
{transport.SymbiosisKnowledgeSharing, "truck"}, // default
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
result := determineTransportMethod(tt.symbiosisType)
|
|
assert.Equal(t, tt.expected, result)
|
|
}
|
|
}
|
|
|
|
func TestFeasibilityToScore(t *testing.T) {
|
|
tests := []struct {
|
|
feasibility string
|
|
expected float64
|
|
}{
|
|
{"high", 0.9},
|
|
{"medium", 0.6},
|
|
{"low", 0.3},
|
|
{"unknown", 0.5},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
result := feasibilityToScore(tt.feasibility)
|
|
assert.Equal(t, tt.expected, result)
|
|
}
|
|
}
|
|
|
|
func TestValidateEconomicCalculation(t *testing.T) {
|
|
validCalc := &EconomicCalculation{
|
|
MatchID: "test_match",
|
|
Calculations: MatchCalculations{
|
|
AnnualSavings: 50000,
|
|
PaybackPeriodYears: 2.0,
|
|
IRRPercent: 15.0,
|
|
},
|
|
}
|
|
|
|
err := ValidateEconomicCalculation(validCalc)
|
|
assert.NoError(t, err)
|
|
|
|
// Test invalid cases
|
|
invalidCalc := &EconomicCalculation{
|
|
Calculations: MatchCalculations{
|
|
AnnualSavings: -1000, // Negative savings
|
|
},
|
|
}
|
|
err = ValidateEconomicCalculation(invalidCalc)
|
|
assert.Error(t, err)
|
|
|
|
emptyIDCalc := &EconomicCalculation{
|
|
Calculations: MatchCalculations{
|
|
AnnualSavings: 50000,
|
|
},
|
|
}
|
|
err = ValidateEconomicCalculation(emptyIDCalc)
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestCalculateMatchNPV(t *testing.T) {
|
|
params := MatchEconomicsParams{
|
|
InitialInvestment: 100000, // High investment
|
|
}
|
|
assumptions := DefaultCalculationAssumptions()
|
|
|
|
npv := calculateMatchNPV(params, assumptions, 5000, 3000) // Only €2k net annual benefit
|
|
|
|
// Should be negative (high investment, low returns)
|
|
assert.Less(t, npv, 0.0)
|
|
}
|
|
|
|
func TestCalculateMatchIRR(t *testing.T) {
|
|
params := MatchEconomicsParams{
|
|
InitialInvestment: 25000,
|
|
}
|
|
assumptions := DefaultCalculationAssumptions()
|
|
|
|
irr := calculateMatchIRR(params, assumptions, 12500, 2500) // €10k net annual benefit
|
|
|
|
// IRR should be reasonable (positive but not too high)
|
|
assert.Greater(t, irr, 0.0)
|
|
assert.Less(t, irr, 0.5) // Less than 50%
|
|
}
|
|
|
|
func TestGenerateMatchID(t *testing.T) {
|
|
id := generateMatchID("source_123", "target_456")
|
|
assert.Equal(t, "match_source_123_target_456", id)
|
|
}
|
|
|
|
func TestCalculateMatchEconomics_InvalidParams(t *testing.T) {
|
|
params := MatchEconomicsParams{
|
|
// Missing resource IDs
|
|
SourceResource: ResourceFlowSummary{ID: ""},
|
|
TargetResource: ResourceFlowSummary{ID: ""},
|
|
}
|
|
|
|
assumptions := DefaultCalculationAssumptions()
|
|
_, err := CalculateMatchEconomics(params, assumptions)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "source and target resource IDs are required")
|
|
}
|