Skip to content

Commit 6320529

Browse files
committed
implement: Model response areas as exported (t6)
1 parent 1b3b4b7 commit 6320529

1 file changed

Lines changed: 65 additions & 11 deletions

File tree

tests/test_exports.py

Lines changed: 65 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
from in2lambda.api.part import Part
1919
from in2lambda.api.question import Question
20-
from in2lambda.api.response_area import Case, ResponseArea, Test
20+
from in2lambda.api.response_area import Case, InputSymbol, ResponseArea, Test
2121
from in2lambda.api.set import Set
2222

2323
each_export = pytest.mark.parametrize("export_dir", EXPORTS, ids=lambda path: path.name)
@@ -132,22 +132,76 @@ def test_written_keys_exist_in_export(export_dir: Path, tmp_path: Path) -> None:
132132
assert not missing, missing
133133

134134

135-
def test_response_area_built_in_python_writes_distinct_ids(tmp_path: Path) -> None:
136-
"""Tests and cases given no id are written with a distinct uuid each, as import needs."""
137-
area = ResponseArea(
138-
tests=[Test("x", True), Test("y", False)],
139-
cases=[Case("x", "", True), Case("y", "", False)],
135+
def _area_shape(area: dict) -> frozenset[str]:
136+
# Without indices, an area's shape is the keys it has, not how many tests, cases
137+
# or symbols it lists.
138+
return frozenset(re.sub(r"\[\d+\]", "[]", path) for path in _key_paths(area))
139+
140+
141+
def test_response_areas_built_in_python_write_as_exported(tmp_path: Path) -> None:
142+
"""Boxes of each exported type built in Python reload unchanged, shaped as exported."""
143+
part = Part(
144+
text="Find the drag, then say whether it scales.",
145+
response_areas=[
146+
ResponseArea(
147+
response_type="MATH_SINGLE_LINE",
148+
answer="(pi/6)*rho*U**2*R**2",
149+
config={
150+
"allowPhoto": True,
151+
"allowHandwrite": True,
152+
"enableRefinement": True,
153+
},
154+
evaluation_function="symbolicEqual",
155+
grade_params={"strict_syntax": False},
156+
pre_text="$D=$",
157+
content_after="Now put in the numbers.",
158+
input_symbols=[InputSymbol("\\(R\\)", "R", ["r"])],
159+
tests=[Test("(pi/6)*rho*U**2*R**2", True)],
160+
cases=[Case("pi*rho*U**2*R**2", "A factor is missing.", False)],
161+
),
162+
ResponseArea(
163+
response_type="NUMERIC_UNITS",
164+
answer="30 N",
165+
evaluation_function="comparePhysicalQuantities",
166+
grade_params={"rtol": 0.05, "strict_syntax": False},
167+
tests=[Test("30 N", True), Test("30", False)],
168+
cases=[
169+
Case("30 kg m s-2", "Put negative exponents in brackets.", False)
170+
],
171+
),
172+
ResponseArea(
173+
response_type="MULTIPLE_CHOICE",
174+
answer=[True, False],
175+
config={"single": True, "options": ["Yes", "No"], "randomise": False},
176+
evaluation_function="arrayEqual",
177+
),
178+
],
140179
)
141-
question_set = Set(questions=[Question(parts=[Part(response_areas=[area])])])
180+
written = _write_back(Set(questions=[Question(parts=[part])]), tmp_path)
181+
182+
# Equality includes the ids, so reloading must keep the ones that were written.
183+
assert Set.from_json(str(written)).questions[0].parts == [part]
142184

143-
written = _write_back(question_set, tmp_path)
144185
(question_file,) = written.glob("question_*.json")
145-
(written_area,) = json.loads(question_file.read_text())["parts"][0]["responseAreas"]
186+
written_areas = json.loads(question_file.read_text())["parts"][0]["responseAreas"]
146187

147-
ids = [item["id"] for item in written_area["tests"] + written_area["cases"]]
148-
assert len(set(ids)) == 4
188+
# Import needs every test and case given no id to be written with its own uuid.
189+
ids = [
190+
item["id"] for area in written_areas for item in area["tests"] + area["cases"]
191+
]
192+
assert len(set(ids)) == 5
149193
assert all(uuid.UUID(id_) for id_ in ids)
150194

195+
exported_shapes = {
196+
_area_shape(area)
197+
for export_dir in EXPORTS
198+
for file in export_dir.glob("question_*.json")
199+
for exported_part in json.loads(file.read_text())["parts"]
200+
for area in exported_part["responseAreas"]
201+
}
202+
for area in written_areas:
203+
assert _area_shape(area) in exported_shapes, area["response"]
204+
151205

152206
def test_from_json_rejects_folder_without_set(tmp_path: Path) -> None:
153207
"""A folder with no set file is refused with an error that says where it looked."""

0 commit comments

Comments
 (0)