1
0
mirror of https://github.com/nvbn/thefuck.git synced 2025-02-07 05:31:18 +00:00

Merge pull request #364 from nvbn/global-settings

Don't pass `settings` explicitly
This commit is contained in:
Vladimir Iakovlev 2015-09-07 19:09:31 +03:00
commit 293f16c3c8
164 changed files with 740 additions and 671 deletions

View File

@ -226,20 +226,21 @@ For adding your own rule you should create `your-rule-name.py`
in `~/.thefuck/rules`. The rule should contain two functions: in `~/.thefuck/rules`. The rule should contain two functions:
```python ```python
match(command: Command, settings: Settings) -> bool match(command: Command) -> bool
get_new_command(command: Command, settings: Settings) -> str | list[str] get_new_command(command: Command) -> str | list[str]
``` ```
Also the rule can contain an optional function Also the rule can contain an optional function
```python ```python
side_effect(old_command: Command, fixed_command: str, settings: Settings) -> None side_effect(old_command: Command, fixed_command: str) -> None
``` ```
and optional `enabled_by_default`, `requires_output` and `priority` variables. and optional `enabled_by_default`, `requires_output` and `priority` variables.
`Command` has three attributes: `script`, `stdout` and `stderr`. `Command` has three attributes: `script`, `stdout` and `stderr`.
`Settings` is a special object filled with `~/.thefuck/settings.py` and values from env ([see more below](#settings)). *Rules api changed in 3.0:* For accessing settings in rule you need to import it with `from thefuck.conf import settings`.
`settings` is a special object filled with `~/.thefuck/settings.py` and values from env ([see more below](#settings)).
Simple example of the rule for running script with `sudo`: Simple example of the rule for running script with `sudo`:
@ -264,7 +265,8 @@ requires_output = True
``` ```
[More examples of rules](https://github.com/nvbn/thefuck/tree/master/thefuck/rules), [More examples of rules](https://github.com/nvbn/thefuck/tree/master/thefuck/rules),
[utility functions for rules](https://github.com/nvbn/thefuck/tree/master/thefuck/utils.py). [utility functions for rules](https://github.com/nvbn/thefuck/tree/master/thefuck/utils.py),
[app/os-specific helpers](https://github.com/nvbn/thefuck/tree/master/thefuck/specific/).
## Settings ## Settings

View File

@ -1,5 +1,6 @@
from pathlib import Path
import pytest import pytest
from mock import Mock from thefuck import conf
def pytest_addoption(parser): def pytest_addoption(parser):
@ -14,9 +15,20 @@ def no_memoize(monkeypatch):
monkeypatch.setattr('thefuck.utils.memoize.disabled', True) monkeypatch.setattr('thefuck.utils.memoize.disabled', True)
@pytest.fixture(autouse=True)
def settings(request):
def _reset_settings():
conf.settings.clear()
conf.settings.update(conf.DEFAULT_SETTINGS)
request.addfinalizer(_reset_settings)
conf.settings.user_dir = Path('~/.thefuck')
return conf.settings
@pytest.fixture @pytest.fixture
def settings(): def no_colors(settings):
return Mock(debug=False, no_colors=True) settings.no_colors = True
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)

View File

@ -11,7 +11,7 @@ from tests.utils import Command
@pytest.mark.parametrize('command', [ @pytest.mark.parametrize('command', [
Command(script='vim', stderr='vim: command not found')]) Command(script='vim', stderr='vim: command not found')])
def test_match(command): def test_match(command):
assert match(command, None) assert match(command)
@pytest.mark.parametrize('command, return_value', [ @pytest.mark.parametrize('command, return_value', [
@ -24,7 +24,7 @@ def test_match(command):
def test_match_mocked(cmdnf_mock, command, return_value): def test_match_mocked(cmdnf_mock, command, return_value):
get_packages = Mock(return_value=return_value) get_packages = Mock(return_value=return_value)
cmdnf_mock.CommandNotFound.return_value = Mock(getPackages=get_packages) cmdnf_mock.CommandNotFound.return_value = Mock(getPackages=get_packages)
assert match(command, None) assert match(command)
assert cmdnf_mock.CommandNotFound.called assert cmdnf_mock.CommandNotFound.called
assert get_packages.called assert get_packages.called
@ -32,7 +32,7 @@ def test_match_mocked(cmdnf_mock, command, return_value):
@pytest.mark.parametrize('command', [ @pytest.mark.parametrize('command', [
Command(script='vim', stderr=''), Command()]) Command(script='vim', stderr=''), Command()])
def test_not_match(command): def test_not_match(command):
assert not match(command, None) assert not match(command)
# python-commandnotfound is available in ubuntu 14.04+ # python-commandnotfound is available in ubuntu 14.04+
@ -44,7 +44,7 @@ def test_not_match(command):
(Command('sudo vim'), 'sudo apt-get install vim && sudo vim'), (Command('sudo vim'), 'sudo apt-get install vim && sudo vim'),
(Command('sudo convert'), 'sudo apt-get install imagemagick && sudo convert')]) (Command('sudo convert'), 'sudo apt-get install imagemagick && sudo convert')])
def test_get_new_command(command, new_command): def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command assert get_new_command(command) == new_command
@pytest.mark.parametrize('command, new_command, return_value', [ @pytest.mark.parametrize('command, new_command, return_value', [
@ -63,4 +63,4 @@ def test_get_new_command(command, new_command):
def test_get_new_command_mocked(cmdnf_mock, command, new_command, return_value): def test_get_new_command_mocked(cmdnf_mock, command, new_command, return_value):
get_packages = Mock(return_value=return_value) get_packages = Mock(return_value=return_value)
cmdnf_mock.CommandNotFound.return_value = Mock(getPackages=get_packages) cmdnf_mock.CommandNotFound.return_value = Mock(getPackages=get_packages)
assert get_new_command(command, None) == new_command assert get_new_command(command) == new_command

View File

@ -4,7 +4,7 @@ from tests.utils import Command
def test_match(): def test_match():
assert match(Command('apt-get search foo'), None) assert match(Command('apt-get search foo'))
@pytest.mark.parametrize('command', [ @pytest.mark.parametrize('command', [
@ -18,8 +18,8 @@ def test_match():
Command('apt-get update') Command('apt-get update')
]) ])
def test_not_match(command): def test_not_match(command):
assert not match(command, None) assert not match(command)
def test_get_new_command(): def test_get_new_command():
assert get_new_command(Command('apt-get search foo'), None) == 'apt-cache search foo' assert get_new_command(Command('apt-get search foo')) == 'apt-cache search foo'

View File

@ -28,9 +28,9 @@ def _is_not_okay_to_test():
def test_match(brew_no_available_formula, brew_already_installed, def test_match(brew_no_available_formula, brew_already_installed,
brew_install_no_argument): brew_install_no_argument):
assert match(Command('brew install elsticsearch', assert match(Command('brew install elsticsearch',
stderr=brew_no_available_formula), None) stderr=brew_no_available_formula))
assert not match(Command('brew install git', assert not match(Command('brew install git',
stderr=brew_already_installed), None) stderr=brew_already_installed))
assert not match(Command('brew install', stderr=brew_install_no_argument), assert not match(Command('brew install', stderr=brew_install_no_argument),
None) None)
@ -39,7 +39,7 @@ def test_match(brew_no_available_formula, brew_already_installed,
reason='No need to run if there\'s no formula') reason='No need to run if there\'s no formula')
def test_get_new_command(brew_no_available_formula): def test_get_new_command(brew_no_available_formula):
assert get_new_command(Command('brew install elsticsearch', assert get_new_command(Command('brew install elsticsearch',
stderr=brew_no_available_formula), None)\ stderr=brew_no_available_formula))\
== 'brew install elasticsearch' == 'brew install elasticsearch'
assert get_new_command(Command('brew install aa', assert get_new_command(Command('brew install aa',

View File

@ -15,15 +15,15 @@ def brew_unknown_cmd2():
def test_match(brew_unknown_cmd): def test_match(brew_unknown_cmd):
assert match(Command('brew inst', stderr=brew_unknown_cmd), None) assert match(Command('brew inst', stderr=brew_unknown_cmd))
for command in _brew_commands(): for command in _brew_commands():
assert not match(Command('brew ' + command), None) assert not match(Command('brew ' + command))
def test_get_new_command(brew_unknown_cmd, brew_unknown_cmd2): def test_get_new_command(brew_unknown_cmd, brew_unknown_cmd2):
assert get_new_command(Command('brew inst', stderr=brew_unknown_cmd), assert get_new_command(Command('brew inst', stderr=brew_unknown_cmd)) \
None) == ['brew list', 'brew install', 'brew uninstall'] == ['brew list', 'brew install', 'brew uninstall']
cmds = get_new_command(Command('brew instaa', stderr=brew_unknown_cmd2), None) cmds = get_new_command(Command('brew instaa', stderr=brew_unknown_cmd2))
assert 'brew install' in cmds assert 'brew install' in cmds
assert 'brew uninstall' in cmds assert 'brew uninstall' in cmds

View File

@ -6,10 +6,10 @@ from tests.utils import Command
@pytest.mark.parametrize('command', [ @pytest.mark.parametrize('command', [
Command(script='brew upgrade')]) Command(script='brew upgrade')])
def test_match(command): def test_match(command):
assert match(command, None) assert match(command)
@pytest.mark.parametrize('command, new_command', [ @pytest.mark.parametrize('command, new_command', [
(Command('brew upgrade'), 'brew upgrade --all')]) (Command('brew upgrade'), 'brew upgrade --all')])
def test_get_new_command(command, new_command): def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command assert get_new_command(command) == new_command

View File

@ -12,10 +12,10 @@ no_such_subcommand = """No such subcommand
@pytest.mark.parametrize('command', [ @pytest.mark.parametrize('command', [
Command(script='cargo buid', stderr=no_such_subcommand)]) Command(script='cargo buid', stderr=no_such_subcommand)])
def test_match(command): def test_match(command):
assert match(command, None) assert match(command)
@pytest.mark.parametrize('command, new_command', [ @pytest.mark.parametrize('command, new_command', [
(Command('cargo buid', stderr=no_such_subcommand), 'cargo build')]) (Command('cargo buid', stderr=no_such_subcommand), 'cargo build')])
def test_get_new_command(command, new_command): def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command assert get_new_command(command) == new_command

View File

@ -9,17 +9,17 @@ from tests.utils import Command
stderr='cd: foo: No such file or directory'), stderr='cd: foo: No such file or directory'),
Command(script='cd foo/bar/baz', stderr='cd: can\'t cd to foo/bar/baz')]) Command(script='cd foo/bar/baz', stderr='cd: can\'t cd to foo/bar/baz')])
def test_match(command): def test_match(command):
assert match(command, None) assert match(command)
@pytest.mark.parametrize('command', [ @pytest.mark.parametrize('command', [
Command(script='cd foo', stderr=''), Command()]) Command(script='cd foo', stderr=''), Command()])
def test_not_match(command): def test_not_match(command):
assert not match(command, None) assert not match(command)
@pytest.mark.parametrize('command, new_command', [ @pytest.mark.parametrize('command, new_command', [
(Command('cd foo'), 'mkdir -p foo && cd foo'), (Command('cd foo'), 'mkdir -p foo && cd foo'),
(Command('cd foo/bar/baz'), 'mkdir -p foo/bar/baz && cd foo/bar/baz')]) (Command('cd foo/bar/baz'), 'mkdir -p foo/bar/baz && cd foo/bar/baz')])
def test_get_new_command(command, new_command): def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command assert get_new_command(command) == new_command

View File

@ -3,10 +3,10 @@ from tests.utils import Command
def test_match(): def test_match():
assert match(Command('cd..', stderr='cd..: command not found'), None) assert match(Command('cd..', stderr='cd..: command not found'))
assert not match(Command(), None) assert not match(Command())
def test_get_new_command(): def test_get_new_command():
assert get_new_command( assert get_new_command(
Command('cd..'), None) == 'cd ..' Command('cd..')) == 'cd ..'

View File

@ -41,17 +41,16 @@ def composer_not_command_one_of_this():
def test_match(composer_not_command, composer_not_command_one_of_this): def test_match(composer_not_command, composer_not_command_one_of_this):
assert match(Command('composer udpate', assert match(Command('composer udpate',
stderr=composer_not_command), None) stderr=composer_not_command))
assert match(Command('composer pdate', assert match(Command('composer pdate',
stderr=composer_not_command_one_of_this), None) stderr=composer_not_command_one_of_this))
assert not match(Command('ls update', stderr=composer_not_command), assert not match(Command('ls update', stderr=composer_not_command))
None)
def test_get_new_command(composer_not_command, composer_not_command_one_of_this): def test_get_new_command(composer_not_command, composer_not_command_one_of_this):
assert get_new_command(Command('composer udpate', assert get_new_command(Command('composer udpate',
stderr=composer_not_command), None) \ stderr=composer_not_command)) \
== 'composer update' == 'composer update'
assert get_new_command( assert get_new_command(
Command('composer pdate', stderr=composer_not_command_one_of_this), Command('composer pdate', stderr=composer_not_command_one_of_this)) \
None) == 'composer selfupdate' == 'composer selfupdate'

View File

@ -7,7 +7,7 @@ from tests.utils import Command
('cp dir', 'cp: dor: is a directory'), ('cp dir', 'cp: dor: is a directory'),
('cp dir', "cp: omitting directory 'dir'")]) ('cp dir', "cp: omitting directory 'dir'")])
def test_match(script, stderr): def test_match(script, stderr):
assert match(Command(script, stderr=stderr), None) assert match(Command(script, stderr=stderr))
@pytest.mark.parametrize('script, stderr', [ @pytest.mark.parametrize('script, stderr', [
@ -15,8 +15,8 @@ def test_match(script, stderr):
('some dir', "cp: omitting directory 'dir'"), ('some dir', "cp: omitting directory 'dir'"),
('cp dir', '')]) ('cp dir', '')])
def test_not_match(script, stderr): def test_not_match(script, stderr):
assert not match(Command(script, stderr=stderr), None) assert not match(Command(script, stderr=stderr))
def test_get_new_command(): def test_get_new_command():
assert get_new_command(Command(script='cp dir'), None) == 'cp -a dir' assert get_new_command(Command(script='cp dir')) == 'cp -a dir'

View File

@ -45,14 +45,14 @@ parametrize_script = pytest.mark.parametrize('script, fixed', [
@parametrize_script @parametrize_script
def test_match(tar_error, filename, script, fixed): def test_match(tar_error, filename, script, fixed):
tar_error(filename) tar_error(filename)
assert match(Command(script=script.format(filename)), None) assert match(Command(script=script.format(filename)))
@parametrize_filename @parametrize_filename
@parametrize_script @parametrize_script
def test_side_effect(tar_error, filename, script, fixed): def test_side_effect(tar_error, filename, script, fixed):
tar_error(filename) tar_error(filename)
side_effect(Command(script=script.format(filename)), None, None) side_effect(Command(script=script.format(filename)), None)
assert(os.listdir('.') == [filename]) assert(os.listdir('.') == [filename])
@ -60,4 +60,4 @@ def test_side_effect(tar_error, filename, script, fixed):
@parametrize_script @parametrize_script
def test_get_new_command(tar_error, filename, script, fixed): def test_get_new_command(tar_error, filename, script, fixed):
tar_error(filename) tar_error(filename)
assert get_new_command(Command(script=script.format(filename)), None) == fixed.format(filename) assert get_new_command(Command(script=script.format(filename))) == fixed.format(filename)

View File

@ -27,14 +27,14 @@ def zip_error(tmpdir):
'unzip foo', 'unzip foo',
'unzip foo.zip']) 'unzip foo.zip'])
def test_match(zip_error, script): def test_match(zip_error, script):
assert match(Command(script=script), None) assert match(Command(script=script))
@pytest.mark.parametrize('script', [ @pytest.mark.parametrize('script', [
'unzip foo', 'unzip foo',
'unzip foo.zip']) 'unzip foo.zip'])
def test_side_effect(zip_error, script): def test_side_effect(zip_error, script):
side_effect(Command(script=script), None, None) side_effect(Command(script=script), None)
assert(os.listdir('.') == ['foo.zip']) assert(os.listdir('.') == ['foo.zip'])
@ -42,4 +42,4 @@ def test_side_effect(zip_error, script):
('unzip foo', 'unzip foo -d foo'), ('unzip foo', 'unzip foo -d foo'),
('unzip foo.zip', 'unzip foo.zip -d foo')]) ('unzip foo.zip', 'unzip foo.zip -d foo')])
def test_get_new_command(zip_error, script, fixed): def test_get_new_command(zip_error, script, fixed):
assert get_new_command(Command(script=script), None) == fixed assert get_new_command(Command(script=script)) == fixed

View File

@ -41,13 +41,13 @@ south.exceptions.GhostMigrations:
def test_match(stderr): def test_match(stderr):
assert match(Command('./manage.py migrate', stderr=stderr), None) assert match(Command('./manage.py migrate', stderr=stderr))
assert match(Command('python manage.py migrate', stderr=stderr), None) assert match(Command('python manage.py migrate', stderr=stderr))
assert not match(Command('./manage.py migrate'), None) assert not match(Command('./manage.py migrate'))
assert not match(Command('app migrate', stderr=stderr), None) assert not match(Command('app migrate', stderr=stderr))
assert not match(Command('./manage.py test', stderr=stderr), None) assert not match(Command('./manage.py test', stderr=stderr))
def test_get_new_command(): def test_get_new_command():
assert get_new_command(Command('./manage.py migrate auth'), None)\ assert get_new_command(Command('./manage.py migrate auth'))\
== './manage.py migrate auth --delete-ghost-migrations' == './manage.py migrate auth --delete-ghost-migrations'

View File

@ -31,13 +31,13 @@ The following options are available:
def test_match(stderr): def test_match(stderr):
assert match(Command('./manage.py migrate', stderr=stderr), None) assert match(Command('./manage.py migrate', stderr=stderr))
assert match(Command('python manage.py migrate', stderr=stderr), None) assert match(Command('python manage.py migrate', stderr=stderr))
assert not match(Command('./manage.py migrate'), None) assert not match(Command('./manage.py migrate'))
assert not match(Command('app migrate', stderr=stderr), None) assert not match(Command('app migrate', stderr=stderr))
assert not match(Command('./manage.py test', stderr=stderr), None) assert not match(Command('./manage.py test', stderr=stderr))
def test_get_new_command(): def test_get_new_command():
assert get_new_command(Command('./manage.py migrate auth'), None) \ assert get_new_command(Command('./manage.py migrate auth')) \
== './manage.py migrate auth --merge' == './manage.py migrate auth --merge'

View File

@ -110,14 +110,14 @@ def stderr(cmd):
def test_match(): def test_match():
assert match(Command('docker pes', stderr=stderr('pes')), None) assert match(Command('docker pes', stderr=stderr('pes')))
@pytest.mark.parametrize('script, stderr', [ @pytest.mark.parametrize('script, stderr', [
('docker ps', ''), ('docker ps', ''),
('cat pes', stderr('pes'))]) ('cat pes', stderr('pes'))])
def test_not_match(script, stderr): def test_not_match(script, stderr):
assert not match(Command(script, stderr=stderr), None) assert not match(Command(script, stderr=stderr))
@pytest.mark.usefixtures('docker_help') @pytest.mark.usefixtures('docker_help')
@ -126,4 +126,4 @@ def test_not_match(script, stderr):
('tags', ['tag', 'stats', 'images'])]) ('tags', ['tag', 'stats', 'images'])])
def test_get_new_command(wrong, fixed): def test_get_new_command(wrong, fixed):
command = Command('docker {}'.format(wrong), stderr=stderr(wrong)) command = Command('docker {}'.format(wrong), stderr=stderr(wrong))
assert get_new_command(command, None) == ['docker {}'.format(x) for x in fixed] assert get_new_command(command) == ['docker {}'.format(x) for x in fixed]

View File

@ -7,11 +7,11 @@ from tests.utils import Command
Command(script='cd cd foo'), Command(script='cd cd foo'),
Command(script='git git push origin/master')]) Command(script='git git push origin/master')])
def test_match(command): def test_match(command):
assert match(command, None) assert match(command)
@pytest.mark.parametrize('command, new_command', [ @pytest.mark.parametrize('command, new_command', [
(Command('cd cd foo'), 'cd foo'), (Command('cd cd foo'), 'cd foo'),
(Command('git git push origin/master'), 'git push origin/master')]) (Command('git git push origin/master'), 'git push origin/master')])
def test_get_new_command(command, new_command): def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command assert get_new_command(command) == new_command

View File

@ -11,12 +11,12 @@ def test_match():
""" """
assert match(Command(u'ps -ef | grep foo', assert match(Command(u'ps -ef | grep foo',
stderr=u'-bash:  grep: command not found'), None) stderr=u'-bash:  grep: command not found'))
assert not match(Command('ps -ef | grep foo'), None) assert not match(Command('ps -ef | grep foo'))
assert not match(Command(), None) assert not match(Command())
def test_get_new_command(): def test_get_new_command():
""" Replace the Alt+Space character by a simple space """ """ Replace the Alt+Space character by a simple space """
assert get_new_command(Command(u'ps -ef | grep foo'), None)\ assert get_new_command(Command(u'ps -ef | grep foo'))\
== 'ps -ef | grep foo' == 'ps -ef | grep foo'

View File

@ -184,7 +184,7 @@ E NameError: name 'mocker' is not defined
def test_match(mocker, monkeypatch, test): def test_match(mocker, monkeypatch, test):
mocker.patch('os.path.isfile', return_value=True) mocker.patch('os.path.isfile', return_value=True)
monkeypatch.setenv('EDITOR', 'dummy_editor') monkeypatch.setenv('EDITOR', 'dummy_editor')
assert match(Command(stdout=test[4], stderr=test[5]), None) assert match(Command(stdout=test[4], stderr=test[5]))
@pytest.mark.parametrize('test', tests) @pytest.mark.parametrize('test', tests)
@ -194,7 +194,7 @@ def test_no_editor(mocker, monkeypatch, test):
if 'EDITOR' in os.environ: if 'EDITOR' in os.environ:
monkeypatch.delenv('EDITOR') monkeypatch.delenv('EDITOR')
assert not match(Command(stdout=test[4], stderr=test[5]), None) assert not match(Command(stdout=test[4], stderr=test[5]))
@pytest.mark.parametrize('test', tests) @pytest.mark.parametrize('test', tests)
@ -203,7 +203,7 @@ def test_not_file(mocker, monkeypatch, test):
mocker.patch('os.path.isfile', return_value=False) mocker.patch('os.path.isfile', return_value=False)
monkeypatch.setenv('EDITOR', 'dummy_editor') monkeypatch.setenv('EDITOR', 'dummy_editor')
assert not match(Command(stdout=test[4], stderr=test[5]), None) assert not match(Command(stdout=test[4], stderr=test[5]))
@pytest.mark.parametrize('test', tests) @pytest.mark.parametrize('test', tests)
@ -219,16 +219,16 @@ def test_get_new_command(mocker, monkeypatch, test):
@pytest.mark.parametrize('test', tests) @pytest.mark.parametrize('test', tests)
@pytest.mark.usefixtures('no_memoize') @pytest.mark.usefixtures('no_memoize')
def test_get_new_command_with_settings(mocker, monkeypatch, test): def test_get_new_command_with_settings(mocker, monkeypatch, test, settings):
mocker.patch('os.path.isfile', return_value=True) mocker.patch('os.path.isfile', return_value=True)
monkeypatch.setenv('EDITOR', 'dummy_editor') monkeypatch.setenv('EDITOR', 'dummy_editor')
cmd = Command(script=test[0], stdout=test[4], stderr=test[5]) cmd = Command(script=test[0], stdout=test[4], stderr=test[5])
settings = Settings({'fixcolcmd': '{editor} {file} +{line}:{col}'}) settings.fixcolcmd = '{editor} {file} +{line}:{col}'
if test[3]: if test[3]:
assert (get_new_command(cmd, settings) == assert (get_new_command(cmd) ==
'dummy_editor {} +{}:{} && {}'.format(test[1], test[2], test[3], test[0])) 'dummy_editor {} +{}:{} && {}'.format(test[1], test[2], test[3], test[0]))
else: else:
assert (get_new_command(cmd, settings) == assert (get_new_command(cmd) ==
'dummy_editor {} +{} && {}'.format(test[1], test[2], test[0])) 'dummy_editor {} +{} && {}'.format(test[1], test[2], test[0]))

View File

@ -18,7 +18,7 @@ def did_not_match(target, did_you_forget=True):
Command(script='git commit unknown', Command(script='git commit unknown',
stderr=did_not_match('unknown'))]) # Older versions of Git stderr=did_not_match('unknown'))]) # Older versions of Git
def test_match(command): def test_match(command):
assert match(command, None) assert match(command)
@pytest.mark.parametrize('command', [ @pytest.mark.parametrize('command', [
@ -27,7 +27,7 @@ def test_match(command):
Command(script='git commit unknown', # Newer versions of Git Command(script='git commit unknown', # Newer versions of Git
stderr=did_not_match('unknown', False))]) stderr=did_not_match('unknown', False))])
def test_not_match(command): def test_not_match(command):
assert not match(command, None) assert not match(command)
@pytest.mark.parametrize('command, new_command', [ @pytest.mark.parametrize('command, new_command', [
@ -36,4 +36,4 @@ def test_not_match(command):
(Command('git commit unknown', stderr=did_not_match('unknown')), # Old Git (Command('git commit unknown', stderr=did_not_match('unknown')), # Old Git
'git add -- unknown && git commit unknown')]) 'git add -- unknown && git commit unknown')])
def test_get_new_command(command, new_command): def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command assert get_new_command(command) == new_command

View File

@ -12,11 +12,11 @@ If you are sure you want to delete it, run 'git branch -D branch'.
def test_match(stderr): def test_match(stderr):
assert match(Command('git branch -d branch', stderr=stderr), None) assert match(Command('git branch -d branch', stderr=stderr))
assert not match(Command('git branch -d branch'), None) assert not match(Command('git branch -d branch'))
assert not match(Command('ls', stderr=stderr), None) assert not match(Command('ls', stderr=stderr))
def test_get_new_command(stderr): def test_get_new_command(stderr):
assert get_new_command(Command('git branch -d branch', stderr=stderr), None)\ assert get_new_command(Command('git branch -d branch', stderr=stderr))\
== "git branch -D branch" == "git branch -D branch"

View File

@ -4,16 +4,16 @@ from tests.utils import Command
def test_match(): def test_match():
assert match(Command('git branch list'), None) assert match(Command('git branch list'))
def test_not_match(): def test_not_match():
assert not match(Command(), None) assert not match(Command())
assert not match(Command('git commit'), None) assert not match(Command('git commit'))
assert not match(Command('git branch'), None) assert not match(Command('git branch'))
assert not match(Command('git stash list'), None) assert not match(Command('git stash list'))
def test_get_new_command(): def test_get_new_command():
assert (get_new_command(Command('git branch list'), None) == assert (get_new_command(Command('git branch list')) ==
shells.and_('git branch --delete list', 'git branch')) shells.and_('git branch --delete list', 'git branch'))

View File

@ -21,7 +21,7 @@ def get_branches(mocker):
Command(script='git checkout unknown', stderr=did_not_match('unknown')), Command(script='git checkout unknown', stderr=did_not_match('unknown')),
Command(script='git commit unknown', stderr=did_not_match('unknown'))]) Command(script='git commit unknown', stderr=did_not_match('unknown'))])
def test_match(command): def test_match(command):
assert match(command, None) assert match(command)
@pytest.mark.parametrize('command', [ @pytest.mark.parametrize('command', [
@ -30,7 +30,7 @@ def test_match(command):
Command(script='git checkout known', stderr=('')), Command(script='git checkout known', stderr=('')),
Command(script='git commit known', stderr=(''))]) Command(script='git commit known', stderr=(''))])
def test_not_match(command): def test_not_match(command):
assert not match(command, None) assert not match(command)
@pytest.mark.parametrize('branches, command, new_command', [ @pytest.mark.parametrize('branches, command, new_command', [
@ -50,4 +50,4 @@ def test_not_match(command):
'git commit test-random-branch-123')]) 'git commit test-random-branch-123')])
def test_get_new_command(branches, command, new_command, get_branches): def test_get_new_command(branches, command, new_command, get_branches):
get_branches.return_value = branches get_branches.return_value = branches
assert get_new_command(command, None) == new_command assert get_new_command(command) == new_command

View File

@ -7,7 +7,7 @@ from tests.utils import Command
Command(script='git diff foo'), Command(script='git diff foo'),
Command(script='git diff')]) Command(script='git diff')])
def test_match(command): def test_match(command):
assert match(command, None) assert match(command)
@pytest.mark.parametrize('command', [ @pytest.mark.parametrize('command', [
@ -16,11 +16,11 @@ def test_match(command):
Command(script='git branch'), Command(script='git branch'),
Command(script='git log')]) Command(script='git log')])
def test_not_match(command): def test_not_match(command):
assert not match(command, None) assert not match(command)
@pytest.mark.parametrize('command, new_command', [ @pytest.mark.parametrize('command, new_command', [
(Command('git diff'), 'git diff --staged'), (Command('git diff'), 'git diff --staged'),
(Command('git diff foo'), 'git diff --staged foo')]) (Command('git diff foo'), 'git diff --staged foo')])
def test_get_new_command(command, new_command): def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command assert get_new_command(command) == new_command

View File

@ -20,7 +20,7 @@ usage: git stash list [<options>]
'git stash Some message', 'git stash Some message',
'git stash saev Some message']) 'git stash saev Some message'])
def test_match(wrong): def test_match(wrong):
assert match(Command(wrong, stderr=git_stash_err), None) assert match(Command(wrong, stderr=git_stash_err))
@pytest.mark.parametrize('wrong,fixed', [ @pytest.mark.parametrize('wrong,fixed', [
@ -28,4 +28,4 @@ def test_match(wrong):
('git stash Some message', 'git stash save Some message'), ('git stash Some message', 'git stash save Some message'),
('git stash saev Some message', 'git stash save Some message')]) ('git stash saev Some message', 'git stash save Some message')])
def test_get_new_command(wrong, fixed): def test_get_new_command(wrong, fixed):
assert get_new_command(Command(wrong, stderr=git_stash_err), None) == fixed assert get_new_command(Command(wrong, stderr=git_stash_err)) == fixed

View File

@ -41,17 +41,17 @@ def git_command():
def test_match(git_not_command, git_command, git_not_command_one_of_this): def test_match(git_not_command, git_command, git_not_command_one_of_this):
assert match(Command('git brnch', stderr=git_not_command), None) assert match(Command('git brnch', stderr=git_not_command))
assert match(Command('git st', stderr=git_not_command_one_of_this), None) assert match(Command('git st', stderr=git_not_command_one_of_this))
assert not match(Command('ls brnch', stderr=git_not_command), None) assert not match(Command('ls brnch', stderr=git_not_command))
assert not match(Command('git branch', stderr=git_command), None) assert not match(Command('git branch', stderr=git_command))
def test_get_new_command(git_not_command, git_not_command_one_of_this, def test_get_new_command(git_not_command, git_not_command_one_of_this,
git_not_command_closest): git_not_command_closest):
assert get_new_command(Command('git brnch', stderr=git_not_command), None) \ assert get_new_command(Command('git brnch', stderr=git_not_command)) \
== ['git branch'] == ['git branch']
assert get_new_command(Command('git st', stderr=git_not_command_one_of_this), assert get_new_command(Command('git st', stderr=git_not_command_one_of_this)) \
None) == ['git stats', 'git stash', 'git stage'] == ['git stats', 'git stash', 'git stage']
assert get_new_command(Command('git tags', stderr=git_not_command_closest), assert get_new_command(Command('git tags', stderr=git_not_command_closest)) \
None) == ['git tag', 'git stage'] == ['git tag', 'git stage']

View File

@ -19,11 +19,11 @@ If you wish to set tracking information for this branch you can do so with:
def test_match(stderr): def test_match(stderr):
assert match(Command('git pull', stderr=stderr), None) assert match(Command('git pull', stderr=stderr))
assert not match(Command('git pull'), None) assert not match(Command('git pull'))
assert not match(Command('ls', stderr=stderr), None) assert not match(Command('ls', stderr=stderr))
def test_get_new_command(stderr): def test_get_new_command(stderr):
assert get_new_command(Command('git pull', stderr=stderr), None) \ assert get_new_command(Command('git pull', stderr=stderr)) \
== "git branch --set-upstream-to=origin/master master && git pull" == "git branch --set-upstream-to=origin/master master && git pull"

View File

@ -12,10 +12,10 @@ Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
@pytest.mark.parametrize('command', [ @pytest.mark.parametrize('command', [
Command(script='git pull git@github.com:mcarton/thefuck.git', stderr=git_err)]) Command(script='git pull git@github.com:mcarton/thefuck.git', stderr=git_err)])
def test_match(command): def test_match(command):
assert match(command, None) assert match(command)
@pytest.mark.parametrize('command, output', [ @pytest.mark.parametrize('command, output', [
(Command(script='git pull git@github.com:mcarton/thefuck.git', stderr=git_err), 'git clone git@github.com:mcarton/thefuck.git')]) (Command(script='git pull git@github.com:mcarton/thefuck.git', stderr=git_err), 'git clone git@github.com:mcarton/thefuck.git')])
def test_get_new_command(command, output): def test_get_new_command(command, output):
assert get_new_command(command, None) == output assert get_new_command(command) == output

View File

@ -14,11 +14,11 @@ To push the current branch and set the remote as upstream, use
def test_match(stderr): def test_match(stderr):
assert match(Command('git push master', stderr=stderr), None) assert match(Command('git push master', stderr=stderr))
assert not match(Command('git push master'), None) assert not match(Command('git push master'))
assert not match(Command('ls', stderr=stderr), None) assert not match(Command('ls', stderr=stderr))
def test_get_new_command(stderr): def test_get_new_command(stderr):
assert get_new_command(Command('git push', stderr=stderr), None)\ assert get_new_command(Command('git push', stderr=stderr))\
== "git push --set-upstream origin master" == "git push --set-upstream origin master"

View File

@ -30,7 +30,7 @@ To /tmp/bar
Command(script='git push nvbn', stderr=git_err), Command(script='git push nvbn', stderr=git_err),
Command(script='git push nvbn master', stderr=git_err)]) Command(script='git push nvbn master', stderr=git_err)])
def test_match(command): def test_match(command):
assert match(command, None) assert match(command)
@pytest.mark.parametrize('command', [ @pytest.mark.parametrize('command', [
@ -41,7 +41,7 @@ def test_match(command):
Command(script='git push nvbn', stderr=git_ok), Command(script='git push nvbn', stderr=git_ok),
Command(script='git push nvbn master', stderr=git_uptodate)]) Command(script='git push nvbn master', stderr=git_uptodate)])
def test_not_match(command): def test_not_match(command):
assert not match(command, None) assert not match(command)
@pytest.mark.parametrize('command, output', [ @pytest.mark.parametrize('command, output', [
@ -49,4 +49,4 @@ def test_not_match(command):
(Command(script='git push nvbn', stderr=git_err), 'git push --force nvbn'), (Command(script='git push nvbn', stderr=git_err), 'git push --force nvbn'),
(Command(script='git push nvbn master', stderr=git_err), 'git push --force nvbn master')]) (Command(script='git push nvbn master', stderr=git_err), 'git push --force nvbn master')])
def test_get_new_command(command, output): def test_get_new_command(command, output):
assert get_new_command(command, None) == output assert get_new_command(command) == output

View File

@ -30,7 +30,7 @@ To /tmp/bar
Command(script='git push nvbn', stderr=git_err), Command(script='git push nvbn', stderr=git_err),
Command(script='git push nvbn master', stderr=git_err)]) Command(script='git push nvbn master', stderr=git_err)])
def test_match(command): def test_match(command):
assert match(command, None) assert match(command)
@pytest.mark.parametrize('command', [ @pytest.mark.parametrize('command', [
@ -41,7 +41,7 @@ def test_match(command):
Command(script='git push nvbn', stderr=git_ok), Command(script='git push nvbn', stderr=git_ok),
Command(script='git push nvbn master', stderr=git_uptodate)]) Command(script='git push nvbn master', stderr=git_uptodate)])
def test_not_match(command): def test_not_match(command):
assert not match(command, None) assert not match(command)
@pytest.mark.parametrize('command, output', [ @pytest.mark.parametrize('command, output', [
@ -51,4 +51,4 @@ def test_not_match(command):
(Command(script='git push nvbn master', stderr=git_err), (Command(script='git push nvbn master', stderr=git_err),
'git pull nvbn master && git push nvbn master')]) 'git pull nvbn master && git push nvbn master')])
def test_get_new_command(command, output): def test_get_new_command(command, output):
assert get_new_command(command, None) == output assert get_new_command(command) == output

View File

@ -18,14 +18,14 @@ rebase_error = (
Command(script='git cherry-pick a1b2c3d', stderr=cherry_pick_error), Command(script='git cherry-pick a1b2c3d', stderr=cherry_pick_error),
Command(script='git rebase -i HEAD~7', stderr=rebase_error)]) Command(script='git rebase -i HEAD~7', stderr=rebase_error)])
def test_match(command): def test_match(command):
assert match(command, None) assert match(command)
@pytest.mark.parametrize('command', [ @pytest.mark.parametrize('command', [
Command(script='git cherry-pick a1b2c3d', stderr=('')), Command(script='git cherry-pick a1b2c3d', stderr=('')),
Command(script='git rebase -i HEAD~7', stderr=(''))]) Command(script='git rebase -i HEAD~7', stderr=(''))])
def test_not_match(command): def test_not_match(command):
assert not match(command, None) assert not match(command)
@pytest.mark.parametrize('command, new_command', [ @pytest.mark.parametrize('command, new_command', [
@ -34,4 +34,4 @@ def test_not_match(command):
(Command('git rebase -i HEAD~7', stderr=rebase_error), (Command('git rebase -i HEAD~7', stderr=rebase_error),
'git stash && git rebase -i HEAD~7')]) 'git stash && git rebase -i HEAD~7')])
def test_get_new_command(command, new_command): def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command assert get_new_command(command) == new_command

View File

@ -7,11 +7,11 @@ from tests.utils import Command
Command(script='go run foo'), Command(script='go run foo'),
Command(script='go run bar')]) Command(script='go run bar')])
def test_match(command): def test_match(command):
assert match(command, None) assert match(command)
@pytest.mark.parametrize('command, new_command', [ @pytest.mark.parametrize('command, new_command', [
(Command('go run foo'), 'go run foo.go'), (Command('go run foo'), 'go run foo.go'),
(Command('go run bar'), 'go run bar.go')]) (Command('go run bar'), 'go run bar.go')])
def test_get_new_command(command, new_command): def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command assert get_new_command(command) == new_command

View File

@ -3,10 +3,10 @@ from tests.utils import Command
def test_match(): def test_match():
assert match(Command('grep blah .', stderr='grep: .: Is a directory'), None) assert match(Command('grep blah .', stderr='grep: .: Is a directory'))
assert not match(Command(), None) assert not match(Command())
def test_get_new_command(): def test_get_new_command():
assert get_new_command( assert get_new_command(
Command('grep blah .'), None) == 'grep -r blah .' Command('grep blah .')) == 'grep -r blah .'

View File

@ -11,18 +11,18 @@ def stdout(task):
def test_match(): def test_match():
assert match(Command('gulp srve', stdout('srve')), None) assert match(Command('gulp srve', stdout('srve')))
@pytest.mark.parametrize('script, stdout', [ @pytest.mark.parametrize('script, stdout', [
('gulp serve', ''), ('gulp serve', ''),
('cat srve', stdout('srve'))]) ('cat srve', stdout('srve'))])
def test_not_march(script, stdout): def test_not_march(script, stdout):
assert not match(Command(script, stdout), None) assert not match(Command(script, stdout))
def test_get_new_command(mocker): def test_get_new_command(mocker):
mocker.patch('thefuck.rules.gulp_not_task.get_gulp_tasks', return_value=[ mocker.patch('thefuck.rules.gulp_not_task.get_gulp_tasks', return_value=[
'serve', 'build', 'default']) 'serve', 'build', 'default'])
command = Command('gulp srve', stdout('srve')) command = Command('gulp srve', stdout('srve'))
assert get_new_command(command, None) == ['gulp serve', 'gulp default'] assert get_new_command(command) == ['gulp serve', 'gulp default']

View File

@ -4,17 +4,14 @@ from thefuck.rules.has_exists_script import match, get_new_command
def test_match(): def test_match():
with patch('os.path.exists', return_value=True): with patch('os.path.exists', return_value=True):
assert match(Mock(script='main', stderr='main: command not found'), assert match(Mock(script='main', stderr='main: command not found'))
None)
assert match(Mock(script='main --help', assert match(Mock(script='main --help',
stderr='main: command not found'), stderr='main: command not found'))
None) assert not match(Mock(script='main', stderr=''))
assert not match(Mock(script='main', stderr=''), None)
with patch('os.path.exists', return_value=False): with patch('os.path.exists', return_value=False):
assert not match(Mock(script='main', stderr='main: command not found'), assert not match(Mock(script='main', stderr='main: command not found'))
None)
def test_get_new_command(): def test_get_new_command():
assert get_new_command(Mock(script='main --help'), None) == './main --help' assert get_new_command(Mock(script='main --help')) == './main --help'

View File

@ -16,14 +16,14 @@ no_suggest_stderr = ''' ! `aaaaa` is not a heroku command.
@pytest.mark.parametrize('cmd', ['log', 'pge']) @pytest.mark.parametrize('cmd', ['log', 'pge'])
def test_match(cmd): def test_match(cmd):
assert match( assert match(
Command('heroku {}'.format(cmd), stderr=suggest_stderr(cmd)), None) Command('heroku {}'.format(cmd), stderr=suggest_stderr(cmd)))
@pytest.mark.parametrize('script, stderr', [ @pytest.mark.parametrize('script, stderr', [
('cat log', suggest_stderr('log')), ('cat log', suggest_stderr('log')),
('heroku aaa', no_suggest_stderr)]) ('heroku aaa', no_suggest_stderr)])
def test_not_match(script, stderr): def test_not_match(script, stderr):
assert not match(Command(script, stderr=stderr), None) assert not match(Command(script, stderr=stderr))
@pytest.mark.parametrize('cmd, result', [ @pytest.mark.parametrize('cmd, result', [
@ -31,4 +31,4 @@ def test_not_match(script, stderr):
('pge', ['heroku pg', 'heroku logs'])]) ('pge', ['heroku pg', 'heroku logs'])])
def test_get_new_command(cmd, result): def test_get_new_command(cmd, result):
command = Command('heroku {}'.format(cmd), stderr=suggest_stderr(cmd)) command = Command('heroku {}'.format(cmd), stderr=suggest_stderr(cmd))
assert get_new_command(command, None) == result assert get_new_command(command) == result

View File

@ -25,13 +25,13 @@ def callables(mocker):
@pytest.mark.usefixtures('history', 'callables', 'no_memoize', 'alias') @pytest.mark.usefixtures('history', 'callables', 'no_memoize', 'alias')
@pytest.mark.parametrize('script', ['ls cet', 'daff x']) @pytest.mark.parametrize('script', ['ls cet', 'daff x'])
def test_match(script): def test_match(script):
assert match(Command(script=script), None) assert match(Command(script=script))
@pytest.mark.usefixtures('history', 'callables', 'no_memoize', 'alias') @pytest.mark.usefixtures('history', 'callables', 'no_memoize', 'alias')
@pytest.mark.parametrize('script', ['apt-get', 'nocommand y']) @pytest.mark.parametrize('script', ['apt-get', 'nocommand y'])
def test_not_match(script): def test_not_match(script):
assert not match(Command(script=script), None) assert not match(Command(script=script))
@pytest.mark.usefixtures('history', 'callables', 'no_memoize', 'alias') @pytest.mark.usefixtures('history', 'callables', 'no_memoize', 'alias')
@ -39,4 +39,4 @@ def test_not_match(script):
('ls cet', 'ls cat'), ('ls cet', 'ls cat'),
('daff x', 'diff x')]) ('daff x', 'diff x')])
def test_get_new_command(script, result): def test_get_new_command(script, result):
assert get_new_command(Command(script), None) == result assert get_new_command(Command(script)) == result

View File

@ -7,11 +7,11 @@ from tests.utils import Command
Command(script='java foo.java'), Command(script='java foo.java'),
Command(script='java bar.java')]) Command(script='java bar.java')])
def test_match(command): def test_match(command):
assert match(command, None) assert match(command)
@pytest.mark.parametrize('command, new_command', [ @pytest.mark.parametrize('command, new_command', [
(Command('java foo.java'), 'java foo'), (Command('java foo.java'), 'java foo'),
(Command('java bar.java'), 'java bar')]) (Command('java bar.java'), 'java bar')])
def test_get_new_command(command, new_command): def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command assert get_new_command(command) == new_command

View File

@ -7,11 +7,11 @@ from tests.utils import Command
Command(script='javac foo'), Command(script='javac foo'),
Command(script='javac bar')]) Command(script='javac bar')])
def test_match(command): def test_match(command):
assert match(command, None) assert match(command)
@pytest.mark.parametrize('command, new_command', [ @pytest.mark.parametrize('command, new_command', [
(Command('javac foo'), 'javac foo.java'), (Command('javac foo'), 'javac foo.java'),
(Command('javac bar'), 'javac bar.java')]) (Command('javac bar'), 'javac bar.java')])
def test_get_new_command(command, new_command): def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command assert get_new_command(command) == new_command

View File

@ -14,10 +14,10 @@ Did you mean this?
def test_match(is_not_task): def test_match(is_not_task):
assert match(Command(script='lein rpl', stderr=is_not_task), None) assert match(Command(script='lein rpl', stderr=is_not_task))
assert not match(Command(script='ls', stderr=is_not_task), None) assert not match(Command(script='ls', stderr=is_not_task))
def test_get_new_command(is_not_task): def test_get_new_command(is_not_task):
assert get_new_command(Command(script='lein rpl --help', stderr=is_not_task), assert get_new_command(Command(script='lein rpl --help', stderr=is_not_task)) \
None) == ['lein repl --help', 'lein jar --help'] == ['lein repl --help', 'lein jar --help']

View File

@ -3,14 +3,14 @@ from tests.utils import Command
def test_match(): def test_match():
assert match(Command(script='ls'), None) assert match(Command(script='ls'))
assert match(Command(script='ls file.py'), None) assert match(Command(script='ls file.py'))
assert match(Command(script='ls /opt'), None) assert match(Command(script='ls /opt'))
assert not match(Command(script='ls -lah /opt'), None) assert not match(Command(script='ls -lah /opt'))
assert not match(Command(script='pacman -S binutils'), None) assert not match(Command(script='pacman -S binutils'))
assert not match(Command(script='lsof'), None) assert not match(Command(script='lsof'))
def test_get_new_command(): def test_get_new_command():
assert get_new_command(Command(script='ls file.py'), None) == 'ls -lah file.py' assert get_new_command(Command(script='ls file.py')) == 'ls -lah file.py'
assert get_new_command(Command(script='ls'), None) == 'ls -lah' assert get_new_command(Command(script='ls')) == 'ls -lah'

View File

@ -12,14 +12,14 @@ from tests.utils import Command
Command('man -s 2 read'), Command('man -s 2 read'),
Command('man -s 3 read')]) Command('man -s 3 read')])
def test_match(command): def test_match(command):
assert match(command, None) assert match(command)
@pytest.mark.parametrize('command', [ @pytest.mark.parametrize('command', [
Command('man'), Command('man'),
Command('man ')]) Command('man ')])
def test_not_match(command): def test_not_match(command):
assert not match(command, None) assert not match(command)
@pytest.mark.parametrize('command, new_command', [ @pytest.mark.parametrize('command, new_command', [
@ -31,4 +31,4 @@ def test_not_match(command):
(Command('man -s 2 read'), 'man -s 3 read'), (Command('man -s 2 read'), 'man -s 3 read'),
(Command('man -s 3 read'), 'man -s 2 read')]) (Command('man -s 3 read'), 'man -s 2 read')])
def test_get_new_command(command, new_command): def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command assert get_new_command(command) == new_command

View File

@ -3,10 +3,10 @@ from tests.utils import Command
def test_match(): def test_match():
assert match(Command('mandiff', stderr='mandiff: command not found'), None) assert match(Command('mandiff', stderr='mandiff: command not found'))
assert not match(Command(), None) assert not match(Command())
def test_get_new_command(): def test_get_new_command():
assert get_new_command( assert get_new_command(
Command('mandiff'), None) == 'man diff' Command('mandiff')) == 'man diff'

View File

@ -37,7 +37,7 @@ from thefuck.rules.mercurial import (
)), )),
]) ])
def test_match(command): def test_match(command):
assert match(command, None) assert match(command)
@pytest.mark.parametrize('command', [ @pytest.mark.parametrize('command', [
@ -63,7 +63,7 @@ def test_match(command):
)), )),
]) ])
def test_not_match(command): def test_not_match(command):
assert not match(command, None) assert not match(command)
@pytest.mark.parametrize('command, possibilities', [ @pytest.mark.parametrize('command, possibilities', [
@ -131,4 +131,4 @@ def test_extract_possibilities(command, possibilities):
)), 'hg rebase re'), )), 'hg rebase re'),
]) ])
def test_get_new_command(command, new_command): def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command assert get_new_command(command) == new_command

View File

@ -9,7 +9,7 @@ from tests.utils import Command
Command('hdfs dfs -mkdir foo/bar/baz', stderr='mkdir: `foo/bar/baz\': No such file or directory') Command('hdfs dfs -mkdir foo/bar/baz', stderr='mkdir: `foo/bar/baz\': No such file or directory')
]) ])
def test_match(command): def test_match(command):
assert match(command, None) assert match(command)
@pytest.mark.parametrize('command', [ @pytest.mark.parametrize('command', [
@ -19,7 +19,7 @@ def test_match(command):
Command('./bin/hdfs dfs -mkdir foo/bar/baz'), Command('./bin/hdfs dfs -mkdir foo/bar/baz'),
Command()]) Command()])
def test_not_match(command): def test_not_match(command):
assert not match(command, None) assert not match(command)
@pytest.mark.parametrize('command, new_command', [ @pytest.mark.parametrize('command, new_command', [
@ -27,5 +27,5 @@ def test_not_match(command):
(Command('hdfs dfs -mkdir foo/bar/baz'), 'hdfs dfs -mkdir -p foo/bar/baz'), (Command('hdfs dfs -mkdir foo/bar/baz'), 'hdfs dfs -mkdir -p foo/bar/baz'),
(Command('./bin/hdfs dfs -mkdir foo/bar/baz'), './bin/hdfs dfs -mkdir -p foo/bar/baz')]) (Command('./bin/hdfs dfs -mkdir foo/bar/baz'), './bin/hdfs dfs -mkdir -p foo/bar/baz')])
def test_get_new_command(command, new_command): def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command assert get_new_command(command) == new_command

View File

@ -6,7 +6,7 @@ from tests.utils import Command
@pytest.mark.parametrize('command', [ @pytest.mark.parametrize('command', [
Command(script='mvn', stdout='[ERROR] No goals have been specified for this build. You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle phases are: validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy, pre-clean, clean, post-clean, pre-site, site, post-site, site-deploy. -> [Help 1]')]) Command(script='mvn', stdout='[ERROR] No goals have been specified for this build. You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle phases are: validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy, pre-clean, clean, post-clean, pre-site, site, post-site, site-deploy. -> [Help 1]')])
def test_match(command): def test_match(command):
assert match(command, None) assert match(command)
@pytest.mark.parametrize('command', [ @pytest.mark.parametrize('command', [
@ -30,11 +30,11 @@ def test_match(command):
Command(script='mvn -v') Command(script='mvn -v')
]) ])
def test_not_match(command): def test_not_match(command):
assert not match(command, None) assert not match(command)
@pytest.mark.parametrize('command, new_command', [ @pytest.mark.parametrize('command, new_command', [
(Command(script='mvn', stdout='[ERROR] No goals have been specified for this build. You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle phases are: validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy, pre-clean, clean, post-clean, pre-site, site, post-site, site-deploy. -> [Help 1]'), ['mvn clean package', 'mvn clean install']), (Command(script='mvn', stdout='[ERROR] No goals have been specified for this build. You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle phases are: validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy, pre-clean, clean, post-clean, pre-site, site, post-site, site-deploy. -> [Help 1]'), ['mvn clean package', 'mvn clean install']),
(Command(script='mvn -N', stdout='[ERROR] No goals have been specified for this build. You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle phases are: validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy, pre-clean, clean, post-clean, pre-site, site, post-site, site-deploy. -> [Help 1]'), ['mvn -N clean package', 'mvn -N clean install'])]) (Command(script='mvn -N', stdout='[ERROR] No goals have been specified for this build. You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle phases are: validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy, pre-clean, clean, post-clean, pre-site, site, post-site, site-deploy. -> [Help 1]'), ['mvn -N clean package', 'mvn -N clean install'])])
def test_get_new_command(command, new_command): def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command assert get_new_command(command) == new_command

View File

@ -6,7 +6,7 @@ from tests.utils import Command
@pytest.mark.parametrize('command', [ @pytest.mark.parametrize('command', [
Command(script='mvn cle', stdout='[ERROR] Unknown lifecycle phase "cle". You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle phases are: validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy, pre-clean, clean, post-clean, pre-site, site, post-site, site-deploy. -> [Help 1]')]) Command(script='mvn cle', stdout='[ERROR] Unknown lifecycle phase "cle". You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle phases are: validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy, pre-clean, clean, post-clean, pre-site, site, post-site, site-deploy. -> [Help 1]')])
def test_match(command): def test_match(command):
assert match(command, None) assert match(command)
@pytest.mark.parametrize('command', [ @pytest.mark.parametrize('command', [
@ -30,11 +30,11 @@ def test_match(command):
Command(script='mvn -v') Command(script='mvn -v')
]) ])
def test_not_match(command): def test_not_match(command):
assert not match(command, None) assert not match(command)
@pytest.mark.parametrize('command, new_command', [ @pytest.mark.parametrize('command, new_command', [
(Command(script='mvn cle', stdout='[ERROR] Unknown lifecycle phase "cle". You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle phases are: validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy, pre-clean, clean, post-clean, pre-site, site, post-site, site-deploy. -> [Help 1]'), ['mvn clean', 'mvn compile']), (Command(script='mvn cle', stdout='[ERROR] Unknown lifecycle phase "cle". You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle phases are: validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy, pre-clean, clean, post-clean, pre-site, site, post-site, site-deploy. -> [Help 1]'), ['mvn clean', 'mvn compile']),
(Command(script='mvn claen package', stdout='[ERROR] Unknown lifecycle phase "claen". You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle phases are: validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy, pre-clean, clean, post-clean, pre-site, site, post-site, site-deploy. -> [Help 1]'), ['mvn clean package'])]) (Command(script='mvn claen package', stdout='[ERROR] Unknown lifecycle phase "claen". You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle phases are: validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy, pre-clean, clean, post-clean, pre-site, site, post-site, site-deploy. -> [Help 1]'), ['mvn clean package'])])
def test_get_new_command(command, new_command): def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command assert get_new_command(command) == new_command

View File

@ -11,19 +11,17 @@ def get_all_executables(mocker):
@pytest.mark.usefixtures('no_memoize') @pytest.mark.usefixtures('no_memoize')
def test_match(): def test_match():
assert match(Command(stderr='vom: not found', script='vom file.py'), None) assert match(Command(stderr='vom: not found', script='vom file.py'))
assert match(Command(stderr='fucck: not found', script='fucck'), None) assert match(Command(stderr='fucck: not found', script='fucck'))
assert not match(Command(stderr='qweqwe: not found', script='qweqwe'), None) assert not match(Command(stderr='qweqwe: not found', script='qweqwe'))
assert not match(Command(stderr='some text', script='vom file.py'), None) assert not match(Command(stderr='some text', script='vom file.py'))
@pytest.mark.usefixtures('no_memoize') @pytest.mark.usefixtures('no_memoize')
def test_get_new_command(): def test_get_new_command():
assert get_new_command( assert get_new_command(
Command(stderr='vom: not found', Command(stderr='vom: not found',
script='vom file.py'), script='vom file.py')) == ['vim file.py']
None) == ['vim file.py']
assert get_new_command( assert get_new_command(
Command(stderr='fucck: not found', Command(stderr='fucck: not found',
script='fucck'), script='fucck')) == ['fsck']
Command) == ['fsck']

View File

@ -8,7 +8,7 @@ from tests.utils import Command
Command(script='mv foo bar/', stderr="mv: cannot move 'foo' to 'bar/': No such file or directory"), Command(script='mv foo bar/', stderr="mv: cannot move 'foo' to 'bar/': No such file or directory"),
]) ])
def test_match(command): def test_match(command):
assert match(command, None) assert match(command)
@pytest.mark.parametrize('command', [ @pytest.mark.parametrize('command', [
@ -16,7 +16,7 @@ def test_match(command):
Command(script='mv foo bar/foo', stderr="mv: permission denied"), Command(script='mv foo bar/foo', stderr="mv: permission denied"),
]) ])
def test_not_match(command): def test_not_match(command):
assert not match(command, None) assert not match(command)
@pytest.mark.parametrize('command, new_command', [ @pytest.mark.parametrize('command, new_command', [
@ -24,4 +24,4 @@ def test_not_match(command):
(Command(script='mv foo bar/', stderr="mv: cannot move 'foo' to 'bar/': No such file or directory"), 'mkdir -p bar && mv foo bar/'), (Command(script='mv foo bar/', stderr="mv: cannot move 'foo' to 'bar/': No such file or directory"), 'mkdir -p bar && mv foo bar/'),
]) ])
def test_get_new_command(command, new_command): def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command assert get_new_command(command) == new_command

View File

@ -14,7 +14,7 @@ from tests.utils import Command
Command(script='gnome-open foo.com'), Command(script='gnome-open foo.com'),
Command(script='kde-open foo.com')]) Command(script='kde-open foo.com')])
def test_match(command): def test_match(command):
assert match(command, None) assert match(command)
@pytest.mark.parametrize('command, new_command', [ @pytest.mark.parametrize('command, new_command', [
@ -28,4 +28,4 @@ def test_match(command):
(Command('gnome-open foo.io'), 'gnome-open http://foo.io'), (Command('gnome-open foo.io'), 'gnome-open http://foo.io'),
(Command('kde-open foo.io'), 'kde-open http://foo.io')]) (Command('kde-open foo.io'), 'kde-open http://foo.io')])
def test_get_new_command(command, new_command): def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command assert get_new_command(command) == new_command

View File

@ -23,7 +23,7 @@ extra/vim-python3 7.4.712-1 \t/usr/bin/vim'''
Command(script='vim', stderr='vim: command not found'), Command(script='vim', stderr='vim: command not found'),
Command(script='sudo vim', stderr='sudo: vim: command not found')]) Command(script='sudo vim', stderr='sudo: vim: command not found')])
def test_match(command): def test_match(command):
assert match(command, None) assert match(command)
@pytest.mark.parametrize('command, return_value', [ @pytest.mark.parametrize('command, return_value', [
@ -33,14 +33,14 @@ def test_match(command):
@patch.multiple(pacman, create=True, pacman=pacman_cmd) @patch.multiple(pacman, create=True, pacman=pacman_cmd)
def test_match_mocked(subp_mock, command, return_value): def test_match_mocked(subp_mock, command, return_value):
subp_mock.check_output.return_value = return_value subp_mock.check_output.return_value = return_value
assert match(command, None) assert match(command)
@pytest.mark.parametrize('command', [ @pytest.mark.parametrize('command', [
Command(script='vim', stderr=''), Command(), Command(script='vim', stderr=''), Command(),
Command(script='sudo vim', stderr=''), Command()]) Command(script='sudo vim', stderr=''), Command()])
def test_not_match(command): def test_not_match(command):
assert not match(command, None) assert not match(command)
sudo_vim_possibilities = ['{} -S extra/gvim && sudo vim', sudo_vim_possibilities = ['{} -S extra/gvim && sudo vim',
@ -66,7 +66,7 @@ vim_possibilities = [s.format(pacman_cmd) for s in vim_possibilities]
(Command('convert'), ['{} -S extra/imagemagick && convert'.format(pacman_cmd)]), (Command('convert'), ['{} -S extra/imagemagick && convert'.format(pacman_cmd)]),
(Command('sudo convert'), ['{} -S extra/imagemagick && sudo convert'.format(pacman_cmd)])]) (Command('sudo convert'), ['{} -S extra/imagemagick && sudo convert'.format(pacman_cmd)])])
def test_get_new_command(command, new_command, mocker): def test_get_new_command(command, new_command, mocker):
assert get_new_command(command, None) == new_command assert get_new_command(command) == new_command
@pytest.mark.parametrize('command, new_command, return_value', [ @pytest.mark.parametrize('command, new_command, return_value', [
@ -79,4 +79,4 @@ def test_get_new_command(command, new_command, mocker):
@patch.multiple(pacman, create=True, pacman=pacman_cmd) @patch.multiple(pacman, create=True, pacman=pacman_cmd)
def test_get_new_command_mocked(subp_mock, command, new_command, return_value): def test_get_new_command_mocked(subp_mock, command, new_command, return_value):
subp_mock.check_output.return_value = return_value subp_mock.check_output.return_value = return_value
assert get_new_command(command, None) == new_command assert get_new_command(command) == new_command

View File

@ -15,7 +15,7 @@ extra/llvm35 3.5.2-13/usr/bin/llc'''
Command(script='pacman llc', stderr='error: target not found: llc'), Command(script='pacman llc', stderr='error: target not found: llc'),
Command(script='sudo pacman llc', stderr='error: target not found: llc')]) Command(script='sudo pacman llc', stderr='error: target not found: llc')])
def test_match(command): def test_match(command):
assert match(command, None) assert match(command)
@pytest.mark.parametrize('command', [ @pytest.mark.parametrize('command', [
@ -25,7 +25,7 @@ def test_match(command):
@patch('thefuck.specific.archlinux.subprocess') @patch('thefuck.specific.archlinux.subprocess')
def test_match_mocked(subp_mock, command): def test_match_mocked(subp_mock, command):
subp_mock.check_output.return_value = PKGFILE_OUTPUT_LLC subp_mock.check_output.return_value = PKGFILE_OUTPUT_LLC
assert match(command, None) assert match(command)
@pytest.mark.skipif(not getattr(pacman_not_found, 'enabled_by_default', True), @pytest.mark.skipif(not getattr(pacman_not_found, 'enabled_by_default', True),
@ -35,7 +35,7 @@ def test_match_mocked(subp_mock, command):
(Command(script='pacman -S llc', stderr='error: target not found: llc'), ['pacman -S extra/llvm', 'pacman -S extra/llvm35']), (Command(script='pacman -S llc', stderr='error: target not found: llc'), ['pacman -S extra/llvm', 'pacman -S extra/llvm35']),
(Command(script='sudo pacman -S llc', stderr='error: target not found: llc'), ['sudo pacman -S extra/llvm', 'sudo pacman -S extra/llvm35'])]) (Command(script='sudo pacman -S llc', stderr='error: target not found: llc'), ['sudo pacman -S extra/llvm', 'sudo pacman -S extra/llvm35'])])
def test_get_new_command(command, fixed): def test_get_new_command(command, fixed):
assert get_new_command(command, None) == fixed assert get_new_command(command) == fixed
@pytest.mark.parametrize('command, fixed', [ @pytest.mark.parametrize('command, fixed', [
@ -45,4 +45,4 @@ def test_get_new_command(command, fixed):
@patch('thefuck.specific.archlinux.subprocess') @patch('thefuck.specific.archlinux.subprocess')
def test_get_new_command_mocked(subp_mock, command, fixed): def test_get_new_command_mocked(subp_mock, command, fixed):
subp_mock.check_output.return_value = PKGFILE_OUTPUT_LLC subp_mock.check_output.return_value = PKGFILE_OUTPUT_LLC
assert get_new_command(command, None) == fixed assert get_new_command(command) == fixed

View File

@ -14,12 +14,11 @@ def pip_unknown_cmd_without_recommend():
def test_match(pip_unknown_cmd, pip_unknown_cmd_without_recommend): def test_match(pip_unknown_cmd, pip_unknown_cmd_without_recommend):
assert match(Command('pip instatl', stderr=pip_unknown_cmd), None) assert match(Command('pip instatl', stderr=pip_unknown_cmd))
assert not match(Command('pip i', assert not match(Command('pip i',
stderr=pip_unknown_cmd_without_recommend), stderr=pip_unknown_cmd_without_recommend))
None)
def test_get_new_command(pip_unknown_cmd): def test_get_new_command(pip_unknown_cmd):
assert get_new_command(Command('pip instatl', stderr=pip_unknown_cmd), assert get_new_command(Command('pip instatl',
None) == 'pip install' stderr=pip_unknown_cmd)) == 'pip install'

View File

@ -3,10 +3,10 @@ from tests.utils import Command
def test_match(): def test_match():
assert match(Command('temp.py', stderr='Permission denied'), None) assert match(Command('temp.py', stderr='Permission denied'))
assert not match(Command(), None) assert not match(Command())
def test_get_new_command(): def test_get_new_command():
assert get_new_command(Command('./test_sudo.py'), None)\ assert get_new_command(Command('./test_sudo.py'))\
== 'python ./test_sudo.py' == 'python ./test_sudo.py'

View File

@ -7,11 +7,11 @@ from tests.utils import Command
Command(script='python foo'), Command(script='python foo'),
Command(script='python bar')]) Command(script='python bar')])
def test_match(command): def test_match(command):
assert match(command, None) assert match(command)
@pytest.mark.parametrize('command, new_command', [ @pytest.mark.parametrize('command, new_command', [
(Command('python foo'), 'python foo.py'), (Command('python foo'), 'python foo.py'),
(Command('python bar'), 'python bar.py')]) (Command('python bar'), 'python bar.py')])
def test_get_new_command(command, new_command): def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command assert get_new_command(command) == new_command

View File

@ -8,7 +8,7 @@ from tests.utils import Command
Command(script="git commit -am \"Mismatched Quotation Marks\'"), Command(script="git commit -am \"Mismatched Quotation Marks\'"),
Command(script="echo \"hello\'")]) Command(script="echo \"hello\'")])
def test_match(command): def test_match(command):
assert match(command, None) assert match(command)
@pytest.mark.parametrize('command, new_command', [ @pytest.mark.parametrize('command, new_command', [
@ -16,4 +16,4 @@ def test_match(command):
(Command("git commit -am \"Mismatched Quotation Marks\'"), "git commit -am \"Mismatched Quotation Marks\""), (Command("git commit -am \"Mismatched Quotation Marks\'"), "git commit -am \"Mismatched Quotation Marks\""),
(Command("echo \"hello\'"), "echo \"hello\"")]) (Command("echo \"hello\'"), "echo \"hello\"")])
def test_get_new_command(command, new_command): def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command assert get_new_command(command) == new_command

View File

@ -10,7 +10,7 @@ from tests.utils import Command
Command('./bin/hdfs dfs -rm foo', stderr='rm: `foo`: Is a directory') Command('./bin/hdfs dfs -rm foo', stderr='rm: `foo`: Is a directory')
]) ])
def test_match(command): def test_match(command):
assert match(command, None) assert match(command)
@pytest.mark.parametrize('command', [ @pytest.mark.parametrize('command', [
@ -19,13 +19,13 @@ def test_match(command):
Command('./bin/hdfs dfs -rm foo'), Command('./bin/hdfs dfs -rm foo'),
Command()]) Command()])
def test_not_match(command): def test_not_match(command):
assert not match(command, None) assert not match(command)
@pytest.mark.parametrize('command, new_command', [ @pytest.mark.parametrize('command, new_command', [
(Command('rm foo'), 'rm -rf foo'), (Command('rm foo'), 'rm -rf foo'),
(Command('hdfs dfs -rm foo'), 'hdfs dfs -rm -r foo')]) (Command('hdfs dfs -rm foo'), 'hdfs dfs -rm -r foo')])
def test_get_new_command(command, new_command): def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command assert get_new_command(command) == new_command

View File

@ -5,7 +5,7 @@ from tests.utils import Command
def test_match(): def test_match():
assert match(Command(script='rm -rf /', assert match(Command(script='rm -rf /',
stderr='add --no-preserve-root'), None) stderr='add --no-preserve-root'))
@pytest.mark.parametrize('command', [ @pytest.mark.parametrize('command', [
@ -13,9 +13,9 @@ def test_match():
Command(script='rm --no-preserve-root /', stderr='add --no-preserve-root'), Command(script='rm --no-preserve-root /', stderr='add --no-preserve-root'),
Command(script='rm -rf /', stderr='')]) Command(script='rm -rf /', stderr='')])
def test_not_match(command): def test_not_match(command):
assert not match(command, None) assert not match(command)
def test_get_new_command(): def test_get_new_command():
assert get_new_command(Command(script='rm -rf /'), None) \ assert get_new_command(Command(script='rm -rf /')) \
== 'rm -rf / --no-preserve-root' == 'rm -rf / --no-preserve-root'

View File

@ -9,20 +9,20 @@ def sed_unterminated_s():
def test_match(sed_unterminated_s): def test_match(sed_unterminated_s):
assert match(Command('sed -e s/foo/bar', stderr=sed_unterminated_s), None) assert match(Command('sed -e s/foo/bar', stderr=sed_unterminated_s))
assert match(Command('sed -es/foo/bar', stderr=sed_unterminated_s), None) assert match(Command('sed -es/foo/bar', stderr=sed_unterminated_s))
assert match(Command('sed -e s/foo/bar -e s/baz/quz', stderr=sed_unterminated_s), None) assert match(Command('sed -e s/foo/bar -e s/baz/quz', stderr=sed_unterminated_s))
assert not match(Command('sed -e s/foo/bar'), None) assert not match(Command('sed -e s/foo/bar'))
assert not match(Command('sed -es/foo/bar'), None) assert not match(Command('sed -es/foo/bar'))
assert not match(Command('sed -e s/foo/bar -e s/baz/quz'), None) assert not match(Command('sed -e s/foo/bar -e s/baz/quz'))
def test_get_new_command(sed_unterminated_s): def test_get_new_command(sed_unterminated_s):
assert get_new_command(Command('sed -e s/foo/bar', stderr=sed_unterminated_s), None) \ assert get_new_command(Command('sed -e s/foo/bar', stderr=sed_unterminated_s)) \
== 'sed -e s/foo/bar/' == 'sed -e s/foo/bar/'
assert get_new_command(Command('sed -es/foo/bar', stderr=sed_unterminated_s), None) \ assert get_new_command(Command('sed -es/foo/bar', stderr=sed_unterminated_s)) \
== 'sed -es/foo/bar/' == 'sed -es/foo/bar/'
assert get_new_command(Command(r"sed -e 's/\/foo/bar'", stderr=sed_unterminated_s), None) \ assert get_new_command(Command(r"sed -e 's/\/foo/bar'", stderr=sed_unterminated_s)) \
== r"sed -e 's/\/foo/bar/'" == r"sed -e 's/\/foo/bar/'"
assert get_new_command(Command(r"sed -e s/foo/bar -es/baz/quz", stderr=sed_unterminated_s), None) \ assert get_new_command(Command(r"sed -e s/foo/bar -es/baz/quz", stderr=sed_unterminated_s)) \
== r"sed -e s/foo/bar/ -es/baz/quz/" == r"sed -e s/foo/bar/ -es/baz/quz/"

View File

@ -4,9 +4,9 @@ from tests.utils import Command
def test_match(): def test_match():
assert match(Command('sl'), None) assert match(Command('sl'))
assert not match(Command('ls'), None) assert not match(Command('ls'))
def test_get_new_command(): def test_get_new_command():
assert get_new_command(Command('sl'), None) == 'ls' assert get_new_command(Command('sl')) == 'ls'

View File

@ -44,23 +44,23 @@ Host key verification failed.""".format(path, '98.765.432.321')
def test_match(ssh_error): def test_match(ssh_error):
errormsg, _, _, _ = ssh_error errormsg, _, _, _ = ssh_error
assert match(Command('ssh', stderr=errormsg), None) assert match(Command('ssh', stderr=errormsg))
assert match(Command('ssh', stderr=errormsg), None) assert match(Command('ssh', stderr=errormsg))
assert match(Command('scp something something', stderr=errormsg), None) assert match(Command('scp something something', stderr=errormsg))
assert match(Command('scp something something', stderr=errormsg), None) assert match(Command('scp something something', stderr=errormsg))
assert not match(Command(stderr=errormsg), None) assert not match(Command(stderr=errormsg))
assert not match(Command('notssh', stderr=errormsg), None) assert not match(Command('notssh', stderr=errormsg))
assert not match(Command('ssh'), None) assert not match(Command('ssh'))
def test_side_effect(ssh_error): def test_side_effect(ssh_error):
errormsg, path, reset, known_hosts = ssh_error errormsg, path, reset, known_hosts = ssh_error
command = Command('ssh user@host', stderr=errormsg) command = Command('ssh user@host', stderr=errormsg)
side_effect(command, None, None) side_effect(command, None)
expected = ['123.234.567.890 asdjkasjdakjsd\n', '111.222.333.444 qwepoiwqepoiss\n'] expected = ['123.234.567.890 asdjkasjdakjsd\n', '111.222.333.444 qwepoiwqepoiss\n']
assert known_hosts(path) == expected assert known_hosts(path) == expected
def test_get_new_command(ssh_error, monkeypatch): def test_get_new_command(ssh_error, monkeypatch):
errormsg, _, _, _ = ssh_error errormsg, _, _, _ = ssh_error
assert get_new_command(Command('ssh user@host', stderr=errormsg), None) == 'ssh user@host' assert get_new_command(Command('ssh user@host', stderr=errormsg)) == 'ssh user@host'

View File

@ -14,11 +14,11 @@ from tests.utils import Command
('You don\'t have access to the history DB.', ''), ('You don\'t have access to the history DB.', ''),
('', "error: [Errno 13] Permission denied: '/usr/local/lib/python2.7/dist-packages/ipaddr.py'")]) ('', "error: [Errno 13] Permission denied: '/usr/local/lib/python2.7/dist-packages/ipaddr.py'")])
def test_match(stderr, stdout): def test_match(stderr, stdout):
assert match(Command(stderr=stderr, stdout=stdout), None) assert match(Command(stderr=stderr, stdout=stdout))
def test_not_match(): def test_not_match():
assert not match(Command(), None) assert not match(Command())
@pytest.mark.parametrize('before, after', [ @pytest.mark.parametrize('before, after', [
@ -26,4 +26,4 @@ def test_not_match():
('echo a > b', 'sudo sh -c "echo a > b"'), ('echo a > b', 'sudo sh -c "echo a > b"'),
('echo "a" >> b', 'sudo sh -c "echo \\"a\\" >> b"')]) ('echo "a" >> b', 'sudo sh -c "echo \\"a\\" >> b"')])
def test_get_new_command(before, after): def test_get_new_command(before, after):
assert get_new_command(Command(before), None) == after assert get_new_command(Command(before)) == after

View File

@ -9,7 +9,7 @@ from tests.utils import Command
Command(stderr='command not found: фзе-пуе', script=u'фзе-пуе'), Command(stderr='command not found: фзе-пуе', script=u'фзе-пуе'),
Command(stderr='command not found: λσ', script=u'λσ')]) Command(stderr='command not found: λσ', script=u'λσ')])
def test_match(command): def test_match(command):
assert switch_lang.match(command, None) assert switch_lang.match(command)
@pytest.mark.parametrize('command', [ @pytest.mark.parametrize('command', [
@ -18,11 +18,11 @@ def test_match(command):
Command(stderr='command not found: агсл', script=u'агсл'), Command(stderr='command not found: агсл', script=u'агсл'),
Command(stderr='some info', script=u'фзе-пуе')]) Command(stderr='some info', script=u'фзе-пуе')])
def test_not_match(command): def test_not_match(command):
assert not switch_lang.match(command, None) assert not switch_lang.match(command)
@pytest.mark.parametrize('command, new_command', [ @pytest.mark.parametrize('command, new_command', [
(Command(u'фзе-пуе штыефдд мшь'), 'apt-get install vim'), (Command(u'фзе-пуе штыефдд мшь'), 'apt-get install vim'),
(Command(u'λσ -λα'), 'ls -la')]) (Command(u'λσ -λα'), 'ls -la')])
def test_get_new_command(command, new_command): def test_get_new_command(command, new_command):
assert switch_lang.get_new_command(command, None) == new_command assert switch_lang.get_new_command(command) == new_command

View File

@ -4,15 +4,15 @@ from tests.utils import Command
def test_match(): def test_match():
assert match(Command('systemctl nginx start', stderr='Unknown operation \'nginx\'.'), None) assert match(Command('systemctl nginx start', stderr='Unknown operation \'nginx\'.'))
assert match(Command('sudo systemctl nginx start', stderr='Unknown operation \'nginx\'.'), None) assert match(Command('sudo systemctl nginx start', stderr='Unknown operation \'nginx\'.'))
assert not match(Command('systemctl start nginx'), None) assert not match(Command('systemctl start nginx'))
assert not match(Command('systemctl start nginx'), None) assert not match(Command('systemctl start nginx'))
assert not match(Command('sudo systemctl nginx', stderr='Unknown operation \'nginx\'.'), None) assert not match(Command('sudo systemctl nginx', stderr='Unknown operation \'nginx\'.'))
assert not match(Command('systemctl nginx', stderr='Unknown operation \'nginx\'.'), None) assert not match(Command('systemctl nginx', stderr='Unknown operation \'nginx\'.'))
assert not match(Command('systemctl start wtf', stderr='Failed to start wtf.service: Unit wtf.service failed to load: No such file or directory.'), None) assert not match(Command('systemctl start wtf', stderr='Failed to start wtf.service: Unit wtf.service failed to load: No such file or directory.'))
def test_get_new_command(): def test_get_new_command():
assert get_new_command(Command('systemctl nginx start'), None) == "systemctl start nginx" assert get_new_command(Command('systemctl nginx start')) == "systemctl start nginx"
assert get_new_command(Command('sudo systemctl nginx start'), None) == "sudo systemctl start nginx" assert get_new_command(Command('sudo systemctl nginx start')) == "sudo systemctl start nginx"

View File

@ -11,9 +11,9 @@ def tmux_ambiguous():
def test_match(tmux_ambiguous): def test_match(tmux_ambiguous):
assert match(Command('tmux list', stderr=tmux_ambiguous), None) assert match(Command('tmux list', stderr=tmux_ambiguous))
def test_get_new_command(tmux_ambiguous): def test_get_new_command(tmux_ambiguous):
assert get_new_command(Command('tmux list', stderr=tmux_ambiguous), None)\ assert get_new_command(Command('tmux list', stderr=tmux_ambiguous))\
== ['tmux list-keys', 'tmux list-panes', 'tmux list-windows'] == ['tmux list-keys', 'tmux list-panes', 'tmux list-windows']

View File

@ -15,7 +15,7 @@ error_msg = (
Command(script='tsuru app-log -f', stderr=error_msg[1]), Command(script='tsuru app-log -f', stderr=error_msg[1]),
]) ])
def test_match(command): def test_match(command):
assert match(command, {}) assert match(command)
@pytest.mark.parametrize('command', [ @pytest.mark.parametrize('command', [
@ -24,7 +24,7 @@ def test_match(command):
Command(script='tsuru app-log -f', stderr=('Error: unparseable data')), Command(script='tsuru app-log -f', stderr=('Error: unparseable data')),
]) ])
def test_not_match(command): def test_not_match(command):
assert not match(command, {}) assert not match(command)
@pytest.mark.parametrize('command, new_command', [ @pytest.mark.parametrize('command, new_command', [
@ -34,4 +34,4 @@ def test_not_match(command):
'tsuru login && tsuru app-log -f'), 'tsuru login && tsuru app-log -f'),
]) ])
def test_get_new_command(command, new_command): def test_get_new_command(command, new_command):
assert get_new_command(command, {}) == new_command assert get_new_command(command) == new_command

