Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
ikkamens committed Mar 27, 2021
2 parents 0901b10 + da3ac09 commit f5bf7b2
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 3 deletions.
8 changes: 5 additions & 3 deletions src/flynt/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@


def main():
return sys.exit(run_flynt_cli())

def run_flynt_cli():
parser = argparse.ArgumentParser(
description=f"flynt v.{__version__}", add_help=True, epilog=__doc__
)
Expand Down Expand Up @@ -109,19 +111,19 @@ def main():

if args.version:
print(__version__)
sys.exit(0)
return 0
elif not args.src:
print("flynt: error: the following arguments are required: src")
parser.print_usage()
sys.exit(1)
return 1

print(f"Running flynt v.{__version__}")
if args.dry_run:
print("Running flynt in dry-run mode. No files will be changed.")

if args.transform_concats and sys.version_info < (3, 8):
raise Exception(
f"""Transforming string concatenations is only possible with flynt
f"""Transforming string concatenations is only possible with flynt
installed to a python3.8+ interpreter. Currently using {sys.version_info}."""
)

Expand Down
11 changes: 11 additions & 0 deletions src/flynt/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,14 @@

concat_candidates = 0
concat_changes = 0

# Backup of the initial state to support the tests, which should start with a clean state each time.
# Note: this assumes that all state variables are immutable.
_initial_state = dict(globals())


def _reset():
"""
Resets the state variables to the initial values seen above.
"""
globals().update(**_initial_state)
12 changes: 12 additions & 0 deletions test/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,15 @@
sys.path.append(os.path.join(home, "src"))
else:
config.add_src_to_path()

import pytest

from flynt.state import _reset


@pytest.fixture(autouse=True)
def reset_state():
"""
Fixture to reset the global state between each test
"""
_reset()
128 changes: 128 additions & 0 deletions test/integration/test_cli.py
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 == ""

0 comments on commit f5bf7b2

Please sign in to comment.