Skip to content

Commit

Permalink
Fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
nvbn committed Sep 7, 2015
1 parent 105d3d8 commit 382eb8b
Show file tree
Hide file tree
Showing 11 changed files with 91 additions and 95 deletions.
12 changes: 9 additions & 3 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import pytest
from mock import Mock
from thefuck import conf


def pytest_addoption(parser):
Expand All @@ -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)
Expand Down
21 changes: 11 additions & 10 deletions tests/test_conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,59 +26,60 @@ 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
assert settings.no_colors is True
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
assert settings.require_confirmation is True
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']


Expand Down
29 changes: 15 additions & 14 deletions tests/test_corrector.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')

Expand Down Expand Up @@ -48,44 +48,45 @@ def _prepare_rules(self, rules):
(['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:'


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):
Expand All @@ -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;']
22 changes: 14 additions & 8 deletions tests/test_logs.py
Original file line number Diff line number Diff line change
@@ -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)
10 changes: 5 additions & 5 deletions tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ def generic_shell(self, monkeypatch):
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,
Expand All @@ -41,6 +41,6 @@ def test_get_command_calls(self, Popen):
(['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
19 changes: 5 additions & 14 deletions tests/test_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -28,24 +20,23 @@ def gen():
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) == []


Expand Down
45 changes: 17 additions & 28 deletions tests/test_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')
6 changes: 3 additions & 3 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -12,9 +12,9 @@
({'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():
Expand Down
10 changes: 5 additions & 5 deletions thefuck/corrector.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
Loading

0 comments on commit 382eb8b

Please sign in to comment.