View File

@ -30,7 +30,7 @@ from thefuck.rules.tsuru_not_command import match, get_new_command
)), )),
]) ])
def test_match(command): def test_match(command):
assert match(command, None) assert match(command)
@pytest.mark.parametrize('command', [ @pytest.mark.parametrize('command', [
@ -58,7 +58,7 @@ def test_match(command):
Command('tsuru env-get', stderr='Error: App thefuck not found.'), Command('tsuru env-get', stderr='Error: App thefuck not found.'),
]) ])
def test_not_match(command): def test_not_match(command):
assert not match(command, None) assert not match(command)
@pytest.mark.parametrize('command, new_commands', [ @pytest.mark.parametrize('command, new_commands', [
@ -87,4 +87,4 @@ def test_not_match(command):
)), ['tsuru target-list']), )), ['tsuru target-list']),
]) ])
def test_get_new_command(command, new_commands): def test_get_new_command(command, new_commands):
assert get_new_command(command, None) == new_commands assert get_new_command(command) == new_commands

View File

@ -9,7 +9,7 @@ from tests.utils import Command
stderr='ls: Unknown command\nDid you mean -ls? This command begins with a dash.'), stderr='ls: Unknown command\nDid you mean -ls? This command begins with a dash.'),
Command(script='hdfs dfs ls /foo/bar', stderr='ls: Unknown command\nDid you mean -ls? This command begins with a dash.')]) Command(script='hdfs dfs ls /foo/bar', stderr='ls: Unknown command\nDid you mean -ls? This command begins with a dash.')])
def test_match(command): def test_match(command):
assert match(command, None) assert match(command)
@pytest.mark.parametrize('command', [ @pytest.mark.parametrize('command', [
@ -18,7 +18,7 @@ def test_match(command):
Command(script='hdfs dfs -ls -R /foo/bar', stderr=''), Command(script='hdfs dfs -ls -R /foo/bar', stderr=''),
Command()]) Command()])
def test_not_match(command): def test_not_match(command):
assert not match(command, None) assert not match(command)
@pytest.mark.parametrize('command, new_command', [ @pytest.mark.parametrize('command, new_command', [
@ -31,5 +31,5 @@ def test_not_match(command):
(Command('./bin/hdfs dfs -Dtest=fred ls -R /foo/bar', (Command('./bin/hdfs dfs -Dtest=fred ls -R /foo/bar',
stderr='ls: Unknown command\nDid you mean -ls? This command begins with a dash.'), ['./bin/hdfs dfs -Dtest=fred -ls -R /foo/bar'])]) stderr='ls: Unknown command\nDid you mean -ls? This command begins with a dash.'), ['./bin/hdfs dfs -Dtest=fred -ls -R /foo/bar'])])
def test_get_new_command(command, new_command): def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command assert get_new_command(command) == new_command

