From 382eb8b86c7e4d403aa3cc00b7d4880b93ebbf42 Mon Sep 17 00:00:00 2001 From: nvbn Date: Mon, 7 Sep 2015 12:12:16 +0300 Subject: [PATCH] Fix tests --- tests/conftest.py | 12 ++++++++--- tests/test_conf.py | 21 +++++++++--------- tests/test_corrector.py | 29 +++++++++++++------------ tests/test_logs.py | 22 ++++++++++++------- tests/test_main.py | 10 ++++----- tests/test_types.py | 19 +++++------------ tests/test_ui.py | 45 +++++++++++++++------------------------ tests/test_utils.py | 6 +++--- thefuck/corrector.py | 10 ++++----- thefuck/rules/fix_file.py | 4 ++-- thefuck/utils.py | 8 ++++--- 11 files changed, 91 insertions(+), 95 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 9e115352..e54acfc0 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,5 +1,5 @@ import pytest -from mock import Mock +from thefuck import conf def pytest_addoption(parser): @@ -14,9 +14,15 @@ def no_memoize(monkeypatch): monkeypatch.setattr('thefuck.utils.memoize.disabled', True) +@pytest.fixture(autouse=True) +def settings(request): + request.addfinalizer(lambda: conf.settings.update(conf.DEFAULT_SETTINGS)) + return conf.settings + + @pytest.fixture -def settings(): - return Mock(debug=False, no_colors=True) +def no_colors(settings): + settings.no_colors = True @pytest.fixture(autouse=True) diff --git a/tests/test_conf.py b/tests/test_conf.py index 411cd063..e1042072 100644 --- a/tests/test_conf.py +++ b/tests/test_conf.py @@ -26,22 +26,23 @@ def environ(monkeypatch): @pytest.mark.usefixture('environ') -def test_settings_defaults(load_source): +def test_settings_defaults(load_source, settings): load_source.return_value = object() + conf.init_settings(Mock()) for key, val in conf.DEFAULT_SETTINGS.items(): - assert getattr(conf.init_settings(Mock()), key) == val + assert getattr(settings, key) == val @pytest.mark.usefixture('environ') class TestSettingsFromFile(object): - def test_from_file(self, load_source): + def test_from_file(self, load_source, settings): load_source.return_value = Mock(rules=['test'], wait_command=10, require_confirmation=True, no_colors=True, priority={'vim': 100}, exclude_rules=['git']) - settings = conf.init_settings(Mock()) + conf.init_settings(Mock()) assert settings.rules == ['test'] assert settings.wait_command == 10 assert settings.require_confirmation is True @@ -49,26 +50,26 @@ class TestSettingsFromFile(object): assert settings.priority == {'vim': 100} assert settings.exclude_rules == ['git'] - def test_from_file_with_DEFAULT(self, load_source): + def test_from_file_with_DEFAULT(self, load_source, settings): load_source.return_value = Mock(rules=conf.DEFAULT_RULES + ['test'], wait_command=10, exclude_rules=[], require_confirmation=True, no_colors=True) - settings = conf.init_settings(Mock()) + conf.init_settings(Mock()) assert settings.rules == conf.DEFAULT_RULES + ['test'] @pytest.mark.usefixture('load_source') class TestSettingsFromEnv(object): - def test_from_env(self, environ): + def test_from_env(self, environ, settings): environ.update({'THEFUCK_RULES': 'bash:lisp', 'THEFUCK_EXCLUDE_RULES': 'git:vim', 'THEFUCK_WAIT_COMMAND': '55', 'THEFUCK_REQUIRE_CONFIRMATION': 'true', 'THEFUCK_NO_COLORS': 'false', 'THEFUCK_PRIORITY': 'bash=10:lisp=wrong:vim=15'}) - settings = conf.init_settings(Mock()) + conf.init_settings(Mock()) assert settings.rules == ['bash', 'lisp'] assert settings.exclude_rules == ['git', 'vim'] assert settings.wait_command == 55 @@ -76,9 +77,9 @@ class TestSettingsFromEnv(object): assert settings.no_colors is False assert settings.priority == {'bash': 10, 'vim': 15} - def test_from_env_with_DEFAULT(self, environ): + def test_from_env_with_DEFAULT(self, environ, settings): environ.update({'THEFUCK_RULES': 'DEFAULT_RULES:bash:lisp'}) - settings = conf.init_settings(Mock()) + conf.init_settings(Mock()) assert settings.rules == conf.DEFAULT_RULES + ['bash', 'lisp'] diff --git a/tests/test_corrector.py b/tests/test_corrector.py index 1071ae47..f84e7d18 100644 --- a/tests/test_corrector.py +++ b/tests/test_corrector.py @@ -16,7 +16,7 @@ def test_load_rule(mocker): enabled_by_default=True, priority=900, requires_output=True)) - assert corrector.load_rule(Path('/rules/bash.py'), settings=Mock(priority={})) \ + assert corrector.load_rule(Path('/rules/bash.py')) \ == Rule('bash', match, get_new_command, priority=900) load_source.assert_called_once_with('bash', '/rules/bash.py') @@ -48,29 +48,30 @@ class TestGetRules(object): (['git.py', 'bash.py'], ['git'], [], ['git']), (['git.py', 'bash.py'], conf.DEFAULT_RULES, ['git'], ['bash']), (['git.py', 'bash.py'], ['git'], ['git'], [])]) - def test_get_rules(self, glob, paths, conf_rules, exclude_rules, loaded_rules): + def test_get_rules(self, glob, settings, paths, conf_rules, exclude_rules, + loaded_rules): glob([PosixPath(path) for path in paths]) - settings = Mock(rules=self._prepare_rules(conf_rules), + settings.update(rules=self._prepare_rules(conf_rules), priority={}, exclude_rules=self._prepare_rules(exclude_rules)) - rules = corrector.get_rules(Path('~'), settings) + rules = corrector.get_rules(Path('~')) self._compare_names(rules, loaded_rules) class TestIsRuleMatch(object): - def test_no_match(self, settings): + def test_no_match(self): assert not corrector.is_rule_match( - Command('ls'), Rule('', lambda *_: False), settings) + Command('ls'), Rule('', lambda *_: False)) - def test_match(self, settings): + def test_match(self): rule = Rule('', lambda x, _: x.script == 'cd ..') - assert corrector.is_rule_match(Command('cd ..'), rule, settings) + assert corrector.is_rule_match(Command('cd ..'), rule) - def test_when_rule_failed(self, capsys, settings): + @pytest.mark.usefixtures('no_colors') + def test_when_rule_failed(self, capsys): rule = Rule('test', Mock(side_effect=OSError('Denied')), requires_output=False) - assert not corrector.is_rule_match( - Command('ls'), rule, settings) + assert not corrector.is_rule_match(Command('ls'), rule) assert capsys.readouterr()[1].split('\n')[0] == '[WARN] Rule test:' @@ -78,14 +79,14 @@ class TestMakeCorrectedCommands(object): def test_with_rule_returns_list(self): rule = Rule(get_new_command=lambda x, _: [x.script + '!', x.script + '@'], priority=100) - assert list(make_corrected_commands(Command(script='test'), rule, None)) \ + assert list(make_corrected_commands(Command(script='test'), rule)) \ == [CorrectedCommand(script='test!', priority=100), CorrectedCommand(script='test@', priority=200)] def test_with_rule_returns_command(self): rule = Rule(get_new_command=lambda x, _: x.script + '!', priority=100) - assert list(make_corrected_commands(Command(script='test'), rule, None)) \ + assert list(make_corrected_commands(Command(script='test'), rule)) \ == [CorrectedCommand(script='test!', priority=100)] def test_get_corrected_commands(mocker): @@ -97,5 +98,5 @@ def test_get_corrected_commands(mocker): get_new_command=lambda x, _: [x.script + '@', x.script + ';'], priority=60)] mocker.patch('thefuck.corrector.get_rules', return_value=rules) - assert [cmd.script for cmd in get_corrected_commands(command, None, Mock(debug=False))] \ + assert [cmd.script for cmd in get_corrected_commands(command, None)] \ == ['test!', 'test@', 'test;'] diff --git a/tests/test_logs.py b/tests/test_logs.py index 6e87fe8b..4b585ee4 100644 --- a/tests/test_logs.py +++ b/tests/test_logs.py @@ -1,14 +1,20 @@ +import pytest from mock import Mock from thefuck import logs -def test_color(): - assert logs.color('red', Mock(no_colors=False)) == 'red' - assert logs.color('red', Mock(no_colors=True)) == '' +def test_color(settings): + settings.no_colors = False + assert logs.color('red') == 'red' + settings.no_colors = True + assert logs.color('red') == '' -def test_debug(capsys): - logs.debug('test', Mock(no_colors=True, debug=True)) - assert capsys.readouterr() == ('', 'DEBUG: test\n') - logs.debug('test', Mock(no_colors=True, debug=False)) - assert capsys.readouterr() == ('', '') +@pytest.mark.usefixtures('no_colors') +@pytest.mark.parametrize('debug, stderr', [ + (True, 'DEBUG: test\n'), + (False, '')]) +def test_debug(capsys, settings, debug, stderr): + settings.debug = debug + logs.debug('test') + assert capsys.readouterr() == ('', stderr) diff --git a/tests/test_main.py b/tests/test_main.py index 0ea2cc2e..d33b539a 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -24,9 +24,9 @@ class TestGetCommand(object): monkeypatch.setattr('thefuck.shells.from_shell', lambda x: x) monkeypatch.setattr('thefuck.shells.to_shell', lambda x: x) - def test_get_command_calls(self, Popen): - assert main.get_command(Mock(env={}), - ['thefuck', 'apt-get', 'search', 'vim']) \ + def test_get_command_calls(self, Popen, settings): + settings.env = {} + assert main.get_command(['thefuck', 'apt-get', 'search', 'vim']) \ == Command('apt-get search vim', 'stdout', 'stderr') Popen.assert_called_once_with('apt-get search vim', shell=True, @@ -41,6 +41,6 @@ class TestGetCommand(object): (['thefuck', 'ls'], 'ls')]) def test_get_command_script(self, args, result): if result: - assert main.get_command(Mock(env={}), args).script == result + assert main.get_command(args).script == result else: - assert main.get_command(Mock(env={}), args) is None + assert main.get_command(args) is None diff --git a/tests/test_types.py b/tests/test_types.py index 1201d2c2..bc57e489 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -10,14 +10,6 @@ def test_rules_names_list(): assert Rule('bash') not in RulesNamesList(['lisp']) -def test_update_settings(): - settings = Settings({'key': 'val'}) - new_settings = settings.update(key='new-val', unset='unset-value') - assert new_settings.key == 'val' - assert new_settings.unset == 'unset-value' - assert settings.key == 'val' - - class TestSortedCorrectedCommandsSequence(object): def test_realises_generator_only_on_demand(self, settings): should_realise = False @@ -28,24 +20,23 @@ class TestSortedCorrectedCommandsSequence(object): assert should_realise yield CorrectedCommand('git checkout', priority=100) - commands = SortedCorrectedCommandsSequence(gen(), settings) + commands = SortedCorrectedCommandsSequence(gen()) assert commands[0] == CorrectedCommand('git commit') should_realise = True assert commands[1] == CorrectedCommand('git checkout', priority=100) assert commands[2] == CorrectedCommand('git branch', priority=200) - def test_remove_duplicates(self, settings): + def test_remove_duplicates(self): side_effect = lambda *_: None seq = SortedCorrectedCommandsSequence( iter([CorrectedCommand('ls', priority=100), CorrectedCommand('ls', priority=200), - CorrectedCommand('ls', side_effect, 300)]), - settings) + CorrectedCommand('ls', side_effect, 300)])) assert set(seq) == {CorrectedCommand('ls', priority=100), CorrectedCommand('ls', side_effect, 300)} - def test_with_blank(self, settings): - seq = SortedCorrectedCommandsSequence(iter([]), settings) + def test_with_blank(self): + seq = SortedCorrectedCommandsSequence(iter([])) assert list(seq) == [] diff --git a/tests/test_ui.py b/tests/test_ui.py index f997374c..aec2f099 100644 --- a/tests/test_ui.py +++ b/tests/test_ui.py @@ -56,66 +56,55 @@ def test_command_selector(): assert changes == [1, 2, 3, 1, 3] +@pytest.mark.usefixtures('no_colors') class TestSelectCommand(object): @pytest.fixture - def commands_with_side_effect(self, settings): + def commands_with_side_effect(self): return SortedCorrectedCommandsSequence( iter([CorrectedCommand('ls', lambda *_: None, 100), - CorrectedCommand('cd', lambda *_: None, 100)]), - settings) + CorrectedCommand('cd', lambda *_: None, 100)])) @pytest.fixture - def commands(self, settings): + def commands(self): return SortedCorrectedCommandsSequence( iter([CorrectedCommand('ls', None, 100), - CorrectedCommand('cd', None, 100)]), - settings) + CorrectedCommand('cd', None, 100)])) def test_without_commands(self, capsys): - assert ui.select_command([], Mock(debug=False, no_color=True)) is None + assert ui.select_command([]) is None assert capsys.readouterr() == ('', 'No fucks given\n') - def test_without_confirmation(self, capsys, commands): - assert ui.select_command(commands, - Mock(debug=False, no_color=True, - require_confirmation=False)) == commands[0] + def test_without_confirmation(self, capsys, commands, settings): + settings.require_confirmation = False + assert ui.select_command(commands) == commands[0] assert capsys.readouterr() == ('', 'ls\n') - def test_without_confirmation_with_side_effects(self, capsys, - commands_with_side_effect): - assert ui.select_command(commands_with_side_effect, - Mock(debug=False, no_color=True, - require_confirmation=False)) \ + def test_without_confirmation_with_side_effects( + self, capsys, commands_with_side_effect, settings): + settings.require_confirmation = False + assert ui.select_command(commands_with_side_effect) \ == commands_with_side_effect[0] assert capsys.readouterr() == ('', 'ls (+side effect)\n') def test_with_confirmation(self, capsys, patch_getch, commands): patch_getch(['\n']) - assert ui.select_command(commands, - Mock(debug=False, no_color=True, - require_confirmation=True)) == commands[0] + assert ui.select_command(commands) == commands[0] assert capsys.readouterr() == ('', u'\x1b[1K\rls [enter/↑/↓/ctrl+c]\n') def test_with_confirmation_abort(self, capsys, patch_getch, commands): patch_getch([KeyboardInterrupt]) - assert ui.select_command(commands, - Mock(debug=False, no_color=True, - require_confirmation=True)) is None + assert ui.select_command(commands) is None assert capsys.readouterr() == ('', u'\x1b[1K\rls [enter/↑/↓/ctrl+c]\nAborted\n') def test_with_confirmation_with_side_effct(self, capsys, patch_getch, commands_with_side_effect): patch_getch(['\n']) - assert ui.select_command(commands_with_side_effect, - Mock(debug=False, no_color=True, - require_confirmation=True))\ + assert ui.select_command(commands_with_side_effect)\ == commands_with_side_effect[0] assert capsys.readouterr() == ('', u'\x1b[1K\rls (+side effect) [enter/↑/↓/ctrl+c]\n') def test_with_confirmation_select_second(self, capsys, patch_getch, commands): patch_getch(['\x1b', '[', 'B', '\n']) - assert ui.select_command(commands, - Mock(debug=False, no_color=True, - require_confirmation=True)) == commands[1] + assert ui.select_command(commands) == commands[1] assert capsys.readouterr() == ( '', u'\x1b[1K\rls [enter/↑/↓/ctrl+c]\x1b[1K\rcd [enter/↑/↓/ctrl+c]\n') diff --git a/tests/test_utils.py b/tests/test_utils.py index b51ec394..3566b4f5 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,7 +1,7 @@ import pytest from mock import Mock import six -from thefuck.utils import wrap_settings, \ +from thefuck.utils import default_settings, \ memoize, get_closest, get_all_executables, replace_argument, \ get_all_matched_commands, is_app, for_app, cache from thefuck.types import Settings @@ -12,9 +12,9 @@ from tests.utils import Command ({'key': 'val'}, {}, {'key': 'val'}), ({'key': 'new-val'}, {'key': 'val'}, {'key': 'val'}), ({'key': 'new-val', 'unset': 'unset'}, {'key': 'val'}, {'key': 'val', 'unset': 'unset'})]) -def test_wrap_settings(override, old, new): +def test_default_settings(override, old, new): fn = lambda _, settings: settings - assert wrap_settings(override)(fn)(None, Settings(old)) == new + assert default_settings(override)(fn)(None, Settings(old)) == new def test_memoize(): diff --git a/thefuck/corrector.py b/thefuck/corrector.py index 8840749a..c1477a57 100644 --- a/thefuck/corrector.py +++ b/thefuck/corrector.py @@ -13,11 +13,11 @@ def load_rule(rule): rule_module = load_source(name, str(rule)) priority = getattr(rule_module, 'priority', DEFAULT_PRIORITY) return Rule(name, rule_module.match, - rule_module.get_new_command, - getattr(rule_module, 'enabled_by_default', True), - getattr(rule_module, 'side_effect', None), - settings.priority.get(name, priority), - getattr(rule_module, 'requires_output', True)) + rule_module.get_new_command, + getattr(rule_module, 'enabled_by_default', True), + getattr(rule_module, 'side_effect', None), + settings.priority.get(name, priority), + getattr(rule_module, 'requires_output', True)) def get_loaded_rules(rules): diff --git a/thefuck/rules/fix_file.py b/thefuck/rules/fix_file.py index 7af1fb31..895244d8 100644 --- a/thefuck/rules/fix_file.py +++ b/thefuck/rules/fix_file.py @@ -1,6 +1,6 @@ import re import os -from thefuck.utils import memoize, wrap_settings +from thefuck.utils import memoize, default_settings from thefuck import shells @@ -57,7 +57,7 @@ def match(command, settings): return _search(command.stderr) or _search(command.stdout) -@wrap_settings({'fixlinecmd': '{editor} {file} +{line}', +@default_settings({'fixlinecmd': '{editor} {file} +{line}', 'fixcolcmd': None}) def get_new_command(command, settings): m = _search(command.stderr) or _search(command.stdout) diff --git a/thefuck/utils.py b/thefuck/utils.py index 59cfcf7f..66d6b15b 100644 --- a/thefuck/utils.py +++ b/thefuck/utils.py @@ -60,18 +60,20 @@ def which(program): return None -def wrap_settings(params): +def default_settings(params): """Adds default values to settings if it not presented. Usage: - @wrap_settings({'apt': '/usr/bin/apt'}) + @default_settings({'apt': '/usr/bin/apt'}) def match(command, settings): print(settings.apt) """ def _wrap_settings(fn, command, settings): - return fn(command, Settings(settings, **params)) + for k, w in params.items(): + settings.setdefault(k, w) + return fn(command, settings) return decorator(_wrap_settings)