Skip to content

Commit

Permalink
pytests
Browse files Browse the repository at this point in the history
  • Loading branch information
mattclifford1 committed Jul 1, 2024
1 parent 3729652 commit db1e7fa
Show file tree
Hide file tree
Showing 9 changed files with 369 additions and 38 deletions.
1 change: 1 addition & 0 deletions IQM_Vis/UI/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def init_layout(self):
self.main_widget.setLayout(self.main_layout)
self.setCentralWidget(self.main_widget)
self.show()
return self

def _init_generic_layout(self):
'''
Expand Down
12 changes: 7 additions & 5 deletions IQM_Vis/UI/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
from IQM_Vis.UI import layout, widgets, images, ProgressBar

class make_app(widgets, layout, images):
def __init__(self, app,
def __init__(self,
app,
data_stores: list,
transformations: dict,
metrics_info_format='graph', # graph or text
Expand Down Expand Up @@ -132,22 +133,23 @@ def load_all_metric_images(self):
self.construct_UI()

def quit(self):
QApplication.instance().quit()
# QApplication.instance().quit()
self.app.quit()

def __del__(self):
# garbage collection
self.range_worker.stop()

def closeEvent(self, event):
# Ask for confirmation
answer = QMessageBox.question(self,
self.close_answer = QMessageBox.question(self,
"Confirm Exit...",
"Are you sure you want to exit?\nAll unsaved data will be lost.",
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
QMessageBox.StandardButton.Yes)

event.ignore()
if answer == QMessageBox.StandardButton.Yes:
if self.close_answer == QMessageBox.StandardButton.Yes:
if hasattr(self, 'range_worker'):
self.range_worker.stop()
event.accept()
Expand Down Expand Up @@ -228,7 +230,7 @@ def construct_UI(self):
self.init_style() # layout.py
self.init_widgets() # widgets.py
self.change_data(0, _redo_plots=True) # images.py
self.init_layout() # layout.py
self.main = self.init_layout() # layout.py
self.tabs['slider'].setCurrentIndex(tabs_index['slider'])
self.tabs['graph'].setCurrentIndex(tabs_index['graph'])
# self.experiments_tab.setCurrentIndex(experi_tabs_index)
Expand Down
12 changes: 8 additions & 4 deletions IQM_Vis/ui_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ def __init__(self,
default_save_dir=IQM_Vis.utils.save_utils.DEFAULT_SAVE_DIR,
restrict_options=None,
num_steps_range=11,
debug=False):
debug=False,
test=False):
if data_store == None:
data_store = IQM_Vis.dataset_holder(image_list,
metrics,
Expand All @@ -51,17 +52,19 @@ def __init__(self,
self.restrict_options = restrict_options
self.num_steps_range = num_steps_range
self.debug = debug
self.test = test
check_pyqt_install_deps()
self.show()
self.showing = True

def show(self):
self._check_restrict_options()
self._check_data_store()
self._check_trans()
if self.debug:
self._check_inputs()
app = QApplication(sys.argv)
window = make_app(app,
self.app = QApplication(sys.argv)
self.window = make_app(self.app,
self.data_store,
self.transformations,
metrics_info_format=self.metrics_info_format,
Expand All @@ -70,7 +73,8 @@ def show(self):
default_save_dir=self.default_save_dir,
restrict_options=self.restrict_options,
num_steps_range=self.num_steps_range)
sys.exit(app.exec())
if self.test == False:
sys.exit(self.app.exec())

def _check_restrict_options(self):
if self.restrict_options == None:
Expand Down
1 change: 1 addition & 0 deletions dev_resources/requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ scipy==1.9.3
notebook
twine
pytest
pytest-qt==4.4.0
sphinx
nbsphinx
sphinx_gallery
Expand Down
42 changes: 42 additions & 0 deletions tests/test_1_making_the_UI.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Author: Matt Clifford <[email protected]>
# License: BSD 3-Clause License

import pytest
from PyQt6 import QtTest, QtWidgets, QtCore
from pytestqt.plugin import QtBot, _close_widgets
import IQM_Vis
import threading


def get_UI():
app = IQM_Vis.make_UI(test=True)
return app


# building and closing function of UI for testing
@pytest.fixture
def build_IQM_Vis():

test_window = get_UI()
qtbotbis = QtBot(test_window.window)

yield test_window, qtbotbis

# need to handle the closing dialog
def handle_dialog():
messagebox = QtWidgets.QApplication.activeWindow()
yes_button = messagebox.button(
QtWidgets.QMessageBox.StandardButton.Yes)
qtbotbis.mouseClick(
yes_button, QtCore.Qt.MouseButton.LeftButton, delay=1)

QtCore.QTimer.singleShot(100, handle_dialog)

# test_window.window.quit()
test_window.window.main.close()


def test_build_1(build_IQM_Vis):
test_window, _ = build_IQM_Vis
assert test_window.showing == True

80 changes: 80 additions & 0 deletions tests/test_2_simple_customisation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Author: Matt Clifford <[email protected]>
# License: BSD 3-Clause License

import pytest
from PyQt6 import QtTest, QtWidgets, QtCore
from pytestqt.plugin import QtBot, _close_widgets
import IQM_Vis


def get_UI():
image1 = IQM_Vis.examples.images.IMAGE1
image2 = IQM_Vis.examples.images.IMAGE2
images = [image1, image2]
print(f'Images files: {images}')

MAE = IQM_Vis.IQMs.MAE()
MSE = IQM_Vis.IQMs.MSE()
SSIM = IQM_Vis.IQMs.SSIM()

metrics = {'MAE': MAE,
'MSE': MSE,
'1-SSIM': SSIM}

MSE_image = IQM_Vis.IQMs.MSE(return_image=True)
SSIM_image = IQM_Vis.IQMs.SSIM(return_image=True)
metric_images = {'MSE': MSE_image,
'1-SSIM': SSIM_image}

rotation = IQM_Vis.transforms.rotation
blur = IQM_Vis.transforms.blur
brightness = IQM_Vis.transforms.brightness
jpeg_compression = IQM_Vis.transforms.jpeg_compression

transformations = {
# normal input
'rotation': {'min': -180, 'max': 180, 'function': rotation},
# only odd ints since it's a kernel
'blur': {'min': 1, 'max': 41, 'function': blur, 'normalise': 'odd'},
# float values
'brightness': {'min': -1.0, 'max': 1.0, 'function': brightness},
# non zero inital value
'jpg comp.': {'min': 1, 'max': 100, 'function': jpeg_compression, 'init_value': 100},
}

test_app = IQM_Vis.make_UI(transformations=transformations,
image_list=images,
metrics=metrics,
metric_images=metric_images,
test=True)
return test_app


# building and closing function of UI for testing
@pytest.fixture
def build_IQM_Vis():

test_window = get_UI()
qtbotbis = QtBot(test_window.window)

yield test_window, qtbotbis

# need to handle the closing dialog
def handle_dialog():
messagebox = QtWidgets.QApplication.activeWindow()
yes_button = messagebox.button(
QtWidgets.QMessageBox.StandardButton.Yes)
qtbotbis.mouseClick(
yes_button, QtCore.Qt.MouseButton.LeftButton, delay=1)

QtCore.QTimer.singleShot(100, handle_dialog)

# test_window.window.quit()
test_window.window.main.close()


def test_build_2(build_IQM_Vis):
test_window, _ = build_IQM_Vis
assert test_window.showing == True


83 changes: 83 additions & 0 deletions tests/test_3_customisation_details.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Author: Matt Clifford <[email protected]>
# License: BSD 3-Clause License

import numpy as np
import pytest
from PyQt6 import QtTest, QtWidgets, QtCore
from pytestqt.plugin import QtBot
import IQM_Vis

def custom_MAE_function(im_ref, im_comp, **kwargs):
L1 = np.abs(im_ref - im_comp)
return L1.mean()


class custom_MAE_class:
def __init__(self, att=0):
self.att = att

def __call__(self, im_ref, im_comp, **kwargs):
L1 = np.abs(im_ref - im_comp)
return L1.mean()


def dummy_args(im_ref, im_comp, param1=0, **kwargs):
# now we can use param here
score = custom_MAE_function(im_ref, im_comp)
return score + param1


def custom_brightness(image, value=0):
return np.clip(image + value, 0, 1)


def get_UI():
metrics = {'MAE function': custom_MAE_function,
'MAE class': custom_MAE_class(),
'dummy args': dummy_args}
params = {'param1': {'min': -1.0, 'max': 1.0, 'init_value': 0}}
transformations = {'brightness': {'min': -1.0,
'max': 1.0, 'function': custom_brightness}}

images = ['/home/matt/datasets/kodak/kodim01.png',
'/home/matt/datasets/kodak/kodim02.png']

test_app = IQM_Vis.make_UI(transformations=transformations,
image_list=images,
metrics=metrics,
metric_params=params,
test=True)
return test_app


# building and closing function of UI for testing
@pytest.fixture
def build_IQM_Vis():

test_window = get_UI()
qtbotbis = QtBot(test_window.window)

yield test_window, qtbotbis

# need to handle the closing dialog
def handle_dialog():
messagebox = QtWidgets.QApplication.activeWindow()
yes_button = messagebox.button(
QtWidgets.QMessageBox.StandardButton.Yes)
qtbotbis.mouseClick(
yes_button, QtCore.Qt.MouseButton.LeftButton, delay=1)

QtCore.QTimer.singleShot(100, handle_dialog)

# test_window.window.quit()
test_window.window.main.close()


@pytest.fixture
def test_build_3(build_IQM_Vis):
test_window, _ = build_IQM_Vis
assert test_window.showing == True


def test_3(test_build_3):
return
Loading

0 comments on commit db1e7fa

Please sign in to comment.