edq-utils 0.0.4__py3-none-any.whl → 0.0.5__py3-none-any.whl
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.
Potentially problematic release.
This version of edq-utils might be problematic. Click here for more details.
- edq/__init__.py +1 -1
- edq/cli/testing/cli-test.py +5 -1
- edq/testing/cli.py +90 -28
- edq/testing/cli_test.py +8 -1
- edq/testing/testdata/cli/tests/platform_skip.txt +5 -0
- edq/testing/unittest.py +17 -2
- edq/util/dirent_test.py +43 -32
- {edq_utils-0.0.4.dist-info → edq_utils-0.0.5.dist-info}/METADATA +1 -1
- {edq_utils-0.0.4.dist-info → edq_utils-0.0.5.dist-info}/RECORD +12 -19
- edq/util/testdata/dirent-operations/a.txt +0 -1
- edq/util/testdata/dirent-operations/dir_1/b.txt +0 -1
- edq/util/testdata/dirent-operations/dir_1/dir_2/c.txt +0 -1
- edq/util/testdata/dirent-operations/file_empty +0 -0
- edq/util/testdata/dirent-operations/symlink_a.txt +0 -1
- edq/util/testdata/dirent-operations/symlink_dir_1/b.txt +0 -1
- edq/util/testdata/dirent-operations/symlink_dir_1/dir_2/c.txt +0 -1
- edq/util/testdata/dirent-operations/symlink_file_empty +0 -0
- {edq_utils-0.0.4.dist-info → edq_utils-0.0.5.dist-info}/WHEEL +0 -0
- {edq_utils-0.0.4.dist-info → edq_utils-0.0.5.dist-info}/licenses/LICENSE +0 -0
- {edq_utils-0.0.4.dist-info → edq_utils-0.0.5.dist-info}/top_level.txt +0 -0
edq/__init__.py
CHANGED
edq/cli/testing/cli-test.py
CHANGED
|
@@ -15,7 +15,7 @@ import edq.testing.cli_test
|
|
|
15
15
|
def run_cli(args: argparse.Namespace) -> int:
|
|
16
16
|
""" Run the CLI. """
|
|
17
17
|
|
|
18
|
-
edq.testing.cli.add_test_paths(edq.testing.cli_test.CLITest, args.paths)
|
|
18
|
+
edq.testing.cli.add_test_paths(edq.testing.cli_test.CLITest, args.data_dir, args.paths)
|
|
19
19
|
|
|
20
20
|
runner = unittest.TextTestRunner(verbosity = 2)
|
|
21
21
|
tests = unittest.defaultTestLoader.loadTestsFromTestCase(edq.testing.cli_test.CLITest)
|
|
@@ -36,6 +36,10 @@ def _get_parser() -> edq.core.argparser.Parser:
|
|
|
36
36
|
type = str, nargs = '+',
|
|
37
37
|
help = 'Path to CLI test case files.')
|
|
38
38
|
|
|
39
|
+
parser.add_argument('--data-dir', dest = 'data_dir',
|
|
40
|
+
action = 'store', type = str, default = '.',
|
|
41
|
+
help = 'The additional data directory (expansion of __DATA_DIR__) used for tests (default: %(default)s).')
|
|
42
|
+
|
|
39
43
|
return parser
|
|
40
44
|
|
|
41
45
|
if (__name__ == '__main__'):
|
edq/testing/cli.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Infrastructure for testing CLI tools using a JSON file which describes a test case,
|
|
3
3
|
which is essentially an invocation of a CLI tool and the expected output.
|
|
4
4
|
|
|
5
|
-
The test case file must be a `.txt` file that live in
|
|
5
|
+
The test case file must be a `.txt` file that live in the test cases dir.
|
|
6
6
|
The file contains two parts (separated by a line with just TEST_CASE_SEP):
|
|
7
7
|
the first part which is a JSON object (see below for available keys),
|
|
8
8
|
and a second part which is the expected text output (stdout).
|
|
@@ -28,15 +28,10 @@ import edq.util.dirent
|
|
|
28
28
|
import edq.util.json
|
|
29
29
|
import edq.util.pyimport
|
|
30
30
|
|
|
31
|
-
THIS_DIR: str = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
|
|
32
|
-
BASE_TESTDATA_DIR: str = os.path.join(THIS_DIR, "testdata", "cli")
|
|
33
|
-
TEST_CASES_DIR: str = os.path.join(BASE_TESTDATA_DIR, "tests")
|
|
34
|
-
DATA_DIR: str = os.path.join(BASE_TESTDATA_DIR, "data")
|
|
35
|
-
|
|
36
31
|
TEST_CASE_SEP: str = '---'
|
|
37
32
|
DATA_DIR_ID: str = '__DATA_DIR__'
|
|
38
33
|
TEMP_DIR_ID: str = '__TEMP_DIR__'
|
|
39
|
-
|
|
34
|
+
BASE_DIR_ID: str = '__BASE_DIR__'
|
|
40
35
|
|
|
41
36
|
DEFAULT_ASSERTION_FUNC_NAME: str = 'edq.testing.asserts.content_equals_normalize'
|
|
42
37
|
|
|
@@ -48,6 +43,7 @@ class CLITestInfo:
|
|
|
48
43
|
def __init__(self,
|
|
49
44
|
test_name: str,
|
|
50
45
|
base_dir: str,
|
|
46
|
+
data_dir: str,
|
|
51
47
|
temp_dir: str,
|
|
52
48
|
cli: typing.Union[str, None] = None,
|
|
53
49
|
arguments: typing.Union[typing.List[str], None] = None,
|
|
@@ -57,16 +53,45 @@ class CLITestInfo:
|
|
|
57
53
|
stderr_assertion_func: typing.Union[str, None] = None,
|
|
58
54
|
expected_stdout: str = '',
|
|
59
55
|
expected_stderr: str = '',
|
|
56
|
+
split_stdout_stderr: bool = False,
|
|
60
57
|
strip_error_output: bool = True,
|
|
58
|
+
extra_options: typing.Union[typing.Dict[str, typing.Any], None] = None,
|
|
61
59
|
**kwargs: typing.Any) -> None:
|
|
60
|
+
self.skip_reasons: typing.List[str] = []
|
|
61
|
+
"""
|
|
62
|
+
Reasons that this test will be skipped.
|
|
63
|
+
Any entries in this list indicate that the test should be skipped.
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
self.platform_skip_pattern: typing.Union[str, None] = platform_skip
|
|
67
|
+
"""
|
|
68
|
+
A pattern to check if the test should be skipped on the current platform.
|
|
69
|
+
Will be used in `re.search()` against `sys.platform`.
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
if ((platform_skip is not None) and re.search(platform_skip, sys.platform)):
|
|
73
|
+
self.skip_reasons.append(f"not available on platform: '{sys.platform}'")
|
|
74
|
+
|
|
62
75
|
self.test_name: str = test_name
|
|
63
76
|
""" The name of this test. """
|
|
64
77
|
|
|
65
78
|
self.base_dir: str = base_dir
|
|
66
|
-
"""
|
|
79
|
+
"""
|
|
80
|
+
The base directory for this test (usually the dir the CLI test file lives.
|
|
81
|
+
This is the expansion for `__BASE_DIR__` paths.
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
self.data_dir: str = data_dir
|
|
85
|
+
"""
|
|
86
|
+
A directory that additional testing data lives in.
|
|
87
|
+
This is the expansion for `__DATA_DIR__` paths.
|
|
88
|
+
"""
|
|
67
89
|
|
|
68
90
|
self.temp_dir: str = temp_dir
|
|
69
|
-
"""
|
|
91
|
+
"""
|
|
92
|
+
A temp directory that this test has access to.
|
|
93
|
+
This is the expansion for `__TEMP_DIR__` paths.
|
|
94
|
+
"""
|
|
70
95
|
|
|
71
96
|
edq.util.dirent.mkdir(temp_dir)
|
|
72
97
|
|
|
@@ -76,9 +101,12 @@ class CLITestInfo:
|
|
|
76
101
|
self.module_name: str = cli
|
|
77
102
|
""" The name of the module to invoke. """
|
|
78
103
|
|
|
79
|
-
self.module: typing.Any =
|
|
104
|
+
self.module: typing.Any = None
|
|
80
105
|
""" The module to invoke. """
|
|
81
106
|
|
|
107
|
+
if (not self.should_skip()):
|
|
108
|
+
self.module = edq.util.pyimport.import_name(self.module_name)
|
|
109
|
+
|
|
82
110
|
if (arguments is None):
|
|
83
111
|
arguments = []
|
|
84
112
|
|
|
@@ -88,19 +116,16 @@ class CLITestInfo:
|
|
|
88
116
|
self.error: bool = error
|
|
89
117
|
""" Whether or not this test is expected to be an error (raise an exception). """
|
|
90
118
|
|
|
91
|
-
self.platform_skip: typing.Union[str, None] = platform_skip
|
|
92
|
-
""" If the current platform matches this regular expression, then the test will be skipped. """
|
|
93
|
-
|
|
94
119
|
self.stdout_assertion_func: typing.Union[edq.testing.asserts.StringComparisonAssertion, None] = None
|
|
95
120
|
""" The assertion func to compare the expected and actual stdout of the CLI. """
|
|
96
121
|
|
|
97
|
-
if (stdout_assertion_func is not None):
|
|
122
|
+
if ((stdout_assertion_func is not None) and (not self.should_skip())):
|
|
98
123
|
self.stdout_assertion_func = edq.util.pyimport.fetch(stdout_assertion_func)
|
|
99
124
|
|
|
100
125
|
self.stderr_assertion_func: typing.Union[edq.testing.asserts.StringComparisonAssertion, None] = None
|
|
101
126
|
""" The assertion func to compare the expected and actual stderr of the CLI. """
|
|
102
127
|
|
|
103
|
-
if (stderr_assertion_func is not None):
|
|
128
|
+
if ((stderr_assertion_func is not None) and (not self.should_skip())):
|
|
104
129
|
self.stderr_assertion_func = edq.util.pyimport.fetch(stderr_assertion_func)
|
|
105
130
|
|
|
106
131
|
self.expected_stdout: str = expected_stdout
|
|
@@ -113,12 +138,33 @@ class CLITestInfo:
|
|
|
113
138
|
self.expected_stdout = self.expected_stdout.strip()
|
|
114
139
|
self.expected_stderr = self.expected_stderr.strip()
|
|
115
140
|
|
|
141
|
+
self.split_stdout_stderr: bool = split_stdout_stderr
|
|
142
|
+
"""
|
|
143
|
+
Split stdout and stderr into different strings for testing.
|
|
144
|
+
By default, these two will be combined.
|
|
145
|
+
If both are non-empty, then they will be joined like: f"{stdout}\n{TEST_CASE_SEP}\n{stderr}".
|
|
146
|
+
Otherwise, only the non-empty one will be present with no separator.
|
|
147
|
+
Any stdout assertions will be applied to the combined text.
|
|
148
|
+
"""
|
|
149
|
+
|
|
116
150
|
# Make any path normalizations over the arguments and expected output.
|
|
117
151
|
self.expected_stdout = self._expand_paths(self.expected_stdout)
|
|
118
152
|
self.expected_stderr = self._expand_paths(self.expected_stderr)
|
|
119
153
|
for (i, argument) in enumerate(self.arguments):
|
|
120
154
|
self.arguments[i] = self._expand_paths(argument)
|
|
121
155
|
|
|
156
|
+
if (extra_options is None):
|
|
157
|
+
extra_options = {}
|
|
158
|
+
|
|
159
|
+
self.extra_options: typing.Union[typing.Dict[str, typing.Any], None] = extra_options
|
|
160
|
+
"""
|
|
161
|
+
A place to store additional options.
|
|
162
|
+
Extra top-level options will cause tests to error.
|
|
163
|
+
"""
|
|
164
|
+
|
|
165
|
+
if (len(kwargs) > 0):
|
|
166
|
+
raise ValueError(f"Found unknown CLI test options: '{kwargs}'.")
|
|
167
|
+
|
|
122
168
|
def _expand_paths(self, text: str) -> str:
|
|
123
169
|
"""
|
|
124
170
|
Expand path replacements in testing text.
|
|
@@ -126,9 +172,9 @@ class CLITestInfo:
|
|
|
126
172
|
"""
|
|
127
173
|
|
|
128
174
|
replacements = [
|
|
129
|
-
(DATA_DIR_ID,
|
|
175
|
+
(DATA_DIR_ID, self.data_dir),
|
|
130
176
|
(TEMP_DIR_ID, self.temp_dir),
|
|
131
|
-
(
|
|
177
|
+
(BASE_DIR_ID, self.base_dir),
|
|
132
178
|
]
|
|
133
179
|
|
|
134
180
|
for (key, target_dir) in replacements:
|
|
@@ -136,8 +182,18 @@ class CLITestInfo:
|
|
|
136
182
|
|
|
137
183
|
return text
|
|
138
184
|
|
|
185
|
+
def should_skip(self) -> bool:
|
|
186
|
+
""" Check if this test should be skipped. """
|
|
187
|
+
|
|
188
|
+
return (len(self.skip_reasons) > 0)
|
|
189
|
+
|
|
190
|
+
def skip_message(self) -> str:
|
|
191
|
+
""" Get a message displaying the reasons this test should be skipped. """
|
|
192
|
+
|
|
193
|
+
return f"This test has been skipped because of the following: {self.skip_reasons}."
|
|
194
|
+
|
|
139
195
|
@staticmethod
|
|
140
|
-
def load_path(path: str, test_name: str, base_temp_dir: str) -> 'CLITestInfo':
|
|
196
|
+
def load_path(path: str, test_name: str, base_temp_dir: str, data_dir: str) -> 'CLITestInfo':
|
|
141
197
|
""" Load a CLI test file and extract the test info. """
|
|
142
198
|
|
|
143
199
|
options, expected_stdout = read_test_file(path)
|
|
@@ -147,7 +203,7 @@ class CLITestInfo:
|
|
|
147
203
|
base_dir = os.path.dirname(os.path.abspath(path))
|
|
148
204
|
temp_dir = os.path.join(base_temp_dir, test_name)
|
|
149
205
|
|
|
150
|
-
return CLITestInfo(test_name, base_dir, temp_dir, **options)
|
|
206
|
+
return CLITestInfo(test_name, base_dir, data_dir, temp_dir, **options)
|
|
151
207
|
|
|
152
208
|
def read_test_file(path: str) -> typing.Tuple[typing.Dict[str, typing.Any], str]:
|
|
153
209
|
""" Read a test case file and split the output into JSON data and text. """
|
|
@@ -189,14 +245,14 @@ def replace_path_pattern(text: str, key: str, target_dir: str) -> str:
|
|
|
189
245
|
|
|
190
246
|
return text
|
|
191
247
|
|
|
192
|
-
def _get_test_method(test_name: str, path: str) -> typing.Callable:
|
|
248
|
+
def _get_test_method(test_name: str, path: str, data_dir: str) -> typing.Callable:
|
|
193
249
|
""" Get a test method that represents the test case at the given path. """
|
|
194
250
|
|
|
195
251
|
def __method(self: edq.testing.unittest.BaseTest) -> None:
|
|
196
|
-
test_info = CLITestInfo.load_path(path, test_name, getattr(self, BASE_TEMP_DIR_ATTR))
|
|
252
|
+
test_info = CLITestInfo.load_path(path, test_name, getattr(self, BASE_TEMP_DIR_ATTR), data_dir)
|
|
197
253
|
|
|
198
|
-
if (
|
|
199
|
-
self.skipTest(
|
|
254
|
+
if (test_info.should_skip()):
|
|
255
|
+
self.skipTest(test_info.skip_message())
|
|
200
256
|
|
|
201
257
|
old_args = sys.argv
|
|
202
258
|
sys.argv = [test_info.module.__file__] + test_info.arguments
|
|
@@ -223,6 +279,12 @@ def _get_test_method(test_name: str, path: str) -> typing.Callable:
|
|
|
223
279
|
finally:
|
|
224
280
|
sys.argv = old_args
|
|
225
281
|
|
|
282
|
+
if (not test_info.split_stdout_stderr):
|
|
283
|
+
if ((len(stdout_text) > 0) and (len(stderr_text) > 0)):
|
|
284
|
+
stdout_text = f"{stdout_text}\n{TEST_CASE_SEP}\n{stderr_text}"
|
|
285
|
+
elif (len(stderr_text) > 0):
|
|
286
|
+
stdout_text = stderr_text
|
|
287
|
+
|
|
226
288
|
if (test_info.stdout_assertion_func is not None):
|
|
227
289
|
test_info.stdout_assertion_func(self, test_info.expected_stdout, stdout_text)
|
|
228
290
|
|
|
@@ -231,7 +293,7 @@ def _get_test_method(test_name: str, path: str) -> typing.Callable:
|
|
|
231
293
|
|
|
232
294
|
return __method
|
|
233
295
|
|
|
234
|
-
def add_test_paths(target_class: type, paths: typing.List[str]) -> None:
|
|
296
|
+
def add_test_paths(target_class: type, data_dir: str, paths: typing.List[str]) -> None:
|
|
235
297
|
""" Add tests from the given test files. """
|
|
236
298
|
|
|
237
299
|
# Attach a temp directory to the testing class so all tests can share a common base temp dir.
|
|
@@ -242,12 +304,12 @@ def add_test_paths(target_class: type, paths: typing.List[str]) -> None:
|
|
|
242
304
|
test_name = 'test_cli__' + os.path.splitext(os.path.basename(path))[0]
|
|
243
305
|
|
|
244
306
|
try:
|
|
245
|
-
setattr(target_class, test_name, _get_test_method(test_name, path))
|
|
307
|
+
setattr(target_class, test_name, _get_test_method(test_name, path, data_dir))
|
|
246
308
|
except Exception as ex:
|
|
247
309
|
raise ValueError(f"Failed to parse test case '{path}'.") from ex
|
|
248
310
|
|
|
249
|
-
def discover_test_cases(target_class: type) -> None:
|
|
311
|
+
def discover_test_cases(target_class: type, test_cases_dir: str, data_dir: str) -> None:
|
|
250
312
|
""" Look in the text cases directory for any test cases and add them as test methods to the test class. """
|
|
251
313
|
|
|
252
|
-
paths = list(sorted(glob.glob(os.path.join(
|
|
253
|
-
add_test_paths(target_class, paths)
|
|
314
|
+
paths = list(sorted(glob.glob(os.path.join(test_cases_dir, "**", "*.txt"), recursive = True)))
|
|
315
|
+
add_test_paths(target_class, data_dir, paths)
|
edq/testing/cli_test.py
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
1
3
|
import edq.testing.cli
|
|
2
4
|
import edq.testing.unittest
|
|
3
5
|
|
|
6
|
+
THIS_DIR: str = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
|
|
7
|
+
BASE_TESTDATA_DIR: str = os.path.join(THIS_DIR, "testdata", "cli")
|
|
8
|
+
TEST_CASES_DIR: str = os.path.join(BASE_TESTDATA_DIR, "tests")
|
|
9
|
+
DATA_DIR: str = os.path.join(BASE_TESTDATA_DIR, "data")
|
|
10
|
+
|
|
4
11
|
class CLITest(edq.testing.unittest.BaseTest):
|
|
5
12
|
""" Test CLI invocations. """
|
|
6
13
|
|
|
7
14
|
# Populate CLITest with all the test methods.
|
|
8
|
-
edq.testing.cli.discover_test_cases(CLITest)
|
|
15
|
+
edq.testing.cli.discover_test_cases(CLITest, TEST_CASES_DIR, DATA_DIR)
|
edq/testing/unittest.py
CHANGED
|
@@ -14,11 +14,26 @@ class BaseTest(unittest.TestCase):
|
|
|
14
14
|
maxDiff = None
|
|
15
15
|
""" Don't limit the size of diffs. """
|
|
16
16
|
|
|
17
|
-
def assertJSONDictEqual(self, a: typing.
|
|
17
|
+
def assertJSONDictEqual(self, a: typing.Any, b: typing.Any) -> None: # pylint: disable=invalid-name
|
|
18
18
|
"""
|
|
19
|
-
|
|
19
|
+
Like unittest.TestCase.assertDictEqual(),
|
|
20
|
+
but will try to convert each comparison argument to a dict if it is not already,
|
|
21
|
+
and uses an assertion message containing the full JSON representation of the arguments.
|
|
22
|
+
|
|
20
23
|
"""
|
|
21
24
|
|
|
25
|
+
if (not isinstance(a, dict)):
|
|
26
|
+
if (isinstance(a, edq.util.json.DictConverter)):
|
|
27
|
+
a = a.to_dict()
|
|
28
|
+
else:
|
|
29
|
+
a = vars(a)
|
|
30
|
+
|
|
31
|
+
if (not isinstance(b, dict)):
|
|
32
|
+
if (isinstance(b, edq.util.json.DictConverter)):
|
|
33
|
+
b = b.to_dict()
|
|
34
|
+
else:
|
|
35
|
+
b = vars(b)
|
|
36
|
+
|
|
22
37
|
a_json = edq.util.json.dumps(a, indent = 4)
|
|
23
38
|
b_json = edq.util.json.dumps(b, indent = 4)
|
|
24
39
|
|
edq/util/dirent_test.py
CHANGED
|
@@ -3,32 +3,51 @@ import os
|
|
|
3
3
|
import edq.testing.unittest
|
|
4
4
|
import edq.util.dirent
|
|
5
5
|
|
|
6
|
-
THIS_DIR = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
|
|
7
|
-
TEST_BASE_DIR = os.path.join(THIS_DIR, 'testdata', 'dirent-operations')
|
|
8
|
-
"""
|
|
9
|
-
This test data directory is laid out as:
|
|
10
|
-
.
|
|
11
|
-
├── a.txt
|
|
12
|
-
├── dir_1
|
|
13
|
-
│ ├── b.txt
|
|
14
|
-
│ └── dir_2
|
|
15
|
-
│ └── c.txt
|
|
16
|
-
├── dir_empty
|
|
17
|
-
├── file_empty
|
|
18
|
-
├── symlink_a.txt -> a.txt
|
|
19
|
-
├── symlink_dir_1 -> dir_1
|
|
20
|
-
├── symlink_dir_empty -> dir_empty
|
|
21
|
-
└── symlink_file_empty -> file_empty
|
|
22
|
-
|
|
23
|
-
Where non-empty files are filled with their filename (without the extension).
|
|
24
|
-
dir_empty will not exist in the repository (since it is an empty directory),
|
|
25
|
-
but it will be created by _prep_temp_dir().
|
|
26
|
-
"""
|
|
27
|
-
|
|
28
6
|
DIRENT_TYPE_DIR = 'dir'
|
|
29
7
|
DIRENT_TYPE_FILE = 'file'
|
|
30
8
|
DIRENT_TYPE_BROKEN_SYMLINK = 'broken_symlink'
|
|
31
9
|
|
|
10
|
+
def create_test_dir(temp_dir_prefix: str) -> str:
|
|
11
|
+
"""
|
|
12
|
+
Create a temp dir and populate it with dirents for testing.
|
|
13
|
+
|
|
14
|
+
This test data directory is laid out as:
|
|
15
|
+
.
|
|
16
|
+
├── a.txt
|
|
17
|
+
├── dir_1
|
|
18
|
+
│ ├── b.txt
|
|
19
|
+
│ └── dir_2
|
|
20
|
+
│ └── c.txt
|
|
21
|
+
├── dir_empty
|
|
22
|
+
├── file_empty
|
|
23
|
+
├── symlink_a.txt -> a.txt
|
|
24
|
+
├── symlink_dir_1 -> dir_1
|
|
25
|
+
├── symlink_dir_empty -> dir_empty
|
|
26
|
+
└── symlink_file_empty -> file_empty
|
|
27
|
+
|
|
28
|
+
Where non-empty files are filled with their filename (without the extension).
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
temp_dir = edq.util.dirent.get_temp_dir(prefix = temp_dir_prefix)
|
|
32
|
+
|
|
33
|
+
# Dirs
|
|
34
|
+
edq.util.dirent.mkdir(os.path.join(temp_dir, 'dir_1', 'dir_2'))
|
|
35
|
+
edq.util.dirent.mkdir(os.path.join(temp_dir, 'dir_empty'))
|
|
36
|
+
|
|
37
|
+
# Files
|
|
38
|
+
edq.util.dirent.write_file(os.path.join(temp_dir, 'a.txt'), 'a')
|
|
39
|
+
edq.util.dirent.write_file(os.path.join(temp_dir, 'file_empty'), '')
|
|
40
|
+
edq.util.dirent.write_file(os.path.join(temp_dir, 'dir_1', 'b.txt'), 'b')
|
|
41
|
+
edq.util.dirent.write_file(os.path.join(temp_dir, 'dir_1', 'dir_2', 'c.txt'), 'c')
|
|
42
|
+
|
|
43
|
+
# Links
|
|
44
|
+
os.symlink('a.txt', os.path.join(temp_dir, 'symlink_a.txt'))
|
|
45
|
+
os.symlink('dir_1', os.path.join(temp_dir, 'symlink_dir_1'))
|
|
46
|
+
os.symlink('dir_empty', os.path.join(temp_dir, 'symlink_dir_empty'))
|
|
47
|
+
os.symlink('file_empty', os.path.join(temp_dir, 'symlink_file_empty'))
|
|
48
|
+
|
|
49
|
+
return temp_dir
|
|
50
|
+
|
|
32
51
|
class TestDirent(edq.testing.unittest.BaseTest):
|
|
33
52
|
""" Test basic operations on dirents. """
|
|
34
53
|
|
|
@@ -363,10 +382,7 @@ class TestDirent(edq.testing.unittest.BaseTest):
|
|
|
363
382
|
self.assertEqual(expected_contents, actual_contents)
|
|
364
383
|
|
|
365
384
|
def test_copy_contents_base(self):
|
|
366
|
-
"""
|
|
367
|
-
Test copying the contents of a dirent.
|
|
368
|
-
Note that the base functionality of copy_contents() is tested by test_setup().
|
|
369
|
-
"""
|
|
385
|
+
""" Test copying the contents of a dirent. """
|
|
370
386
|
|
|
371
387
|
# [(source, dest, no clobber?, error substring), ...]
|
|
372
388
|
test_cases = [
|
|
@@ -877,12 +893,7 @@ class TestDirent(edq.testing.unittest.BaseTest):
|
|
|
877
893
|
self._check_existing_paths(temp_dir, expected_paths)
|
|
878
894
|
|
|
879
895
|
def _prep_temp_dir(self):
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
edq.util.dirent.mkdir(os.path.join(temp_dir, 'dir_empty'))
|
|
883
|
-
edq.util.dirent.copy_contents(TEST_BASE_DIR, temp_dir)
|
|
884
|
-
|
|
885
|
-
return temp_dir
|
|
896
|
+
return create_test_dir('edq_test_dirent_')
|
|
886
897
|
|
|
887
898
|
def _check_existing_paths(self, base_dir, raw_paths):
|
|
888
899
|
"""
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
edq/__init__.py,sha256=
|
|
1
|
+
edq/__init__.py,sha256=vFC64jsA6hRuFLt0-n4VoH-Khj2zMdd46uFIzH1bZmM,86
|
|
2
2
|
edq/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
3
|
edq/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
edq/cli/version.py,sha256=hEz8DonP6cmDMiNPpUT4V4hbSQhcC7z6NhJSxqVY6NY,592
|
|
5
5
|
edq/cli/testing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
edq/cli/testing/cli-test.py,sha256=
|
|
6
|
+
edq/cli/testing/cli-test.py,sha256=LJJNC_l-7Me2tXKZba0xqmhm08XiPAj5Zt9fsfwAT04,1289
|
|
7
7
|
edq/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
8
|
edq/core/argparser.py,sha256=LWv4EYlgmqEw0jscpV_-aKSobBEDAZ02Zv3cF2JArx8,4180
|
|
9
9
|
edq/core/argparser_test.py,sha256=YzNft7c1Nk5tQzHEW7nEuJakjvk1IZiYimaQ_6HI6Bo,4046
|
|
@@ -11,14 +11,15 @@ edq/core/log.py,sha256=Aq5-Tznq5fgCfU0OI4ECy2OnCoiwV4bTFkhXXdLoG7Q,3726
|
|
|
11
11
|
edq/core/version.py,sha256=cCadcn3M4qoxbQRu4WRHXUu_xl49GTGSDpr6hpr7Vxw,124
|
|
12
12
|
edq/testing/__init__.py,sha256=IKd3fPU_8d_jP19HxG-zKwxFwn7nqFGGtXOY5slY41c,32
|
|
13
13
|
edq/testing/asserts.py,sha256=kxNdAC3usbOBQXuagxUNv8IDQ57I3Moe4eWc51xaNIo,2524
|
|
14
|
-
edq/testing/cli.py,sha256=
|
|
15
|
-
edq/testing/cli_test.py,sha256=
|
|
14
|
+
edq/testing/cli.py,sha256=gbvPKbPQRUnKzT6AOA72zvwS1tfm4eZoEIWrd6goqYw,12034
|
|
15
|
+
edq/testing/cli_test.py,sha256=IqzdK1fEit_3HagSU-nNI4EjkoQp6-I88JGZ1_x_uQk,525
|
|
16
16
|
edq/testing/run.py,sha256=qnqGCEwZP-hY87X99EJw2xoMaTF8QeOf7Lx8JI7oM_4,3843
|
|
17
|
-
edq/testing/unittest.py,sha256=
|
|
17
|
+
edq/testing/unittest.py,sha256=gATi1nZF14hMJ-n5ClqL3Lue241JCOh0ax9v8ZG3vDE,2196
|
|
18
|
+
edq/testing/testdata/cli/tests/platform_skip.txt,sha256=J6n7v3LhfTyjR3Ejo-uR-g6Xdxx34Fu_cmyGSii_elc,103
|
|
18
19
|
edq/testing/testdata/cli/tests/version_base.txt,sha256=5e9oSQaivA-0Th7wXpNRhACluyDwvFTL_1xfAkS2Pko,69
|
|
19
20
|
edq/util/__init__.py,sha256=9EFKQE77S-B6OJJKFaMg8k3WkMMUQYlGjlTv6tQmWVo,29
|
|
20
21
|
edq/util/dirent.py,sha256=YDgHW9xcYzid1rxsk3LowIBXW-JIokdN5SXaVSTFt4U,10334
|
|
21
|
-
edq/util/dirent_test.py,sha256=
|
|
22
|
+
edq/util/dirent_test.py,sha256=WUx6Ux-13L9YIg2rDyOROv5Kbvgr4xy693ceG1osAP0,33855
|
|
22
23
|
edq/util/json.py,sha256=IOTJqZGFYWgng7D1NMd6NDbbmOuw8C4Mpo6-2w1JFNY,5344
|
|
23
24
|
edq/util/json_test.py,sha256=utUVRbw3z42ke4fpRVI294RrFHcMKms8khVYRkISNk4,8009
|
|
24
25
|
edq/util/pyimport.py,sha256=26OIuCXELyqtwlooMqDEs4GJQrkrAgxnXNYTlqqtsBY,2852
|
|
@@ -26,16 +27,8 @@ edq/util/pyimport_test.py,sha256=Xno0MIa3yMTfBfoTgjKCIMpr1ZShU6bvo9rBRdecXQU,420
|
|
|
26
27
|
edq/util/reflection.py,sha256=jPcW6h0fwSDYh04O5rUxlgoF7HK6fVQ2mq7DD9qPrEg,972
|
|
27
28
|
edq/util/time.py,sha256=anoNM_KniARLombv2BnsoHuCzDqMKiDdIzV7RUe2ZOk,2648
|
|
28
29
|
edq/util/time_test.py,sha256=iQZwzVTVQQ4TdXrLb9MUMCYlKrIe8qyF-hiC9YLTaMo,4610
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
edq/util/testdata/dirent-operations/dir_1/dir_2/c.txt,sha256=o6XnFfDMV0pzw_m-u2vCTzL_1bZ7OHJEwskJ2neaFHg,2
|
|
35
|
-
edq/util/testdata/dirent-operations/symlink_dir_1/b.txt,sha256=AmOCmYm2_ZVPcrqvL8ZLwuLwHWktTecphuqAj26ZgT8,2
|
|
36
|
-
edq/util/testdata/dirent-operations/symlink_dir_1/dir_2/c.txt,sha256=o6XnFfDMV0pzw_m-u2vCTzL_1bZ7OHJEwskJ2neaFHg,2
|
|
37
|
-
edq_utils-0.0.4.dist-info/licenses/LICENSE,sha256=MS4iYEl4rOxMoprZuc86iYVoyk4YgaVoMt7WmGvVF8w,1064
|
|
38
|
-
edq_utils-0.0.4.dist-info/METADATA,sha256=Pt_CQ94UC8ePrD8iEFGSSltVQUJPh8h9-d3Pt_Ll1RE,2471
|
|
39
|
-
edq_utils-0.0.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
40
|
-
edq_utils-0.0.4.dist-info/top_level.txt,sha256=znBHSj6tgXtcMKrUVtovLli5fIEJCb7d-BMxTLRK4zk,4
|
|
41
|
-
edq_utils-0.0.4.dist-info/RECORD,,
|
|
30
|
+
edq_utils-0.0.5.dist-info/licenses/LICENSE,sha256=MS4iYEl4rOxMoprZuc86iYVoyk4YgaVoMt7WmGvVF8w,1064
|
|
31
|
+
edq_utils-0.0.5.dist-info/METADATA,sha256=bbRLMEvtC7oomfF1BEtfXapK2lHfrcXMme1rDTedJL4,2471
|
|
32
|
+
edq_utils-0.0.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
33
|
+
edq_utils-0.0.5.dist-info/top_level.txt,sha256=znBHSj6tgXtcMKrUVtovLli5fIEJCb7d-BMxTLRK4zk,4
|
|
34
|
+
edq_utils-0.0.5.dist-info/RECORD,,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
a
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
b
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
c
|
|
File without changes
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
a
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
b
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
c
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|