View File

@ -11,7 +11,7 @@ from tests.utils import Command
Command(script='vagrant rdp devbox', Command(script='vagrant rdp devbox',
stderr='VM must be created before running this command. Run `vagrant up` first.')]) stderr='VM must be created before running this command. Run `vagrant up` first.')])
def test_match(command): def test_match(command):
assert match(command, None) assert match(command)
@pytest.mark.parametrize('command', [ @pytest.mark.parametrize('command', [
@ -20,7 +20,7 @@ def test_match(command):
Command(script='vagrant ssh', stderr='A Vagrant environment or target machine is required to run this command. Run `vagrant init` to create a new Vagrant environment. Or, get an ID of a target machine from `vagrant global-status` to run this command on. A final option is to change to a directory with a Vagrantfile and to try again.'), Command(script='vagrant ssh', stderr='A Vagrant environment or target machine is required to run this command. Run `vagrant init` to create a new Vagrant environment. Or, get an ID of a target machine from `vagrant global-status` to run this command on. A final option is to change to a directory with a Vagrantfile and to try again.'),
Command()]) Command()])
def test_not_match(command): def test_not_match(command):
assert not match(command, None) assert not match(command)
@pytest.mark.parametrize('command, new_command', [ @pytest.mark.parametrize('command, new_command', [
@ -31,5 +31,5 @@ def test_not_match(command):
(Command(script='vagrant rdp devbox', (Command(script='vagrant rdp devbox',
stderr='VM must be created before running this command. Run `vagrant up` first.'), ['vagrant up devbox && vagrant rdp devbox', 'vagrant up && vagrant rdp devbox'])]) stderr='VM must be created before running this command. Run `vagrant up` first.'), ['vagrant up devbox && vagrant rdp devbox', 'vagrant up && vagrant rdp devbox'])])
def test_get_new_command(command, new_command): def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command assert get_new_command(command) == new_command

