Increased test coverage

pull/282/head
Holger Müller 2020-07-25 21:34:49 +02:00
rodzic e6d3ea0c12
commit 3bfd99ad3d
8 zmienionych plików z 116 dodań i 141 usunięć

Wyświetl plik

@ -10,7 +10,7 @@ omit =
NanoVNASaver/Inputs.py
NanoVNASaver/Marker/*.py
NanoVNASaver/NanoVNASaver.py
NanoVNASaver/Settings.py
NanoVNASaver/Settings/Bands.py
NanoVNASaver/SweepWorker.py
NanoVNASaver/Windows/*.py
**/__init__.py

Wyświetl plik

@ -104,7 +104,7 @@ def format_group_delay(val: float) -> str:
def format_phase(val: float) -> str:
return f"{math.degrees(val):.2f}\N{DEGREE SIGN}"
return f"{math.degrees(val):.2f}""\N{DEGREE SIGN}"
def format_complex_imp(z: complex, allow_negative: bool = False) -> str:
@ -113,7 +113,7 @@ def format_complex_imp(z: complex, allow_negative: bool = False) -> str:
fmt_re = FMT_COMPLEX_NEG
re = SITools.Value(z.real, fmt=fmt_re)
im = SITools.Value(abs(z.imag), fmt=FMT_COMPLEX)
return f"{re}{'-' if z.imag < 0 else '+'}j{im} \N{OHM SIGN}"
return f"{re}{'-' if z.imag < 0 else '+'}j{im} ""\N{OHM SIGN}"
def format_wavelength(length: Number) -> str:
return str(SITools.Value(length, "m", FMT_WAVELENGTH))

Wyświetl plik

@ -58,7 +58,7 @@ class Sweep():
def stepsize(self) -> int:
return round(self.span / ((self.points -1) * self.segments))
def _exp_factor(self, index: int) -> int:
def _exp_factor(self, index: int) -> float:
return 1 - log(self.segments + 1 - index) / log(self.segments + 1)
def get_index_range(self, index: int) -> Tuple[int, int]:
@ -66,8 +66,8 @@ class Sweep():
start = self.start + index * self.points * self.step
end = start + (self.points - 1) * self.step
else:
start = self.start + self.span * self._exp_factor(index)
end = self.start + self.span * self._exp_factor(index + 1)
start = round(self.start + self.span * self._exp_factor(index))
end = round(self.start + self.span * self._exp_factor(index + 1))
logger.debug("get_index_range(%s) -> (%s, %s)", index, start, end)
return (start, end)

Wyświetl plik

