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 CHANGED
@@ -2,4 +2,4 @@
2
2
  General Python tools used by several EduLinq projects.
3
3
  """
4
4
 
5
- __version__ = '0.0.4'
5
+ __version__ = '0.0.5'
@@ -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 TEST_CASES_DIR.
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
- REL_DIR_ID: str = '__REL_DIR__'
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
- """ The base directory for this test (usually the dir the CLI test file lives. """
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
- """ A temp directory that this test has access to. """
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 = edq.util.pyimport.import_name(self.module_name)
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, DATA_DIR),
175
+ (DATA_DIR_ID, self.data_dir),
130
176
  (TEMP_DIR_ID, self.temp_dir),
131
- (REL_DIR_ID, self.base_dir),
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 ((test_info.platform_skip is not None) and re.search(test_info.platform_skip, sys.platform)):
199
- self.skipTest(f"Test is not available on {sys.platform}.")
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(TEST_CASES_DIR, "**", "*.txt"), recursive = True)))
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)
@@ -0,0 +1,5 @@
1
+ {
2
+ "cli": "package.that.does.not.exist.and.should.never.be.called",
3
+ "platform_skip": ".*"
4
+ }
5
+ ---
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.Dict[str, typing.Any], b: typing.Dict[str, typing.Any]) -> None: # pylint: disable=invalid-name
17
+ def assertJSONDictEqual(self, a: typing.Any, b: typing.Any) -> None: # pylint: disable=invalid-name
18
18
  """
19
- Call assertDictEqual(), but supply a message containing the full JSON representation of the arguments.
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
- temp_dir = edq.util.dirent.get_temp_dir(prefix = 'edq_test_dirent_')
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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: edq-utils
3
- Version: 0.0.4
3
+ Version: 0.0.5
4
4
  Summary: Common utilities used by EduLinq Python projects.
5
5
  Author-email: Eriq Augustine <eriq@edulinq.org>
6
6
  License: MIT License
@@ -1,9 +1,9 @@
1
- edq/__init__.py,sha256=POoiN2MIpiTQijlzxyJCeYpx1EkkrGbcPzAy_Raps7A,86
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=1hjTnAjOKZu69yBBjsO4dn0m9ApF26luo2huSZr5_Yo,1048
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=u1GfgYz4_1oEKftCjrrg-gMQZpj_ry1hXvec2OQQA2M,9728
15
- edq/testing/cli_test.py,sha256=l-CPBXpiMb12_qgQj5FoXHM8GJBKnXieogrCb191Dlc,224
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=ysv_XTL14sDRf4EVx6lRN44A0InQSh-dYeG3bTJ9dzU,1751
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=oXpAaEhOkEr0zw0fdAPypx7QH1aFbY2Hpox-9OpZjhs,33380
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
- edq/util/testdata/dirent-operations/a.txt,sha256=h0KPxSKAPTEGXnvOPPA_5HUJZjHl4Hu9eg_eYMTPJcc,2
30
- edq/util/testdata/dirent-operations/file_empty,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
- edq/util/testdata/dirent-operations/symlink_a.txt,sha256=h0KPxSKAPTEGXnvOPPA_5HUJZjHl4Hu9eg_eYMTPJcc,2
32
- edq/util/testdata/dirent-operations/symlink_file_empty,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
- edq/util/testdata/dirent-operations/dir_1/b.txt,sha256=AmOCmYm2_ZVPcrqvL8ZLwuLwHWktTecphuqAj26ZgT8,2
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
File without changes
File without changes