Skip to content

Commit

Permalink
Fix code is None in CodeExercise with ExerciseRegistry (PR #57)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
agoscinski authored Jul 9, 2024
2 parents 2cb8e81 + cf83143 commit 7519ac6
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 15 deletions.
27 changes: 17 additions & 10 deletions src/scwidgets/exercise/_widget_code_exercise.py
Original file line number Diff line number Diff line change
Expand Up @@ -327,21 +327,28 @@ def __init__(
self._load_button = None
self._save_cue_box = None
else:
save_widgets_to_observe = [self._code]
save_traits_to_observe = ["function_body"]
save_widgets_to_observe = []
save_traits_to_observe = []

if self._cue_code is not None:
save_widgets_to_observe.append(self._code)
save_traits_to_observe.append("function_body")

if self._parameter_panel is not None:
save_widgets_to_observe.extend(self._parameter_panel.parameters_widget)
save_traits_to_observe.extend(self._parameter_panel.parameters_trait)
self._cue_code = SaveCueBox(
save_widgets_to_observe,
save_traits_to_observe,
self._cue_code,
cued=True,
)

if self._cue_code is not None:
self._cue_code = SaveCueBox(
save_widgets_to_observe,
save_traits_to_observe,
self._cue_code,
cued=True,
)

self._save_cue_box = self._cue_code
self._save_button = SaveResetCueButton(
self._cue_code,
SaveCueBox(Box()), # dummy cue box, because we set cues later on
self._on_click_save_action,
cued=True,
disable_on_successful_action=kwargs.pop(
Expand All @@ -354,7 +361,7 @@ def __init__(
button_tooltip="Loads your code and parameters from the loaded file",
)
self._load_button = SaveResetCueButton(
self._cue_code,
SaveCueBox(Box()), # dummy cue box, because we set cues later on
self._on_click_load_action,
cued=True,
disable_on_successful_action=kwargs.pop(
Expand Down
39 changes: 36 additions & 3 deletions tests/test_code.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import Callable, List
import os
from typing import Callable, List, Optional

import numpy as np
import pytest
Expand All @@ -8,7 +9,7 @@
from scwidgets.check import Check, CheckRegistry, ChecksResult
from scwidgets.code import CodeInput
from scwidgets.cue import CueObject
from scwidgets.exercise import CodeExercise
from scwidgets.exercise import CodeExercise, ExerciseRegistry

from .test_check import multi_param_check, single_param_check

Expand Down Expand Up @@ -76,7 +77,7 @@ def test_invalid_code_theme_raises_error(self):

def get_code_exercise(
checks: List[Check],
code: Callable = None,
code: Optional[Callable] = None,
include_checks=True,
include_params=True,
tunable_params=False,
Expand Down Expand Up @@ -221,3 +222,35 @@ def test_erroneous_run_code(self, code_ex):
match="NameError in code input: name 'bug' is not defined.*",
):
code_ex.run_code(**code_ex.parameters)

@pytest.mark.parametrize(
"function",
[
None,
TestCodeInput.mock_function_1,
],
)
def test_save_registry(self, function):
"""
Verifies that the CodeExercise works with an answer_registry.
"""

def print_success(code_ex: CodeExercise | None):
code_ex.cue_outputs[0].display_object = "Success"

cue_output = CueObject("Not initialized")
exercise_registry = ExerciseRegistry()

code_ex = CodeExercise(
code=function,
parameters={"parameter": fixed(5)},
exercise_registry=exercise_registry,
exercise_key="test_save_registry_ex",
cue_outputs=[cue_output],
update_func=print_success,
)

exercise_registry._student_name_text.value = "test_save_registry-student_name"
exercise_registry.create_new_file()
code_ex._save_button.click()
os.remove("test_save_registry-student_name.json")
4 changes: 2 additions & 2 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ deps =
commands =
# converts the python files to ipython notebooks
jupytext tests/notebooks/*.py --to ipynb
pytest {posargs:-v --reruns 2} --driver Firefox
pytest {posargs:-v --reruns 4} --driver Firefox

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

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

0 comments on commit 7519ac6

Please sign in to comment.