1
0
mirror of https://github.com/nvbn/thefuck.git synced 2025-01-31 10:11:14 +00:00

Refine tests

This commit is contained in:
nvbn 2015-05-02 04:29:55 +02:00
parent ba601644d6
commit dd1861955c
4 changed files with 237 additions and 191 deletions

View File

@ -1,83 +1,94 @@
import pytest
import six
from mock import patch, Mock
from mock import Mock
from thefuck import conf
from tests.utils import Rule
def test_default():
assert Rule('test', enabled_by_default=True) in conf.DEFAULT_RULES
assert Rule('test', enabled_by_default=False) not in conf.DEFAULT_RULES
assert Rule('test', enabled_by_default=False) in (conf.DEFAULT_RULES + ['test'])
@pytest.mark.parametrize('enabled, rules, result', [
(True, conf.DEFAULT_RULES, True),
(False, conf.DEFAULT_RULES, False),
(False, conf.DEFAULT_RULES + ['test'], True)])
def test_default(enabled, rules, result):
assert (Rule('test', enabled_by_default=enabled) in rules) == result
def test_settings_defaults():
with patch('thefuck.conf.load_source', return_value=object()), \
patch('thefuck.conf.os.environ', new_callable=lambda: {}):
@pytest.fixture
def load_source(monkeypatch):
mock = Mock()
monkeypatch.setattr('thefuck.conf.load_source', mock)
return mock
@pytest.fixture
def environ(monkeypatch):
data = {}
monkeypatch.setattr('thefuck.conf.os.environ', data)
return data
@pytest.mark.usefixture('environ')
def test_settings_defaults(load_source):
load_source.return_value = object()
for key, val in conf.DEFAULT_SETTINGS.items():
assert getattr(conf.get_settings(Mock()), key) == val
def test_settings_from_file():
with patch('thefuck.conf.load_source', return_value=Mock(rules=['test'],
@pytest.mark.usefixture('environ')
class TestSettingsFromFile(object):
def test_from_file(self, load_source):
load_source.return_value = Mock(rules=['test'],
wait_command=10,
require_confirmation=True,
no_colors=True)), \
patch('thefuck.conf.os.environ', new_callable=lambda: {}):
no_colors=True)
settings = conf.get_settings(Mock())
assert settings.rules == ['test']
assert settings.wait_command == 10
assert settings.require_confirmation is True
assert settings.no_colors is True
def test_settings_from_file_with_DEFAULT():
with patch('thefuck.conf.load_source', return_value=Mock(rules=conf.DEFAULT_RULES + ['test'],
def test_from_file_with_DEFAULT(self, load_source):
load_source.return_value = Mock(rules=conf.DEFAULT_RULES + ['test'],
wait_command=10,
require_confirmation=True,
no_colors=True)), \
patch('thefuck.conf.os.environ', new_callable=lambda: {}):
no_colors=True)
settings = conf.get_settings(Mock())
assert settings.rules == conf.DEFAULT_RULES + ['test']
def test_settings_from_env():
with patch('thefuck.conf.load_source', return_value=Mock(rules=['test'],
wait_command=10)), \
patch('thefuck.conf.os.environ',
new_callable=lambda: {'THEFUCK_RULES': 'bash:lisp',
@pytest.mark.usefixture('load_source')
class TestSettingsFromEnv(object):
def test_from_env(self, environ):
environ.update({'THEFUCK_RULES': 'bash:lisp',
'THEFUCK_WAIT_COMMAND': '55',
'THEFUCK_REQUIRE_CONFIRMATION': 'true',
'THEFUCK_NO_COLORS': 'false'}):
'THEFUCK_NO_COLORS': 'false'})
settings = conf.get_settings(Mock())
assert settings.rules == ['bash', 'lisp']
assert settings.wait_command == 55
assert settings.require_confirmation is True
assert settings.no_colors is False
def test_settings_from_env_with_DEFAULT():
with patch('thefuck.conf.load_source', return_value=Mock()), \
patch('thefuck.conf.os.environ', new_callable=lambda: {'THEFUCK_RULES': 'DEFAULT_RULES:bash:lisp'}):
def test_from_env_with_DEFAULT(self, environ):
environ.update({'THEFUCK_RULES': 'DEFAULT_RULES:bash:lisp'})
settings = conf.get_settings(Mock())
assert settings.rules == conf.DEFAULT_RULES + ['bash', 'lisp']
def test_initialize_settings_file_ignore_if_exists():
class TestInitializeSettingsFile(object):
def test_ignore_if_exists(self):
settings_path_mock = Mock(is_file=Mock(return_value=True), open=Mock())
user_dir_mock = Mock(joinpath=Mock(return_value=settings_path_mock))
conf.initialize_settings_file(user_dir_mock)
assert settings_path_mock.is_file.call_count == 1
assert not settings_path_mock.open.called
def test_initialize_settings_file_create_if_exists_not():
def test_create_if_doesnt_exists(self):
settings_file = six.StringIO()
settings_path_mock = Mock(
is_file=Mock(return_value=False),
open=Mock(return_value=Mock(
__exit__=lambda *args: None, __enter__=lambda *args: settings_file
)),
)
__exit__=lambda *args: None, __enter__=lambda *args: settings_file)))
user_dir_mock = Mock(joinpath=Mock(return_value=settings_path_mock))
conf.initialize_settings_file(user_dir_mock)
settings_file_contents = settings_file.getvalue()

