Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests for qtpy sub-module #64

Merged
merged 4 commits into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion brainglobe_utils/qtpy/dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def display_warning(widget: QWidget, title: str, message: str) -> bool:
return False


def display_info(widget, title, message):
def display_info(widget: QWidget, title: str, message: str):
"""
Display information in a pop-up that can only be accepted
"""
Expand Down
50 changes: 32 additions & 18 deletions brainglobe_utils/qtpy/interaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,16 @@ def add_button(


def add_checkbox(
layout, default, label, row: int = 0, column: int = 0, tooltip=None
):
layout: QLayout,
default: bool,
label: str,
row: int = 0,
column: int = 0,
tooltip: Optional[str] = None,
) -> QCheckBox:
"""
Add a checkbox to *layout*.
"""
box = QCheckBox()
box.setChecked(default)
if tooltip:
Expand All @@ -58,16 +66,19 @@ def add_checkbox(


def add_float_box(
layout,
default,
minimum,
maximum,
label,
step,
layout: QLayout,
default: float,
minimum: float,
maximum: float,
label: str,
step: float,
row: int = 0,
column: int = 0,
tooltip=None,
):
tooltip: Optional[str] = None,
) -> QDoubleSpinBox:
"""
Add a spin box for float values to *layout*.
"""
box = QDoubleSpinBox()
box.setMinimum(minimum)
box.setMaximum(maximum)
Expand All @@ -81,15 +92,18 @@ def add_float_box(


def add_int_box(
layout,
default,
minimum,
maximum,
label,
layout: QLayout,
default: int,
minimum: int,
maximum: int,
label: str,
row: int = 0,
column: int = 0,
tooltip=None,
):
tooltip: Optional[str] = None,
) -> QSpinBox:
"""
Add a spin box for integer values to *layout*.
"""
box = QSpinBox()
box.setMinimum(minimum)
box.setMaximum(maximum)
Expand All @@ -109,7 +123,7 @@ def add_combobox(
row: int = 0,
column: int = 0,
label_stack: bool = False,
callback=None,
callback: Optional[Callable] = None,
width: int = 150,
) -> Tuple[QComboBox, Optional[QLabel]]:
"""
Expand Down
27 changes: 27 additions & 0 deletions tests/tests/test_qtpy/test_dialog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import pytest
from qtpy.QtWidgets import QGroupBox, QMessageBox

from brainglobe_utils.qtpy.dialog import display_warning


@pytest.mark.parametrize(
"messagebox_return",
[QMessageBox.Yes, QMessageBox.Cancel],
ids=["Yes", "Cancel"],
)
def test_display_warning(qtbot, monkeypatch, messagebox_return):
"""
Test display_warning returns True/False when accepted/cancelled.
"""
# Use monkeypatch to return a set value from the modal dialog.
monkeypatch.setattr(
QMessageBox, "question", lambda *args: messagebox_return
)

box = QGroupBox()
qtbot.addWidget(box)
response = display_warning(box, "warning", "an example message")
if messagebox_return == QMessageBox.Yes:
assert response is True
else:
assert response is False
148 changes: 137 additions & 11 deletions tests/tests/test_qtpy/test_interaction.py
Original file line number Diff line number Diff line change
@@ -1,39 +1,165 @@
import pytest
from qtpy.QtWidgets import QGridLayout
from qtpy.QtWidgets import QGridLayout, QGroupBox

from brainglobe_utils.qtpy.interaction import add_button, add_combobox
from brainglobe_utils.qtpy.interaction import (
add_button,
add_checkbox,
add_combobox,
add_float_box,
add_int_box,
)


@pytest.fixture()
def box() -> QGroupBox:
"""
Return a QGroupBox with a grid layout.
"""
box = QGroupBox()
layout = QGridLayout()
box.setLayout(layout)

return box


@pytest.mark.parametrize("label_stack", [True, False])
@pytest.mark.parametrize("label", ["A label", None])
def test_add_combobox(label, label_stack):
def test_add_combobox(qtbot, box, label, label_stack):
"""
Smoke test for add_combobox for all conditional branches
"""
layout = QGridLayout()
qtbot.addWidget(box)
layout = box.layout()
items = ["item 1", "item 2"]

# callback function for whenever the current index of the combobox changes
def callback():
pass

# returns tuple of (combobox, combobox_label)
combobox = add_combobox(
layout,
row=0,
label=label,
items=["item 1", "item 2"],
items=items,
label_stack=label_stack,
callback=callback,
)

assert combobox is not None
assert combobox[0].count() == len(items)

if label is None:
assert combobox[1] is None
assert layout.count() == 1
else:
assert combobox[1].text() == label
assert layout.count() == 2

@pytest.mark.parametrize(
argnames="alignment", argvalues=["center", "left", "right"]
)
def test_add_button(alignment):

@pytest.mark.parametrize("alignment", ["center", "left", "right"])
def test_add_button(qtbot, box, alignment):
"""
Smoke tests for add_button for all conditional branches
"""
layout = QGridLayout()
qtbot.addWidget(box)
layout = box.layout()
label = "A button"
tooltip = "A useful tooltip"

button = add_button(
layout=layout,
connected_function=lambda: None,
label="A button",
label=label,
row=0,
alignment=alignment,
tooltip=tooltip,
)

assert button is not None
assert layout.count() == 1
assert button.text() == label
assert button.toolTip() == tooltip


def test_add_checkbox(qtbot, box):
"""
Smoke tests for add_checkbox for all conditional branches
"""
qtbot.addWidget(box)
layout = box.layout()
label = "A checkbox"
tooltip = "A useful tooltip"

checkbox = add_checkbox(
layout=layout, default=True, label=label, tooltip=tooltip
)

assert checkbox is not None
# layout should contain 2 items: QLabel and QCheckbox
assert layout.count() == 2
assert layout.itemAt(0).widget().text() == label
assert checkbox.toolTip() == tooltip


def test_add_float_box(qtbot, box):
"""
Smoke tests for add_float_box for all conditional branches
"""
qtbot.addWidget(box)
layout = box.layout()
label = "A float box"
tooltip = "A useful tooltip"
default = 0.5
minimum = 0.0
maximum = 1.0

floatbox = add_float_box(
layout=layout,
default=default,
minimum=minimum,
maximum=maximum,
label=label,
step=0.1,
tooltip=tooltip,
)

assert floatbox is not None
# layout should contain 2 items: QLabel and QDoubleSpinBox
assert layout.count() == 2
assert layout.itemAt(0).widget().text() == label
assert floatbox.maximum() == maximum
assert floatbox.minimum() == minimum
assert floatbox.value() == default
assert floatbox.toolTip() == tooltip


def test_add_int_box(qtbot, box):
"""
Smoke tests for add_float_box for all conditional branches
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Smoke tests for add_float_box for all conditional branches
Smoke tests for add_int_box for all conditional branches

Could you clarify what "all conditional branches" means in each of the tests in this file by updating the docstrings?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated the docstrings to make it clearer what each of these tests do. Feel free to merge if you're happy with it!

"""
qtbot.addWidget(box)
layout = box.layout()
label = "An int box"
tooltip = "A useful tooltip"
default = 5
minimum = 0
maximum = 10

intbox = add_int_box(
layout=layout,
default=default,
minimum=minimum,
maximum=maximum,
label=label,
tooltip=tooltip,
)

assert intbox is not None
# layout should contain 2 items: QLabel and QSpinBox
assert layout.count() == 2
assert layout.itemAt(0).widget().text() == label
assert intbox.maximum() == maximum
assert intbox.minimum() == minimum
assert intbox.value() == default
assert intbox.toolTip() == tooltip
Loading