dir-content-diff 1.7.0__tar.gz → 1.8.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/.copier-answers.yml +1 -1
  2. dir-content-diff-1.8.0/.coveragerc_py38 +11 -0
  3. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/.github/workflows/commitlint.yml +1 -1
  4. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/.github/workflows/run-tox.yml +1 -0
  5. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/CHANGELOG.md +8 -0
  6. {dir-content-diff-1.7.0/dir_content_diff.egg-info → dir-content-diff-1.8.0}/PKG-INFO +5 -2
  7. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/dir_content_diff/pandas.py +39 -0
  8. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0/dir_content_diff.egg-info}/PKG-INFO +5 -2
  9. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/dir_content_diff.egg-info/SOURCES.txt +1 -0
  10. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/dir_content_diff.egg-info/requires.txt +4 -1
  11. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/setup.py +2 -1
  12. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/tests/test_pandas.py +211 -26
  13. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/tox.ini +1 -0
  14. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/.auto-changelog +0 -0
  15. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/.auto-changelog-template.hbs +0 -0
  16. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/.codespellignorelines +0 -0
  17. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/.codespellrc +0 -0
  18. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/.coveragerc +0 -0
  19. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/.flake8 +0 -0
  20. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/.gitattributes +0 -0
  21. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/.github/ISSUE_TEMPLATE/bug_report.yaml +0 -0
  22. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  23. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/.github/ISSUE_TEMPLATE/feature_request.yaml +0 -0
  24. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/.github/ISSUE_TEMPLATE/how_to_use.yaml +0 -0
  25. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/.github/dependabot.yml +0 -0
  26. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/.github/pull_request_template.md +0 -0
  27. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/.github/workflows/publish-sdist.yml +0 -0
  28. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/.gitignore +0 -0
  29. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/.gitreview +0 -0
  30. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/.pre-commit-config.yaml +0 -0
  31. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/.pylintrc +0 -0
  32. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/.readthedocs.yml +0 -0
  33. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/AUTHORS.md +0 -0
  34. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/CONTRIBUTING.md +0 -0
  35. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/LICENSE.txt +0 -0
  36. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/MANIFEST.in +0 -0
  37. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/README.md +0 -0
  38. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/codecov.yml +0 -0
  39. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/commitlint.config.js +0 -0
  40. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/dir_content_diff/__init__.py +0 -0
  41. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/dir_content_diff/base_comparators.py +0 -0
  42. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/dir_content_diff/pytest_plugin.py +0 -0
  43. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/dir_content_diff/util.py +0 -0
  44. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/dir_content_diff.egg-info/dependency_links.txt +0 -0
  45. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/dir_content_diff.egg-info/entry_points.txt +0 -0
  46. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/dir_content_diff.egg-info/top_level.txt +0 -0
  47. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/docs/Makefile +0 -0
  48. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/docs/source/.gitignore +0 -0
  49. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/docs/source/api_ref.rst +0 -0
  50. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/docs/source/changelog.rst +0 -0
  51. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/docs/source/conf.py +0 -0
  52. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/docs/source/contributing.rst +0 -0
  53. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/docs/source/index.rst +0 -0
  54. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/package.json +0 -0
  55. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/pyproject.toml +0 -0
  56. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/setup.cfg +0 -0
  57. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/tests/__init__.py +0 -0
  58. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/tests/conftest.py +0 -0
  59. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/tests/generate_test_files.py +0 -0
  60. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/tests/test_base.py +0 -0
  61. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/tests/test_pytest_plugin.py +0 -0
  62. {dir-content-diff-1.7.0 → dir-content-diff-1.8.0}/tests/test_version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  # Changes here will be overwritten by Copier
2
2
 
3
- _commit: 0.1.53
3
+ _commit: 0.1.54
4
4
  _src_path: git@bbpgitlab.epfl.ch:neuromath/python-template.git
5
5
  author_email: ''
6
6
  author_name: Blue Brain Project, EPFL