View File

@ -8,11 +8,11 @@ from tests.utils import Command
Command(script='whois https://en.wikipedia.org/'), Command(script='whois https://en.wikipedia.org/'),
Command(script='whois meta.unix.stackexchange.com')]) Command(script='whois meta.unix.stackexchange.com')])
def test_match(command): def test_match(command):
assert match(command, None) assert match(command)
def test_not_match(): def test_not_match():
assert not match(Command(script='whois'), None) assert not match(Command(script='whois'))
# `whois com` actually makes sense # `whois com` actually makes sense
@ -23,4 +23,4 @@ def test_not_match():
'whois stackexchange.com', 'whois stackexchange.com',
'whois com'])]) 'whois com'])])
def test_get_new_command(command, new_command): def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command assert get_new_command(command) == new_command

View File

@ -9,9 +9,10 @@ from tests.utils import Command
"19:23:25.470911 git.c:282 trace: alias expansion: com => 'commit' '--verbose'")]) "19:23:25.470911 git.c:282 trace: alias expansion: com => 'commit' '--verbose'")])
def test_git_support(called, command, stderr): def test_git_support(called, command, stderr):
@git_support @git_support
def fn(command, settings): return command.script def fn(command):
return command.script
assert fn(Command(script=called, stderr=stderr), None) == command assert fn(Command(script=called, stderr=stderr)) == command
@pytest.mark.parametrize('command, is_git', [ @pytest.mark.parametrize('command, is_git', [
@ -24,6 +25,7 @@ def test_git_support(called, command, stderr):
('cat hub', False)]) ('cat hub', False)])
def test_git_support_match(command, is_git): def test_git_support_match(command, is_git):
@git_support @git_support
def fn(command, settings): return True def fn(command):
return True
assert fn(Command(script=command), None) == is_git assert fn(Command(script=command)) == is_git

