import pytest from pathlib import PosixPath, Path from mock import Mock from thefuck import corrector, conf from tests.utils import Rule, Command, CorrectedCommand from thefuck.corrector import make_corrected_commands, get_corrected_commands,\ is_rule_enabled, organize_commands def test_load_rule(mocker): match = object() get_new_command = object() load_source = mocker.patch( 'thefuck.corrector.load_source', return_value=Mock(match=match, get_new_command=get_new_command, enabled_by_default=True, priority=900, requires_output=True)) 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') @pytest.mark.parametrize('rules, exclude_rules, rule, is_enabled', [ (conf.DEFAULT_RULES, [], Rule('git', enabled_by_default=True), True), (conf.DEFAULT_RULES, [], Rule('git', enabled_by_default=False), False), ([], [], Rule('git', enabled_by_default=False), False), ([], [], Rule('git', enabled_by_default=True), False), (conf.DEFAULT_RULES + ['git'], [], Rule('git', enabled_by_default=False), True), (['git'], [], Rule('git', enabled_by_default=False), True), (conf.DEFAULT_RULES, ['git'], Rule('git', enabled_by_default=True), False), (conf.DEFAULT_RULES, ['git'], Rule('git', enabled_by_default=False), False), ([], ['git'], Rule('git', enabled_by_default=True), False), ([], ['git'], Rule('git', enabled_by_default=False), False)]) def test_is_rule_enabled(settings, rules, exclude_rules, rule, is_enabled): settings.update(rules=rules, exclude_rules=exclude_rules) assert is_rule_enabled(rule) == is_enabled class TestGetRules(object): @pytest.fixture def glob(self, mocker): results = {} mocker.patch('pathlib.Path.glob', new_callable=lambda: lambda *_: results.pop('value', [])) return lambda value: results.update({'value': value}) @pytest.fixture(autouse=True) def load_source(self, monkeypatch): monkeypatch.setattr('thefuck.corrector.load_source', lambda x, _: Rule(x)) def _compare_names(self, rules, names): assert {r.name for r in rules} == set(names) @pytest.mark.parametrize('paths, conf_rules, exclude_rules, loaded_rules', [ (['git.py', 'bash.py'], conf.DEFAULT_RULES, [], ['git', 'bash']), (['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, settings, paths, conf_rules, exclude_rules, loaded_rules): glob([PosixPath(path) for path in paths]) settings.update(rules=conf_rules, priority={}, exclude_rules=exclude_rules) rules = corrector.get_rules() self._compare_names(rules, loaded_rules) class TestIsRuleMatch(object): def test_no_match(self): assert not corrector.is_rule_match( Command('ls'), Rule('', lambda _: False)) def test_match(self): rule = Rule('', lambda x: x.script == 'cd ..') assert corrector.is_rule_match(Command('cd ..'), rule) @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) 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)) \ == [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)) \ == [CorrectedCommand(script='test!', priority=100)] def test_get_corrected_commands(mocker): command = Command('test', 'test', 'test') rules = [Rule(match=lambda _: False), Rule(match=lambda _: True, get_new_command=lambda x: x.script + '!', priority=100), Rule(match=lambda _: True, 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)] \ == ['test!', 'test@', 'test;'] def test_organize_commands(): """Ensures that the function removes duplicates and sorts commands.""" commands = [CorrectedCommand('ls'), CorrectedCommand('ls -la', priority=9000), CorrectedCommand('ls -lh', priority=100), CorrectedCommand('ls -lh', priority=9999)] assert list(organize_commands(iter(commands))) \ == [CorrectedCommand('ls'), CorrectedCommand('ls -lh', priority=100), CorrectedCommand('ls -la', priority=9000)]