Team Ai
Apppublic

blackopsrepl/portfolio-optimization-python

sourceHugging Faceapache-2.0updated 10mo agoView on Hugging Face
1likes
test_solver_config.py91 linesDownload Raw Back to tests
1"""
2Tests for solver configuration functionality.
3
4Tests the create_solver_config factory function and dynamic termination time.
5"""
6import pytest
7from portfolio_optimization.solver import create_solver_config
8from portfolio_optimization.domain import SolverConfigModel
9
10
11class TestCreateSolverConfig:
12    """Tests for the create_solver_config factory function."""
13
14    def test_default_termination(self):
15        """Default solver should terminate after 30 seconds."""
16        config = create_solver_config()
17        assert config.termination_config.spent_limit.seconds == 30
18
19    def test_custom_termination_60s(self):
20        """Custom termination time of 60 seconds should be respected."""
21        config = create_solver_config(termination_seconds=60)
22        assert config.termination_config.spent_limit.seconds == 60
23
24    def test_custom_termination_10s(self):
25        """Minimum termination time of 10 seconds should work."""
26        config = create_solver_config(termination_seconds=10)
27        assert config.termination_config.spent_limit.seconds == 10
28
29    def test_custom_termination_300s(self):
30        """Maximum termination time of 300 seconds (5 min) should work."""
31        config = create_solver_config(termination_seconds=300)
32        assert config.termination_config.spent_limit.seconds == 300
33
34    def test_solver_config_has_correct_solution_class(self):
35        """Solver config should reference PortfolioOptimizationPlan."""
36        from portfolio_optimization.domain import PortfolioOptimizationPlan
37        config = create_solver_config()
38        assert config.solution_class == PortfolioOptimizationPlan
39
40    def test_solver_config_has_correct_entity_class(self):
41        """Solver config should include StockSelection entity."""
42        from portfolio_optimization.domain import StockSelection
43        config = create_solver_config()
44        assert StockSelection in config.entity_class_list
45
46
47class TestSolverConfigModel:
48    """Tests for the SolverConfigModel Pydantic model."""
49
50    def test_default_values(self):
51        """SolverConfigModel should have default termination of 30 seconds."""
52        model = SolverConfigModel()
53        assert model.termination_seconds == 30
54
55    def test_custom_termination(self):
56        """SolverConfigModel should accept custom termination."""
57        model = SolverConfigModel(termination_seconds=60)
58        assert model.termination_seconds == 60
59
60    def test_alias_serialization(self):
61        """SolverConfigModel should serialize with camelCase alias."""
62        model = SolverConfigModel(termination_seconds=45)
63        data = model.model_dump(by_alias=True)
64        assert "terminationSeconds" in data
65        assert data["terminationSeconds"] == 45
66
67    def test_alias_deserialization(self):
68        """SolverConfigModel should deserialize from camelCase."""
69        model = SolverConfigModel.model_validate({"terminationSeconds": 90})
70        assert model.termination_seconds == 90
71
72    def test_minimum_validation(self):
73        """SolverConfigModel should reject termination < 10 seconds."""
74        with pytest.raises(ValueError):
75            SolverConfigModel(termination_seconds=5)
76
77    def test_maximum_validation(self):
78        """SolverConfigModel should reject termination > 300 seconds."""
79        with pytest.raises(ValueError):
80            SolverConfigModel(termination_seconds=400)
81
82    def test_boundary_min(self):
83        """SolverConfigModel should accept exactly 10 seconds."""
84        model = SolverConfigModel(termination_seconds=10)
85        assert model.termination_seconds == 10
86
87    def test_boundary_max(self):
88        """SolverConfigModel should accept exactly 300 seconds."""
89        model = SolverConfigModel(termination_seconds=300)
90        assert model.termination_seconds == 300
91