View File

@ -13,8 +13,8 @@ from tests.utils import Command
(False, 'sudo ls', 'ls', False), (False, 'sudo ls', 'ls', False),
(False, 'ls', 'ls', False)]) (False, 'ls', 'ls', False)])
def test_sudo_support(return_value, command, called, result): def test_sudo_support(return_value, command, called, result):
def fn(command, settings): def fn(command):
assert command == Command(called) assert command == Command(called)
return return_value return return_value
assert sudo_support(fn)(Command(command), None) == result assert sudo_support(fn)(Command(command)) == result

View File

@ -26,22 +26,23 @@ def environ(monkeypatch):
@pytest.mark.usefixture('environ') @pytest.mark.usefixture('environ')
def test_settings_defaults(load_source): def test_settings_defaults(load_source, settings):
load_source.return_value = object() load_source.return_value = object()
conf.init_settings(Mock())
for key, val in conf.DEFAULT_SETTINGS.items(): for key, val in conf.DEFAULT_SETTINGS.items():
assert getattr(conf.get_settings(Mock()), key) == val assert getattr(settings, key) == val
@pytest.mark.usefixture('environ') @pytest.mark.usefixture('environ')
class TestSettingsFromFile(object): 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'], load_source.return_value = Mock(rules=['test'],
wait_command=10, wait_command=10,
require_confirmation=True, require_confirmation=True,
no_colors=True, no_colors=True,
priority={'vim': 100}, priority={'vim': 100},
exclude_rules=['git']) exclude_rules=['git'])
settings = conf.get_settings(Mock()) conf.init_settings(Mock())
assert settings.rules == ['test'] assert settings.rules == ['test']
assert settings.wait_command == 10 assert settings.wait_command == 10
assert settings.require_confirmation is True assert settings.require_confirmation is True
@ -49,26 +50,26 @@ class TestSettingsFromFile(object):
assert settings.priority == {'vim': 100} assert settings.priority == {'vim': 100}
assert settings.exclude_rules == ['git'] 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'], load_source.return_value = Mock(rules=conf.DEFAULT_RULES + ['test'],
wait_command=10, wait_command=10,
exclude_rules=[], exclude_rules=[],
require_confirmation=True, require_confirmation=True,
no_colors=True) no_colors=True)
settings = conf.get_settings(Mock()) conf.init_settings(Mock())
assert settings.rules == conf.DEFAULT_RULES + ['test'] assert settings.rules == conf.DEFAULT_RULES + ['test']
@pytest.mark.usefixture('load_source') @pytest.mark.usefixture('load_source')
class TestSettingsFromEnv(object): class TestSettingsFromEnv(object):
def test_from_env(self, environ): def test_from_env(self, environ, settings):
environ.update({'THEFUCK_RULES': 'bash:lisp', environ.update({'THEFUCK_RULES': 'bash:lisp',
'THEFUCK_EXCLUDE_RULES': 'git:vim', 'THEFUCK_EXCLUDE_RULES': 'git:vim',
'THEFUCK_WAIT_COMMAND': '55', 'THEFUCK_WAIT_COMMAND': '55',
'THEFUCK_REQUIRE_CONFIRMATION': 'true', 'THEFUCK_REQUIRE_CONFIRMATION': 'true',
'THEFUCK_NO_COLORS': 'false', 'THEFUCK_NO_COLORS': 'false',
'THEFUCK_PRIORITY': 'bash=10:lisp=wrong:vim=15'}) 'THEFUCK_PRIORITY': 'bash=10:lisp=wrong:vim=15'})
settings = conf.get_settings(Mock()) conf.init_settings(Mock())
assert settings.rules == ['bash', 'lisp'] assert settings.rules == ['bash', 'lisp']
assert settings.exclude_rules == ['git', 'vim'] assert settings.exclude_rules == ['git', 'vim']
assert settings.wait_command == 55 assert settings.wait_command == 55
@ -76,9 +77,9 @@ class TestSettingsFromEnv(object):
assert settings.no_colors is False assert settings.no_colors is False
assert settings.priority == {'bash': 10, 'vim': 15} 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'}) environ.update({'THEFUCK_RULES': 'DEFAULT_RULES:bash:lisp'})
settings = conf.get_settings(Mock()) conf.init_settings(Mock())
assert settings.rules == conf.DEFAULT_RULES + ['bash', 'lisp'] assert settings.rules == conf.DEFAULT_RULES + ['bash', 'lisp']

