1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251
|
# -*- coding: utf-8 -*-
import os
import platform
import sys
from pathlib import Path
from typing import Tuple
import pytest
import wx
from wx import AppConsole, Button
from DisplayCAL import display_cal, config
from DisplayCAL.cgats import CGATS
from DisplayCAL.config import geticon
from DisplayCAL.dev.mocks import check_call, check_call_str
from DisplayCAL.display_cal import (
app_update_check,
app_uptodate,
check_donation,
colorimeter_correction_check_overwrite,
donation_message,
ExtraArgsFrame,
GamapFrame,
get_cgats_measurement_mode,
get_cgats_path,
get_profile_load_on_login_label,
IncrementingInt,
install_scope_handler,
MainFrame,
MeasurementFileCheckSanityDialog,
show_ccxx_error_dialog,
StartupFrame,
webbrowser_open,
)
from DisplayCAL.util_str import universal_newlines
from DisplayCAL.util_list import intlist
from DisplayCAL.worker import Worker, check_ti3
from DisplayCAL.wxwindows import ConfirmDialog, BaseInteractiveDialog
@pytest.fixture(scope="class", name="app", autouse=True)
def fixture_app() -> AppConsole:
"""Return app for tests."""
return wx.GetApp() or wx.App()
@pytest.fixture(scope="class", name="mainframe")
def fixture_mainframe() -> MainFrame:
"""Return mainframe for tests."""
worker = Worker()
return display_cal.MainFrame(worker=worker)
def test_update_colorimeter_correction_matrix_ctrl_items_1(
mainframe: MainFrame,
) -> None:
"""testing the MainFrame.update_colorimeter_correction_matrix_ctrl_items() method"""
# I have no idea how it works, let's see...
assert mainframe.colorimeter_correction_matrix_ctrl.Items != []
before_items = mainframe.colorimeter_correction_matrix_ctrl.Items
before_length = len(before_items)
mainframe.update_colorimeter_correction_matrix_ctrl_items()
after_items = mainframe.colorimeter_correction_matrix_ctrl.Items
after_length = len(after_items)
assert before_length == after_length
assert before_items == after_items # Really don't know anything about the method
# but it was raising errors before, now it is fixed.
def test_show_ccxx_error_dialog(mainframe: MainFrame) -> None:
"""Test if error message is shown."""
with check_call_str("DisplayCAL.display_cal.show_result_dialog"):
show_ccxx_error_dialog(Exception("Malformed demo"), "path", mainframe)
@pytest.mark.parametrize("argyll", (True, False), ids=("With argyll", "without argyll"))
@pytest.mark.parametrize("snapshot", (True, False), ids=("Snapshot", "No snapshot"))
@pytest.mark.parametrize("silent", (True, False), ids=("Silent", "Not silent"))
def test_app_update_check(
mainframe: MainFrame, silent: bool, snapshot: bool, argyll: bool
) -> None:
"""Test the application update check."""
with check_call(wx, "CallAfter", call_count=1):
app_update_check(mainframe, silent, snapshot, argyll)
def test_check_donation(mainframe: MainFrame) -> None:
"""Test check for user disabled donation."""
with check_call(wx, "CallAfter", call_count=-1):
check_donation(mainframe, False)
def test_app_uptodate(mainframe: MainFrame) -> None:
"""Test if 'up to date' messagebox is shown."""
with check_call(BaseInteractiveDialog, "ShowModalThenDestroy", call_count=1):
app_uptodate(mainframe)
@pytest.mark.parametrize("response", (wx.ID_OK, wx.ID_NO), ids=("Ok", "Cancel"))
def test_donation_message(mainframe: MainFrame, response: int) -> None:
"""Test if donation messagebox is shown as expected."""
with check_call(BaseInteractiveDialog, "ShowModal", response, call_count=1):
with check_call_str(
"DisplayCAL.display_cal.launch_file",
call_count=1 if response == wx.ID_OK else 0,
):
donation_message(mainframe)
# todo: test is working locally but not on CI
@pytest.mark.skip(
reason="Seems like the first call of ShowWindowModalBlocking always fails on remote."
"Locally however the problem cannot be reproduced, skipping test for now."
)
@pytest.mark.parametrize(
"update", (True, False), ids=("update comports", "dont update comports")
)
@pytest.mark.parametrize(
"response,value", ((wx.ID_OK, True), (wx.ID_NO, False)), ids=("Ok", "Cancel")
)
def test_colorimeter_correction_check_overwrite(
data_files, mainframe: MainFrame, response: int, value: bool, update: bool
) -> None:
"""Test if function reacts as expected to user input."""
path = data_files["0_16.ti3"].absolute()
with open(path, "rb") as cgatsfile:
cgats = universal_newlines(cgatsfile.read())
with check_call(BaseInteractiveDialog, "ShowWindowModalBlocking", response):
assert colorimeter_correction_check_overwrite(mainframe, cgats, update) == value
@pytest.mark.parametrize("file", ("0_16.ti3", "0_16_with_refresh.ti3", "default.ti3"))
@pytest.mark.parametrize(
"instrument,modes",
(
("ColorHug", ("F", "c", None)),
("ColorHug2", ("F", "c", None)),
("ColorMunki Smile", ("f", "c", None)),
("Colorimtre HCFR", ("R", "c", None)),
("K-10", ("F", "c", None)),
("fake_instrument", ("l", "c", None)),
),
)
def test_get_cgats_measurement_mode(
data_files, instrument: str, file: str, modes: Tuple[str, str, None]
) -> None:
"""Test if expected measurement mode is returned."""
path = data_files[file].absolute()
cgats = CGATS(cgats=path)
if file == "0_16.ti3":
mode = modes[0]
elif file == "0_16_with_refresh.ti3":
mode = modes[1]
else:
mode = modes[2]
assert get_cgats_measurement_mode(cgats, instrument) == mode
def test_get_cgats_path(data_files) -> None:
"""Test if correct cgats path is returned."""
path = data_files["default.ti3"].absolute()
with open(path, "rb") as cgatsfile:
cgats = universal_newlines(cgatsfile.read())
assert Path(
config.get_argyll_data_dir()
) / "Argyll Calibration Target chart information 3.cti3" == Path(
get_cgats_path(cgats)
)
def test_get_profile_load_on_login_label() -> None:
"""Test if load on login label is returned."""
assert get_profile_load_on_login_label(True) == "profile.load_on_login"
def test_install_scope_handler(mainframe: MainFrame) -> None:
"""Test if install scope handler calls the correct methods for authentication dialog."""
dlg = ConfirmDialog(
mainframe,
title="colorimeter_correction.import",
msg="msg",
ok="ok",
cancel="cancel",
bitmap=geticon(32, "dialog-information"),
alt="file.select",
)
dlg.install_systemwide = wx.RadioButton(dlg, -1, "install_local_system")
dlg.install_systemwide.Bind(wx.EVT_RADIOBUTTON, install_scope_handler)
with check_call(Button, "SetAuthNeeded", call_count=2):
install_scope_handler(dlg=dlg)
def test_webbrowser_open(monkeypatch) -> None:
"""Test if function calls browser as expected."""
opened_urls = []
class PatchedWebBrowser:
@staticmethod
def open(url: str, new: int = 0, autoraise: bool = True) -> bool:
opened_urls.append(url)
return True
# patch webbrowser.open
monkeypatch.setattr("DisplayCAL.display_cal.webbrowser", PatchedWebBrowser)
assert opened_urls == []
url = "https://github.com/eoyilmaz/displaycal-py3"
assert webbrowser_open(url)
assert opened_urls == [url]
def test_incrementing_int() -> None:
"""Testing if self incrementing int increments every time it is used."""
inc_integer = IncrementingInt()
assert int(inc_integer) == 0
[int(inc_integer) for _ in range(9)]
assert int(inc_integer) == 10
def test_init_extra_args_frame(mainframe: MainFrame) -> None:
"""Test if ExtraArgsFrame is initialized properly"""
with check_call(ExtraArgsFrame, "update_controls"):
ExtraArgsFrame(mainframe)
def test_init_gamap_frame(mainframe: MainFrame) -> None:
"""Test if GamapFrame is initialized properly."""
with check_call(GamapFrame, "update_layout"):
GamapFrame(mainframe)
def test_init_startup_frame() -> None:
"""Test if StartupFrame is initialized properly."""
show_func_name = "Show"
if (
sys.platform == "darwin"
and intlist(platform.mac_ver()[0].split(".")) >= [10, 10]
) or os.getenv("XDG_SESSION_TYPE") == "wayland":
show_func_name = "ShowModal"
with check_call(StartupFrame, show_func_name):
StartupFrame()
def test_init_measurement_file_check_sanity_dialog_frame(
data_files, mainframe: MainFrame
) -> None:
"""Test if MeasurementFileCheckSanityDialog is initialized properly."""
path = data_files["0_16.ti3"].absolute()
cgats = CGATS(cgats=path)
with check_call(MeasurementFileCheckSanityDialog, "Center"):
MeasurementFileCheckSanityDialog(mainframe, cgats[0], check_ti3(cgats), False)
|