From 398d62097d84fb0871809a7e555cb4b89bb5f2ea Mon Sep 17 00:00:00 2001 From: lola Date: Tue, 21 Oct 2025 11:08:49 -0700 Subject: [PATCH 1/2] add tests for multiple assignments and unpacking --- tests/syntax/test_assignments.py | 66 ++++++++++++++++++++++++++++++++ tests/syntax/test_parser.py | 14 +++++++ 2 files changed, 80 insertions(+) create mode 100644 tests/syntax/test_assignments.py diff --git a/tests/syntax/test_assignments.py b/tests/syntax/test_assignments.py new file mode 100644 index 000000000..fe7812d65 --- /dev/null +++ b/tests/syntax/test_assignments.py @@ -0,0 +1,66 @@ +# Minimal semantics tests for multiple assignment and LHS unpacking. + +import pytest + +from tests.utils import compileScenic, sampleEgoActions + + +def test_multiple_assignment_swap(): + scenario = compileScenic( + """ + behavior Foo(): + a = 1 + b = 2 + a, b = b, a + take a + take b + ego = new Object with behavior Foo + """ + ) + actions = sampleEgoActions(scenario, maxSteps=2) + assert actions == [2, 1] + + +def test_lhs_tuple_unpack(): + scenario = compileScenic( + """ + behavior Foo(): + x, y = (3, 4) + take x + take y + ego = new Object with behavior Foo + """ + ) + assert sampleEgoActions(scenario, maxSteps=2) == [3, 4] + + +def test_unpack_from_distribution_pair(): + scenario = compileScenic( + """ + behavior Foo(): + pair = Uniform((0, 1), (1, 0)) + x, y = pair + take x + take y + ego = new Object with behavior Foo + """ + ) + outs = [tuple(sampleEgoActions(scenario, maxSteps=2)) for _ in range(60)] + assert {(0, 1), (1, 0)} <= set(outs) + + +@pytest.mark.parametrize( + "rhs", + ["(1, 2, 3)", "(1,)"], # too many; not enough +) +def test_unpack_arity_mismatch_exec_raises(rhs): + scenario = compileScenic( + f""" + behavior Foo(): + x, y = {rhs} + take x + ego = new Object with behavior Foo + """ + ) + with pytest.raises(ValueError): + sampleEgoActions(scenario, maxSteps=1) diff --git a/tests/syntax/test_parser.py b/tests/syntax/test_parser.py index 8267466c6..e073cb655 100644 --- a/tests/syntax/test_parser.py +++ b/tests/syntax/test_parser.py @@ -168,6 +168,20 @@ def test_workspace_assign(self): assert False +class TestAssign: + def test_tuple_lhs_parses(self): + mod = parse_string_helper("a, b = 1, 2") + stmt = mod.body[0] + match stmt: + case Assign( + targets=[Tuple([Name("a"), Name("b")])], + value=Tuple([Constant(1), Constant(2)]), + ): + assert True + case _: + assert False + + class TestInitialScenario: def test_initial_scenario(self): mod = parse_string_helper("initial scenario") From b4052bf1a1af21e964524a225de98ad81a6e4384 Mon Sep 17 00:00:00 2001 From: lola Date: Mon, 17 Nov 2025 11:30:12 -0800 Subject: [PATCH 2/2] simplify tests, just use top level code --- tests/syntax/test_assignments.py | 66 +++++++++++++------------------- 1 file changed, 27 insertions(+), 39 deletions(-) diff --git a/tests/syntax/test_assignments.py b/tests/syntax/test_assignments.py index fe7812d65..99b36abbc 100644 --- a/tests/syntax/test_assignments.py +++ b/tests/syntax/test_assignments.py @@ -2,51 +2,42 @@ import pytest -from tests.utils import compileScenic, sampleEgoActions +from tests.utils import sampleParamPFrom def test_multiple_assignment_swap(): - scenario = compileScenic( + p = sampleParamPFrom( """ - behavior Foo(): - a = 1 - b = 2 - a, b = b, a - take a - take b - ego = new Object with behavior Foo + a = 1 + b = 2 + a, b = b, a + param p = (a, b) """ ) - actions = sampleEgoActions(scenario, maxSteps=2) - assert actions == [2, 1] + assert p == (2, 1) def test_lhs_tuple_unpack(): - scenario = compileScenic( + p = sampleParamPFrom( """ - behavior Foo(): - x, y = (3, 4) - take x - take y - ego = new Object with behavior Foo + x, y = (3, 4) + param p = (x, y) """ ) - assert sampleEgoActions(scenario, maxSteps=2) == [3, 4] + assert p == (3, 4) def test_unpack_from_distribution_pair(): - scenario = compileScenic( - """ - behavior Foo(): - pair = Uniform((0, 1), (1, 0)) - x, y = pair - take x - take y - ego = new Object with behavior Foo - """ - ) - outs = [tuple(sampleEgoActions(scenario, maxSteps=2)) for _ in range(60)] - assert {(0, 1), (1, 0)} <= set(outs) + code = """ + pair = (Uniform(0, 1), Uniform(0, 1)) + x, y = pair + param p = (x, y) + """ + outs = [sampleParamPFrom(code) for _ in range(20)] + assert len(set(outs)) > 1 + for x, y in outs: + assert 0 <= x <= 1 + assert 0 <= y <= 1 @pytest.mark.parametrize( @@ -54,13 +45,10 @@ def test_unpack_from_distribution_pair(): ["(1, 2, 3)", "(1,)"], # too many; not enough ) def test_unpack_arity_mismatch_exec_raises(rhs): - scenario = compileScenic( - f""" - behavior Foo(): - x, y = {rhs} - take x - ego = new Object with behavior Foo - """ - ) with pytest.raises(ValueError): - sampleEgoActions(scenario, maxSteps=1) + sampleParamPFrom( + f""" + x, y = {rhs} + param p = x + """ + )