View File

@ -16,7 +16,7 @@ def test_load_rule(mocker):
enabled_by_default=True, enabled_by_default=True,
priority=900, priority=900,
requires_output=True)) 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) == Rule('bash', match, get_new_command, priority=900)
load_source.assert_called_once_with('bash', '/rules/bash.py') load_source.assert_called_once_with('bash', '/rules/bash.py')
@ -25,7 +25,7 @@ class TestGetRules(object):
@pytest.fixture @pytest.fixture
def glob(self, mocker): def glob(self, mocker):
results = {} results = {}
mocker.patch('thefuck.corrector.Path.glob', mocker.patch('pathlib.Path.glob',
new_callable=lambda: lambda *_: results.pop('value', [])) new_callable=lambda: lambda *_: results.pop('value', []))
return lambda value: results.update({'value': value}) return lambda value: results.update({'value': value})
@ -48,54 +48,55 @@ class TestGetRules(object):
(['git.py', 'bash.py'], ['git'], [], ['git']), (['git.py', 'bash.py'], ['git'], [], ['git']),
(['git.py', 'bash.py'], conf.DEFAULT_RULES, ['git'], ['bash']), (['git.py', 'bash.py'], conf.DEFAULT_RULES, ['git'], ['bash']),
(['git.py', 'bash.py'], ['git'], ['git'], [])]) (['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]) glob([PosixPath(path) for path in paths])
settings = Mock(rules=self._prepare_rules(conf_rules), settings.update(rules=self._prepare_rules(conf_rules),
priority={}, priority={},
exclude_rules=self._prepare_rules(exclude_rules)) exclude_rules=self._prepare_rules(exclude_rules))
rules = corrector.get_rules(Path('~'), settings) rules = corrector.get_rules()
self._compare_names(rules, loaded_rules) self._compare_names(rules, loaded_rules)
class TestIsRuleMatch(object): class TestIsRuleMatch(object):
def test_no_match(self, settings): def test_no_match(self):
assert not corrector.is_rule_match( 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 ..') 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')), rule = Rule('test', Mock(side_effect=OSError('Denied')),
requires_output=False) requires_output=False)
assert not corrector.is_rule_match( assert not corrector.is_rule_match(Command('ls'), rule)
Command('ls'), rule, settings)
assert capsys.readouterr()[1].split('\n')[0] == '[WARN] Rule test:' assert capsys.readouterr()[1].split('\n')[0] == '[WARN] Rule test:'
class TestMakeCorrectedCommands(object): class TestMakeCorrectedCommands(object):
def test_with_rule_returns_list(self): def test_with_rule_returns_list(self):
rule = Rule(get_new_command=lambda x, _: [x.script + '!', x.script + '@'], rule = Rule(get_new_command=lambda x: [x.script + '!', x.script + '@'],
priority=100) 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=100),
CorrectedCommand(script='test@', priority=200)] CorrectedCommand(script='test@', priority=200)]
def test_with_rule_returns_command(self): def test_with_rule_returns_command(self):
rule = Rule(get_new_command=lambda x, _: x.script + '!', rule = Rule(get_new_command=lambda x: x.script + '!',
priority=100) 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=100)]
def test_get_corrected_commands(mocker): def test_get_corrected_commands(mocker):
command = Command('test', 'test', 'test') command = Command('test', 'test', 'test')
rules = [Rule(match=lambda *_: False), rules = [Rule(match=lambda _: False),
Rule(match=lambda *_: True, Rule(match=lambda _: True,
get_new_command=lambda x, _: x.script + '!', priority=100), get_new_command=lambda x: x.script + '!', priority=100),
Rule(match=lambda *_: True, Rule(match=lambda _: True,
get_new_command=lambda x, _: [x.script + '@', x.script + ';'], get_new_command=lambda x: [x.script + '@', x.script + ';'],
priority=60)] priority=60)]
mocker.patch('thefuck.corrector.get_rules', return_value=rules) 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)] \
== ['test!', 'test@', 'test;'] == ['test!', 'test@', 'test;']

View File

@ -1,14 +1,20 @@
import pytest
from mock import Mock from mock import Mock
from thefuck import logs from thefuck import logs
def test_color(): def test_color(settings):
assert logs.color('red', Mock(no_colors=False)) == 'red' settings.no_colors = False
assert logs.color('red', Mock(no_colors=True)) == '' assert logs.color('red') == 'red'
settings.no_colors = True
assert logs.color('red') == ''
def test_debug(capsys): @pytest.mark.usefixtures('no_colors')
logs.debug('test', Mock(no_colors=True, debug=True)) @pytest.mark.parametrize('debug, stderr', [
assert capsys.readouterr() == ('', 'DEBUG: test\n') (True, 'DEBUG: test\n'),
logs.debug('test', Mock(no_colors=True, debug=False)) (False, '')])
assert capsys.readouterr() == ('', '') def test_debug(capsys, settings, debug, stderr):
settings.debug = debug
logs.debug('test')
assert capsys.readouterr() == ('', stderr)

View File

@ -24,9 +24,9 @@ class TestGetCommand(object):
monkeypatch.setattr('thefuck.shells.from_shell', lambda x: x) monkeypatch.setattr('thefuck.shells.from_shell', lambda x: x)
monkeypatch.setattr('thefuck.shells.to_shell', lambda x: x) monkeypatch.setattr('thefuck.shells.to_shell', lambda x: x)
def test_get_command_calls(self, Popen): def test_get_command_calls(self, Popen, settings):
assert main.get_command(Mock(env={}), settings.env = {}
['thefuck', 'apt-get', 'search', 'vim']) \ assert main.get_command(['thefuck', 'apt-get', 'search', 'vim']) \
== Command('apt-get search vim', 'stdout', 'stderr') == Command('apt-get search vim', 'stdout', 'stderr')
Popen.assert_called_once_with('apt-get search vim', Popen.assert_called_once_with('apt-get search vim',
shell=True, shell=True,
@ -41,6 +41,6 @@ class TestGetCommand(object):
(['thefuck', 'ls'], 'ls')]) (['thefuck', 'ls'], 'ls')])
def test_get_command_script(self, args, result): def test_get_command_script(self, args, result):
if result: if result:
assert main.get_command(Mock(env={}), args).script == result assert main.get_command(args).script == result
else: else:
assert main.get_command(Mock(env={}), args) is None assert main.get_command(args) is None

View File

@ -10,14 +10,6 @@ def test_rules_names_list():
assert Rule('bash') not in RulesNamesList(['lisp']) 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): class TestSortedCorrectedCommandsSequence(object):
def test_realises_generator_only_on_demand(self, settings): def test_realises_generator_only_on_demand(self, settings):
should_realise = False should_realise = False
@ -28,24 +20,23 @@ class TestSortedCorrectedCommandsSequence(object):
assert should_realise assert should_realise
yield CorrectedCommand('git checkout', priority=100) yield CorrectedCommand('git checkout', priority=100)
commands = SortedCorrectedCommandsSequence(gen(), settings) commands = SortedCorrectedCommandsSequence(gen())
assert commands[0] == CorrectedCommand('git commit') assert commands[0] == CorrectedCommand('git commit')
should_realise = True should_realise = True
assert commands[1] == CorrectedCommand('git checkout', priority=100) assert commands[1] == CorrectedCommand('git checkout', priority=100)
assert commands[2] == CorrectedCommand('git branch', priority=200) assert commands[2] == CorrectedCommand('git branch', priority=200)
def test_remove_duplicates(self, settings): def test_remove_duplicates(self):
side_effect = lambda *_: None side_effect = lambda *_: None
seq = SortedCorrectedCommandsSequence( seq = SortedCorrectedCommandsSequence(
iter([CorrectedCommand('ls', priority=100), iter([CorrectedCommand('ls', priority=100),
CorrectedCommand('ls', priority=200), CorrectedCommand('ls', priority=200),
CorrectedCommand('ls', side_effect, 300)]), CorrectedCommand('ls', side_effect, 300)]))
settings)
assert set(seq) == {CorrectedCommand('ls', priority=100), assert set(seq) == {CorrectedCommand('ls', priority=100),
CorrectedCommand('ls', side_effect, 300)} CorrectedCommand('ls', side_effect, 300)}
def test_with_blank(self, settings): def test_with_blank(self):
seq = SortedCorrectedCommandsSequence(iter([]), settings) seq = SortedCorrectedCommandsSequence(iter([]))
assert list(seq) == [] assert list(seq) == []

View File

