Skip to content

Commit

Permalink
In an effort to be more universally appropriate to the test suite, I …
Browse files Browse the repository at this point in the history
…moved the headerToModule() to a top level of the Qt.py. This allowed the function itself to be tested and no longer relies on the variety of paths the code may take in the when calling the QtCompat.loadui().
  • Loading branch information
jasonbrackman committed Mar 13, 2024
1 parent 7d6d0e2 commit ecf9db6
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 62 deletions.
41 changes: 18 additions & 23 deletions Qt.py
Original file line number Diff line number Diff line change
Expand Up @@ -874,6 +874,23 @@ def get_arg(index):
return app.translate(*sanitized_args)


def _headerToModule(header):
"""
Translate a header file to python module path
foo/bar.h => foo.bar
"""

# Only manipulate header files, identified by the `.h` ext.
if header.endswith(".h") is False:
return header

# Remove header extension
module = os.path.splitext(header)[0]

# Replace os separator by python module separator
return module.replace("/", ".").replace("\\", ".")


def _loadUi(uifile, baseinstance=None):
"""Dynamically load a user interface from the given `uifile`
Expand Down Expand Up @@ -925,22 +942,6 @@ def _loadCustomWidgets(self, etree):
objects. Then we can directly use them in createWidget method.
"""

def headerToModule(header):
"""
Translate a header file to python module path
foo/bar.h => foo.bar
"""

if header.endswith(".h") is False:
# Only manipulate header files, identified by the `.h` ext.
return header

# Remove header extension
module = os.path.splitext(header)[0]

# Replace os separator by python module separator
return module.replace("/", ".").replace("\\", ".")

custom_widgets = etree.find("customwidgets")

if custom_widgets is None:
Expand All @@ -949,13 +950,7 @@ def headerToModule(header):
for custom_widget in custom_widgets:
class_name = custom_widget.find("class").text
header = custom_widget.find("header").text
try:
header = headerToModule(header)
module = importlib.import_module(header)
except ImportError as _error:
# ReRaising the ImportError with a more informative
# message to aid in the creation of Tests for this case.
raise ImportError("No module named '%s'" % header)
module = importlib.import_module(_headerToModule(header))
self.custom_widgets[class_name] = getattr(module,
class_name)

Expand Down
46 changes: 7 additions & 39 deletions tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -449,25 +449,10 @@ def test_load_ui_customwidget():
app.exit()


def _rewrite_file(file, current, provided):
with open(file, "r") as f:
new = f.read().replace(
"<header>" + current + "</header>",
"<header>" + provided + "</header>"
)
with open(self.ui_qpycustomwidget, "w") as f:
f.write(new)


def test_load_ui_pycustomwidget():
"""Tests to see if loadUi loads a custom widget from different sources,
such as a Python path or a .h path can be parsed properly.
The structure of the current code does not provide direct access to the
headertomodule function. Instead, the test updates the temp.ui file to
contain a different header and tries to load the UI. All cases are
designed to trigger a ModuleImport Exception which reports the path
expected.
def test_headerToModule():
"""
Tests to see if headerToModule manipulates the path passed in appropriately.
- It should only affect `Header` files and paths, marked with an .h extension.
"""

path_tests = {
Expand All @@ -489,30 +474,13 @@ def test_load_ui_pycustomwidget():
"path/to/module": "path/to/module",
"module.py": "module.py",
}
import sys
from Qt import QtWidgets, QtCompat

app = QtWidgets.QApplication(sys.argv)
win = QtWidgets.QMainWindow()
import Qt

current = "tests"
for provided, expected in path_tests.items():
_rewrite_file(self.ui_qpycustomwidget, current, provided)
current = provided
result = Qt._headerToModule(provided)
assert result == expected, "Provided: %s expected: %s got: %s" % (provided, expected, result)

try:
# actual test
QtCompat.loadUi(self.ui_qpycustomwidget, win)

except ImportError as error:
# Since the loadUi is a blackbox it is not possible to test the
# `headertomodule` function directly. Test if the ImportError
# error contains the correct import path.
result = str(error).split("'")[1]
assert result == expected, (
"Provided: %s expected: %s got: %s" % (provided, expected, result)
)
app.exit()

def test_load_ui_invalidpath():
"""Tests to see if loadUi successfully fails on invalid paths"""
Expand Down

0 comments on commit ecf9db6

Please sign in to comment.