-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Test coverage for the CLI part (#96)
* Test coverage for the CLI part This can help ensure the CLI code is valid and that the output is as expected * Reset global state between each test
- Loading branch information
jonathangjertsen
authored
Mar 27, 2021
1 parent
6b1b5cb
commit da3ac09
Showing
4 changed files
with
156 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
import argparse | ||
import os | ||
|
||
import pytest | ||
|
||
import flynt | ||
from flynt.cli import run_flynt_cli | ||
from flynt.cli_messages import farewell_message | ||
|
||
|
||
class ArgumentParser(object): | ||
""" | ||
Mock class for argparse.ArgumentParser | ||
Parameters: | ||
shadow_parser: a real argparse.ArgumentParser | ||
parse_args_return_value: the Namespace that should be returned from parse_args. | ||
""" | ||
|
||
def __init__( | ||
self, | ||
shadow_parser: argparse.ArgumentParser, | ||
parse_args_return_value: argparse.Namespace, | ||
*args, | ||
**kwargs, | ||
): | ||
self.parse_args_return_value = parse_args_return_value | ||
self.shadow_parser = shadow_parser | ||
|
||
def add_mutually_exclusive_group(self): | ||
return MutuallyExclusiveGroup(self) | ||
|
||
def add_argument(self, *args, **kwargs): | ||
arg = self.shadow_parser.add_argument(*args, **kwargs) | ||
if arg.dest not in self.parse_args_return_value: | ||
setattr(self.parse_args_return_value, arg.dest, arg.default) | ||
return arg | ||
|
||
def print_usage(self): | ||
return self.shadow_parser.print_usage() | ||
|
||
def parse_args(self): | ||
return self.parse_args_return_value | ||
|
||
|
||
class MutuallyExclusiveGroup(object): | ||
""" | ||
Mock class for argparse.MutuallyExclusiveGroup | ||
""" | ||
|
||
def __init__(self, parent): | ||
self.parent = parent | ||
|
||
def add_argument(self, *args, **kwargs): | ||
return self.parent.add_argument(*args, **kwargs) | ||
|
||
|
||
def run_cli_test(monkeypatch, **kwargs): | ||
""" | ||
Runs the CLI, setting arguments according to **kwargs. | ||
For example, running with version=True is like passing the --version argument to the CLI. | ||
""" | ||
shadow_parser = argparse.ArgumentParser() | ||
parse_args_return_value = argparse.Namespace(**kwargs) | ||
|
||
def argument_parser_mock(*args, **kwargs): | ||
return ArgumentParser(shadow_parser, parse_args_return_value, *args, **kwargs) | ||
|
||
monkeypatch.setattr(argparse, "ArgumentParser", argument_parser_mock) | ||
return run_flynt_cli() | ||
|
||
|
||
def test_cli_no_args(monkeypatch, capsys): | ||
""" | ||
With no arguments, it should require src to be set | ||
""" | ||
return_code = run_cli_test(monkeypatch) | ||
assert return_code == 1 | ||
|
||
out, err = capsys.readouterr() | ||
assert "the following arguments are required: src" in out | ||
|
||
|
||
def test_cli_version(monkeypatch, capsys): | ||
""" | ||
With --version set, it should only print the version | ||
""" | ||
return_code = run_cli_test(monkeypatch, version=True) | ||
assert return_code == 0 | ||
|
||
out, err = capsys.readouterr() | ||
assert out == f"{flynt.__version__}\n" | ||
assert err == "" | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"sample_file", | ||
["all_named.py", "first_string.py", "percent_dict.py", "multiline_limit.py"], | ||
) | ||
def test_cli_dry_run(monkeypatch, capsys, sample_file): | ||
""" | ||
Tests the --dry-run option with a few files, all changed lines should be shown in the diff | ||
""" | ||
# Get input/output paths and read them | ||
folder = os.path.dirname(__file__) | ||
source_path = os.path.join(folder, "samples_in", sample_file) | ||
expected_path = os.path.join(folder, "expected_out", sample_file) | ||
with open(source_path) as file: | ||
source_lines = file.readlines() | ||
with open(expected_path) as file: | ||
converted_lines = file.readlines() | ||
|
||
# Run the CLI | ||
return_code = run_cli_test(monkeypatch, dry_run=True, src=[source_path]) | ||
assert return_code == 0 | ||
|
||
# Check that the output includes all changed lines, and the farewell message | ||
out, err = capsys.readouterr() | ||
|
||
for line in source_lines: | ||
if line not in converted_lines: | ||
assert f"-{line}" in out, "Original source line missing from output" | ||
for line in converted_lines: | ||
if line not in source_lines: | ||
assert f"+{line}" in out, "Converted source line missing from output" | ||
|
||
assert out.strip().endswith(farewell_message.strip()) | ||
assert err == "" |