@ -56,66 +56,55 @@ def test_command_selector():
assert changes == [1, 2, 3, 1, 3] assert changes == [1, 2, 3, 1, 3]
@pytest.mark.usefixtures('no_colors')
class TestSelectCommand(object): class TestSelectCommand(object):
@pytest.fixture @pytest.fixture
def commands_with_side_effect(self, settings): def commands_with_side_effect(self):
return SortedCorrectedCommandsSequence( return SortedCorrectedCommandsSequence(
iter([CorrectedCommand('ls', lambda *_: None, 100), iter([CorrectedCommand('ls', lambda *_: None, 100),
CorrectedCommand('cd', lambda *_: None, 100)]), CorrectedCommand('cd', lambda *_: None, 100)]))
settings)
@pytest.fixture @pytest.fixture
def commands(self, settings): def commands(self):
return SortedCorrectedCommandsSequence( return SortedCorrectedCommandsSequence(
iter([CorrectedCommand('ls', None, 100), iter([CorrectedCommand('ls', None, 100),
CorrectedCommand('cd', None, 100)]), CorrectedCommand('cd', None, 100)]))
settings)
def test_without_commands(self, capsys): 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') assert capsys.readouterr() == ('', 'No fucks given\n')
def test_without_confirmation(self, capsys, commands): def test_without_confirmation(self, capsys, commands, settings):
assert ui.select_command(commands, settings.require_confirmation = False
Mock(debug=False, no_color=True, assert ui.select_command(commands) == commands[0]
require_confirmation=False)) == commands[0]
assert capsys.readouterr() == ('', 'ls\n') assert capsys.readouterr() == ('', 'ls\n')
def test_without_confirmation_with_side_effects(self, capsys, def test_without_confirmation_with_side_effects(
commands_with_side_effect): self, capsys, commands_with_side_effect, settings):
assert ui.select_command(commands_with_side_effect, settings.require_confirmation = False
Mock(debug=False, no_color=True, assert ui.select_command(commands_with_side_effect) \
require_confirmation=False)) \
== commands_with_side_effect[0] == commands_with_side_effect[0]
assert capsys.readouterr() == ('', 'ls (+side effect)\n') assert capsys.readouterr() == ('', 'ls (+side effect)\n')
def test_with_confirmation(self, capsys, patch_getch, commands): def test_with_confirmation(self, capsys, patch_getch, commands):
patch_getch(['\n']) patch_getch(['\n'])
assert ui.select_command(commands, assert ui.select_command(commands) == commands[0]
Mock(debug=False, no_color=True,
require_confirmation=True)) == commands[0]
assert capsys.readouterr() == ('', u'\x1b[1K\rls [enter/↑/↓/ctrl+c]\n') assert capsys.readouterr() == ('', u'\x1b[1K\rls [enter/↑/↓/ctrl+c]\n')
def test_with_confirmation_abort(self, capsys, patch_getch, commands): def test_with_confirmation_abort(self, capsys, patch_getch, commands):
patch_getch([KeyboardInterrupt]) patch_getch([KeyboardInterrupt])
assert ui.select_command(commands, assert ui.select_command(commands) is None
Mock(debug=False, no_color=True,
require_confirmation=True)) is None
assert capsys.readouterr() == ('', u'\x1b[1K\rls [enter/↑/↓/ctrl+c]\nAborted\n') assert capsys.readouterr() == ('', u'\x1b[1K\rls [enter/↑/↓/ctrl+c]\nAborted\n')
def test_with_confirmation_with_side_effct(self, capsys, patch_getch, def test_with_confirmation_with_side_effct(self, capsys, patch_getch,
commands_with_side_effect): commands_with_side_effect):
patch_getch(['\n']) patch_getch(['\n'])
assert ui.select_command(commands_with_side_effect, assert ui.select_command(commands_with_side_effect)\
Mock(debug=False, no_color=True,
require_confirmation=True))\
== commands_with_side_effect[0] == commands_with_side_effect[0]
assert capsys.readouterr() == ('', u'\x1b[1K\rls (+side effect) [enter/↑/↓/ctrl+c]\n') assert capsys.readouterr() == ('', u'\x1b[1K\rls (+side effect) [enter/↑/↓/ctrl+c]\n')
def test_with_confirmation_select_second(self, capsys, patch_getch, commands): def test_with_confirmation_select_second(self, capsys, patch_getch, commands):
patch_getch(['\x1b', '[', 'B', '\n']) patch_getch(['\x1b', '[', 'B', '\n'])
assert ui.select_command(commands, assert ui.select_command(commands) == commands[1]
Mock(debug=False, no_color=True,
require_confirmation=True)) == commands[1]
assert capsys.readouterr() == ( assert capsys.readouterr() == (
'', u'\x1b[1K\rls [enter/↑/↓/ctrl+c]\x1b[1K\rcd [enter/↑/↓/ctrl+c]\n') '', u'\x1b[1K\rls [enter/↑/↓/ctrl+c]\x1b[1K\rcd [enter/↑/↓/ctrl+c]\n')

View File

@ -1,10 +1,9 @@
import pytest import pytest
from mock import Mock from mock import Mock
import six import six
from thefuck.utils import wrap_settings, \ from thefuck.utils import default_settings, \
memoize, get_closest, get_all_executables, replace_argument, \ memoize, get_closest, get_all_executables, replace_argument, \
get_all_matched_commands, is_app, for_app, cache get_all_matched_commands, is_app, for_app, cache, compatibility_call
from thefuck.types import Settings
from tests.utils import Command from tests.utils import Command
@ -12,9 +11,12 @@ from tests.utils import Command
({'key': 'val'}, {}, {'key': 'val'}), ({'key': 'val'}, {}, {'key': 'val'}),
({'key': 'new-val'}, {'key': 'val'}, {'key': 'val'}), ({'key': 'new-val'}, {'key': 'val'}, {'key': 'val'}),
({'key': 'new-val', 'unset': 'unset'}, {'key': 'val'}, {'key': 'val', 'unset': 'unset'})]) ({'key': 'new-val', 'unset': 'unset'}, {'key': 'val'}, {'key': 'val', 'unset': 'unset'})])
def test_wrap_settings(override, old, new): def test_default_settings(settings, override, old, new):
fn = lambda _, settings: settings settings.clear()
assert wrap_settings(override)(fn)(None, Settings(old)) == new settings.update(old)
fn = lambda _: _
default_settings(override)(fn)(None)
assert settings == new
def test_memoize(): def test_memoize():
@ -112,10 +114,10 @@ def test_is_app(script, names, result):
('hg diff', ['git', 'hub'], False)]) ('hg diff', ['git', 'hub'], False)])
def test_for_app(script, names, result): def test_for_app(script, names, result):
@for_app(*names) @for_app(*names)
def match(command, settings): def match(command):
return True return True
assert match(Command(script), None) == result assert match(Command(script)) == result
class TestCache(object): class TestCache(object):
@ -180,3 +182,50 @@ class TestCache(object):
shelve.update({key: {'etag': '-1', 'value': 'old-value'}}) shelve.update({key: {'etag': '-1', 'value': 'old-value'}})
assert fn() == 'test' assert fn() == 'test'
assert shelve == {key: {'etag': '0', 'value': 'test'}} assert shelve == {key: {'etag': '0', 'value': 'test'}}
class TestCompatibilityCall(object):
def test_match(self):
def match(command):
assert command == Command()
return True
assert compatibility_call(match, Command())
def test_old_match(self, settings):
def match(command, _settings):
assert command == Command()
assert settings == _settings
return True
assert compatibility_call(match, Command())
def test_get_new_command(self):
def get_new_command(command):
assert command == Command()
return True
assert compatibility_call(get_new_command, Command())
def test_old_get_new_command(self, settings):
def get_new_command(command, _settings):
assert command == Command()
assert settings == _settings
return True
assert compatibility_call(get_new_command, Command())
def test_side_effect(self):
def side_effect(command, new_command):
assert command == Command() == new_command
return True
assert compatibility_call(side_effect, Command(), Command())
def test_old_side_effect(self, settings):
def side_effect(command, new_command, _settings):
assert command == Command() == new_command
assert settings == _settings
return True
assert compatibility_call(side_effect, Command(), Command())

View File

@ -1,12 +1,11 @@
from copy import copy
from imp import load_source from imp import load_source
import os import os
import sys import sys
from six import text_type from six import text_type
from . import logs, types from .types import RulesNamesList, Settings
class _DefaultRulesNames(types.RulesNamesList): class _DefaultRulesNames(RulesNamesList):
def __add__(self, items): def __add__(self, items):
return _DefaultRulesNames(list(self) + items) return _DefaultRulesNames(list(self) + items)
@ -24,7 +23,6 @@ class _DefaultRulesNames(types.RulesNamesList):
DEFAULT_RULES = _DefaultRulesNames([]) DEFAULT_RULES = _DefaultRulesNames([])
DEFAULT_PRIORITY = 1000 DEFAULT_PRIORITY = 1000
DEFAULT_SETTINGS = {'rules': DEFAULT_RULES, DEFAULT_SETTINGS = {'rules': DEFAULT_RULES,
'exclude_rules': [], 'exclude_rules': [],
'wait_command': 3, 'wait_command': 3,
@ -42,7 +40,6 @@ ENV_TO_ATTR = {'THEFUCK_RULES': 'rules',
'THEFUCK_PRIORITY': 'priority', 'THEFUCK_PRIORITY': 'priority',
'THEFUCK_DEBUG': 'debug'} 'THEFUCK_DEBUG': 'debug'}
SETTINGS_HEADER = u"""# ~/.thefuck/settings.py: The Fuck settings file SETTINGS_HEADER = u"""# ~/.thefuck/settings.py: The Fuck settings file
# #
# The rules are defined as in the example bellow: # The rules are defined as in the example bellow:
@ -105,30 +102,30 @@ def _settings_from_env():
if env in os.environ} if env in os.environ}
def get_settings(user_dir): settings = Settings(DEFAULT_SETTINGS)
"""Returns settings filled with values from `settings.py` and env."""
conf = copy(DEFAULT_SETTINGS)
try: def init_settings(user_dir):
conf.update(_settings_from_file(user_dir)) """Fills `settings` with values from `settings.py` and env."""
except Exception: from .logs import exception
logs.exception("Can't load settings from file",
sys.exc_info(), settings.user_dir = user_dir
types.Settings(conf))
try: try:
conf.update(_settings_from_env()) settings.update(_settings_from_file(user_dir))
except Exception: except Exception:
logs.exception("Can't load settings from env", exception("Can't load settings from file", sys.exc_info())
sys.exc_info(),
types.Settings(conf))
if not isinstance(conf['rules'], types.RulesNamesList): try:
conf['rules'] = types.RulesNamesList(conf['rules']) settings.update(_settings_from_env())
except Exception:
exception("Can't load settings from env", sys.exc_info())
if not isinstance(conf['exclude_rules'], types.RulesNamesList): if not isinstance(settings['rules'], RulesNamesList):
conf['exclude_rules'] = types.RulesNamesList(conf['exclude_rules']) settings.rules = RulesNamesList(settings['rules'])
return types.Settings(conf) if not isinstance(settings.exclude_rules, RulesNamesList):
settings.exclude_rules = RulesNamesList(settings.exclude_rules)
def initialize_settings_file(user_dir): def initialize_settings_file(user_dir):

View File

@ -1,44 +1,47 @@
import sys import sys
from imp import load_source from imp import load_source
from pathlib import Path from pathlib import Path
from . import conf, types, logs from .conf import settings, DEFAULT_PRIORITY
from .types import Rule, CorrectedCommand, SortedCorrectedCommandsSequence
from .utils import compatibility_call
from . import logs
def load_rule(rule, settings): def load_rule(rule):
"""Imports rule module and returns it.""" """Imports rule module and returns it."""
name = rule.name[:-3] name = rule.name[:-3]
with logs.debug_time(u'Importing rule: {};'.format(name), settings): with logs.debug_time(u'Importing rule: {};'.format(name)):
rule_module = load_source(name, str(rule)) rule_module = load_source(name, str(rule))
priority = getattr(rule_module, 'priority', conf.DEFAULT_PRIORITY) priority = getattr(rule_module, 'priority', DEFAULT_PRIORITY)
return types.Rule(name, rule_module.match, return Rule(name, rule_module.match,
rule_module.get_new_command, rule_module.get_new_command,
getattr(rule_module, 'enabled_by_default', True), getattr(rule_module, 'enabled_by_default', True),
getattr(rule_module, 'side_effect', None), getattr(rule_module, 'side_effect', None),
settings.priority.get(name, priority), settings.priority.get(name, priority),
getattr(rule_module, 'requires_output', True)) getattr(rule_module, 'requires_output', True))
def get_loaded_rules(rules, settings): def get_loaded_rules(rules):
"""Yields all available rules.""" """Yields all available rules."""
for rule in rules: for rule in rules:
if rule.name != '__init__.py': if rule.name != '__init__.py':
loaded_rule = load_rule(rule, settings) loaded_rule = load_rule(rule)
if loaded_rule in settings.rules and \ if loaded_rule in settings.rules and \
loaded_rule not in settings.exclude_rules: loaded_rule not in settings.exclude_rules:
yield loaded_rule yield loaded_rule
def get_rules(user_dir, settings): def get_rules():
"""Returns all enabled rules.""" """Returns all enabled rules."""
bundled = Path(__file__).parent \ bundled = Path(__file__).parent \
.joinpath('rules') \ .joinpath('rules') \
.glob('*.py') .glob('*.py')
user = user_dir.joinpath('rules').glob('*.py') user = settings.user_dir.joinpath('rules').glob('*.py')
return sorted(get_loaded_rules(sorted(bundled) + sorted(user), settings), return sorted(get_loaded_rules(sorted(bundled) + sorted(user)),
key=lambda rule: rule.priority) key=lambda rule: rule.priority)
def is_rule_match(command, rule, settings): def is_rule_match(command, rule):
"""Returns first matched rule for command.""" """Returns first matched rule for command."""
script_only = command.stdout is None and command.stderr is None script_only = command.stdout is None and command.stderr is None
@ -46,27 +49,26 @@ def is_rule_match(command, rule, settings):
return False return False
try: try:
with logs.debug_time(u'Trying rule: {};'.format(rule.name), with logs.debug_time(u'Trying rule: {};'.format(rule.name)):
settings): if compatibility_call(rule.match, command):
if rule.match(command, settings):
return True return True
except Exception: except Exception:
logs.rule_failed(rule, sys.exc_info(), settings) logs.rule_failed(rule, sys.exc_info())
def make_corrected_commands(command, rule, settings): def make_corrected_commands(command, rule):
new_commands = rule.get_new_command(command, settings) new_commands = compatibility_call(rule.get_new_command, command)
if not isinstance(new_commands, list): if not isinstance(new_commands, list):
new_commands = (new_commands,) new_commands = (new_commands,)
for n, new_command in enumerate(new_commands): for n, new_command in enumerate(new_commands):
yield types.CorrectedCommand(script=new_command, yield CorrectedCommand(script=new_command,
side_effect=rule.side_effect, side_effect=rule.side_effect,
priority=(n + 1) * rule.priority) priority=(n + 1) * rule.priority)
def get_corrected_commands(command, user_dir, settings): def get_corrected_commands(command):
corrected_commands = ( corrected_commands = (
corrected for rule in get_rules(user_dir, settings) corrected for rule in get_rules()
if is_rule_match(command, rule, settings) if is_rule_match(command, rule)
for corrected in make_corrected_commands(command, rule, settings)) for corrected in make_corrected_commands(command, rule))
return types.SortedCorrectedCommandsSequence(corrected_commands, settings) return SortedCorrectedCommandsSequence(corrected_commands)

View File

@ -5,9 +5,10 @@ from datetime import datetime
import sys import sys
from traceback import format_exception from traceback import format_exception
import colorama import colorama
from .conf import settings
def color(color_, settings): def color(color_):
"""Utility for ability to disabling colored output.""" """Utility for ability to disabling colored output."""
if settings.no_colors: if settings.no_colors:
return '' return ''
@ -15,37 +16,37 @@ def color(color_, settings):
return color_ return color_
def exception(title, exc_info, settings): def exception(title, exc_info):
sys.stderr.write( sys.stderr.write(
u'{warn}[WARN] {title}:{reset}\n{trace}' u'{warn}[WARN] {title}:{reset}\n{trace}'
u'{warn}----------------------------{reset}\n\n'.format( u'{warn}----------------------------{reset}\n\n'.format(
warn=color(colorama.Back.RED + colorama.Fore.WHITE warn=color(colorama.Back.RED + colorama.Fore.WHITE
+ colorama.Style.BRIGHT, settings), + colorama.Style.BRIGHT),
reset=color(colorama.Style.RESET_ALL, settings), reset=color(colorama.Style.RESET_ALL),
title=title, title=title,
trace=''.join(format_exception(*exc_info)))) trace=''.join(format_exception(*exc_info))))
def rule_failed(rule, exc_info, settings): def rule_failed(rule, exc_info):
exception('Rule {}'.format(rule.name), exc_info, settings) exception('Rule {}'.format(rule.name), exc_info)
def failed(msg, settings): def failed(msg):
sys.stderr.write('{red}{msg}{reset}\n'.format( sys.stderr.write('{red}{msg}{reset}\n'.format(
msg=msg, msg=msg,
red=color(colorama.Fore.RED, settings), red=color(colorama.Fore.RED),
reset=color(colorama.Style.RESET_ALL, settings))) reset=color(colorama.Style.RESET_ALL)))
def show_corrected_command(corrected_command, settings): def show_corrected_command(corrected_command):
sys.stderr.write('{bold}{script}{reset}{side_effect}\n'.format( sys.stderr.write('{bold}{script}{reset}{side_effect}\n'.format(
script=corrected_command.script, script=corrected_command.script,
side_effect=' (+side effect)' if corrected_command.side_effect else '', side_effect=' (+side effect)' if corrected_command.side_effect else '',
bold=color(colorama.Style.BRIGHT, settings), bold=color(colorama.Style.BRIGHT),
reset=color(colorama.Style.RESET_ALL, settings))) reset=color(colorama.Style.RESET_ALL)))
def confirm_text(corrected_command, settings): def confirm_text(corrected_command):
sys.stderr.write( sys.stderr.write(
('{clear}{bold}{script}{reset}{side_effect} ' ('{clear}{bold}{script}{reset}{side_effect} '
'[{green}enter{reset}/{blue}{reset}/{blue}{reset}' '[{green}enter{reset}/{blue}{reset}/{blue}{reset}'
@ -53,42 +54,42 @@ def confirm_text(corrected_command, settings):
script=corrected_command.script, script=corrected_command.script,
side_effect=' (+side effect)' if corrected_command.side_effect else '', side_effect=' (+side effect)' if corrected_command.side_effect else '',
clear='\033[1K\r', clear='\033[1K\r',
bold=color(colorama.Style.BRIGHT, settings), bold=color(colorama.Style.BRIGHT),
green=color(colorama.Fore.GREEN, settings), green=color(colorama.Fore.GREEN),
red=color(colorama.Fore.RED, settings), red=color(colorama.Fore.RED),
reset=color(colorama.Style.RESET_ALL, settings), reset=color(colorama.Style.RESET_ALL),
blue=color(colorama.Fore.BLUE, settings))) blue=color(colorama.Fore.BLUE)))
def debug(msg, settings): def debug(msg):
if settings.debug: if settings.debug:
sys.stderr.write(u'{blue}{bold}DEBUG:{reset} {msg}\n'.format( sys.stderr.write(u'{blue}{bold}DEBUG:{reset} {msg}\n'.format(
msg=msg, msg=msg,
reset=color(colorama.Style.RESET_ALL, settings), reset=color(colorama.Style.RESET_ALL),
blue=color(colorama.Fore.BLUE, settings), blue=color(colorama.Fore.BLUE),
bold=color(colorama.Style.BRIGHT, settings))) bold=color(colorama.Style.BRIGHT)))
@contextmanager @contextmanager
def debug_time(msg, settings): def debug_time(msg):
started = datetime.now() started = datetime.now()
try: try:
yield yield
finally: finally:
debug(u'{} took: {}'.format(msg, datetime.now() - started), settings) debug(u'{} took: {}'.format(msg, datetime.now() - started))
def how_to_configure_alias(configuration_details, settings): def how_to_configure_alias(configuration_details):
print("Seems like {bold}fuck{reset} alias isn't configured!".format( print("Seems like {bold}fuck{reset} alias isn't configured!".format(
bold=color(colorama.Style.BRIGHT, settings), bold=color(colorama.Style.BRIGHT),
reset=color(colorama.Style.RESET_ALL, settings))) reset=color(colorama.Style.RESET_ALL)))
if configuration_details: if configuration_details:
content, path = configuration_details content, path = configuration_details
print( print(
"Please put {bold}{content}{reset} in your " "Please put {bold}{content}{reset} in your "
"{bold}{path}{reset}.".format( "{bold}{path}{reset}.".format(
bold=color(colorama.Style.BRIGHT, settings), bold=color(colorama.Style.BRIGHT),
reset=color(colorama.Style.RESET_ALL, settings), reset=color(colorama.Style.RESET_ALL),
path=path, path=path,
content=content)) content=content))
print('More details - https://github.com/nvbn/thefuck#manual-installation') print('More details - https://github.com/nvbn/thefuck#manual-installation')