@@ -0,0 +1,11 @@
1
+ [paths]
2
+ source_paths =
3
+ dir_content_diff
4
+ */site-packages/dir_content_diff
5
+ */dir_content_diff/dir_content_diff
6
+ */dir-content-diff/dir_content_diff
7
+
8
+ [report]
9
+ exclude_also =
10
+ return pd\.read_feather\(path, \*\*kwargs\)
11
+ data\.to_feather\(path, \*\*kwargs\)
@@ -12,7 +12,7 @@ jobs:
12
12
  - uses: actions/checkout@v4
13
13
  - uses: actions/setup-node@v4
14
14
  with:
15
- node-version: '16'
15
+ node-version: '20'
16
16
  - run: npm install -g --force commitlint @commitlint/cli commitlint-plugin-cleanfeet
17
17
  - run: npm install conventional-changelog-conventionalcommits
18
18
  - run: touch .git/COMMIT_EDITMSG
@@ -70,6 +70,7 @@ jobs:
70
70
  directory: ./reports
71
71
  flags: pytest
72
72
  name: "dir-content-diff-py${{ matrix.python-version }}-${{ matrix.min_versions }}"
73
+ token: ${{ secrets.CODECOV_TOKEN }}
73
74
  - name: Upload test artifacts
74
75
  uses: actions/upload-artifact@v4
