Skip to content

Commit ffdab49

Browse files
authored
Merge pull request #158 from MODFLOW-USGS/v1.6.0
Release 1.6.0
2 parents 78eee25 + aa1bf71 commit ffdab49

10 files changed

Lines changed: 162 additions & 24 deletions

File tree

HISTORY.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
### Version 1.6.0
2+
3+
#### New features
4+
5+
* [feat(snapshots)](https://github.com/MODFLOW-USGS/modflow-devtools/commit/4e289ee4a13d13724c5cbcb7a1ee5328fc588c13): Add --snapshot-disable cli option (#157). Committed by wpbonelli on 2024-05-21.
6+
7+
#### Bug fixes
8+
9+
* [fix(get_model_paths)](https://github.com/MODFLOW-USGS/modflow-devtools/commit/0e3120a9d1cf53ecc98b861aeb05e3a8fa7afb71): Fix model order within scenario (#156). Committed by wpbonelli on 2024-05-21.
10+
111
### Version 1.5.0
212

313
#### New features

autotest/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
from pathlib import Path
22

3-
pytest_plugins = ["modflow_devtools.fixtures"]
3+
pytest_plugins = ["modflow_devtools.fixtures", "modflow_devtools.snapshots"]
44
project_root_path = Path(__file__).parent

autotest/test_misc.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,12 +151,12 @@ def get_expected_namefiles(path, pattern="mfsim.nam") -> List[Path]:
151151
def test_get_model_paths_examples():
152152
expected_paths = get_expected_model_dirs(_examples_path)
153153
paths = get_model_paths(_examples_path)
154-
assert paths == sorted(list(set(paths))) # no duplicates
154+
assert sorted(paths) == sorted(list(set(paths))) # no duplicates
155155
assert set(expected_paths) == set(paths)
156156

157157
expected_paths = get_expected_model_dirs(_examples_path, "*.nam")
158158
paths = get_model_paths(_examples_path, namefile="*.nam")
159-
assert paths == sorted(list(set(paths)))
159+
assert sorted(paths) == sorted(list(set(paths)))
160160
assert set(expected_paths) == set(paths)
161161

162162

@@ -166,12 +166,12 @@ def test_get_model_paths_examples():
166166
def test_get_model_paths_largetestmodels():
167167
expected_paths = get_expected_model_dirs(_examples_path)
168168
paths = get_model_paths(_examples_path)
169-
assert paths == sorted(list(set(paths)))
169+
assert sorted(paths) == sorted(list(set(paths)))
170170
assert set(expected_paths) == set(paths)
171171

172172
expected_paths = get_expected_model_dirs(_examples_path)
173173
paths = get_model_paths(_examples_path)
174-
assert paths == sorted(list(set(paths)))
174+
assert sorted(paths) == sorted(list(set(paths)))
175175
assert set(expected_paths) == set(paths)
176176

177177

autotest/test_snapshots.py

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22
from pathlib import Path
33

44
import numpy as np
5+
import pytest
6+
from _pytest.config import ExitCode
57

68
proj_root = Path(__file__).parents[1]
79
module_path = Path(inspect.getmodulename(__file__))
8-
pytest_plugins = [ "modflow_devtools.snapshots" ] # activate snapshot fixtures
910
snapshot_array = np.array([1.1, 2.2, 3.3])
1011
snapshots_path = proj_root / "autotest" / "__snapshots__"
1112

@@ -61,3 +62,47 @@ def test_readable_text_array_snapshot(readable_array_snapshot):
6162
),
6263
snapshot_array,
6364
)
65+
66+
67+
@pytest.mark.meta("test_snapshot_disable")
68+
def test_snapshot_disable_inner(snapshot):
69+
assert snapshot == "match this!"
70+
71+
72+
@pytest.mark.parametrize("disable", [True, False])
73+
def test_snapshot_disable(disable):
74+
inner_fn = test_snapshot_disable_inner.__name__
75+
args = [
76+
__file__,
77+
"-v",
78+
"-s",
79+
"-k",
80+
inner_fn,
81+
"-M",
82+
"test_snapshot_disable",
83+
]
84+
if disable:
85+
args.append("--snapshot-disable")
86+
assert pytest.main(args) == (ExitCode.OK if disable else ExitCode.TESTS_FAILED)
87+
88+
89+
@pytest.mark.meta("test_array_snapshot_disable")
90+
def test_array_snapshot_disable_inner(array_snapshot):
91+
assert array_snapshot == "can you match that?"
92+
93+
94+
@pytest.mark.parametrize("disable", [True, False])
95+
def test_array_snapshot_disable(disable):
96+
inner_fn = test_array_snapshot_disable_inner.__name__
97+
args = [
98+
__file__,
99+
"-v",
100+
"-s",
101+
"-k",
102+
inner_fn,
103+
"-M",
104+
"test_array_snapshot_disable",
105+
]
106+
if disable:
107+
args.append("--snapshot-disable")
108+
assert pytest.main(args) == (ExitCode.OK if disable else ExitCode.TESTS_FAILED)

docs/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
project = "modflow-devtools"
1010
author = "MODFLOW Team"
11-
release = '1.5.0'
11+
release = '1.6.0'
1212

1313
# -- General configuration ---------------------------------------------------
1414
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