View File

@ -1,17 +1,18 @@
import pytest
from mock import patch, Mock
from mock import Mock
from thefuck.history import History
@pytest.fixture
def process(monkeypatch):
class TestHistory(object):
@pytest.fixture(autouse=True)
def process(self, monkeypatch):
Process = Mock()
Process.return_value.parent.return_value.pid = 1
monkeypatch.setattr('thefuck.history.Process', Process)
return Process
@pytest.fixture
def db(monkeypatch):
@pytest.fixture(autouse=True)
def db(self, monkeypatch):
class DBMock(dict):
def __init__(self):
super(DBMock, self).__init__()
@ -24,9 +25,6 @@ def db(monkeypatch):
monkeypatch.setattr('thefuck.history.shelve.open', db)
return db
@pytest.mark.usefixtures('process')
class TestHistory(object):
def test_set(self, db):
history = History()
history.update(last_script='ls',
@ -39,6 +37,6 @@ class TestHistory(object):
db['1-last_script'] = 'cd ..'
assert history.last_script == 'cd ..'
def test_get_without_value(self, db):
def test_get_without_value(self):
history = History()
assert history.last_script is None

View File

@ -1,51 +1,56 @@
import pytest
from subprocess import PIPE
from pathlib import PosixPath, Path
from mock import patch, Mock
from mock import Mock
from thefuck import main, conf, types
from tests.utils import Rule, Command
def test_load_rule():
def test_load_rule(monkeypatch):
match = object()
get_new_command = object()
with patch('thefuck.main.load_source',
return_value=Mock(
match=match,
load_source = Mock()
load_source.return_value = Mock(match=match,
get_new_command=get_new_command,
enabled_by_default=True)) as load_source:
enabled_by_default=True)
monkeypatch.setattr('thefuck.main.load_source', load_source)
assert main.load_rule(Path('/rules/bash.py')) \
== Rule('bash', match, get_new_command)
load_source.assert_called_once_with('bash', '/rules/bash.py')
def test_get_rules():
with patch('thefuck.main.Path.glob') as glob, \
patch('thefuck.main.load_source',
lambda x, _: Mock(match=x, get_new_command=x,
enabled_by_default=True)):
glob.return_value = [PosixPath('bash.py'), PosixPath('lisp.py')]
assert list(main.get_rules(
Path('~'),
Mock(rules=conf.DEFAULT_RULES))) \
== [Rule('bash', 'bash', 'bash'),
@pytest.mark.parametrize('conf_rules, rules', [
(conf.DEFAULT_RULES, [Rule('bash', 'bash', 'bash'),
Rule('lisp', 'lisp', 'lisp'),
Rule('bash', 'bash', 'bash'),
Rule('lisp', 'lisp', 'lisp')]
assert list(main.get_rules(
Path('~'),
Mock(rules=types.RulesNamesList(['bash'])))) \
== [Rule('bash', 'bash', 'bash'),
Rule('bash', 'bash', 'bash')]
Rule('lisp', 'lisp', 'lisp')]),
(types.RulesNamesList(['bash']), [Rule('bash', 'bash', 'bash'),
Rule('bash', 'bash', 'bash')])])
def test_get_rules(monkeypatch, conf_rules, rules):
monkeypatch.setattr(
'thefuck.main.Path.glob',
lambda *_: [PosixPath('bash.py'), PosixPath('lisp.py')])
monkeypatch.setattr('thefuck.main.load_source',
lambda x, _: Mock(match=x, get_new_command=x,
enabled_by_default=True))
assert list(main.get_rules(Path('~'), Mock(rules=conf_rules))) == rules
def test_get_command():
with patch('thefuck.main.Popen') as Popen, \
patch('thefuck.main.os.environ',
new_callable=lambda: {}), \
patch('thefuck.main.wait_output',
return_value=True):
class TestGetCommand(object):
@pytest.fixture(autouse=True)
def Popen(self, monkeypatch):
Popen = Mock()
Popen.return_value.stdout.read.return_value = b'stdout'
Popen.return_value.stderr.read.return_value = b'stderr'
monkeypatch.setattr('thefuck.main.Popen', Popen)
return Popen
@pytest.fixture(autouse=True)
def prepare(self, monkeypatch):
monkeypatch.setattr('thefuck.main.os.environ', {})
monkeypatch.setattr('thefuck.main.wait_output', lambda *_: True)
def test_get_command_calls(self, Popen):
assert main.get_command(Mock(), Mock(),
['thefuck', 'apt-get', 'search', 'vim']) \
== Command('apt-get search vim', 'stdout', 'stderr')
@ -54,81 +59,113 @@ def test_get_command():
stdout=PIPE,
stderr=PIPE,
env={'LANG': 'C'})
assert main.get_command(Mock(), Mock(), ['']) is None
# When command is `fuck`:
assert main.get_command(
Mock(),
Mock(last_script='ls', last_fixed_script='ls -la'),
['thefuck', 'fuck']).script == 'ls -la'
# When command equals to last command:
assert main.get_command(
Mock(),
Mock(last_script='ls', last_fixed_script='ls -la'),
['thefuck', 'ls']).script == 'ls -la'
# When last command is `fuck` and no last fixed script:
assert main.get_command(
Mock(),
Mock(last_script='ls', last_fixed_script=''),
['thefuck', 'ls']).script == 'ls'
@pytest.mark.parametrize('history, args, result', [
(Mock(), [''], None),
(Mock(last_script='ls', last_fixed_script='ls -la'),
['thefuck', 'fuck'], 'ls -la'),
(Mock(last_script='ls', last_fixed_script='ls -la'),
['thefuck', 'ls'], 'ls -la'),
(Mock(last_script='ls', last_fixed_script=''),
['thefuck', 'ls'], 'ls'),
(Mock(last_script='ls', last_fixed_script=''),
['thefuck', 'fuck'], 'ls')])
def test_get_command_script(self, history, args, result):
if result:
assert main.get_command(Mock(), history, args).script == result
else:
assert main.get_command(Mock(), history, args) is None
def test_get_matched_rule(capsys):
rules = [Rule('', lambda x, _: x.script == 'cd ..'),
class TestGetMatchedRule(object):
@pytest.fixture
def rules(self):
return [Rule('', lambda x, _: x.script == 'cd ..'),
Rule('', lambda *_: False),
Rule('rule', Mock(side_effect=OSError('Denied')))]
assert main.get_matched_rule(Command('ls'),
rules, Mock(no_colors=True)) is None
assert main.get_matched_rule(Command('cd ..'),
rules, Mock(no_colors=True)) == rules[0]
assert capsys.readouterr()[1].split('\n')[0] \
== '[WARN] Rule rule:'
def test_no_match(self):
assert main.get_matched_rule(
Command('ls'), [Rule('', lambda *_: False)],
Mock(no_colors=True)) is None
def test_match(self):
rule = Rule('', lambda x, _: x.script == 'cd ..')
assert main.get_matched_rule(
Command('cd ..'), [rule], Mock(no_colors=True)) == rule
def test_when_rule_failed(self, capsys):
main.get_matched_rule(
Command('ls'), [Rule('test', Mock(side_effect=OSError('Denied')))],
Mock(no_colors=True))
assert capsys.readouterr()[1].split('\n')[0] == '[WARN] Rule test:'
def test_run_rule(capsys):
with patch('thefuck.main.confirm', return_value=True):
class TestRunRule(object):
@pytest.fixture(autouse=True)
def confirm(self, monkeypatch):
mock = Mock(return_value=True)
monkeypatch.setattr('thefuck.main.confirm', mock)
return mock
def test_run_rule(self, capsys):
main.run_rule(Rule(get_new_command=lambda *_: 'new-command'),
Command(), Mock(), None)
assert capsys.readouterr() == ('new-command\n', '')
# With side effect:
def test_run_rule_with_side_effect(self, capsys):
side_effect = Mock()
settings = Mock()
command = Mock(script='ls')
history = Mock()
command = Command()
main.run_rule(Rule(get_new_command=lambda *_: 'new-command',
side_effect=side_effect),
command, history, settings)
command, Mock(), settings)
assert capsys.readouterr() == ('new-command\n', '')
side_effect.assert_called_once_with(command, settings)
# Ensure that history updated:
def test_hisotry_updated(self):
history = Mock()
main.run_rule(Rule(get_new_command=lambda *_: 'ls -lah'),
Command('ls'), history, None)
history.update.assert_called_once_with(last_script='ls',
last_fixed_script='new-command')
with patch('thefuck.main.confirm', return_value=False):
last_fixed_script='ls -lah')
def test_when_not_comfirmed(self, capsys, confirm):
confirm.return_value = False
main.run_rule(Rule(get_new_command=lambda *_: 'new-command'),
Command(), Mock(), None)
assert capsys.readouterr() == ('', '')
def test_confirm(capsys):
# When confirmation not required:
class TestConfirm(object):
@pytest.fixture
def stdin(self, monkeypatch):
mock = Mock(return_value='\n')
monkeypatch.setattr('sys.stdin.read', mock)
return mock
def test_when_not_required(self, capsys):
assert main.confirm('command', None, Mock(require_confirmation=False))
assert capsys.readouterr() == ('', 'command\n')
# With side effect and without confirmation:
def test_with_side_effect_and_without_confirmation(self, capsys):
assert main.confirm('command', Mock(), Mock(require_confirmation=False))
assert capsys.readouterr() == ('', 'command*\n')
# When confirmation required and confirmed:
with patch('thefuck.main.sys.stdin.read', return_value='\n'):
assert main.confirm(
'command', None, Mock(require_confirmation=True,
# `stdin` fixture should be applied after `capsys`
def test_when_confirmation_required_and_confirmed(self, capsys, stdin):
assert main.confirm('command', None, Mock(require_confirmation=True,
no_colors=True))
assert capsys.readouterr() == ('', 'command [enter/ctrl+c]')
# With side effect:
assert main.confirm(
'command', Mock(), Mock(require_confirmation=True,
# `stdin` fixture should be applied after `capsys`
def test_when_confirmation_required_and_confirmed_with_side_effect(self, capsys, stdin):
assert main.confirm('command', Mock(), Mock(require_confirmation=True,
no_colors=True))
assert capsys.readouterr() == ('', 'command* [enter/ctrl+c]')
# When confirmation required and ctrl+c:
with patch('thefuck.main.sys.stdin.read', side_effect=KeyboardInterrupt):
assert not main.confirm('command', None,
Mock(require_confirmation=True,
def test_when_confirmation_required_and_aborted(self, capsys, stdin):
stdin.side_effect = KeyboardInterrupt
assert not main.confirm('command', None, Mock(require_confirmation=True,
no_colors=True))
assert capsys.readouterr() == ('', 'command [enter/ctrl+c]Aborted\n')

View File

@ -1,26 +1,26 @@
import pytest
from mock import Mock
from thefuck.utils import sudo_support, wrap_settings
from thefuck.types import Settings
from tests.utils import Command
def test_wrap_settings():
@pytest.mark.parametrize('override, old, new', [
({'key': 'val'}, {}, {'key': 'val'}),
({'key': 'new-val'}, {'key': 'val'}, {'key': 'new-val'})])
def test_wrap_settings(override, old, new):
fn = lambda _, settings: settings
assert wrap_settings({'key': 'val'})(fn)(None, Settings({})) \
== {'key': 'val'}
assert wrap_settings({'key': 'new-val'})(fn)(
None, Settings({'key': 'val'})) == {'key': 'new-val'}
assert wrap_settings(override)(fn)(None, Settings(old)) == new
def test_sudo_support():
fn = Mock(return_value=True, __name__='')
assert sudo_support(fn)(Command('sudo ls'), None)
fn.assert_called_once_with(Command('ls'), None)
fn.return_value = False
assert not sudo_support(fn)(Command('sudo ls'), None)
fn.return_value = 'pwd'
assert sudo_support(fn)(Command('sudo ls'), None) == 'sudo pwd'
assert sudo_support(fn)(Command('ls'), None) == 'pwd'
@pytest.mark.parametrize('return_value, command, called, result', [
('ls -lah', 'sudo ls', 'ls', 'sudo ls -lah'),
('ls -lah', 'ls', 'ls', 'ls -lah'),
(True, 'sudo ls', 'ls', True),
(True, 'ls', 'ls', True),
(False, 'sudo ls', 'ls', False),
(False, 'ls', 'ls', False)])
def test_sudo_support(return_value, command, called, result):
fn = Mock(return_value=return_value, __name__='')
assert sudo_support(fn)(Command(command), None) == result
fn.assert_called_once_with(Command(called), None)