|
| 1 | +import difflib |
1 | 2 | import glob |
| 3 | +import logging |
2 | 4 | import subprocess |
3 | 5 | import yaml |
4 | 6 |
|
5 | 7 |
|
6 | | -def test_via_yaml_data(): |
7 | | - filenames = glob.glob("t/*.yaml") |
| 8 | +logger = logging.getLogger(__name__) |
| 9 | + |
| 10 | + |
| 11 | +def test_all_yaml_files(): |
| 12 | + filenames = glob.glob('t/*.yaml') |
8 | 13 | for filename in filenames: |
9 | | - with open(filename, "r") as f: |
10 | | - tests = yaml.load_all(f, yaml.FullLoader) |
11 | | - for test in tests: |
12 | | - test = massage_test(test) |
13 | | - run_test(test) |
| 14 | + logger.info('YAML: %s' % filename) |
| 15 | + with open(filename, 'r') as f: |
| 16 | + cases = yaml.load_all(f, yaml.FullLoader) |
| 17 | + for case in cases: |
| 18 | + case = massage_case(case) |
| 19 | + run_case(case) |
| 20 | + |
| 21 | + |
| 22 | +def massage_case(case: dict): |
| 23 | + """ |
| 24 | + Takes the raw case from the YAML and sets defaults. |
| 25 | + """ |
| 26 | + if 'exitcode' not in case: |
| 27 | + case['exitcode'] = 0 |
14 | 28 |
|
| 29 | + # Make an array of args arrays out of it if it's not already. |
| 30 | + if not isinstance(case['args'], list): |
| 31 | + case['args'] = [case['args']] |
15 | 32 |
|
16 | | -def massage_test(test: dict): |
17 | | - if "exitcode" not in test: |
18 | | - test["exitcode"] = 0 |
| 33 | + if case['stdout'] is None: |
| 34 | + case['stdout'] = '' |
19 | 35 |
|
20 | | - # Make an array of args arrays out of it if it"s not already. |
21 | | - if not isinstance(test["args"], list): |
22 | | - test["args"] = [test["args"]] |
| 36 | + return case |
23 | 37 |
|
24 | | - return test |
25 | 38 |
|
| 39 | +def expected_lines(test): |
| 40 | + lines = test['stdout'].splitlines() |
| 41 | + if indent := test.get('indent-stdout', 0): |
| 42 | + lines = [' ' * indent + x for x in lines] |
26 | 43 |
|
27 | | -def sorted_output(block: str): |
28 | | - return sorted([x.rstrip() for x in block.split("\n")]) if block else None |
| 44 | + return lines |
29 | 45 |
|
30 | 46 |
|
31 | | -def run_test(test): |
32 | | - for args in test["args"]: |
33 | | - command = ["perl", "-Mblib", "ack", "--noenv"] + args.split() |
| 47 | +def show_diff(exp, got): |
| 48 | + """ |
| 49 | + Shows the diffs between two sets of strings |
| 50 | + """ |
| 51 | + diff = '\n'.join( |
| 52 | + difflib.unified_diff( |
| 53 | + exp, got, fromfile='expected', tofile='got', lineterm='' |
| 54 | + ) |
| 55 | + ) |
| 56 | + print(diff) |
| 57 | + |
| 58 | + |
| 59 | +def run_case(case): |
| 60 | + """ |
| 61 | + Runs an individual case from the YAML. |
| 62 | + """ |
| 63 | + logger.info(' Case: %s' % case['name']) |
| 64 | + for args in case['args']: |
| 65 | + command = ['perl', '-Mblib', 'ack', '--noenv'] + args.split() |
| 66 | + logger.info(' Command: %s' % ' '.join(command)) |
34 | 67 | result = subprocess.run( |
35 | | - command, capture_output=True, text=True, check=(not test["exitcode"]) |
| 68 | + command, |
| 69 | + input=case.get('stdin',None), |
| 70 | + capture_output=True, |
| 71 | + text=True, |
| 72 | + check=(not case['exitcode']), |
36 | 73 | ) |
37 | 74 |
|
38 | | - if test["exitcode"]: |
39 | | - assert result.returncode == test["exitcode"] |
| 75 | + if case['exitcode']: |
| 76 | + assert result.returncode == case['exitcode'] |
| 77 | + |
| 78 | + exp_lines = expected_lines(case) |
| 79 | + got_lines = result.stdout.splitlines() |
| 80 | + if not case.get('ordered', False): |
| 81 | + got_lines = sorted(got_lines) |
| 82 | + exp_lines = sorted(exp_lines) |
40 | 83 |
|
41 | | - if "ordered" in test and test["ordered"]: |
42 | | - assert result.stdout == test["stdout"] |
43 | | - else: |
44 | | - assert sorted_output(result.stdout) == sorted_output(test["stdout"]) |
| 84 | + # show_diff(exp_lines, got_lines) |
| 85 | + assert got_lines == exp_lines |
45 | 86 |
|
46 | 87 |
|
47 | | -test_via_yaml_data() |
| 88 | +test_all_yaml_files() |
0 commit comments