docs/md/snapshots.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,8 @@ To use snapshot fixtures, add the following line to a test file or `conftest.py`
1414

1515
```python
1616
pytest_plugins = [ "modflow_devtools.snapshots" ]
17-
```
17+
```
18+
19+
## Disable snapshots
20+
21+
Snapshot comparisons can be disabled by invoked `pytest` with the `--snapshot-disable` flag.

modflow_devtools/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
__author__ = "Joseph D. Hughes"
2-
__date__ = "May 15, 2024"
3-
__version__ = "1.5.0"
2+
__date__ = "May 30, 2024"
3+
__version__ = "1.6.0"
44
__maintainer__ = "Joseph D. Hughes"
55
__email__ = "jdhughes@usgs.gov"
66
__status__ = "Production"

modflow_devtools/misc.py

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -284,13 +284,41 @@ def get_model_paths(
284284
Find model directories recursively in the given location.
285285
A model directory is any directory containing one or more
286286
namefiles. Model directories can be filtered or excluded,
287-
by prefix, pattern, namefile name, or packages used.
288-
"""
289-
290-
namefile_paths = get_namefile_paths(
291-
path, prefix, namefile, excluded, selected, packages
292-
)
293-
model_paths = sorted(list(set([p.parent for p in namefile_paths if p.parent.name])))
287+
by prefix, pattern, namefile name, or packages used. The
288+
directories are returned in order within scenario folders
289+
such that groundwater flow model workspaces precede other
290+
model types. This allows models which depend on the flow
291+
model's outputs to consume its head or budget, and models
292+
should successfully run in the sequence returned provided
293+
input files (e.g. FMI) refer to output via relative paths.
294+
"""
295+
296+
def keyfunc(v):
297+
v = str(v)
298+
if "gwf" in v:
299+
return 0
300+
else:
301+
return 1
302+
303+
model_paths = []
304+
globbed = path.rglob(f"{prefix if prefix else ''}*")
305+
example_paths = [p for p in globbed if p.is_dir()]
306+
for p in example_paths:
307+
for mp in sorted(
308+
list(
309+
set(
310+
[
311+
p.parent
312+
for p in get_namefile_paths(
313+
p, prefix, namefile, excluded, selected, packages
314+
)
315+
]
316+
)
317+
),
318+
key=keyfunc,
319+
):
320+
if mp not in model_paths:
321+
model_paths.append(mp)
294322
return model_paths
295323

296324

modflow_devtools/snapshots.py

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,13 @@
88
syrupy = import_optional_dependency("syrupy")
99

1010
# ruff: noqa: E402
11+
from syrupy import __import_extension
12+
from syrupy.assertion import SnapshotAssertion
1113
from syrupy.extensions.single_file import (
1214
SingleFileSnapshotExtension,
1315
WriteMode,
1416
)
17+
from syrupy.location import PyTestLocation
1518
from syrupy.types import (
1619
PropertyFilter,
1720
PropertyMatcher,
@@ -90,19 +93,67 @@ def serialize(
9093
return np.array2string(data, threshold=np.inf)
9194

9295

96+
class MatchAnything:
97+
def __eq__(self, _):
98+
return True
99+
100+
93101
# fixtures
94102

95103

104+
@pytest.fixture(scope="session")
105+
def snapshot_disable(pytestconfig) -> bool:
106+
return pytestconfig.getoption("--snapshot-disable")
107+
108+
96109
@pytest.fixture
97-
def array_snapshot(snapshot):
98-
return snapshot.use_extension(BinaryArrayExtension)
110+
def snapshot(request, snapshot_disable) -> "SnapshotAssertion":
111+
return (
112+
MatchAnything()
113+
if snapshot_disable
114+
else SnapshotAssertion(
115+
update_snapshots=request.config.option.update_snapshots,
116+
extension_class=__import_extension(request.config.option.default_extension),
117+
test_location=PyTestLocation(request.node),
118+
session=request.session.config._syrupy,
119+
)
120+
)
99121

100122

101123
@pytest.fixture
102-
def text_array_snapshot(snapshot):
103-
return snapshot.use_extension(TextArrayExtension)
124+
def array_snapshot(snapshot, snapshot_disable):
125+
return (
126+
MatchAnything()
127+
if snapshot_disable
128+
else snapshot.use_extension(BinaryArrayExtension)
129+
)
104130

105131

106132
@pytest.fixture
107-
def readable_array_snapshot(snapshot):
108-
return snapshot.use_extension(ReadableArrayExtension)
133+
def text_array_snapshot(snapshot, snapshot_disable):
134+
return (
135+
MatchAnything()
136+
if snapshot_disable
137+
else snapshot.use_extension(TextArrayExtension)
138+
)
139+
140+
141+
@pytest.fixture
142+
def readable_array_snapshot(snapshot, snapshot_disable):
143+
return (
144+
MatchAnything()
145+
if snapshot_disable
146+
else snapshot.use_extension(ReadableArrayExtension)
147+
)
148+
149+
150+
# pytest config hooks
151+
152+
153+
def pytest_addoption(parser):
154+
parser.addoption(
155+
"--snapshot-disable",
156+
action="store_true",
157+
default=False,
158+
help="Disable snapshot comparisons.",
159+
)

version.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.5.0
1+
1.6.0

0 commit comments

Comments
 (0)