From ac545c6f0ae6012460b4bcc45e37ad604ee60b7e Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Sat, 18 Apr 2015 16:32:50 -0500 Subject: [PATCH] improve no_comamnd rule, test it --- tests/rules/test_no_command.py | 43 ++++++++++++++++++++++++++++++---- thefuck/rules/no_command.py | 9 +++---- 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/tests/rules/test_no_command.py b/tests/rules/test_no_command.py index 85727856..015c70ba 100644 --- a/tests/rules/test_no_command.py +++ b/tests/rules/test_no_command.py @@ -9,16 +9,27 @@ from thefuck.main import Command def command_found(): return b'''No command 'aptget' found, did you mean: Command 'apt-get' from package 'apt' (main) + Command 'not-installed' from package 'derp' (main) + Command 'not-really-used' from package 'whatever' (main) aptget: command not found ''' +@pytest.fixture +def uninstalled_command_found(): + return b'''No command 'pish' found, did you mean: + Command 'vish' from package 'vish' (universe) + Command 'wish' from package 'tk' (main) + Command 'fish' from package 'fish' (universe) + Command 'pdsh' from package 'pdsh' (universe) +pish: command not found +''' + @pytest.fixture def command_not_found(): return b'''No command 'vom' found, but there are 19 similar ones vom: command not found ''' - @pytest.fixture def bins_exists(request): p = patch('thefuck.rules.no_command.which', @@ -26,6 +37,27 @@ def bins_exists(request): p.start() request.addfinalizer(p.stop) +@pytest.fixture +def bin_might_exist(request): + def side_effect(name): + return name in ['not-really-used', 'apt-get', '/usr/lib/command-not-found', 'test'] + p = patch('thefuck.rules.no_command.which', + side_effect = side_effect) + p.start() + request.addfinalizer(p.stop) + + +@pytest.fixture +def patch_history(request): + def side_effect(name): + print("history('{}')".format(name)) + count = 2 if name == 'not-really-used' else 12 + p = patch('thefuck.rules.no_command._count_history_uses', + side_effect = side_effect) + p.start() + request.addfinalizer(p.stop) + + @pytest.fixture def settings(): @@ -34,8 +66,8 @@ def settings(): return _Settings -@pytest.mark.usefixtures('bins_exists') -def test_match(command_found, command_not_found, settings): +@pytest.mark.usefixtures('bin_might_exist', 'patch_history') +def test_match(command_found, command_not_found, uninstalled_command_found, settings): with patch('thefuck.rules.no_command.Popen') as Popen: Popen.return_value.stderr.read.return_value = command_found assert match(Command('aptget install vim', '', ''), settings) @@ -51,8 +83,11 @@ def test_match(command_found, command_not_found, settings): Popen.assert_called_with('test aptget', shell=True, stderr=PIPE) + with patch('thefuck.rules.no_command.Popen') as Popen: + Popen.return_value.stderr.read.return_value = uninstalled_command_found + assert not match(Command('pish bla blah', '', ''), settings) -@pytest.mark.usefixtures('bins_exists') +@pytest.mark.usefixtures('bin_might_exist', 'patch_history') def test_get_new_command(command_found): with patch('thefuck.rules.no_command._get_output', return_value=command_found.decode()): diff --git a/thefuck/rules/no_command.py b/thefuck/rules/no_command.py index ad778ac4..7e7aa484 100644 --- a/thefuck/rules/no_command.py +++ b/thefuck/rules/no_command.py @@ -12,9 +12,10 @@ def _get_output(command, settings): return result.stderr.read().decode() def _count_history_uses(name): - script = 'history | grep {}'.format(name) - result = Popen(script, shell=True, stdout=PIPE) - return len(list(result.stdout)) + script = "history | egrep '\\b{}\\b' | wc -l".format(name) + result = Popen(script, shell=True, + stdout=PIPE) + return int(result.stdout.read()) def _get_candidate_commands(command, settings): output = _get_output(command, settings) @@ -40,6 +41,6 @@ def get_new_command(command, settings): broken_name = re.findall(r"No command '([^']*)' found", output)[0] candidates = _get_candidate_commands(command, settings) - fixed_name = sorted(candidates, key=_count_history_uses)[0] + fixed_name = sorted(candidates, key=_count_history_uses, reverse=True)[0] return command.script.replace(broken_name, fixed_name)