Skip to content

Commit

Permalink
Merge pull request gridhead#178 from sdglitched/test/scan
Browse files Browse the repository at this point in the history
Add test for `scan` window
  • Loading branch information
gridhead authored Oct 8, 2024
2 parents 2db28db + 8ed0583 commit 596e1be
Show file tree
Hide file tree
Showing 13 changed files with 585 additions and 25 deletions.
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ jobs:
xcb-util-keysyms \
xcb-util-wm \
xorg-x11-server-Xvfb \
tesseract \
--assumeyes
- name: Install the base dependencies
Expand Down
10 changes: 5 additions & 5 deletions assets/wind.ui
Original file line number Diff line number Diff line change
Expand Up @@ -3004,7 +3004,7 @@
</size>
</property>
<property name="toolTip">
<string>Load</string>
<string>Scan</string>
</property>
<property name="styleSheet">
<string notr="true">#arti_ccol_scan {font: 87 10pt &quot;Font Awesome 6 Free Solid&quot;;}</string>
Expand Down Expand Up @@ -4055,7 +4055,7 @@
</size>
</property>
<property name="toolTip">
<string>Load</string>
<string>Scan</string>
</property>
<property name="styleSheet">
<string notr="true">#arti_gboe_scan {font: 87 10pt &quot;Font Awesome 6 Free Solid&quot;;}</string>
Expand Down Expand Up @@ -4323,7 +4323,7 @@
</size>
</property>
<property name="toolTip">
<string>Load</string>
<string>Scan</string>
</property>
<property name="styleSheet">
<string notr="true">#arti_sdoe_scan {font: 87 10pt &quot;Font Awesome 6 Free Solid&quot;;}</string>
Expand Down Expand Up @@ -4591,7 +4591,7 @@
</size>
</property>
<property name="toolTip">
<string>Load</string>
<string>Scan</string>
</property>
<property name="styleSheet">
<string notr="true">#arti_pmod_scan {font: 87 10pt &quot;Font Awesome 6 Free Solid&quot;;}</string>
Expand Down Expand Up @@ -4859,7 +4859,7 @@
</size>
</property>
<property name="toolTip">
<string>Load</string>
<string>Scan</string>
</property>
<property name="styleSheet">
<string notr="true">#arti_fwol_scan {font: 87 10pt &quot;Font Awesome 6 Free Solid&quot;;}</string>
Expand Down
15 changes: 11 additions & 4 deletions gi_loadouts/conf.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
from platform import system

if system() == "Windows":
tessexec = "C:\\Program Files\\Tesseract-OCR\\tesseract.exe"
else:
tessexec = "/usr/bin/tesseract"

def get_tessexec_path():
if system() == "Windows":
return "C:\\Program Files\\Tesseract-OCR\\tesseract.exe"
else:
return "/usr/bin/tesseract"

tessexec = get_tessexec_path()

tempname = ""
temppath = ""
stattime = 5000

data_prefix = "gi-loadouts-"
data_suffix = ".traineddata"
6 changes: 3 additions & 3 deletions gi_loadouts/face/rsrc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def make_temp_file() -> None:
Remove the residual cache data from the temporary directory left over during previous sessions
due to unsuccessful termination before instantiating the same for this session.
"""
ptrn = r"gi-loadouts-[a-z0-9_]+\.traineddata"
ptrn = fr"{conf.data_prefix}[a-z0-9_]+\{conf.data_suffix}"
temp = Path(gettempdir())
resi = [temp / file.name for file in temp.iterdir() if file.is_file() if match(ptrn, file.name)]

Expand All @@ -45,10 +45,10 @@ def make_temp_file() -> None:
have to be created and deleted manually. On UNIX based operating systems like GNU/Linux or
MacOS, files can be reliably opened even when they have been marked for deletion.
"""
temp = NamedTemporaryFile(prefix="gi-loadouts-", suffix=".traineddata", delete=False, mode="w+b")
temp = NamedTemporaryFile(prefix=conf.data_prefix, suffix=conf.data_suffix, delete=False, mode="w+b")
temp.write(cont)
temp.close()
conf.tempname = Path(temp.name).name.replace(".traineddata", "")
conf.tempname = Path(temp.name).name.replace(conf.data_suffix, "")
conf.temppath = temp.name


