Skip to content

Commit

Permalink
added tests
Browse files Browse the repository at this point in the history
  • Loading branch information
RabiyaF committed Sep 1, 2024
1 parent 84fb0d3 commit a944047
Show file tree
Hide file tree
Showing 5 changed files with 189 additions and 55 deletions.
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ To install pytest use

Run the tests and generate a coverage report with

pytest tests --cov=RAT
pytest tests --cov=rascal2

The coverage report can be saved to the directory htmlcov by running the tests with

pytest tests --cov-report html --cov=RAT
pytest tests --cov-report html --cov=rascal2

For information on other coverage report formats, see https://pytest-cov.readthedocs.io/en/latest/reporting.html

Expand Down
45 changes: 15 additions & 30 deletions rascal2/dialogs/project_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,14 @@ class ProjectDialog(QtWidgets.QDialog):
_error_style = "color: #E34234"
_line_edit_error_style = "border: 1px solid #E34234"

def __init__(self, parent=None):
def __init__(self, parent):
"""
Initializes the dialog
Parameters
----------
parent: MainWindowView
An instance of the MainWindowView
"""
super().__init__(parent)

Expand Down Expand Up @@ -86,7 +91,7 @@ def create_project_dialog_labels(self) -> None:
self.project_name = QtWidgets.QLineEdit(self)
self.project_name.setPlaceholderText("Enter project name")

self.project_name_error = QtWidgets.QLabel("", self)
self.project_name_error = QtWidgets.QLabel("Project name needs to be specified.", self)
self.project_name_error.setStyleSheet(self._error_style)
self.project_name_error.hide()

Expand All @@ -99,7 +104,7 @@ def create_project_dialog_labels(self) -> None:
self.project_folder.setReadOnly(True)
self.project_folder.setPlaceholderText("Select project folder")

self.project_folder_error = QtWidgets.QLabel("", self)
self.project_folder_error = QtWidgets.QLabel("An empty project folder needs to be selected.", self)
self.project_folder_error.setStyleSheet(self._error_style)
self.project_folder_error.hide()

Expand All @@ -126,10 +131,7 @@ def cancel_project_creation(self) -> None:
"""
Cancel project creation.
"""
if self.parent().new_project_action_called:
self.close()
else:
self.parent().toggleView()
self.close() if self.parent().new_project_action_called else self.parent().toggleView()
self.reset_variables()

def reset_variables(self) -> None:
Expand All @@ -149,12 +151,12 @@ def open_folder_selector(self) -> None:
if folder_path:
files_in_folder = list(filter(lambda x: x[0] != ".", os.listdir(folder_path)))
if files_in_folder:
self.handle_error("folder", "Selected folder contains files. Select an empty folder.")
self.handle_error("folder")
else:
self.handle_non_error("folder")
self.project_folder.setText(folder_path)

def handle_error(self, tag: Literal["name", "folder"], msg: str) -> None:
def handle_error(self, tag: Literal["name", "folder"]) -> None:
"""
Displays the line edit error msgs.
Expand All @@ -163,16 +165,11 @@ def handle_error(self, tag: Literal["name", "folder"], msg: str) -> None:
tag: Literal["name", "folder"]
Specifies whether the input verification
is for the project name or folder.
msg: str
Specifies the msg to display.
"""
input = getattr(self, "project_" + tag)
input.setStyleSheet(self._line_edit_error_style)

error_label = getattr(self, "project_" + tag + "_error")
error_label.setText(msg)
error_label.show()

setattr(self, tag + "_error", True)

