From 823301520ea6226f7402d3be003e9a534ac770be Mon Sep 17 00:00:00 2001 From: Eric Blevins Date: Fri, 14 Jun 2024 21:13:14 -0400 Subject: [PATCH 1/9] Removed html report from coverage --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 22521d22..178f5b64 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -69,7 +69,7 @@ filterwarnings = [ # I belive this is warning that pyqt needs updated if you update to python 3.12 "ignore:sipPyTypeDict.*:DeprecationWarning:.*:" ] -addopts = "-vv --cov=src --cov-report html:extras/extras/test_results/htmlcov/ --cov-report term-missing --strict-markers -rfE" +addopts = "-vv --cov=src --cov-report term-missing --cov-branch --cov-report xml --cov-report term --strict-markers -rfE" [tool.coverage.run] relative_files = true From fbc47e1e78f564618dda951cf4cb4b4522282d6c Mon Sep 17 00:00:00 2001 From: Eric Blevins Date: Fri, 14 Jun 2024 21:29:53 -0400 Subject: [PATCH 2/9] Start making test for altimeter --- tests/instruments/altimeter/test_altimeter.py | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 tests/instruments/altimeter/test_altimeter.py diff --git a/tests/instruments/altimeter/test_altimeter.py b/tests/instruments/altimeter/test_altimeter.py new file mode 100644 index 00000000..c724b89b --- /dev/null +++ b/tests/instruments/altimeter/test_altimeter.py @@ -0,0 +1,23 @@ +import pytest +from unittest import mock +from PyQt5.QtWidgets import QApplication +from PyQt5.QtCore import Qt, qRound +from PyQt5.QtGui import QColor, QBrush, QPen, QFont, QPaintEvent, QFontMetrics +from pyefis.instruments import altimeter +import pyefis.hmi as hmi +from tests.utils import track_calls + + +@pytest.fixture +def app(qtbot): + test_app = QApplication.instance() + if test_app is None: + test_app = QApplication([]) + return test_app + + +def test_altimeter(fix,qtbot): + widget = altimeter.Altimeter() + assert widget.getRatio() == 1 + qtbot.addWidget(widget) + assert widget.item.value == 0 From 4d94a140862e8ad661da50ec1c91457bb268bb18 Mon Sep 17 00:00:00 2001 From: Eric Blevins Date: Fri, 14 Jun 2024 21:31:42 -0400 Subject: [PATCH 3/9] Forgot to commit the DB key ALT --- conftest.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/conftest.py b/conftest.py index 1e2b84a4..3bf1ef08 100644 --- a/conftest.py +++ b/conftest.py @@ -95,5 +95,17 @@ def create_numbers(key, value, old=False, bad=False, fail=False, annunciate=Fals fix.db.get_item("IAS").set_aux_value("Vne", 140.0) fix.db.get_item("IAS").set_aux_value("Vfe", 70.0) + fix.db.define_item( + "ALT", + "Indicated Altitude", + "float", + -2000.0, + 60000.0, + "ft", + 50000, + "" + ) + fix.db.set_value("ALT", 0) + return fix From c2f4acdbf311f4ba533ff50e313533f09081a10b Mon Sep 17 00:00:00 2001 From: Eric Blevins Date: Fri, 14 Jun 2024 21:39:21 -0400 Subject: [PATCH 4/9] formatted altimeter with black --- src/pyefis/instruments/altimeter/__init__.py | 191 ++++++++++++------- 1 file changed, 123 insertions(+), 68 deletions(-) diff --git a/src/pyefis/instruments/altimeter/__init__.py b/src/pyefis/instruments/altimeter/__init__.py index 9709e995..a13efa0d 100644 --- a/src/pyefis/instruments/altimeter/__init__.py +++ b/src/pyefis/instruments/altimeter/__init__.py @@ -23,12 +23,16 @@ import pyavtools.fix as fix from pyefis.instruments.NumericalDisplay import NumericalDisplay -import pyefis.hmi as hmi +import pyefis.hmi as hmi from pyefis.instruments import helpers + class Altimeter(QWidget): FULL_WIDTH = 300 - def __init__(self, parent=None, bg_color=Qt.black, font_family="DejaVu Sans Condensed"): + + def __init__( + self, parent=None, bg_color=Qt.black, font_family="DejaVu Sans Condensed" + ): super(Altimeter, self).__init__(parent) self.setStyleSheet("border: 0px") self.font_family = font_family @@ -56,10 +60,10 @@ def paintEvent(self, event): h = self.height() dial = QPainter(self) dial.setRenderHint(QPainter.Antialiasing) - radius = int(round(min(w,h)*.45)) + radius = int(round(min(w, h) * 0.45)) diameter = radius * 2 - center_x = w/2 - center_y = h/2 + center_x = w / 2 + center_y = h / 2 # Draw the Black Background dial.fillRect(0, 0, w, h, QColor(self.bg_color)) @@ -76,7 +80,9 @@ def paintEvent(self, event): # Dial Setup dial.setPen(dialPen) - dial.drawEllipse(QRectF(center_x-radius, center_y-radius, diameter, diameter)) + dial.drawEllipse( + QRectF(center_x - radius, center_y - radius, diameter, diameter) + ) f = QFont(self.font_family) fs = int(round(20 * w / self.FULL_WIDTH)) @@ -91,20 +97,21 @@ def paintEvent(self, event): altimeter_numbers = 0 while count < 360: if count % 36 == 0: - dial.drawLine(0, -(radius), 0, -(radius-15)) + dial.drawLine(0, -(radius), 0, -(radius - 15)) x = fontMetrics.width(str(altimeter_numbers)) / 2 y = f.pixelSize() - dial.drawText(qRound(-x), qRound(-(radius-15-y)), - str(altimeter_numbers)) + dial.drawText( + qRound(-x), qRound(-(radius - 15 - y)), str(altimeter_numbers) + ) altimeter_numbers += 1 else: - dial.drawLine(0, -(radius), 0, -(radius-10)) + dial.drawLine(0, -(radius), 0, -(radius - 10)) dial.rotate(36) count += 36 count = 0 while count < 360: - dial.drawLine(0, -(radius), 0, -(radius-10)) + dial.drawLine(0, -(radius), 0, -(radius - 10)) dial.rotate(7.2) count += 7.2 @@ -112,26 +119,38 @@ def paintEvent(self, event): if self.item.fail: warn_font = QFont(self.font_family, 30, QFont.Bold) dial.resetTransform() - dial.setPen (QPen(QColor(Qt.red))) - dial.setBrush (QBrush(QColor(Qt.red))) - dial.setFont (warn_font) - dial.drawText (0,0,w,h, Qt.AlignCenter, "XXX") + dial.setPen(QPen(QColor(Qt.red))) + dial.setBrush(QBrush(QColor(Qt.red))) + dial.setFont(warn_font) + dial.drawText(0, 0, w, h, Qt.AlignCenter, "XXX") return dial.setBrush(dialBrush) # Needle Movement - sm_dial = QPolygonF([QPointF(5, 0), QPointF(0, +5), QPointF(-5, 0), - QPointF(0, -(radius-15))]) - lg_dial = QPolygonF([QPointF(10, -(radius/9)), QPointF(5, 0), - QPointF(0, +5), QPointF(-5, 0), - QPointF(-10, -(radius/9)), - QPointF(0, -int(round((radius*.6))))]) - outside_dial = QPolygonF([QPointF( 7.5, -(radius)), QPointF( -7.5 , -(radius)), - QPointF(0, -(radius-10))]) - - sm_dial_angle = self._altimeter * .36 - 7.2 - lg_dial_angle = self._altimeter / 10 * .36 - 7.2 - outside_dial_angle = self._altimeter / 100 * .36 - 7.2 + sm_dial = QPolygonF( + [QPointF(5, 0), QPointF(0, +5), QPointF(-5, 0), QPointF(0, -(radius - 15))] + ) + lg_dial = QPolygonF( + [ + QPointF(10, -(radius / 9)), + QPointF(5, 0), + QPointF(0, +5), + QPointF(-5, 0), + QPointF(-10, -(radius / 9)), + QPointF(0, -int(round((radius * 0.6)))), + ] + ) + outside_dial = QPolygonF( + [ + QPointF(7.5, -(radius)), + QPointF(-7.5, -(radius)), + QPointF(0, -(radius - 10)), + ] + ) + + sm_dial_angle = self._altimeter * 0.36 - 7.2 + lg_dial_angle = self._altimeter / 10 * 0.36 - 7.2 + outside_dial_angle = self._altimeter / 100 * 0.36 - 7.2 dial.rotate(sm_dial_angle) dial.drawPolygon(sm_dial) @@ -166,11 +185,11 @@ def setUnitSwitching(self): self.update() def setUnits(self, args): - x = args.split(':') + x = args.split(":") command = x[1].lower() - names = x[0].split(',') - if self.item.key in names or '*' in names or self.unitGroup in names: - #item = fix.db.get_item(self.dbkey) + names = x[0].split(",") + if self.item.key in names or "*" in names or self.unitGroup in names: + # item = fix.db.get_item(self.dbkey) if command == "toggle": if self.__currentUnits == 1: self.unitsOverride = self.unitsOverride2 @@ -180,9 +199,8 @@ def setUnits(self, args): self.unitsOverride = self.unitsOverride1 self.conversionFunction = self.conversionFunction1 self.__currentUnits = 1 - #self.setAuxData(item.aux) # Trigger conversion for aux data - self.altimeter = self.item.value # Trigger the conversion for value - + # self.setAuxData(item.aux) # Trigger conversion for aux data + self.altimeter = self.item.value # Trigger the conversion for value def getAltimeter(self): return self._altimeter @@ -197,7 +215,15 @@ def setAltimeter(self, altimeter): class Altimeter_Tape(QGraphicsView): - def __init__(self, parent=None, dbkey="ALT", maxalt=50000, fontsize=15,font_percent=None,font_family="DejaVu Sans Condensed"): + def __init__( + self, + parent=None, + dbkey="ALT", + maxalt=50000, + fontsize=15, + font_percent=None, + font_family="DejaVu Sans Condensed", + ): super(Altimeter_Tape, self).__init__(parent) self.setStyleSheet("background: transparent") self.font_family = font_family @@ -221,7 +247,6 @@ def __init__(self, parent=None, dbkey="ALT", maxalt=50000, fontsize=15,font_perc self.majorDiv = 200 self.minorDiv = 100 - self.maxalt = maxalt self._maxalt = maxalt self.total_decimals = 5 @@ -234,25 +259,38 @@ def __init__(self, parent=None, dbkey="ALT", maxalt=50000, fontsize=15,font_perc def resizeEvent(self, event): if self.font_percent: self.fontsize = qRound(self.width() * self.font_percent) - self.pph = self.fontsize / ( self.height() / 20) + self.pph = self.fontsize / (self.height() / 20) w = self.width() - w_2 = w/2 + w_2 = w / 2 h = self.height() f = QFont(self.font_family) if self.font_mask: - self.font_size = helpers.fit_to_mask(self.width()*.55,self.height()*0.05,self.font_mask,self.font_family) + self.font_size = helpers.fit_to_mask( + self.width() * 0.55, + self.height() * 0.05, + self.font_mask, + self.font_family, + ) f.setPointSizeF(self.font_size) else: f.setPixelSize(self.fontsize) - self.height_pixel = (self.maxalt*2*self.pph + h ) #+ abs(self.minalt*self.pph) + self.height_pixel = ( + self.maxalt * 2 * self.pph + h + ) # + abs(self.minalt*self.pph) dialPen = QPen(QColor(Qt.white)) dialPen.setWidth(int(self.height() * 0.005)) self.scene = QGraphicsScene(0, 0, w, self.height_pixel) - x = self.scene.addRect(0, 0, w, self.height_pixel, - QPen(QColor(32, 32, 32)), QBrush(QColor(32, 32, 32))) + x = self.scene.addRect( + 0, + 0, + w, + self.height_pixel, + QPen(QColor(32, 32, 32)), + QBrush(QColor(32, 32, 32)), + ) x.setOpacity(self.backgroundOpacity) for i in range(self.maxalt * 2, -1, -self.minorDiv): @@ -260,7 +298,7 @@ def resizeEvent(self, event): if (i - self.maxalt) % self.majorDiv == 0: l = self.scene.addLine(w_2 + 15, y, w, y, dialPen) l.setOpacity(self.foregroundOpacity) - t = self.scene.addText(str(i-self.maxalt)) + t = self.scene.addText(str(i - self.maxalt)) t.setFont(f) self.scene.setFont(f) t.setDefaultTextColor(QColor(Qt.white)) @@ -273,16 +311,24 @@ def resizeEvent(self, event): l.setOpacity(self.foregroundOpacity) self.setScene(self.scene) - self.numerical_display = NumericalDisplay(self, total_decimals=self.total_decimals, scroll_decimal=2) - nbh=w/1.20 - self.numerical_display.resize (qRound(w/1.20), qRound(nbh/1.45)) - self.numeric_box_pos = QPoint(0, qRound(h/2-(nbh/1.45)/2)) + self.numerical_display = NumericalDisplay( + self, total_decimals=self.total_decimals, scroll_decimal=2 + ) + nbh = w / 1.20 + self.numerical_display.resize(qRound(w / 1.20), qRound(nbh / 1.45)) + self.numeric_box_pos = QPoint(0, qRound(h / 2 - (nbh / 1.45) / 2)) self.numerical_display.move(self.numeric_box_pos) - self.numeric_box_pos.setX(self.numeric_box_pos.x()+self.numerical_display.width()) - self.numeric_box_pos.setY(qRound(self.numeric_box_pos.y()+(nbh/1.45)/2)+1) + self.numeric_box_pos.setX( + self.numeric_box_pos.x() + self.numerical_display.width() + ) + self.numeric_box_pos.setY( + qRound(self.numeric_box_pos.y() + (nbh / 1.45) / 2) + 1 + ) self.numerical_display.show() self.numerical_display.value = self._altimeter - self.centerOn(self.scene.width() / 2, self.y_offset(self._altimeter+self.maxalt)) + self.centerOn( + self.scene.width() / 2, self.y_offset(self._altimeter + self.maxalt) + ) self.setAltOld(self.item.old) self.setAltBad(self.item.bad) self.setAltFail(self.item.fail) @@ -292,12 +338,15 @@ def resizeEvent(self, event): self.item.failChanged[bool].connect(self.setAltFail) def y_offset(self, alt): - return self.height_pixel - (alt*self.pph) - self.height() + return self.height_pixel - (alt * self.pph) - self.height() def redraw(self): - if not self.isVisible(): return + if not self.isVisible(): + return self.resetTransform() - self.centerOn(self.scene.width() / 2, self.y_offset(self._altimeter+self.maxalt)) + self.centerOn( + self.scene.width() / 2, self.y_offset(self._altimeter + self.maxalt) + ) self.numerical_display.value = self._altimeter # Index Line that doesn't move to make it easy to read the altimeter. @@ -312,10 +361,16 @@ def paintEvent(self, event): p.translate(self.numeric_box_pos.x(), self.numeric_box_pos.y()) p.setPen(marks) p.setBrush(QBrush(Qt.black)) - triangle_size = w/8 - p.drawConvexPolygon(QPolygonF([QPointF(0, -triangle_size), - QPointF(0, triangle_size), - QPointF(triangle_size, 0)])) + triangle_size = w / 8 + p.drawConvexPolygon( + QPolygonF( + [ + QPointF(0, -triangle_size), + QPointF(0, triangle_size), + QPointF(triangle_size, 0), + ] + ) + ) def setUnitSwitching(self): """When this function is called the unit switching features are used""" @@ -323,14 +378,15 @@ def setUnitSwitching(self): self.unitsOverride = self.unitsOverride1 self.conversionFunction = self.conversionFunction1 hmi.actions.setInstUnits.connect(self.setUnits) - if self.isVisible(): self.update() + if self.isVisible(): + self.update() def setUnits(self, args): - x = args.split(':') + x = args.split(":") command = x[1].lower() - names = x[0].split(',') - if self.item.key in names or '*' in names or self.unitGroup in names: - #item = fix.db.get_item(self.dbkey) + names = x[0].split(",") + if self.item.key in names or "*" in names or self.unitGroup in names: + # item = fix.db.get_item(self.dbkey) if command == "toggle": if self.__currentUnits == 1: self.unitsOverride = self.unitsOverride2 @@ -340,8 +396,8 @@ def setUnits(self, args): self.unitsOverride = self.unitsOverride1 self.conversionFunction = self.conversionFunction1 self.__currentUnits = 1 - #self.setAuxData(item.aux) # Trigger conversion for aux data - self.altimeter = self.item.value # Trigger the conversion for value + # self.setAuxData(item.aux) # Trigger conversion for aux data + self.altimeter = self.item.value # Trigger the conversion for value def getAltimeter(self): return self._altimeter @@ -354,13 +410,13 @@ def setAltimeter(self, altimeter): altimeter = property(getAltimeter, setAltimeter) - def setAltOld(self,b): + def setAltOld(self, b): self.numerical_display.old = b - def setAltBad(self,b): + def setAltBad(self, b): self.numerical_display.bad = b - def setAltFail(self,b): + def setAltFail(self, b): self.numerical_display.fail = b # We don't want this responding to keystrokes @@ -370,4 +426,3 @@ def keyPressEvent(self, event): # Don't want it acting with the mouse scroll wheel either def wheelEvent(self, event): pass - From c6abfbdc8d2beadc1e4d688615dd26d8fba20ec4 Mon Sep 17 00:00:00 2001 From: Eric Blevins Date: Fri, 14 Jun 2024 21:39:54 -0400 Subject: [PATCH 5/9] Minor progress on altimeter tests --- tests/instruments/altimeter/__init__.py | 0 tests/instruments/altimeter/test_altimeter.py | 4 ++++ 2 files changed, 4 insertions(+) create mode 100644 tests/instruments/altimeter/__init__.py diff --git a/tests/instruments/altimeter/__init__.py b/tests/instruments/altimeter/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/instruments/altimeter/test_altimeter.py b/tests/instruments/altimeter/test_altimeter.py index c724b89b..fe5a2ec2 100644 --- a/tests/instruments/altimeter/test_altimeter.py +++ b/tests/instruments/altimeter/test_altimeter.py @@ -21,3 +21,7 @@ def test_altimeter(fix,qtbot): assert widget.getRatio() == 1 qtbot.addWidget(widget) assert widget.item.value == 0 + widget.resize(200,200) + widget.show() + qtbot.waitExposed(widget) + qtbot.wait(3000) From 97a584f130efb7a9846dab8b0eedec503637334b Mon Sep 17 00:00:00 2001 From: Eric Blevins Date: Fri, 14 Jun 2024 21:43:55 -0400 Subject: [PATCH 6/9] See if coverage report on github changes --- tests/instruments/altimeter/test_altimeter.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/instruments/altimeter/test_altimeter.py b/tests/instruments/altimeter/test_altimeter.py index fe5a2ec2..8cdc1fa3 100644 --- a/tests/instruments/altimeter/test_altimeter.py +++ b/tests/instruments/altimeter/test_altimeter.py @@ -24,4 +24,6 @@ def test_altimeter(fix,qtbot): widget.resize(200,200) widget.show() qtbot.waitExposed(widget) + widget.paintEvent(None) + qtbot.wait(3000) From 1276ef3cf15ee7660554eaea2e49ff95e41129ee Mon Sep 17 00:00:00 2001 From: Eric Blevins Date: Fri, 14 Jun 2024 22:16:46 -0400 Subject: [PATCH 7/9] Updated coverage options in pyproject.toml --- pyproject.toml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 178f5b64..317b59a4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -69,7 +69,11 @@ filterwarnings = [ # I belive this is warning that pyqt needs updated if you update to python 3.12 "ignore:sipPyTypeDict.*:DeprecationWarning:.*:" ] -addopts = "-vv --cov=src --cov-report term-missing --cov-branch --cov-report xml --cov-report term --strict-markers -rfE" +addopts = """ + --cov-report term-missing --cov-branch --cov-report html --cov-report term + --cov=pyefis --cov-context=test -vv --strict-markers -rfE + --ignore=tests/end_to_end/repo +""" [tool.coverage.run] relative_files = true From d6381d546a76bc7c8a7cc5e4bfb56828d75fb93f Mon Sep 17 00:00:00 2001 From: Eric Blevins Date: Fri, 14 Jun 2024 22:30:38 -0400 Subject: [PATCH 8/9] Added coverage badge to readme --- README.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.rst b/README.rst index d6da5386..fe844bb2 100644 --- a/README.rst +++ b/README.rst @@ -3,6 +3,9 @@ .. |Website snapcraft.io| image:: https://snapcraft.io/pyefis/badge.svg :target: https://snapcraft.io/pyefis +.. |Coverage Badge| image:: https://raw.githubusercontent.com/makerplane/pyEfis/python-coverage-comment-action-data/badge.svg + :target: https://htmlpreview.github.io/?https://github.com/makerplane/pyEfis/blob/python-coverage-comment-action-data/htmlcov/index.html + pyEfis ================== From 63c671e9866291f6fbdb9eac40ac858a3953827a Mon Sep 17 00:00:00 2001 From: Eric Blevins Date: Fri, 14 Jun 2024 22:32:42 -0400 Subject: [PATCH 9/9] Guessing how to get the image to show in Readme --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index fe844bb2..41d6e697 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,4 @@ -|Website snapcraft.io| +|Website snapcraft.io| |Coverage Badge| .. |Website snapcraft.io| image:: https://snapcraft.io/pyefis/badge.svg :target: https://snapcraft.io/pyefis