Skip to content

Commit 7519ac6

Browse files
authored
Fix code is None in CodeExercise with ExerciseRegistry (PR #57)
When the code is None in the CodeExercise and a ExerciseRegistry is given, then an error is raised when the save cue box is created, because the cue_widget is None.
2 parents 2cb8e81 + cf83143 commit 7519ac6

File tree

3 files changed

+55
-15
lines changed

3 files changed

+55
-15
lines changed

src/scwidgets/exercise/_widget_code_exercise.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -327,21 +327,28 @@ def __init__(
327327
self._load_button = None
328328
self._save_cue_box = None
329329
else:
330-
save_widgets_to_observe = [self._code]
331-
save_traits_to_observe = ["function_body"]
330+
save_widgets_to_observe = []
331+
save_traits_to_observe = []
332+
333+
if self._cue_code is not None:
334+
save_widgets_to_observe.append(self._code)
335+
save_traits_to_observe.append("function_body")
336+
332337
if self._parameter_panel is not None:
333338
save_widgets_to_observe.extend(self._parameter_panel.parameters_widget)
334339
save_traits_to_observe.extend(self._parameter_panel.parameters_trait)
335-
self._cue_code = SaveCueBox(
336-
save_widgets_to_observe,
337-
save_traits_to_observe,
338-
self._cue_code,
339-
cued=True,
340-
)
340+
341+
if self._cue_code is not None:
342+
self._cue_code = SaveCueBox(
343+
save_widgets_to_observe,
344+
save_traits_to_observe,
345+
self._cue_code,
346+
cued=True,
347+
)
341348

342349
self._save_cue_box = self._cue_code
343350
self._save_button = SaveResetCueButton(
344-
self._cue_code,
351+
SaveCueBox(Box()), # dummy cue box, because we set cues later on
345352
self._on_click_save_action,
346353
cued=True,
347354
disable_on_successful_action=kwargs.pop(
@@ -354,7 +361,7 @@ def __init__(
354361
button_tooltip="Loads your code and parameters from the loaded file",
355362
)
356363
self._load_button = SaveResetCueButton(
357-
self._cue_code,
364+
SaveCueBox(Box()), # dummy cue box, because we set cues later on
358365
self._on_click_load_action,
359366
cued=True,
360367
disable_on_successful_action=kwargs.pop(

tests/test_code.py

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
from typing import Callable, List
1+
import os
2+
from typing import Callable, List, Optional
23

34
import numpy as np
45
import pytest
@@ -8,7 +9,7 @@
89
from scwidgets.check import Check, CheckRegistry, ChecksResult
910
from scwidgets.code import CodeInput
1011
from scwidgets.cue import CueObject
11-
from scwidgets.exercise import CodeExercise
12+
from scwidgets.exercise import CodeExercise, ExerciseRegistry
1213

1314
from .test_check import multi_param_check, single_param_check
1415

@@ -76,7 +77,7 @@ def test_invalid_code_theme_raises_error(self):
7677

7778
def get_code_exercise(
7879
checks: List[Check],
79-
code: Callable = None,
80+
code: Optional[Callable] = None,
8081
include_checks=True,
8182
include_params=True,
8283
tunable_params=False,
@@ -221,3 +222,35 @@ def test_erroneous_run_code(self, code_ex):
221222
match="NameError in code input: name 'bug' is not defined.*",
222223
):
223224
code_ex.run_code(**code_ex.parameters)
225+
226+
@pytest.mark.parametrize(
227+
"function",
228+
[
229+
None,
230+
TestCodeInput.mock_function_1,
231+
],
232+
)
233+
def test_save_registry(self, function):
234+
"""
235+
Verifies that the CodeExercise works with an answer_registry.
236+
"""
237+
238+
def print_success(code_ex: CodeExercise | None):
239+
code_ex.cue_outputs[0].display_object = "Success"
240+
241+
cue_output = CueObject("Not initialized")
242+
exercise_registry = ExerciseRegistry()
243+
244+
code_ex = CodeExercise(
245+
code=function,
246+
parameters={"parameter": fixed(5)},
247+
exercise_registry=exercise_registry,
248+
exercise_key="test_save_registry_ex",
249+
cue_outputs=[cue_output],
250+
update_func=print_success,
251+
)
252+
253+
exercise_registry._student_name_text.value = "test_save_registry-student_name"
254+
exercise_registry.create_new_file()
255+
code_ex._save_button.click()
256+
os.remove("test_save_registry-student_name.json")

tox.ini

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ deps =
4242
commands =
4343
# converts the python files to ipython notebooks
4444
jupytext tests/notebooks/*.py --to ipynb
45-
pytest {posargs:-v --reruns 2} --driver Firefox
45+
pytest {posargs:-v --reruns 4} --driver Firefox
4646

4747
[testenv:tests-lab-4]
4848
description =
@@ -75,7 +75,7 @@ deps =
7575
commands =
7676
# converts the python files to ipython notebooks
7777
jupytext tests/notebooks/*.py --to ipynb
78-
pytest {posargs:-v --reruns 2} -m "not matplotlib" --driver Firefox
78+
pytest {posargs:-v --reruns 4} -m "not matplotlib" --driver Firefox
7979

8080
[testenv:coverage]
8181
# We do coverage in a separate environment that skips the selenium tests but

0 commit comments

Comments
 (0)