View File

@ -10,8 +10,10 @@ import sys
from psutil import Process, TimeoutExpired from psutil import Process, TimeoutExpired
import colorama import colorama
import six import six
from . import logs, conf, types, shells from . import logs, types, shells
from .conf import initialize_settings_file, init_settings, settings
from .corrector import get_corrected_commands from .corrector import get_corrected_commands
from .utils import compatibility_call
from .ui import select_command from .ui import select_command
@ -21,11 +23,11 @@ def setup_user_dir():
rules_dir = user_dir.joinpath('rules') rules_dir = user_dir.joinpath('rules')
if not rules_dir.is_dir(): if not rules_dir.is_dir():
rules_dir.mkdir(parents=True) rules_dir.mkdir(parents=True)
conf.initialize_settings_file(user_dir) initialize_settings_file(user_dir)
return user_dir return user_dir
def wait_output(settings, popen): def wait_output(popen):
"""Returns `True` if we can get output of the command in the """Returns `True` if we can get output of the command in the
`settings.wait_command` time. `settings.wait_command` time.
@ -43,7 +45,7 @@ def wait_output(settings, popen):
return False return False
def get_command(settings, args): def get_command(args):
"""Creates command from `args` and executes it.""" """Creates command from `args` and executes it."""
if six.PY2: if six.PY2:
script = ' '.join(arg.decode('utf-8') for arg in args[1:]) script = ' '.join(arg.decode('utf-8') for arg in args[1:])
@ -58,26 +60,25 @@ def get_command(settings, args):
env = dict(os.environ) env = dict(os.environ)
env.update(settings.env) env.update(settings.env)
with logs.debug_time(u'Call: {}; with env: {};'.format(script, env), with logs.debug_time(u'Call: {}; with env: {};'.format(script, env)):
settings):
result = Popen(script, shell=True, stdout=PIPE, stderr=PIPE, env=env) result = Popen(script, shell=True, stdout=PIPE, stderr=PIPE, env=env)
if wait_output(settings, result): if wait_output(result):
stdout = result.stdout.read().decode('utf-8') stdout = result.stdout.read().decode('utf-8')
stderr = result.stderr.read().decode('utf-8') stderr = result.stderr.read().decode('utf-8')
logs.debug(u'Received stdout: {}'.format(stdout), settings) logs.debug(u'Received stdout: {}'.format(stdout))
logs.debug(u'Received stderr: {}'.format(stderr), settings) logs.debug(u'Received stderr: {}'.format(stderr))
return types.Command(script, stdout, stderr) return types.Command(script, stdout, stderr)
else: else:
logs.debug(u'Execution timed out!', settings) logs.debug(u'Execution timed out!')
return types.Command(script, None, None) return types.Command(script, None, None)
def run_command(old_cmd, command, settings): def run_command(old_cmd, command):
"""Runs command from rule for passed command.""" """Runs command from rule for passed command."""
if command.side_effect: if command.side_effect:
command.side_effect(old_cmd, command.script, settings) compatibility_call(command.side_effect, old_cmd, command.script)
shells.put_to_history(command.script) shells.put_to_history(command.script)
print(command.script) print(command.script)
@ -87,20 +88,20 @@ def run_command(old_cmd, command, settings):
def fix_command(): def fix_command():
colorama.init() colorama.init()
user_dir = setup_user_dir() user_dir = setup_user_dir()
settings = conf.get_settings(user_dir) init_settings(user_dir)
with logs.debug_time('Total', settings): with logs.debug_time('Total'):
logs.debug(u'Run with settings: {}'.format(pformat(settings)), settings) logs.debug(u'Run with settings: {}'.format(pformat(settings)))
command = get_command(settings, sys.argv) command = get_command(sys.argv)
if not command: if not command:
logs.debug('Empty command, nothing to do', settings) logs.debug('Empty command, nothing to do')
return return
corrected_commands = get_corrected_commands(command, user_dir, settings) corrected_commands = get_corrected_commands(command)
selected_command = select_command(corrected_commands, settings) selected_command = select_command(corrected_commands)
if selected_command: if selected_command:
run_command(command, selected_command, settings) run_command(command, selected_command)
def _get_current_version(): def _get_current_version():
@ -128,8 +129,8 @@ def how_to_configure_alias():
""" """
colorama.init() colorama.init()
user_dir = setup_user_dir() user_dir = setup_user_dir()
settings = conf.get_settings(user_dir) init_settings(user_dir)
logs.how_to_configure_alias(shells.how_to_configure(), settings) logs.how_to_configure_alias(shells.how_to_configure())
def main(): def main():

View File

@ -20,11 +20,11 @@ def get_package(command):
return None return None
def match(command, settings): def match(command):
return 'not found' in command.stderr and get_package(command.script) return 'not found' in command.stderr and get_package(command.script)
def get_new_command(command, settings): def get_new_command(command):
name = get_package(command.script) name = get_package(command.script)
formatme = shells.and_('sudo apt-get install {}', '{}') formatme = shells.and_('sudo apt-get install {}', '{}')
return formatme.format(name, command.script) return formatme.format(name, command.script)

View File

@ -3,9 +3,9 @@ from thefuck.utils import for_app
@for_app('apt-get') @for_app('apt-get')
def match(command, settings): def match(command):
return command.script.startswith('apt-get search') return command.script.startswith('apt-get search')
def get_new_command(command, settings): def get_new_command(command):
return re.sub(r'^apt-get', 'apt-cache', command.script) return re.sub(r'^apt-get', 'apt-cache', command.script)

View File

@ -24,7 +24,7 @@ def _get_similar_formula(formula_name):
return get_closest(formula_name, _get_formulas(), 1, 0.85) return get_closest(formula_name, _get_formulas(), 1, 0.85)
def match(command, settings): def match(command):
is_proper_command = ('brew install' in command.script and is_proper_command = ('brew install' in command.script and
'No available formula' in command.stderr) 'No available formula' in command.stderr)
@ -35,7 +35,7 @@ def match(command, settings):
return False return False
def get_new_command(command, settings): def get_new_command(command):
not_exist_formula = re.findall(r'Error: No available formula for ([a-z]+)', not_exist_formula = re.findall(r'Error: No available formula for ([a-z]+)',
command.stderr)[0] command.stderr)[0]
exist_formula = _get_similar_formula(not_exist_formula) exist_formula = _get_similar_formula(not_exist_formula)

View File

@ -63,7 +63,7 @@ def _brew_commands():
'doctor', 'create', 'edit'] 'doctor', 'create', 'edit']
def match(command, settings): def match(command):
is_proper_command = ('brew' in command.script and is_proper_command = ('brew' in command.script and
'Unknown command' in command.stderr) 'Unknown command' in command.stderr)
@ -74,7 +74,7 @@ def match(command, settings):
return False return False
def get_new_command(command, settings): def get_new_command(command):
broken_cmd = re.findall(r'Error: Unknown command: ([a-z]+)', broken_cmd = re.findall(r'Error: Unknown command: ([a-z]+)',
command.stderr)[0] command.stderr)[0]
return replace_command(command, broken_cmd, _brew_commands()) return replace_command(command, broken_cmd, _brew_commands())

View File

@ -6,9 +6,9 @@
# It currently upgrades all formula but this will soon change to require '--all'. # It currently upgrades all formula but this will soon change to require '--all'.
def match(command, settings): def match(command):
return command.script == 'brew upgrade' return command.script == 'brew upgrade'
def get_new_command(command, settings): def get_new_command(command):
return command.script + ' --all' return command.script + ' --all'

View File

@ -1,6 +1,6 @@
def match(command, settings): def match(command):
return command.script == 'cargo' return command.script == 'cargo'
def get_new_command(command, settings): def get_new_command(command):
return 'cargo build' return 'cargo build'

View File

@ -3,12 +3,12 @@ from thefuck.utils import replace_argument, for_app
@for_app('cargo') @for_app('cargo')
def match(command, settings): def match(command):
return ('No such subcommand' in command.stderr return ('No such subcommand' in command.stderr
and 'Did you mean' in command.stderr) and 'Did you mean' in command.stderr)
def get_new_command(command, settings): def get_new_command(command):
broken = command.script.split()[1] broken = command.script.split()[1]
fix = re.findall(r'Did you mean `([^`]*)`', command.stderr)[0] fix = re.findall(r'Did you mean `([^`]*)`', command.stderr)[0]

View File

@ -18,7 +18,7 @@ def _get_sub_dirs(parent):
@sudo_support @sudo_support
@for_app('cd') @for_app('cd')
def match(command, settings): def match(command):
"""Match function copied from cd_mkdir.py""" """Match function copied from cd_mkdir.py"""
return (command.script.startswith('cd ') return (command.script.startswith('cd ')
and ('no such file or directory' in command.stderr.lower() and ('no such file or directory' in command.stderr.lower()
@ -26,7 +26,7 @@ def match(command, settings):
@sudo_support @sudo_support
def get_new_command(command, settings): def get_new_command(command):
""" """
Attempt to rebuild the path string by spellchecking the directories. Attempt to rebuild the path string by spellchecking the directories.
If it fails (i.e. no directories are a close enough match), then it If it fails (i.e. no directories are a close enough match), then it
@ -47,7 +47,7 @@ def get_new_command(command, settings):
if best_matches: if best_matches:
cwd = os.path.join(cwd, best_matches[0]) cwd = os.path.join(cwd, best_matches[0])
else: else:
return cd_mkdir.get_new_command(command, settings) return cd_mkdir.get_new_command(command)
return 'cd "{0}"'.format(cwd) return 'cd "{0}"'.format(cwd)

View File

@ -6,12 +6,12 @@ from thefuck.specific.sudo import sudo_support
@sudo_support @sudo_support
@for_app('cd') @for_app('cd')
def match(command, settings): def match(command):
return (('no such file or directory' in command.stderr.lower() return (('no such file or directory' in command.stderr.lower()
or 'cd: can\'t cd to' in command.stderr.lower())) or 'cd: can\'t cd to' in command.stderr.lower()))
@sudo_support @sudo_support
def get_new_command(command, settings): def get_new_command(command):
repl = shells.and_('mkdir -p \\1', 'cd \\1') repl = shells.and_('mkdir -p \\1', 'cd \\1')
return re.sub(r'^cd (.*)', repl, command.script) return re.sub(r'^cd (.*)', repl, command.script)

View File

@ -8,9 +8,9 @@
# cd..: command not found # cd..: command not found
def match(command, settings): def match(command):
return command.script == 'cd..' return command.script == 'cd..'
def get_new_command(command, settings): def get_new_command(command):
return 'cd ..' return 'cd ..'

View File

@ -3,12 +3,12 @@ from thefuck.utils import replace_argument, for_app
@for_app('composer') @for_app('composer')
def match(command, settings): def match(command):
return (('did you mean this?' in command.stderr.lower() return (('did you mean this?' in command.stderr.lower()
or 'did you mean one of these?' in command.stderr.lower())) or 'did you mean one of these?' in command.stderr.lower()))
def get_new_command(command, settings): def get_new_command(command):
broken_cmd = re.findall(r"Command \"([^']*)\" is not defined", command.stderr)[0] broken_cmd = re.findall(r"Command \"([^']*)\" is not defined", command.stderr)[0]
new_cmd = re.findall(r'Did you mean this\?[^\n]*\n\s*([^\n]*)', command.stderr) new_cmd = re.findall(r'Did you mean this\?[^\n]*\n\s*([^\n]*)', command.stderr)
if not new_cmd: if not new_cmd:

View File

@ -5,11 +5,11 @@ from thefuck.utils import for_app
@sudo_support @sudo_support
@for_app('cp') @for_app('cp')
def match(command, settings): def match(command):
stderr = command.stderr.lower() stderr = command.stderr.lower()
return 'omitting directory' in stderr or 'is a directory' in stderr return 'omitting directory' in stderr or 'is a directory' in stderr
@sudo_support @sudo_support
def get_new_command(command, settings): def get_new_command(command):
return re.sub(r'^cp', 'cp -a', command.script) return re.sub(r'^cp', 'cp -a', command.script)

View File

@ -2,11 +2,11 @@ from thefuck.utils import for_app
@for_app(['g++', 'clang++']) @for_app(['g++', 'clang++'])
def match(command, settings): def match(command):
return ('This file requires compiler and library support for the ' return ('This file requires compiler and library support for the '
'ISO C++ 2011 standard.' in command.stderr or 'ISO C++ 2011 standard.' in command.stderr or
'-Wc++11-extensions' in command.stderr) '-Wc++11-extensions' in command.stderr)
def get_new_command(command, settings): def get_new_command(command):
return command.script + ' -std=c++11' return command.script + ' -std=c++11'

View File

@ -25,18 +25,18 @@ def _tar_file(cmd):
@for_app('tar') @for_app('tar')
def match(command, settings): def match(command):
return ('-C' not in command.script return ('-C' not in command.script
and _is_tar_extract(command.script) and _is_tar_extract(command.script)
and _tar_file(command.script) is not None) and _tar_file(command.script) is not None)
def get_new_command(command, settings): def get_new_command(command):
return shells.and_('mkdir -p {dir}', '{cmd} -C {dir}') \ return shells.and_('mkdir -p {dir}', '{cmd} -C {dir}') \
.format(dir=_tar_file(command.script)[1], cmd=command.script) .format(dir=_tar_file(command.script)[1], cmd=command.script)
def side_effect(old_cmd, command, settings): def side_effect(old_cmd, command):
with tarfile.TarFile(_tar_file(old_cmd.script)[0]) as archive: with tarfile.TarFile(_tar_file(old_cmd.script)[0]) as archive:
for file in archive.getnames(): for file in archive.getnames():
os.remove(file) os.remove(file)

View File

@ -22,16 +22,16 @@ def _zip_file(command):
@for_app('unzip') @for_app('unzip')
def match(command, settings): def match(command):
return ('-d' not in command.script return ('-d' not in command.script
and _is_bad_zip(_zip_file(command))) and _is_bad_zip(_zip_file(command)))
def get_new_command(command, settings): def get_new_command(command):
return '{} -d {}'.format(command.script, _zip_file(command)[:-4]) return '{} -d {}'.format(command.script, _zip_file(command)[:-4])
def side_effect(old_cmd, command, settings): def side_effect(old_cmd, command):
with zipfile.ZipFile(_zip_file(old_cmd), 'r') as archive: with zipfile.ZipFile(_zip_file(old_cmd), 'r') as archive:
for file in archive.namelist(): for file in archive.namelist():
os.remove(file) os.remove(file)

Some files were not shown because too many files have changed in this diff Show More