Expand Down
12 changes: 11 additions & 1 deletion gi_loadouts/face/scan/rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,18 @@ def register_return_from_scanning(self, rslt: tuple) -> None:
:return:
"""
area, main, seco, team, levl, rare, duration, expt = rslt

if expt:
self.show_dialog(
QMessageBox.Information,
"Faulty scanning",
f"Please consider checking your input after ensuring that the proper Tesseract OCR executable has been selected.\n\n{expt}"
)
return

self.arti_shot.setPixmap(self.shot)
area, main, seco, team, levl, rare, duration = rslt

if area in [self.arti_dist.itemText(indx) for indx in range(self.arti_dist.count())]:
self.arti_dist.setCurrentText(area)
if team in [self.arti_type.itemText(indx) for indx in range(self.arti_type.count())]:
Expand Down
19 changes: 14 additions & 5 deletions gi_loadouts/face/scan/work.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,19 @@ def __init__(self, snap: ImageFile):
super().__init__()
self.snap = snap

def scan_artifact(self) -> None:
def scan_artifact(self) -> None: # pragma: no cover
"""
Scan the screenshot for computing artifact information using Tesseract OCR
Offload a long running task to a thread to keep the user interface from becoming unresponsive
:return: Collection of artifact information and duration of computation
"""
"""
coverage.py does not seem to correctly work with the QThread.
Even though this part is tested but the coverage remains unchanged. https://github.com/nedbat/coveragepy/issues/686
"""

strttime = time()

area, main, seco, team, levl, rare = "", ATTR(), {"a": ATTR(), "b": ATTR(), "c": ATTR(), "d": ATTR()}, "", "Level 00", "Star 0"
Expand All @@ -45,9 +50,13 @@ def scan_artifact(self) -> None:
text = image_to_string(self.snap, lang=conf.tempname, config=f"--tessdata-dir {location}")
except (OSError, TesseractError) as expt:
if isinstance(expt, OSError):
raise OSError("Selected executable of Tesseract OCR is unfunctional.") from expt
elif isinstance(expt, TesseractError):
raise ValueError("Processing failed as either Tesseract OCR executable ceased to function or training data was tampered with.") from expt
expt = "Selected executable of Tesseract OCR is unfunctional."
else:
expt = "Processing failed as either Tesseract OCR executable ceased to function or training data was tampered with."
stoptime = time()
rslt = area, main, seco, team, levl, rare, (stoptime - strttime), expt
self.result.emit(rslt)
return

# DISTRIBUTION AREA
areadict = {}
Expand Down Expand Up @@ -148,6 +157,6 @@ def scan_artifact(self) -> None:

stoptime = time()

rslt = area, main, seco, team, levl, rare, (stoptime - strttime)
rslt = area, main, seco, team, levl, rare, (stoptime - strttime), None

self.result.emit(rslt)
2 changes: 1 addition & 1 deletion gi_loadouts/face/wind/calc.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@


class Assess:
def __init__(self) -> None:
def __init__(self) -> None: # pragma: no cover
self.collection = Collection()
self.c_team = None
self.c_weap = None
Expand Down
1 change: 0 additions & 1 deletion gi_loadouts/face/wind/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ def initialize_events(self) -> None:
drop, text = getattr(self, f"arti_{part}_name_{alfa}"), getattr(self, f"arti_{part}_data_{alfa}")
drop.currentTextChanged.connect(lambda _, a_drop=drop, a_text=text: self.render_lineedit_readonly_when_none(a_drop, a_text))
text.textChanged.connect(self.validate_lineedit_userdata)
for part in ["fwol", "pmod", "sdoe", "gboe", "ccol"]:
getattr(self, f"arti_{part}_scan").clicked.connect(lambda _, a_part=part: self.show_scan_dialog(a_part))
getattr(self, f"arti_{part}_load").clicked.connect(lambda _, a_part=part: self.arti_load(a_part))
getattr(self, f"arti_{part}_save").clicked.connect(lambda _, a_part=part: self.arti_save(a_part))
Expand Down
10 changes: 5 additions & 5 deletions gi_loadouts/face/wind/wind.py
Original file line number Diff line number Diff line change
Expand Up @@ -2025,7 +2025,7 @@ def retranslateUi(self, mainwind):
#endif // QT_CONFIG(tooltip)
self.arti_ccol_wipe.setText(QCoreApplication.translate("mainwind", "trash", None))
#if QT_CONFIG(tooltip)
self.arti_ccol_scan.setToolTip(QCoreApplication.translate("mainwind", "Load", None))
self.arti_ccol_scan.setToolTip(QCoreApplication.translate("mainwind", "Scan", None))
#endif // QT_CONFIG(tooltip)
self.arti_ccol_scan.setText(QCoreApplication.translate("mainwind", "eye", None))
self.arti_ccol_data_d.setPlaceholderText(QCoreApplication.translate("mainwind", "Data", None))
Expand Down Expand Up @@ -2057,7 +2057,7 @@ def retranslateUi(self, mainwind):
#endif // QT_CONFIG(tooltip)
self.arti_gboe_wipe.setText(QCoreApplication.translate("mainwind", "trash", None))
#if QT_CONFIG(tooltip)
self.arti_gboe_scan.setToolTip(QCoreApplication.translate("mainwind", "Load", None))
self.arti_gboe_scan.setToolTip(QCoreApplication.translate("mainwind", "Scan", None))
#endif // QT_CONFIG(tooltip)
self.arti_gboe_scan.setText(QCoreApplication.translate("mainwind", "eye", None))
#if QT_CONFIG(tooltip)
Expand All @@ -2077,7 +2077,7 @@ def retranslateUi(self, mainwind):
#endif // QT_CONFIG(tooltip)
self.arti_sdoe_wipe.setText(QCoreApplication.translate("mainwind", "trash", None))
#if QT_CONFIG(tooltip)
self.arti_sdoe_scan.setToolTip(QCoreApplication.translate("mainwind", "Load", None))
self.arti_sdoe_scan.setToolTip(QCoreApplication.translate("mainwind", "Scan", None))
#endif // QT_CONFIG(tooltip)
self.arti_sdoe_scan.setText(QCoreApplication.translate("mainwind", "eye", None))
#if QT_CONFIG(tooltip)
Expand All @@ -2097,7 +2097,7 @@ def retranslateUi(self, mainwind):
#endif // QT_CONFIG(tooltip)
self.arti_pmod_wipe.setText(QCoreApplication.translate("mainwind", "trash", None))
#if QT_CONFIG(tooltip)
self.arti_pmod_scan.setToolTip(QCoreApplication.translate("mainwind", "Load", None))
self.arti_pmod_scan.setToolTip(QCoreApplication.translate("mainwind", "Scan", None))
#endif // QT_CONFIG(tooltip)
self.arti_pmod_scan.setText(QCoreApplication.translate("mainwind", "eye", None))
#if QT_CONFIG(tooltip)
Expand All @@ -2117,7 +2117,7 @@ def retranslateUi(self, mainwind):
#endif // QT_CONFIG(tooltip)
self.arti_fwol_wipe.setText(QCoreApplication.translate("mainwind", "trash", None))
#if QT_CONFIG(tooltip)
self.arti_fwol_scan.setToolTip(QCoreApplication.translate("mainwind", "Load", None))
self.arti_fwol_scan.setToolTip(QCoreApplication.translate("mainwind", "Scan", None))
#endif // QT_CONFIG(tooltip)
self.arti_fwol_scan.setText(QCoreApplication.translate("mainwind", "eye", None))
self.pair_area_desc.setDocumentTitle(QCoreApplication.translate("mainwind", "pair_area_desc", None))
Expand Down
12 changes: 12 additions & 0 deletions test/conftest.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import pytest

from gi_loadouts.face.scan.main import ScanDialog
from gi_loadouts.face.wind.main import MainWindow


Expand All @@ -8,3 +9,14 @@ def runner(qtbot):
testwind = MainWindow()
qtbot.addWidget(testwind)
return testwind


@pytest.fixture
def scantest(qtbot):
"""
The codebase will automatically detect the part once the artifact is changed manually in the
window or changed by the after the scan
"""
testscan = ScanDialog("fwol")
qtbot.addWidget(testscan)
return testscan
32 changes: 32 additions & 0 deletions test/face/scan/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from gi_loadouts.type.arti.base import (
MainStatType_CCOL,
MainStatType_FWOL,
MainStatType_GBOE,
MainStatType_PMOD,
MainStatType_SDOE,
)
from gi_loadouts.type.stat import ATTR, STAT

__dist__ = {
"Flower of Life": {"list": MainStatType_FWOL, "part": "fwol"},
"Plume of Death": {"list": MainStatType_PMOD, "part": "pmod"},
"Sands of Eon": {"list": MainStatType_SDOE, "part": "sdoe"},
"Goblet of Eonothem": {"list": MainStatType_GBOE, "part": "gboe"},
"Circlet of Logos": {"list": MainStatType_CCOL, "part": "ccol"},
}

__rtrn__ = {
"part": "sdoe",
"team": "Shimenawa's Reminiscence",
"rare": "Star 5",
"levl": "Level 20",
"stat": {
"main": ATTR(stat_name=STAT.energy_recharge_perc, stat_data=51.8),
"seco": {
"a": ATTR(stat_name=STAT.elemental_mastery, stat_data=23.0),
"b": ATTR(stat_name=STAT.critical_rate_perc, stat_data=6.6),
"c": ATTR(stat_name=STAT.critical_damage_perc, stat_data=21.0),
"d": ATTR(stat_name=STAT.health_points_perc, stat_data=13.4)
}
}
}
Loading

0 comments on commit 596e1be

Please sign in to comment.