def handle_non_error(self, tag: Literal["name", "folder"]) -> None:
Expand All @@ -187,13 +184,11 @@ def handle_non_error(self, tag: Literal["name", "folder"]) -> None:
"""
input = getattr(self, "project_" + tag)
input.setStyleSheet("")

error_label = getattr(self, "project_" + tag + "_error")
error_label.hide()

setattr(self, tag + "_error", False)

def verify_inputs(self, tag: Literal["name", "folder"], msg: str) -> None:
def verify_inputs(self, tag: Literal["name", "folder"]) -> None:
"""
Verifies the name and folder inputs of the project dialog.
Expand All @@ -202,27 +197,17 @@ def verify_inputs(self, tag: Literal["name", "folder"], msg: str) -> None:
tag: Literal["name", "folder"]
Specifies whether the input verification
is for the project name or folder.
msg: str
Specifies the msg to display if there is an error
in verification.
"""
if getattr(self, "project_" + tag).text() == "":
self.handle_error(tag, msg)
self.handle_error(tag)
else:
self.handle_non_error(tag)

def create_project(self) -> None:
"""
Verifies the inputs specified.
"""
self.verify_inputs("name", "Project name needs to be specified.")
self.verify_inputs("folder", "An empty project folder needs to be selected.")
self.verify_inputs("name")
self.verify_inputs("folder")
if not self.name_error and not self.folder_error:
self.parent().createNewProject()

def resizeEvent(self, _) -> None:
"""
Recenters the dialog when project folder is selected.
"""
if self.parent():
self.move(self.parent().geometry().center() - self.rect().center())
23 changes: 17 additions & 6 deletions rascal2/widgets/startup_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,14 @@ class StartUpWidget(QtWidgets.QWidget):

_label_style = "font-weight: bold; font-size: 1em;"

def __init__(self, parent=None):
def __init__(self, parent):
"""
Initializes the widget
Parameters
----------
parent: MainWindowView
An instance of the MainWindowView
"""
super().__init__(parent)

Expand All @@ -29,7 +34,7 @@ def __init__(self, parent=None):

self.add_widgets_to_startup_page_layout()

def add_widgets_to_startup_page_layout(self):
def add_widgets_to_startup_page_layout(self) -> None:
"""
Adds the widgets to the startup layout.
"""
Expand All @@ -55,7 +60,7 @@ def add_widgets_to_startup_page_layout(self):

self.setLayout(startup_layout)

def create_banner_and_footer(self):
def create_banner_and_footer(self) -> None:
"""
Creates the banner and footer for the startup page.
"""
Expand All @@ -69,13 +74,19 @@ def create_banner_and_footer(self):
self.footer_label.setPixmap(QtGui.QPixmap(path_for("footer.png")))
self.footer_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)

def create_buttons_for_startup_page(self):
def toggle_view(self) -> None:
"""
Shows the project dialog
"""
self.parent().toggleView()

def create_buttons_for_startup_page(self) -> None:
"""
Creates the buttons for the startup page.
"""
self.new_project_button = QtWidgets.QPushButton(self)
self.new_project_button.setIcon(QtGui.QIcon(path_for("plus.png")))
self.new_project_button.clicked.connect(self.parent().toggleView)
self.new_project_button.clicked.connect(self.toggle_view)
self.new_project_button.setStyleSheet(self._button_style)

self.import_project_button = QtWidgets.QPushButton(self)
Expand All @@ -86,7 +97,7 @@ def create_buttons_for_startup_page(self):
self.import_r1_button.setIcon(QtGui.QIcon(path_for("import-r1.png")))
self.import_r1_button.setStyleSheet(self._button_style)

def create_labels_for_startup_page(self):
def create_labels_for_startup_page(self) -> None:
"""
Creates the labels for the startup page.
"""
Expand Down
136 changes: 130 additions & 6 deletions tests/test_dialogs.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,38 @@
from PyQt6 import QtCore
from unittest.mock import patch

import pytest
from PyQt6 import QtCore, QtTest, QtWidgets

from rascal2.dialogs.project_dialog import ProjectDialog


def test_project_dialog_initial_state():
class MockParentWindow(QtWidgets.QMainWindow):
new_project_action_called = False

def toggleView(self):
pass

def createNewProject(self):
pass


@pytest.fixture
def setup_project_dialog_widget():
parent = MockParentWindow()
project_dialog = ProjectDialog(parent)
return project_dialog, parent


def test_project_dialog_initial_state(setup_project_dialog_widget):
"""
Tests the inital state of the project dialog.
"""
project_dialog = ProjectDialog()
project_dialog, _ = setup_project_dialog_widget

assert project_dialog.windowFlags() == (QtCore.Qt.WindowType.FramelessWindowHint | QtCore.Qt.WindowType.Dialog)

assert project_dialog.isModal()
assert project_dialog.minimumWidth() == 700

assert project_dialog.create_button.isEnabled()
assert project_dialog.cancel_button.isEnabled()
Expand All @@ -21,10 +42,113 @@ def test_project_dialog_initial_state():
assert project_dialog.cancel_button.text() == " Cancel"
assert project_dialog.browse_button.text() == " Browse"

assert project_dialog.project_name.placeholderText() == "Enter project name"
assert project_dialog.project_name_label.text() == "Project Name:"
assert project_dialog.project_name_error.text() == "Project name needs to be specified."
assert project_dialog.project_name_error.isHidden()

assert project_dialog.project_folder.placeholderText() == "Select project folder"
assert project_dialog.project_folder_label.text() == "Project Folder:"
assert project_dialog.project_folder.text() == "No folder selected"
assert project_dialog.project_folder_error.text() == "An empty project folder needs to be selected."
assert project_dialog.project_folder_error.isHidden()
assert project_dialog.project_folder.isReadOnly()

assert not project_dialog.name_error
assert not project_dialog.folder_error


def test_lineedit_errors(setup_project_dialog_widget):
"""
Tests the project name and folder line edit errors displayed.
"""
project_dialog, _ = setup_project_dialog_widget

# tests the project name and folder line edit errors displayed.
QtTest.QTest.mouseClick(project_dialog.create_button, QtCore.Qt.MouseButton.LeftButton)

assert not project_dialog.project_name_error.isHidden()
assert project_dialog.name_error
assert not project_dialog.project_folder_error.isHidden()
assert project_dialog.folder_error

# tests the project name line edit error displayed.
project_dialog.project_folder.setText("test-folder")
QtTest.QTest.mouseClick(project_dialog.create_button, QtCore.Qt.MouseButton.LeftButton)

assert not project_dialog.project_name_error.isHidden()
assert project_dialog.name_error
assert project_dialog.project_folder_error.isHidden()
assert not project_dialog.folder_error

# tests the project folder line edit error displayed.
project_dialog.project_name.setText("test-name")
project_dialog.project_folder.setText("")
QtTest.QTest.mouseClick(project_dialog.create_button, QtCore.Qt.MouseButton.LeftButton)

assert project_dialog.project_name_error.isHidden()
assert not project_dialog.name_error
assert not project_dialog.project_folder_error.isHidden()
assert project_dialog.folder_error


@patch.object(MockParentWindow, "createNewProject")
def test_create_button(mock_create_new_project, setup_project_dialog_widget):
"""
Tests create button on the ProjectDialog class.
"""
project_dialog, _ = setup_project_dialog_widget

project_dialog.project_name.setText("test-name")
project_dialog.project_folder.setText("test-folder")
QtTest.QTest.mouseClick(project_dialog.create_button, QtCore.Qt.MouseButton.LeftButton)
mock_create_new_project.assert_called_once()


@patch.object(MockParentWindow, "toggleView")
def test_cancel_button(mock_toggle_view, setup_project_dialog_widget):
"""
Tests cancel button on the ProjectDialog class.
"""
project_dialog, _ = setup_project_dialog_widget

project_dialog.project_name.setText("test-name")
project_dialog.name_error = True
project_dialog.project_folder.setText("test-folder")
project_dialog.folder_error = True

QtTest.QTest.mouseClick(project_dialog.cancel_button, QtCore.Qt.MouseButton.LeftButton)

mock_toggle_view.assert_called_once()

assert project_dialog.project_name.text() == ""
assert project_dialog.project_name.placeholderText() == "Enter project name"
assert not project_dialog.folder_selected
assert not project_dialog.name_error
assert project_dialog.project_folder.text() == ""
assert not project_dialog.folder_error


@patch("os.listdir")
@patch("PyQt6.QtWidgets.QFileDialog.getExistingDirectory")
def test_browse_button(mock_get_existing_directory, mock_listdir, setup_project_dialog_widget):
"""
Tests the browse button on the ProjectDialog class.
"""
project_dialog, _ = setup_project_dialog_widget

# When empty folder is selected.
mock_get_existing_directory.return_value = "/test/folder/path"
mock_listdir.return_value = [".hiddenfile"]

QtTest.QTest.mouseClick(project_dialog.browse_button, QtCore.Qt.MouseButton.LeftButton)

assert project_dialog.project_folder.text() == "/test/folder/path"
assert not project_dialog.folder_error

project_dialog.reset_variables()

# When a non empty folder is selected.
mock_listdir.return_value = [".hiddenfile", "testfile"]

QtTest.QTest.mouseClick(project_dialog.browse_button, QtCore.Qt.MouseButton.LeftButton)

assert project_dialog.project_folder.text() == ""
assert project_dialog.folder_error
Loading

0 comments on commit a944047

Please sign in to comment.