kopia lustrzana https://github.com/corrscope/corrscope
Update dependencies, fix unit tests on Python 3.9
rodzic
a655f562f8
commit
635f0f95e6
Plik diff jest za duży
Load Diff
|
@ -19,34 +19,30 @@ repository = "https://github.com/corrscope/corrscope/"
|
|||
documentation = "https://corrscope.github.io/corrscope/"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.6"
|
||||
"ruamel.yaml" = "^0.16"
|
||||
python = "^3.6.2"
|
||||
"ruamel.yaml" = "^0.17"
|
||||
numpy = "^1.15"
|
||||
click = "^7.0"
|
||||
click = "^8.0.1"
|
||||
matplotlib = "^3.1"
|
||||
attrs = "^18.2.0"
|
||||
PyQt5 = "^5.11"
|
||||
appdirs = "^1.4"
|
||||
attrs = "^21.2.0"
|
||||
PyQt5 = "^5.15.4"
|
||||
appdirs = "^1.4.4"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
pytest = "^4.0"
|
||||
pytest_mock = "^1.10"
|
||||
hypothesis = "^3.84"
|
||||
delayed-assert = "^0.2.3"
|
||||
pytest = "^6.2.4"
|
||||
pytest-mock = "^3.6.1"
|
||||
hypothesis = "^6.14.0"
|
||||
delayed-assert = "^0.3.5"
|
||||
|
||||
pyinstaller = "^3.6"
|
||||
pyinstaller = "^4.3"
|
||||
|
||||
# poetry fails to pick up pyinstaller's dependencies.
|
||||
# https://github.com/python-poetry/poetry/issues/1431#issuecomment-571661982
|
||||
# https://github.com/pyinstaller/pyinstaller/issues/4609 fixed in pyinstaller, but not released yet.
|
||||
pywin32-ctypes = {version = ">=0.2.0", platform = "win32"}
|
||||
pefile = {version = ">=2017.8.1", platform = "win32"}
|
||||
pefile = {version = "^2021.5.24", platform = "win32"}
|
||||
|
||||
coverage = "^4.5"
|
||||
pytest-cov = "^2.6"
|
||||
codecov = "^2.1"
|
||||
pytest_cases = "^1.2"
|
||||
black = {version = "^18.3-alpha.0", allow-prereleases = true}
|
||||
coverage = "^5.5"
|
||||
pytest-cov = "^2.12.1"
|
||||
codecov = "^2.1.11"
|
||||
pytest-cases = "^3.6.1"
|
||||
black = "^21.6b0"
|
||||
|
||||
[tool.poetry.scripts]
|
||||
corr = 'corrscope.cli:main'
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
from contextlib import ExitStack
|
||||
from typing import Optional
|
||||
|
||||
import hypothesis.strategies as hs
|
||||
import numpy as np
|
||||
import pytest
|
||||
from hypothesis import given
|
||||
from pytest_mock import MockFixture
|
||||
from unittest.mock import patch
|
||||
|
||||
import corrscope.channel
|
||||
import corrscope.corrscope
|
||||
|
@ -49,7 +50,6 @@ def test_config_channel_integration(
|
|||
rsub: int,
|
||||
default_label: DefaultLabel,
|
||||
override_label: bool,
|
||||
mocker: MockFixture,
|
||||
):
|
||||
"""(Tautologically) verify:
|
||||
- channel. r_samp (given cfg)
|
||||
|
@ -59,77 +59,80 @@ def test_config_channel_integration(
|
|||
- rendered label (channel.label, given cfg, corr_cfg.default_label)
|
||||
"""
|
||||
|
||||
# region setup test variables
|
||||
corrscope.corrscope.PRINT_TIMESTAMP = False # Cleanup Hypothesis testing logs
|
||||
with ExitStack() as stack:
|
||||
# region setup test variables
|
||||
corrscope.corrscope.PRINT_TIMESTAMP = False # Cleanup Hypothesis testing logs
|
||||
|
||||
Wave = mocker.patch.object(corrscope.channel, "Wave")
|
||||
wave = Wave.return_value
|
||||
Wave = stack.enter_context(patch.object(corrscope.channel, "Wave"))
|
||||
wave = Wave.return_value
|
||||
|
||||
def get_around(sample: int, return_nsamp: int, stride: int):
|
||||
return np.zeros(return_nsamp)
|
||||
def get_around(sample: int, return_nsamp: int, stride: int):
|
||||
return np.zeros(return_nsamp)
|
||||
|
||||
wave.get_around.side_effect = get_around
|
||||
wave.with_flatten.return_value = wave
|
||||
wave.nsamp = 10000
|
||||
wave.smp_s = 48000
|
||||
wave.get_around.side_effect = get_around
|
||||
wave.with_flatten.return_value = wave
|
||||
wave.nsamp = 10000
|
||||
wave.smp_s = 48000
|
||||
|
||||
ccfg = ChannelConfig(
|
||||
"tests/sine440.wav",
|
||||
trigger_width=c_trigger_width,
|
||||
render_width=c_render_width,
|
||||
amplification=c_amplification,
|
||||
label="label" if override_label else "",
|
||||
)
|
||||
|
||||
def get_cfg():
|
||||
return template_config(
|
||||
trigger_ms=trigger_ms,
|
||||
render_ms=render_ms,
|
||||
trigger_subsampling=tsub,
|
||||
render_subsampling=rsub,
|
||||
amplification=amplification,
|
||||
channels=[ccfg],
|
||||
default_label=default_label,
|
||||
trigger=NullTriggerConfig(),
|
||||
benchmark_mode=BenchmarkMode.OUTPUT,
|
||||
ccfg = ChannelConfig(
|
||||
"tests/sine440.wav",
|
||||
trigger_width=c_trigger_width,
|
||||
render_width=c_render_width,
|
||||
amplification=c_amplification,
|
||||
label="label" if override_label else "",
|
||||
)
|
||||
|
||||
# endregion
|
||||
def get_cfg():
|
||||
return template_config(
|
||||
trigger_ms=trigger_ms,
|
||||
render_ms=render_ms,
|
||||
trigger_subsampling=tsub,
|
||||
render_subsampling=rsub,
|
||||
amplification=amplification,
|
||||
channels=[ccfg],
|
||||
default_label=default_label,
|
||||
trigger=NullTriggerConfig(),
|
||||
benchmark_mode=BenchmarkMode.OUTPUT,
|
||||
)
|
||||
|
||||
cfg = get_cfg()
|
||||
channel = Channel(ccfg, cfg)
|
||||
# endregion
|
||||
|
||||
# Ensure cfg.width_ms etc. are correct
|
||||
assert cfg.trigger_ms == trigger_ms
|
||||
assert cfg.render_ms == render_ms
|
||||
cfg = get_cfg()
|
||||
channel = Channel(ccfg, cfg)
|
||||
|
||||
# Ensure channel.window_samp, trigger_subsampling, render_subsampling are correct.
|
||||
def ideal_samp(width_ms, sub):
|
||||
width_s = width_ms / 1000
|
||||
return pytest.approx(
|
||||
round(width_s * channel.trigger_wave.smp_s / sub), rel=1e-6
|
||||
)
|
||||
# Ensure cfg.width_ms etc. are correct
|
||||
assert cfg.trigger_ms == trigger_ms
|
||||
assert cfg.render_ms == render_ms
|
||||
|
||||
ideal_tsamp = ideal_samp(cfg.trigger_ms, tsub)
|
||||
ideal_rsamp = ideal_samp(cfg.render_ms, rsub)
|
||||
assert channel._render_samp == ideal_rsamp
|
||||
# Ensure channel.window_samp, trigger_subsampling, render_subsampling are correct.
|
||||
def ideal_samp(width_ms, sub):
|
||||
width_s = width_ms / 1000
|
||||
return pytest.approx(
|
||||
round(width_s * channel.trigger_wave.smp_s / sub), rel=1e-6
|
||||
)
|
||||
|
||||
assert channel._trigger_stride == tsub * c_trigger_width
|
||||
assert channel.render_stride == rsub * c_render_width
|
||||
ideal_tsamp = ideal_samp(cfg.trigger_ms, tsub)
|
||||
ideal_rsamp = ideal_samp(cfg.render_ms, rsub)
|
||||
assert channel._render_samp == ideal_rsamp
|
||||
|
||||
# Ensure amplification override works
|
||||
args, kwargs = Wave.call_args
|
||||
assert kwargs["amplification"] == coalesce(c_amplification, amplification)
|
||||
assert channel._trigger_stride == tsub * c_trigger_width
|
||||
assert channel.render_stride == rsub * c_render_width
|
||||
|
||||
## Ensure trigger uses channel.window_samp and _trigger_stride.
|
||||
trigger = channel.trigger
|
||||
assert trigger._tsamp == ideal_tsamp
|
||||
assert trigger._stride == channel._trigger_stride
|
||||
# Ensure amplification override works
|
||||
args, kwargs = Wave.call_args
|
||||
assert kwargs["amplification"] == coalesce(c_amplification, amplification)
|
||||
|
||||
## Ensure corrscope calls render using channel._render_samp and _render_stride.
|
||||
corr = CorrScope(cfg, Arguments(cfg_dir=".", outputs=[]))
|
||||
renderer = mocker.patch.object(CorrScope, "_load_renderer").return_value
|
||||
corr.play()
|
||||
## Ensure trigger uses channel.window_samp and _trigger_stride.
|
||||
trigger = channel.trigger
|
||||
assert trigger._tsamp == ideal_tsamp
|
||||
assert trigger._stride == channel._trigger_stride
|
||||
|
||||
## Ensure corrscope calls render using channel._render_samp and _render_stride.
|
||||
corr = CorrScope(cfg, Arguments(cfg_dir=".", outputs=[]))
|
||||
renderer = stack.enter_context(
|
||||
patch.object(CorrScope, "_load_renderer")
|
||||
).return_value
|
||||
corr.play()
|
||||
|
||||
# Only Channel.get_render_around() (not NullTrigger) calls wave.get_around().
|
||||
(_sample, _return_nsamp, _subsampling), kwargs = wave.get_around.call_args
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import pytest
|
||||
from pytest_cases import pytest_fixture_plus
|
||||
from pytest_cases import fixture
|
||||
|
||||
from corrscope.gui.model_bind import rgetattr, rsetattr, rhasattr, flatten_attr
|
||||
|
||||
|
@ -22,7 +22,7 @@ class Residence(object):
|
|||
self.sqft = sqft
|
||||
|
||||
|
||||
@pytest_fixture_plus
|
||||
@fixture
|
||||
@pytest.mark.parametrize("s", ["__", "."])
|
||||
def separator(s: str) -> str:
|
||||
return s
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
from contextlib import ExitStack
|
||||
from typing import Optional, TYPE_CHECKING, List
|
||||
from unittest.mock import patch
|
||||
|
||||
import attr
|
||||
import hypothesis.strategies as hs
|
||||
|
@ -396,15 +398,14 @@ def test_res_divisor_rounding_fixed(target_int: int, res_divisor: float):
|
|||
|
||||
|
||||
@given(target_int=hs.integers(1, 10000), res_divisor=hs.floats(1, 100))
|
||||
def test_res_divisor_rounding_hypothesis(target_int: int, res_divisor: float, mocker):
|
||||
verify_res_divisor_rounding(target_int, res_divisor, speed_hack=True, mocker=mocker)
|
||||
def test_res_divisor_rounding_hypothesis(target_int: int, res_divisor: float):
|
||||
verify_res_divisor_rounding(target_int, res_divisor, speed_hack=True)
|
||||
|
||||
|
||||
def verify_res_divisor_rounding(
|
||||
target_int: int,
|
||||
res_divisor: float,
|
||||
speed_hack: bool,
|
||||
mocker: "pytest_mock.MockFixture" = None,
|
||||
):
|
||||
"""Ensure that pathological-case float rounding errors
|
||||
don't cause inconsistent dimensions and assertion errors."""
|
||||
|
@ -414,20 +415,23 @@ def verify_res_divisor_rounding(
|
|||
cfg = RendererConfig(undivided_dim, undivided_dim, res_divisor=res_divisor)
|
||||
cfg.before_preview()
|
||||
|
||||
if speed_hack:
|
||||
mocker.patch.object(AbstractMatplotlibRenderer, "_save_background")
|
||||
datas = []
|
||||
else:
|
||||
datas = [RENDER_Y_ZEROS]
|
||||
with ExitStack() as stack:
|
||||
if speed_hack:
|
||||
stack.enter_context(
|
||||
patch.object(AbstractMatplotlibRenderer, "_save_background")
|
||||
)
|
||||
datas = []
|
||||
else:
|
||||
datas = [RENDER_Y_ZEROS]
|
||||
|
||||
try:
|
||||
renderer = Renderer(cfg, LayoutConfig(), datas, None, None)
|
||||
if not speed_hack:
|
||||
renderer.update_main_lines(datas)
|
||||
renderer.get_frame()
|
||||
except Exception:
|
||||
perr(cfg.divided_width)
|
||||
raise
|
||||
try:
|
||||
renderer = Renderer(cfg, LayoutConfig(), datas, None, None)
|
||||
if not speed_hack:
|
||||
renderer.update_main_lines(datas)
|
||||
renderer.get_frame()
|
||||
except Exception:
|
||||
perr(cfg.divided_width)
|
||||
raise
|
||||
|
||||
|
||||
# X-axis stride tests
|
||||
|
|
|
@ -7,7 +7,7 @@ from matplotlib.axes import Axes
|
|||
from matplotlib.figure import Figure
|
||||
|
||||
# Pycharm assumes anything called "fixture" is pytest.fixture.
|
||||
from pytest_cases import pytest_fixture_plus as fixture
|
||||
from pytest_cases import fixture
|
||||
|
||||
from corrscope import triggers
|
||||
from corrscope.triggers import (
|
||||
|
|
Ładowanie…
Reference in New Issue