75
76
  if: always()
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.8.0](https://github.com/BlueBrain/dir-content-diff/compare/1.7.0..1.8.0)
4
+
5
+ > 8 April 2024
6
+
7
+ ### New Features
8
+
9
+ - Add new comparators for Feather, Parquet and Stata files (Adrien Berchet - [#56](https://github.com/BlueBrain/dir-content-diff/pull/56))
10
+
3
11
  ## [1.7.0](https://github.com/BlueBrain/dir-content-diff/compare/1.6.0..1.7.0)
4
12
 
5
13
  > 5 February 2024
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dir-content-diff
3
- Version: 1.7.0
3
+ Version: 1.8.0
4
4
  Summary: Simple tool to compare directory contents.
5
5
  Home-page: https://dir-content-diff.readthedocs.io
6
6
  Author: Blue Brain Project, EPFL
@@ -28,21 +28,24 @@ Requires-Dist: jsonpath-ng>=1.5
28
28
  Requires-Dist: PyYaml>=6
29
29
  Provides-Extra: pandas
30
30
  Requires-Dist: pandas>=1.4; extra == "pandas"
31
+ Requires-Dist: pyarrow>=11; extra == "pandas"
31
32
  Requires-Dist: tables>=3.7; extra == "pandas"
32
33
  Provides-Extra: docs
33
34
  Requires-Dist: m2r2; extra == "docs"
34
35
  Requires-Dist: sphinx; extra == "docs"
35
36
  Requires-Dist: sphinx-bluebrain-theme; extra == "docs"
36
37
  Requires-Dist: pandas>=1.4; extra == "docs"
38
+ Requires-Dist: pyarrow>=11; extra == "docs"
37
39
  Requires-Dist: tables>=3.7; extra == "docs"
38
40
  Provides-Extra: test
39
- Requires-Dist: coverage>=6; extra == "test"
41
+ Requires-Dist: coverage>=7.2; extra == "test"
40
42
  Requires-Dist: dicttoxml>=1.7.16; extra == "test"
41
43
  Requires-Dist: matplotlib>=3; extra == "test"
42
44
  Requires-Dist: rst2pdf>=0.99; extra == "test"
43
45
  Requires-Dist: pytest>=6.2; extra == "test"
44
46
  Requires-Dist: pytest-html<4,>=2; extra == "test"
45
47
  Requires-Dist: pandas>=1.4; extra == "test"
48
+ Requires-Dist: pyarrow>=11; extra == "test"
46
49
  Requires-Dist: tables>=3.7; extra == "test"
47
50
 
48
51
  [![Version](https://img.shields.io/pypi/v/dir-content-diff)](https://github.com/BlueBrain/dir-content-diff/releases)
@@ -147,6 +147,42 @@ class HdfComparator(DataframeComparator):
147
147
  data.to_hdf(path, index=index, key=key, **kwargs)
148
148
 
149
149
 
150
+ class FeatherComparator(DataframeComparator):
151
+ """Comparator for Feather files."""
152
+
153
+ def load(self, path, **kwargs):
154
+ """Load a Feather file into a :class:`pandas.DataFrame` object."""
155
+ return pd.read_feather(path, **kwargs)
156
+
157
+ def save(self, data, path, **kwargs):
158
+ """Save data to a Feather file."""
159
+ data.to_feather(path, **kwargs)
160
+
161
+
162
+ class ParquetComparator(DataframeComparator):
163
+ """Comparator for Parquet files."""
164
+
165
+ def load(self, path, **kwargs):
166
+ """Load a Parquet file into a :class:`pandas.DataFrame` object."""
167
+ return pd.read_parquet(path, **kwargs)
168
+
169
+ def save(self, data, path, **kwargs):
170
+ """Save data to a Parquet file."""
171
+ data.to_parquet(path, **kwargs)
172
+
173
+
174
+ class StataComparator(DataframeComparator):
175
+ """Comparator for Stata files."""
176
+
177
+ def load(self, path, **kwargs):
178
+ """Load a Stata file into a :class:`pandas.DataFrame` object."""
179
+ return pd.read_stata(path, **kwargs)
180
+
181
+ def save(self, data, path, **kwargs):
182
+ """Save data to a Stata file."""
183
+ data.to_stata(path, **kwargs)
184
+
185
+
150
186
  def register():
151
187
  """Register Pandas extensions."""
152
188
  register_comparator(".csv", CsvComparator())
@@ -156,3 +192,6 @@ def register():
156
192
  register_comparator(".hdf", HdfComparator())
157
193
  register_comparator(".hdf4", HdfComparator())
158
194
  register_comparator(".hdf5", HdfComparator())
195
+ register_comparator(".feather", FeatherComparator())
196
+ register_comparator(".parquet", ParquetComparator())
197
+ register_comparator(".dta", StataComparator())
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dir-content-diff
3
- Version: 1.7.0
3
+ Version: 1.8.0
4
4
  Summary: Simple tool to compare directory contents.
5
5
  Home-page: https://dir-content-diff.readthedocs.io
6
6
  Author: Blue Brain Project, EPFL
@@ -28,21 +28,24 @@ Requires-Dist: jsonpath-ng>=1.5
28
28
  Requires-Dist: PyYaml>=6
29
29
  Provides-Extra: pandas
30
30
  Requires-Dist: pandas>=1.4; extra == "pandas"
31
+ Requires-Dist: pyarrow>=11; extra == "pandas"
31
32
  Requires-Dist: tables>=3.7; extra == "pandas"
32
33
  Provides-Extra: docs
33
34
  Requires-Dist: m2r2; extra == "docs"
34
35
  Requires-Dist: sphinx; extra == "docs"
35
36
  Requires-Dist: sphinx-bluebrain-theme; extra == "docs"
36
37
  Requires-Dist: pandas>=1.4; extra == "docs"
38
+ Requires-Dist: pyarrow>=11; extra == "docs"
37
39
  Requires-Dist: tables>=3.7; extra == "docs"
38
40
  Provides-Extra: test
39
- Requires-Dist: coverage>=6; extra == "test"
41
+ Requires-Dist: coverage>=7.2; extra == "test"
40
42
  Requires-Dist: dicttoxml>=1.7.16; extra == "test"
41
43
  Requires-Dist: matplotlib>=3; extra == "test"
42
44
  Requires-Dist: rst2pdf>=0.99; extra == "test"
43
45
  Requires-Dist: pytest>=6.2; extra == "test"
44
46
  Requires-Dist: pytest-html<4,>=2; extra == "test"
45
47
  Requires-Dist: pandas>=1.4; extra == "test"
48
+ Requires-Dist: pyarrow>=11; extra == "test"
46
49
  Requires-Dist: tables>=3.7; extra == "test"
47
50
 
48
51
  [![Version](https://img.shields.io/pypi/v/dir-content-diff)](https://github.com/BlueBrain/dir-content-diff/releases)
@@ -4,6 +4,7 @@
4
4
  .codespellrc
5
5
  .copier-answers.yml
6
6
  .coveragerc
7
+ .coveragerc_py38
7
8
  .flake8
8
9
  .gitattributes
9
10
  .gitignore
@@ -9,18 +9,21 @@ m2r2
9
9
  sphinx
10
10
  sphinx-bluebrain-theme
11
11
  pandas>=1.4
12
+ pyarrow>=11
12
13
  tables>=3.7
13
14
 
14
15
  [pandas]
15
16
  pandas>=1.4
17
+ pyarrow>=11
16
18
  tables>=3.7
17
19
 
18
20
  [test]
19
- coverage>=6
21
+ coverage>=7.2
20
22
  dicttoxml>=1.7.16
21
23
  matplotlib>=3
22
24
  rst2pdf>=0.99
23
25
  pytest>=6.2
24
26
  pytest-html<4,>=2
25
27
  pandas>=1.4
28
+ pyarrow>=11
26
29
  tables>=3.7
@@ -20,11 +20,12 @@ doc_reqs = [
20
20
 
21
21
  pandas_reqs = [
22
22
  "pandas>=1.4",
23
+ "pyarrow>=11",
23
24
  "tables>=3.7",
24
25
  ]
25
26
 
26
27
  test_reqs = [
27
- "coverage>=6",
28
+ "coverage>=7.2",
28
29
  "dicttoxml>=1.7.16",
29
30
  "matplotlib>=3",
30
31
  "rst2pdf>=0.99",
@@ -4,6 +4,7 @@
4
4
  # pylint: disable=unused-argument
5
5
  # pylint: disable=use-implicit-booleaness-not-comparison
6
6
  import re
7
+ import sys
7
8
 
8
9
  import pandas as pd
9
10
  import pytest
@@ -49,6 +50,9 @@ class TestRegistry:
49
50
  ".hdf": dir_content_diff.pandas.HdfComparator(),
50
51
  ".hdf4": dir_content_diff.pandas.HdfComparator(),
51
52
  ".hdf5": dir_content_diff.pandas.HdfComparator(),
53
+ ".feather": dir_content_diff.pandas.FeatherComparator(),
54
+ ".parquet": dir_content_diff.pandas.ParquetComparator(),
55
+ ".dta": dir_content_diff.pandas.StataComparator(),
52
56
  }
53
57
 
54
58
 
@@ -59,19 +63,71 @@ def pandas_registry_reseter(registry_reseter):
59
63
 
60
64
 
61
65
  @pytest.fixture
62
- def ref_hdf5(empty_ref_tree):
63
- """The reference HDF5 file."""
66
+ def ref_data(empty_ref_tree):
64
67
  ref_data = {
65
68
  "col_a": [1, 2, 3],
66
69
  "col_b": ["a", "b", "c"],
67
70
  "col_c": [4, 5, 6],
68
71
  }
69
72
  df = pd.DataFrame(ref_data, index=["idx1", "idx2", "idx3"])
73
+ return df
74
+
75
+
76
+ @pytest.fixture
77
+ def ref_hdf5(ref_data, empty_ref_tree):
78
+ """The reference HDF5 file."""
70
79
  filename = empty_ref_tree / "file.h5"
71
- df.to_hdf(filename, key="data", index=True)
80
+ ref_data.to_hdf(filename, key="data", index=True)
81
+ return filename
82
+
83
+
84
+ @pytest.fixture
85
+ def ref_feather(ref_data, empty_ref_tree):
86
+ """The reference Feather file."""
87
+ filename = empty_ref_tree / "file.feather"
88
+ ref_data.to_feather(filename)
72
89
  return filename
73
90
 
74
91
 
92
+ @pytest.fixture
93
+ def ref_parquet(ref_data, empty_ref_tree):
94
+ """The reference Parquet file."""
95
+ filename = empty_ref_tree / "file.parquet"
96
+ ref_data.to_parquet(filename)
97
+ return filename
98
+
99
+
100
+ @pytest.fixture
101
+ def ref_stata(ref_data, empty_ref_tree):
102
+ """The reference Stata file."""
103
+ filename = empty_ref_tree / "file.dta"
104
+ ref_data.to_stata(filename)
105
+ return filename
106
+
107
+
108
+ def _update_df(df):
109
+ df.loc["idx1", "col_a"] *= 10
110
+ df.loc["idx2", "col_b"] += "_new"
111
+
112
+
113
+ @pytest.fixture
114
+ def res_diff_checker():
115
+ """The regex used to check the diff result."""
116
+ return (
117
+ r"The files '\S*/ref/file\.\S*' and '\S*/res/file\.\S*' are different:\n\n"
118
+ r"Column 'col_a': Series are different\n\n"
119
+ r"Series values are different \(33\.33333 %\)\n"
120
+ r"\[index\]: \[idx1, idx2, idx3\]\n"
121
+ r"\[left\]: \[1, 2, 3\]\n\[right\]: \[10, 2, 3\]\n"
122
+ r"""(At positional index 0, first diff: 1 != 10\n)?\n"""
123
+ r"Column 'col_b': Series are different\n\n"
124
+ r"Series values are different \(33\.33333 %\)\n"
125
+ r"\[index\]: \[idx1, idx2, idx3\]\n"
126
+ r"\[left\]: \[a, b, c\]\n\[right\]: \[a, b_new, c\]"
127
+ r"""(\nAt positional index 1, first diff: b != b_new)?"""
128
+ )
129
+
130
+
75
131
  @pytest.fixture
76
132
  def res_hdf5_equal(ref_hdf5, empty_res_tree):
77
133
  """The result hdf5 file equal to the reference."""
@@ -85,13 +141,69 @@ def res_hdf5_equal(ref_hdf5, empty_res_tree):
85
141
  def res_hdf5_diff(ref_hdf5, empty_res_tree):
86
142
  """The result hdf5 file different from the reference."""
87
143
  df = pd.read_hdf(ref_hdf5, index_col="index")
88
- df.loc["idx1", "col_a"] *= 10
89
- df.loc["idx2", "col_b"] += "_new"
144
+ _update_df(df)
90
145
  filename = empty_res_tree / "file.h5"
91
146
  df.to_hdf(filename, key="data", index=True)
92
147
  return filename
93
148
 
94
149
 
150
+ @pytest.fixture
151
+ def res_feather_equal(ref_feather, empty_res_tree):
152
+ """The result feather file equal to the reference."""
153
+ df = pd.read_feather(ref_feather)
154
+ filename = empty_res_tree / "file.feather"
155
+ df.to_feather(filename)
156
+ return filename
157
+
158
+
159
+ @pytest.fixture
160
+ def res_feather_diff(ref_feather, empty_res_tree):
161
+ """The result feather file different from the reference."""
162
+ df = pd.read_feather(ref_feather)
163
+ _update_df(df)
164
+ filename = empty_res_tree / "file.feather"
165
+ df.to_feather(filename)
166
+ return filename
167
+
168
+
169
+ @pytest.fixture
170
+ def res_parquet_equal(ref_parquet, empty_res_tree):
171
+ """The result parquet file equal to the reference."""
172
+ df = pd.read_parquet(ref_parquet)
173
+ filename = empty_res_tree / "file.parquet"
174
+ df.to_parquet(filename)
175
+ return filename
176
+
177
+
178
+ @pytest.fixture
179
+ def res_parquet_diff(ref_parquet, empty_res_tree):
180
+ """The result parquet file different from the reference."""
181
+ df = pd.read_parquet(ref_parquet)
182
+ _update_df(df)
183
+ filename = empty_res_tree / "file.parquet"
184
+ df.to_parquet(filename)
185
+ return filename
186
+
187
+
188
+ @pytest.fixture
189
+ def res_stata_equal(ref_stata, empty_res_tree):
190
+ """The result stata file equal to the reference."""
191
+ df = pd.read_stata(ref_stata, index_col="index")
192
+ filename = empty_res_tree / "file.dta"
193
+ df.to_stata(filename)
194
+ return filename
195
+
196
+
197
+ @pytest.fixture
198
+ def res_stata_diff(ref_stata, empty_res_tree):
199
+ """The result stata file different from the reference."""
200
+ df = pd.read_stata(ref_stata, index_col="index")
201
+ _update_df(df)
202
+ filename = empty_res_tree / "file.dta"
203
+ df.to_stata(filename)
204
+ return filename
205
+
206
+
95
207
  class TestEqualTrees:
96
208
  """Tests that should return no difference."""
97
209
 
@@ -222,17 +334,46 @@ class TestEqualTrees:
222
334
  )
223
335
  assert match_res is not None
224
336
 
225
- def test_hdf5_comparator(
226
- self, empty_ref_tree, empty_res_tree, res_hdf5_equal, pandas_registry_reseter
227
- ):
228
- """Test the comparator for HDF5 files."""
337
+ def _check_equal(self, empty_ref_tree, empty_res_tree):
229
338
  assert_equal_trees(empty_ref_tree, empty_res_tree, export_formatted_files=True)
230
339
  ref_files = list(empty_ref_tree.rglob("*"))
231
340
  res_files = list(empty_res_tree.rglob("*"))
232
341
  assert len(ref_files) == len(res_files)
342
+ return ref_files, res_files
343
+
344
+ def test_hdf5_comparator(
345
+ self, empty_ref_tree, empty_res_tree, res_hdf5_equal, pandas_registry_reseter
346
+ ):
347
+ """Test the comparator for HDF5 files."""
348
+ ref_files, res_files = self._check_equal(empty_ref_tree, empty_res_tree)
233
349
  for i, j in zip(ref_files, res_files):
234
350
  assert pd.read_hdf(i).equals(pd.read_hdf(j))
235
351
 
352
+ @pytest.mark.skipif(sys.version_info < (3, 9), reason="requires python3.9 or higher")
353
+ def test_feather_comparator(
354
+ self, empty_ref_tree, empty_res_tree, res_feather_equal, pandas_registry_reseter
355
+ ):
356
+ """Test the comparator for Feather files."""
357
+ ref_files, res_files = self._check_equal(empty_ref_tree, empty_res_tree)
358
+ for i, j in zip(ref_files, res_files):
359
+ assert pd.read_feather(i).equals(pd.read_feather(j))
360
+
361
+ def test_parquet_comparator(
362
+ self, empty_ref_tree, empty_res_tree, res_parquet_equal, pandas_registry_reseter
363
+ ):
364
+ """Test the comparator for Parquet files."""
365
+ ref_files, res_files = self._check_equal(empty_ref_tree, empty_res_tree)
366
+ for i, j in zip(ref_files, res_files):
367
+ assert pd.read_parquet(i).equals(pd.read_parquet(j))
368
+
369
+ def test_stata_comparator(
370
+ self, empty_ref_tree, empty_res_tree, res_stata_equal, pandas_registry_reseter
371
+ ):
372
+ """Test the comparator for Stata files."""
373
+ ref_files, res_files = self._check_equal(empty_ref_tree, empty_res_tree)
374
+ for i, j in zip(ref_files, res_files):
375
+ assert pd.read_stata(i).equals(pd.read_stata(j))
376
+
236
377
 
237
378
  class TestDiffTrees:
238
379
  """Tests that should return differences."""
@@ -287,26 +428,70 @@ class TestDiffTrees:
287
428
  )
288
429
  assert match_res is not None
289
430
 
290
- def test_hdf5_comparator(
291
- self, empty_ref_tree, empty_res_tree, res_hdf5_diff, pandas_registry_reseter
431
+ def _check_diff_comparator(
432
+ self, empty_ref_tree, empty_res_tree, res_diff_checker, ext, specific_args=None
292
433
  ):
293
- """Test the comparator for HDF5 files."""
294
- res = compare_trees(empty_ref_tree, empty_res_tree)
434
+ res = compare_trees(empty_ref_tree, empty_res_tree, specific_args=specific_args)
295
435
 
296
436
  assert len(res) == 1
297
- res_hdf = res["file.h5"]
437
+ filename = f"file.{ext}"
438
+ res_ext = res[filename]
439
+ if specific_args is not None and filename in specific_args:
440
+ res_diff_checker = res_diff_checker.replace(
441
+ "' are different:",
442
+ "' are different:\nKwargs used for loading data: "
443
+ f"{specific_args[filename]['load_kwargs']}",
444
+ )
298
445
  match_res = re.match(
299
- r"The files '\S*/ref/file\.h5' and '\S*/res/file\.h5' are different:\n\n"
300
- r"Column 'col_a': Series are different\n\n"
301
- r"Series values are different \(33\.33333 %\)\n"
302
- r"\[index\]: \[idx1, idx2, idx3\]\n"
303
- r"\[left\]: \[1, 2, 3\]\n\[right\]: \[10, 2, 3\]\n"
304
- r"""(At positional index 0, first diff: 1 != 10\n)?\n"""
305
- r"Column 'col_b': Series are different\n\n"
306
- r"Series values are different \(33\.33333 %\)\n"
307
- r"\[index\]: \[idx1, idx2, idx3\]\n"
308
- r"\[left\]: \[a, b, c\]\n\[right\]: \[a, b_new, c\]"
309
- r"""(\nAt positional index 1, first diff: b != b_new)?""",
310
- res_hdf,
446
+ res_diff_checker,
447
+ res_ext,
311
448
  )
312
449
  assert match_res is not None
450
+
451
+ def test_hdf5_comparator(
452
+ self,
453
+ empty_ref_tree,
454
+ empty_res_tree,
455
+ res_hdf5_diff,
456
+ res_diff_checker,
457
+ pandas_registry_reseter,
458
+ ):
459
+ """Test the comparator for HDF5 files."""
460
+ self._check_diff_comparator(empty_ref_tree, empty_res_tree, res_diff_checker, "h5")
461
+
462
+ @pytest.mark.skipif(sys.version_info < (3, 9), reason="requires python3.9 or higher")
463
+ def test_feather_comparator(
464
+ self,
465
+ empty_ref_tree,
466
+ empty_res_tree,
467
+ res_feather_diff,
468
+ res_diff_checker,
469
+ pandas_registry_reseter,
470
+ ):
471
+ """Test the comparator for feather files."""
472
+ self._check_diff_comparator(empty_ref_tree, empty_res_tree, res_diff_checker, "feather")
473
+
474
+ def test_parquet_comparator(
475
+ self,
476
+ empty_ref_tree,
477
+ empty_res_tree,
478
+ res_parquet_diff,
479
+ res_diff_checker,
480
+ pandas_registry_reseter,
481
+ ):
482
+ """Test the comparator for parquet files."""
483
+ self._check_diff_comparator(empty_ref_tree, empty_res_tree, res_diff_checker, "parquet")
484
+
485
+ def test_stata_comparator(
486
+ self,
487
+ empty_ref_tree,
488
+ empty_res_tree,
489
+ res_stata_diff,
490
+ res_diff_checker,
491
+ pandas_registry_reseter,
492
+ ):
493
+ """Test the comparator for stata files."""
494
+ specific_args = {"file.dta": {"load_kwargs": {"index_col": "index"}}}
495
+ self._check_diff_comparator(
496
+ empty_ref_tree, empty_res_tree, res_diff_checker, "dta", specific_args=specific_args
497
+ )
@@ -19,6 +19,7 @@ extras =
19
19
  test
20
20
  setenv =
21
21
  COVERAGE_FILE = {env:COVERAGE_FILE:.coverage-{envname}}
22
+ py38,min_versions: COVERAGE_RCFILE=.coveragerc_py38
22
23
  deps =
23
24
  min_versions: Requirements-Builder
24
25
  commands =