@ -1,5 +1,4 @@
# NanoVNASaver
#
# A python program to view and export Touchstone data from a NanoVNA
# Copyright (C) 2019, 2020 Rune B. Broberg
# Copyright (C) 2020 NanoVNA-Saver Authors
@ -18,142 +17,10 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import logging
import re
import typing
from typing import List, Tuple
from PyQt5 import QtCore, QtGui
from PyQt5.QtCore import QModelIndex
logger = logging.getLogger(__name__)
class BandsModel(QtCore.QAbstractTableModel):
bands: List[Tuple[str, int, int]] = []
enabled = False
color = QtGui.QColor(128, 128, 128, 48)
# These bands correspond broadly to the Danish Amateur Radio allocation
default_bands = ["2200 m;135700;137800",
"630 m;472000;479000",
"160 m;1800000;2000000",
"80 m;3500000;3800000",
"60 m;5250000;5450000",
"40 m;7000000;7200000",
"30 m;10100000;10150000",
"20 m;14000000;14350000",
"17 m;18068000;18168000",
"15 m;21000000;21450000",
"12 m;24890000;24990000",
"10 m;28000000;29700000",
"6 m;50000000;52000000",
"4 m;69887500;70512500",
"2 m;144000000;146000000",
"70 cm;432000000;438000000",
"23 cm;1240000000;1300000000",
"13 cm;2320000000;2450000000"]
def __init__(self):
super().__init__()
self.settings = QtCore.QSettings(QtCore.QSettings.IniFormat,
QtCore.QSettings.UserScope,
"NanoVNASaver", "Bands")
self.settings.setIniCodec("UTF-8")
self.enabled = self.settings.value("ShowBands", False, bool)
stored_bands: List[str] = self.settings.value("bands", self.default_bands)
if stored_bands:
for b in stored_bands:
(name, start, end) = b.split(";")
self.bands.append((name, int(start), int(end)))
def saveSettings(self):
stored_bands = []
for b in self.bands:
stored_bands.append(b[0] + ";" + str(b[1]) + ";" + str(b[2]))
self.settings.setValue("bands", stored_bands)
self.settings.sync()
def resetBands(self):
self.bands = []
for b in self.default_bands:
(name, start, end) = b.split(";")
self.bands.append((name, int(start), int(end)))
self.layoutChanged.emit()
self.saveSettings()
def columnCount(self, parent: QModelIndex = ...) -> int:
return 3
def rowCount(self, parent: QModelIndex = ...) -> int:
return len(self.bands)
def data(self, index: QModelIndex, role: int = ...) -> QtCore.QVariant:
if (role == QtCore.Qt.DisplayRole or
role == QtCore.Qt.ItemDataRole or role == QtCore.Qt.EditRole):
return QtCore.QVariant(self.bands[index.row()][index.column()])
if role == QtCore.Qt.TextAlignmentRole:
if index.column() == 0:
return QtCore.QVariant(QtCore.Qt.AlignCenter)
return QtCore.QVariant(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
return QtCore.QVariant()
def setData(self, index: QModelIndex, value: typing.Any, role: int = ...) -> bool:
if role == QtCore.Qt.EditRole and index.isValid():
t = self.bands[index.row()]
name = t[0]
start = t[1]
end = t[2]
if index.column() == 0:
name = value
elif index.column() == 1:
start = value
elif index.column() == 2:
end = value
self.bands[index.row()] = (name, start, end)
self.dataChanged.emit(index, index)
self.saveSettings()
return True
return False
def index(self, row: int, column: int, parent: QModelIndex = ...) -> QModelIndex:
return self.createIndex(row, column)
def addRow(self):
self.bands.append(("New", 0, 0))
self.dataChanged.emit(self.index(len(self.bands), 0), self.index(len(self.bands), 2))
self.layoutChanged.emit()
def removeRow(self, row: int, parent: QModelIndex = ...) -> bool:
self.bands.remove(self.bands[row])
self.layoutChanged.emit()
self.saveSettings()
return True
def headerData(self, section: int,
orientation: QtCore.Qt.Orientation, role: int = ...):
if (role == QtCore.Qt.DisplayRole and
orientation == QtCore.Qt.Horizontal):
if section == 0:
return "Band"
if section == 1:
return "Start (Hz)"
if section == 2:
return "End (Hz)"
return "Invalid"
super().headerData(section, orientation, role)
def flags(self, index: QModelIndex) -> QtCore.Qt.ItemFlags:
if index.isValid():
return QtCore.Qt.ItemFlags(
QtCore.Qt.ItemIsEditable |
QtCore.Qt.ItemIsEnabled |
QtCore.Qt.ItemIsSelectable)
super().flags(index)
def setColor(self, color):
self.color = color
class Version:
RXP = re.compile(r"""^
\D*

Wyświetl plik

@ -77,7 +77,7 @@ class SweepSettingsWindow(QtWidgets.QWidget):
"averages. Common values are 3/0, 5/2, 9/4 and 25/6.\n")
label.setWordWrap(True)
settings_layout.addRow(label)
self.s21att = QtWidgets.QLineEdit("0")
label = QtWidgets.QLabel(
"Some times when you measure amplifiers you need to use an"
@ -88,7 +88,8 @@ class SweepSettingsWindow(QtWidgets.QWidget):
settings_layout.addRow("Attenuator in port CH1 (s21) in dB", self.s21att)
# settings_layout.addRow(QtWidgets.QLabel("Common values with un-un are 16.9 (49:1 2450) 9.54 (9:1 450)"))
# settings_layout.addRow(QtWidgets.QLabel(
# "Common values with un-un are 16.9 (49:1 2450) 9.54 (9:1 450)"))
self.continuous_sweep_radiobutton.toggled.connect(
lambda: self.app.worker.setContinuousSweep(

Wyświetl plik

@ -25,6 +25,15 @@ from NanoVNASaver import Formatting as fmt
class TestCases(unittest.TestCase):
def test_format_frequency(self):
self.assertEqual(fmt.format_frequency(1), '1.00000Hz')
self.assertEqual(fmt.format_frequency(12), '12.0000Hz')
self.assertEqual(fmt.format_frequency(123), '123.000Hz')
self.assertEqual(fmt.format_frequency(1234), '1.23400kHz')
self.assertEqual(fmt.format_frequency(1234567), '1.23457MHz')
self.assertEqual(fmt.format_frequency(1234567890), '1.23457GHz')
self.assertEqual(fmt.format_frequency(0), '0.00000Hz')
self.assertEqual(fmt.format_frequency(-1), '-1.00000Hz')
self.assertEqual(fmt.format_frequency_space(1), '1.00000 Hz')
self.assertEqual(fmt.format_frequency_space(12), '12.0000 Hz')
self.assertEqual(fmt.format_frequency_space(123), '123.000 Hz')
@ -34,6 +43,15 @@ class TestCases(unittest.TestCase):
self.assertEqual(fmt.format_frequency_space(0), '0.00000 Hz')
self.assertEqual(fmt.format_frequency_space(-1), '-1.00000 Hz')
self.assertEqual(fmt.format_frequency_short(1), '1.000Hz')
self.assertEqual(fmt.format_frequency_short(12), '12.00Hz')
self.assertEqual(fmt.format_frequency_short(123), '123.0Hz')
self.assertEqual(fmt.format_frequency_short(1234), '1.234kHz')
self.assertEqual(fmt.format_frequency_short(1234567), '1.235MHz')
self.assertEqual(fmt.format_frequency_short(1234567890), '1.235GHz')
self.assertEqual(fmt.format_frequency_short(0), '0.000Hz')
self.assertEqual(fmt.format_frequency_short(-1), '-1.000Hz')
def test_format_frequency_inputs(self):
self.assertEqual(fmt.format_frequency_inputs(1), '1Hz')
self.assertEqual(fmt.format_frequency_inputs(12), '12Hz')
@ -65,6 +83,11 @@ class TestCases(unittest.TestCase):
self.assertEqual(fmt.format_vswr(1.234), '1.234')
self.assertEqual(fmt.format_vswr(12345.12345), '12345.123')
def test_format_magnitude(self):
self.assertEqual(fmt.format_magnitude(1), '1.000')
self.assertEqual(fmt.format_magnitude(1.234), '1.234')
self.assertEqual(fmt.format_magnitude(12345.12345), '12345.123')
def test_format_resistance(self):
self.assertEqual(fmt.format_resistance(1), '1 \N{OHM SIGN}')
self.assertEqual(fmt.format_resistance(12), '12 \N{OHM SIGN}')
@ -112,3 +135,7 @@ class TestCases(unittest.TestCase):
self.assertEqual(fmt.format_complex_imp(complex(1234, -1234)), '1.23k-j1.23k \N{OHM SIGN}')
self.assertEqual(fmt.format_complex_imp(complex(1.234, 1234)), '1.23+j1.23k \N{OHM SIGN}')
self.assertEqual(fmt.format_complex_imp(complex(-1, 1.23e-3)), '- +j1.23m \N{OHM SIGN}')
self.assertEqual(fmt.format_complex_imp(complex(-1, 1.23e-3), True), '-1+j1.23m \N{OHM SIGN}')
def test_format_wavelength(self):
self.assertEqual(fmt.format_wavelength(12.3456), '12.35 m')

42
test/test_sweep.py 100644
Wyświetl plik

@ -0,0 +1,42 @@
# NanoVNASaver
#
# A python program to view and export Touchstone data from a NanoVNA
# Copyright (C) 2019, 2020 Rune B. Broberg
# Copyright (C) 2020 NanoVNA-Saver Authors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import unittest
# Import targets to be tested
from NanoVNASaver.Settings import Sweep
class TestCases(unittest.TestCase):
def test_sweep(self):
sweep = Sweep()
self.assertEqual(str(sweep), 'Sweep(3600000, 30000000, 101, 1, False)')
self.assertTrue(Sweep(3600000) == sweep)
self.assertFalse(Sweep(3600001) == sweep)
self.assertRaises(ValueError, Sweep, -1)
sweep = Sweep(segments = 3)
self.assertEqual(sweep.get_index_range(1), (12488000, 21288000))
data = list(sweep.get_frequencies())
self.assertEqual(data[0], 3600000)
self.assertEqual(data[-1], 30000000)
sweep = Sweep(segments = 3, logarithmic=True)
self.assertEqual(sweep.get_index_range(1), (9078495, 16800000))
data = list(sweep.get_frequencies())
self.assertEqual(data[0], 3600000)
self.assertEqual(data[-1], 29869307)

Wyświetl plik

@ -0,0 +1,38 @@
# NanoVNASaver
#
# A python program to view and export Touchstone data from a NanoVNA
# Copyright (C) 2019, 2020 Rune B. Broberg
# Copyright (C) 2020 NanoVNA-Saver Authors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import unittest
# Import targets to be tested
from NanoVNASaver.Version import Version
class TestCases(unittest.TestCase):
def test_version(self):
ver = Version("v1.2.3-test")
self.assertEqual(str(ver), '1.2.3-test')
self.assertLessEqual(ver, Version("1.2.4"))
self.assertFalse(ver > Version("1.2.4"))
self.assertFalse(ver > Version("1.2.3-u"))
self.assertTrue(Version("1.2.4") >= ver)
self.assertFalse(Version("0.0.0") == Version("0.0.0-rc"))
self.assertEqual(ver.major, 1)
self.assertEqual(ver.minor, 2)
self.assertEqual(ver.revision, 3)
self.assertEqual(ver.note, '-test')
Version("asdasd")