From f5fb308a459ebbfb72b50ce95a3021252ad9f7b6 Mon Sep 17 00:00:00 2001 From: Alexander Goscinski Date: Thu, 4 Jul 2024 10:39:27 +0200 Subject: [PATCH 1/4] Core: Fixing unlinked traits for WCI #53 --- src/scwidgets/code/_widget_code_input.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/scwidgets/code/_widget_code_input.py b/src/scwidgets/code/_widget_code_input.py index 39cbd51..cb5fb53 100644 --- a/src/scwidgets/code/_widget_code_input.py +++ b/src/scwidgets/code/_widget_code_input.py @@ -13,6 +13,8 @@ class CodeInput(WidgetCodeInput): Small wrapper around WidgetCodeInput that controls the output """ + valid_code_themes = ["nord", "solarizedLight", "basicLight"] + def __init__( self, function: Optional[types.FunctionType] = None, @@ -20,7 +22,7 @@ def __init__( function_parameters: Optional[str] = None, docstring: Optional[str] = None, function_body: Optional[str] = None, - code_theme: str = "default", + code_theme: str = "basicLight", ): if function is not None: function_name = ( @@ -46,6 +48,14 @@ def __init__( function_name, function_parameters, docstring, function_body, code_theme ) + # this list is retrieved from + # https://github.com/osscar-org/widget-code-input/blob/eb10ca0baee65dd3bf62c9ec5d9cb2f152932ff5/js/widget.js#L249-L253 + if code_theme not in CodeInput.valid_code_themes: + raise ValueError( + f"Given code_theme {code_theme!r} invalid. Please use one of " + f"the values {CodeInput.valid_code_themes}" + ) + @property def function(self) -> types.FunctionType: """ From 92fe2c98a7f47f892e499d74d7840ee8d465ebd8 Mon Sep 17 00:00:00 2001 From: Alexander Goscinski Date: Thu, 4 Jul 2024 10:37:43 +0200 Subject: [PATCH 2/4] Tests: Adding tests for fix of #53 Adding tests if invalid code theme returns error. Adding tests if widget view is updated on change of function_body trait. --- .../notebooks/widget_scwidgets_code_input.py | 38 +++++++++++++++++++ tests/test_code.py | 6 +++ tests/test_widgets.py | 17 +++++++++ 3 files changed, 61 insertions(+) create mode 100644 tests/notebooks/widget_scwidgets_code_input.py diff --git a/tests/notebooks/widget_scwidgets_code_input.py b/tests/notebooks/widget_scwidgets_code_input.py new file mode 100644 index 0000000..88d42df --- /dev/null +++ b/tests/notebooks/widget_scwidgets_code_input.py @@ -0,0 +1,38 @@ +# --- +# jupyter: +# jupytext: +# cell_metadata_filter: -all +# text_representation: +# extension: .py +# format_name: light +# format_version: '1.5' +# jupytext_version: 1.15.0 +# kernelspec: +# display_name: Python 3 (ipykernel) +# language: python +# name: python3 +# --- + +# + +import scwidgets +from scwidgets.code import CodeInput + +# - + +scwidgets.get_css_style() + +# Test 1: +# ------- +# Test if CodeInput traits are updading the widget view + + +# + +def foo(): + return "init" + + +ci = CodeInput(foo) +ci +# - + +ci.function_body = """return 'change'""" diff --git a/tests/test_code.py b/tests/test_code.py index 47d2ea0..e516f0f 100644 --- a/tests/test_code.py +++ b/tests/test_code.py @@ -67,6 +67,12 @@ def test_get_code(self): ): CodeInput.get_code(lambda x: x) + def test_invalid_code_theme_raises_error(self): + with pytest.raises( + ValueError, match=r"Given code_theme 'invalid_theme' invalid.*" + ): + CodeInput(TestCodeInput.mock_function_1, code_theme="invalid_theme") + def get_code_exercise( checks: List[Check], diff --git a/tests/test_widgets.py b/tests/test_widgets.py index 179a264..50bf0f6 100644 --- a/tests/test_widgets.py +++ b/tests/test_widgets.py @@ -249,6 +249,23 @@ def test_privacy_policy(selenium_driver): ).click() +def test_scwidgets_code_input(selenium_driver): + """ + Tests the widget of the module code + + :param selenium_driver: see conftest.py + """ + driver = selenium_driver("tests/notebooks/widget_scwidgets_code_input.ipynb") + + nb_cells = NotebookCellList(driver) + # Test 1: + # ------- + + # Tests if change in function_body changed the widget view + code_input_lines = nb_cells[2].find_elements(By.CLASS_NAME, CODE_MIRROR_CLASS_NAME) + assert "return 'change'" in code_input_lines[-1].text + + class TestExerciseWidgets: prefix = "pytest" From c8de27d3b78edf77288d00c06da0b2ee7cfa0944 Mon Sep 17 00:00:00 2001 From: Alexander Goscinski Date: Thu, 4 Jul 2024 13:11:40 +0200 Subject: [PATCH 3/4] Tests: Increase time to run all cells to make tests more robust Increase waiting time and add sleep when a notebook is restarted. The notebook is sometimes run before jupyter has finished loading everything in the background. --- tests/conftest.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index 137662e..2b7f2ce 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -143,7 +143,7 @@ def _selenium_driver(nb_path): # ) # ) restart_kernel_button = None - waiting_time = 10 + waiting_time = 20 start = time.time() while restart_kernel_button is None and time.time() - start < waiting_time: @@ -219,6 +219,7 @@ def _selenium_driver(nb_path): (By.CLASS_NAME, "jp-Notebook-ExecutionIndicator"), "data-status", "idle" ) ) + time.sleep(1) return selenium From b1ba4cd51a7c19d4bf4820e184b58b7be295297d Mon Sep 17 00:00:00 2001 From: Alexander Goscinski Date: Thu, 4 Jul 2024 13:33:01 +0200 Subject: [PATCH 4/4] Tests: Adding sleep to code input test The change in the last cell does not get active, since the widget has not been loaded fully. --- tests/notebooks/widget_scwidgets_code_input.py | 3 +++ tests/test_widgets.py | 1 + 2 files changed, 4 insertions(+) diff --git a/tests/notebooks/widget_scwidgets_code_input.py b/tests/notebooks/widget_scwidgets_code_input.py index 88d42df..5b52bd6 100644 --- a/tests/notebooks/widget_scwidgets_code_input.py +++ b/tests/notebooks/widget_scwidgets_code_input.py @@ -14,6 +14,8 @@ # --- # + +import time + import scwidgets from scwidgets.code import CodeInput @@ -35,4 +37,5 @@ def foo(): ci # - +time.sleep(1) ci.function_body = """return 'change'""" diff --git a/tests/test_widgets.py b/tests/test_widgets.py index 50bf0f6..ac4d4fd 100644 --- a/tests/test_widgets.py +++ b/tests/test_widgets.py @@ -262,6 +262,7 @@ def test_scwidgets_code_input(selenium_driver): # ------- # Tests if change in function_body changed the widget view + time.sleep(2) code_input_lines = nb_cells[2].find_elements(By.CLASS_NAME, CODE_MIRROR_CLASS_NAME) assert "return 'change'" in code_input_lines[-1].text