From d4b852e272c576d240ca8c9e6592b6d051866b75 Mon Sep 17 00:00:00 2001 From: Floris-Jan Willemsen Date: Wed, 25 Jun 2025 15:31:44 +0200 Subject: [PATCH 1/2] Extended tests for non-integer and mixed types --- tests/test_parser.py | 19 +++++++++++++++++++ tests/test_solvers.py | 34 +++++++++++++++++++++++++++++++--- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/tests/test_parser.py b/tests/test_parser.py index 2d4117a..7788aff 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -137,3 +137,22 @@ def test_compile_to_constraints_picklable(): assert callable(r) else: assert isinstance(r, expected) + +def test_compile_non_numeric(): + domains = {"x": ["a", "b", "c"], "y": [True, False]} + constraints = [ + "x != 'a'", + "y == 'd' or x != 'b'", + "'a' <= x + y < 'c'" + ] + + compiled = compile_to_constraints(constraints, domains, picklable=False) + + assert len(compiled) == 4 + for r, vals, r_str in compiled: + assert isinstance(r, Constraint) + assert isinstance(vals, Iterable) and all(isinstance(v, str) for v in vals) + if isinstance(r, (FunctionConstraint, CompilableFunctionConstraint)): + assert isinstance(r_str, str) + else: + assert r_str is None diff --git a/tests/test_solvers.py b/tests/test_solvers.py index adc4c31..2698537 100644 --- a/tests/test_solvers.py +++ b/tests/test_solvers.py @@ -94,7 +94,7 @@ def test_parallel_solver(): order = ["x", "y"] # get all solutions - solutions_list, solutions_dict, size = problem.getSolutionsAsListDict(order=order) + solutions_list, _, size = problem.getSolutionsAsListDict(order=order) # validate all solutions assert size == len(true_solutions) @@ -120,7 +120,7 @@ def test_parallel_solver_process_mode(): order = ["x", "y"] # get all solutions - solutions_list, solutions_dict, size = problem.getSolutionsAsListDict(order=order) + solutions_list, _, size = problem.getSolutionsAsListDict(order=order) # validate all solutions assert size == len(true_solutions) @@ -175,4 +175,32 @@ def create_problem(solver): base_solution = solutions_list else: assert size == len(base_solution) - # assert all(sol in solutions_list for sol in base_solution) \ No newline at end of file + # assert all(sol in solutions_list for sol in base_solution) + +def test_mixed_type_constraints(): + """Test that mixed type constraints are handled correctly.""" + problem = Problem() + domains = {"x": ["a", "b", "c"], "y": [True, False], "z": [0, 1]} + for var, domain in domains.items(): + problem.addVariable(var, domain) + constraints = [ + "x != 'a' or y < z", + "y or x != 'b'", + ] + problem.addConstraint(constraints) + solutions, _, _ = problem.getSolutionsAsListDict(order=list(domains.keys())) + + possible_solutions = [ + ('c', False, 1), + ('c', False, 0), + ('a', False, 1), + ('b', True, 0), + ('b', True, 1), + ('c', True, 0), + ('c', True, 1) + ] + + assert len(solutions) == len(possible_solutions), "Number of solutions does not match expected" + assert len(set(solutions)) == len(possible_solutions), "Number of unique solutions does not match expected" + for solution in solutions: + assert solution in possible_solutions, f"Unexpected solution: {solution}" From 859d1ab4979fcb4669e46b824b4d24ad7d2c0f4c Mon Sep 17 00:00:00 2001 From: Floris-Jan Willemsen Date: Wed, 25 Jun 2025 16:36:08 +0200 Subject: [PATCH 2/2] Extended tests for non-integer and mixed types --- tests/test_parser.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_parser.py b/tests/test_parser.py index 7788aff..2219722 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -139,9 +139,9 @@ def test_compile_to_constraints_picklable(): assert isinstance(r, expected) def test_compile_non_numeric(): - domains = {"x": ["a", "b", "c"], "y": [True, False]} + domains = {"x": ["a2", "b4", "c6"], "y": [True, False]} constraints = [ - "x != 'a'", + "x == 'a'", "y == 'd' or x != 'b'", "'a' <= x + y < 'c'" ] @@ -150,7 +150,7 @@ def test_compile_non_numeric(): assert len(compiled) == 4 for r, vals, r_str in compiled: - assert isinstance(r, Constraint) + assert isinstance(r, (Constraint, CompilableFunctionConstraint)) assert isinstance(vals, Iterable) and all(isinstance(v, str) for v in vals) if isinstance(r, (FunctionConstraint, CompilableFunctionConstraint)): assert isinstance(r_str, str)