Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix some broken tests (and improve developer experience) #91

Merged
merged 5 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 20 additions & 14 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,20 @@ name: Checks

on:
push:
branches: [main, master]
pull_request:
workflow_dispatch:

concurrency:
group: test-${{ github.head_ref }}
cancel-in-progress: true

env:
PYTHONUNBUFFERED: "1"
FORCE_COLOR: "1"

jobs:
build:

runs-on: ${{ matrix.os }}
strategy:
matrix:
Expand All @@ -21,18 +30,15 @@ jobs:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
# prerequisites
python -m pip install --upgrade pip wheel
python -m pip install codecov coverage pytest pytest-cov
# install dependencies
pip install -e .[all]
# show installed packages
pip freeze
python -m pip install --upgrade pip
python -m pip install pytest pytest-cov
- name: Install package
run: pip install -e .
- name: Show installed packages
run: pip freeze
- name: Test with pytest
run: |
pytest
run: pytest --cov --showlocals
- name: Submit code coverage
run: |
pytest --cov=findiff --cov-report=html tests
codecov -t ${{ secrets.CODECOV_TOKEN }}

uses: codecov/codecov-action@v5
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
59 changes: 58 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,61 @@ tracker = "https://github.com/maroba/findiff/issues"
include = ["findiff"]

[tool.setuptools.dynamic]
version = { attr = "findiff.__version__" }
version = { attr = "findiff.__version__" }

[tool.coverage]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why include "tests" in source_pkgs? In the workflow, the command that is called for coverage is:

pytest --cov=findiff --cov-report=html tests

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I consider it a best practice because unexecuted lines in a test file smell like a bug.
This can detect function name collisions. (test_calc_accuracy_from_offsets_symbolic)

run.source_pkgs = ["findiff", "tests"]
run.branch = true
run.parallel = true
report.exclude_lines = [
"no cov",
"if __name__ == .__main__.:",
"if TYPE_CHECKING:",
"@overload",
"@unittest.skip",
]

[tool.tox]
requires = ["tox>=4.21"]
env_list = [
"fmt", "lint",
"3.13", "3.12", "3.11", "3.10", "3.9", "3.8",
]

[tool.tox.env_run_base]
wheel_build_env = ".pkg"
deps = [
"pytest",
]
commands = [
["pytest"],
]

[tool.tox.env.fmt]
package = "skip"
deps = [
"ruff",
]
commands = [
["ruff", "format", "--check", { replace = "posargs", default = ["."], extend = true }],
]

[tool.tox.env.lint]
package = "skip"
deps = [
"ruff",
]
commands = [
["ruff", "check", "--no-fix", { replace = "posargs", default = ["."], extend = true }],
]

[tool.ruff]
line-length = 88
lint.extend-select = [
"B", # flake8-bugbear
"I", # isort
"UP", # pyupgrade
]
extend-exclude = [
"docs/source/**/*.ipynb",
]
16 changes: 9 additions & 7 deletions tests/test_bugs.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class TestOldBugs(unittest.TestCase):

def test_findiff_should_raise_exception_when_applied_to_unevaluated_function(self):
def f(x, y):
return 5 * x**2 - 5 * x + 10 * y**2 - 10 * y
return 5 * x**2 - 5 * x + 10 * y**2 - 10 * y # pragma: no cover

d_dx = FinDiff(1, 0.01)
self.assertRaises(ValueError, lambda ff: d_dx(ff), f)
Expand Down Expand Up @@ -128,12 +128,14 @@ def test_order_as_numpy_integer(self):

np.testing.assert_allclose(d_dx(np.linspace(0, 1, 11)), np.ones(11))

def assert_dict_almost_equal(self, actual, expected, places=7):
if len(actual) != len(expected):
return False

for key, value in actual.items():
self.assertAlmostEqual(actual[key], expected[key], places=places)
def assert_dict_almost_equal(self, first, second, places=7):
for k in set(first) & set(second):
self.assertAlmostEqual(first[k], second[k], places=places)
# NOTE: missing item(s) should be zero
for k in set(first) - set(second):
self.assertAlmostEqual(first[k], 0, places=places)
for k in set(second) - set(first):
self.assertAlmostEqual(0, second[k], places=places)


if __name__ == "__main__":
Expand Down
4 changes: 2 additions & 2 deletions tests/test_coefs.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,15 +138,15 @@ def test_calc_accuracy_left0_right3_deriv1_acc3(self):
with self.subTest():
self.assertEqual(2, coefs["accuracy"])

def test_calc_accuracy_from_offsets_symbolic(self):
def test_calc_accuracy_from_offsets_symbolic1(self):
for analytic_inv in [True, False]:
coefs = calc_coefs(
2, [0, 1, 2, 3], symbolic=True, analytic_inv=analytic_inv
)
with self.subTest():
self.assertEqual(2, coefs["accuracy"])

def test_calc_accuracy_from_offsets_symbolic(self):
def test_calc_accuracy_from_offsets_symbolic2(self):
for analytic_inv in [True, False]:
coefs = calc_coefs(
2, [-4, -2, 0, 2, 4], symbolic=True, analytic_inv=analytic_inv
Expand Down
11 changes: 3 additions & 8 deletions tests/test_findiff.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,13 +287,6 @@ def test_local_stencil_operator_with_coef(self):

np.testing.assert_array_almost_equal(2 * np.ones_like(X), du_dx)

def dict_almost_equal(self, d1, d2):

self.assertEqual(len(d1), len(d2))

for k, v in d1.items():
self.assertAlmostEqual(v, d2[k])

def test_matrix_1d(self):

x = np.linspace(0, 6, 7)
Expand Down Expand Up @@ -509,14 +502,16 @@ def test_matrix_3d_nonuni_performance(self):
6 * np.ones_like(X).reshape(-1), mat.dot(u.reshape(-1))
)

def test_grid(self):
np.testing.assert_equal(grid(2, 50, 0, 1), grid(2, [50, 50], [0, 0], [1, 1]))

def grid(ndim, npts, a, b):

if not hasattr(a, "__len__"):
a = [a] * ndim
if not hasattr(b, "__len__"):
b = [b] * ndim
if not hasattr(np, "__len__"):
if not hasattr(npts, "__len__"):
npts = [npts] * ndim

coords = [np.linspace(a[i], b[i], npts[i]) for i in range(ndim)]
Expand Down
Loading