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

Merge branch 'josephfrazier-flake8'

This commit is contained in:
Vladimir Iakovlev 2017-03-13 13:39:16 +01:00
commit 02bcd8331d
60 changed files with 172 additions and 173 deletions

View File

@ -42,6 +42,7 @@ install:
- python setup.py develop - python setup.py develop
- rm -rf build - rm -rf build
script: script:
- flake8
- export COVERAGE_PYTHON_VERSION=python-${TRAVIS_PYTHON_VERSION:0:1} - export COVERAGE_PYTHON_VERSION=python-${TRAVIS_PYTHON_VERSION:0:1}
- export RUN_TESTS="coverage run --source=thefuck,tests -m py.test -v --capture=sys tests" - export RUN_TESTS="coverage run --source=thefuck,tests -m py.test -v --capture=sys tests"
- if [[ $TRAVIS_PYTHON_VERSION == 3.6 && $TRAVIS_OS_NAME != "osx" ]]; then $RUN_TESTS --enable-functional; fi - if [[ $TRAVIS_PYTHON_VERSION == 3.6 && $TRAVIS_OS_NAME != "osx" ]]; then $RUN_TESTS --enable-functional; fi

View File

@ -388,6 +388,12 @@ pip install -r requirements.txt
python setup.py develop python setup.py develop
``` ```
Run code style checks:
```bash
flake8
```
Run unit tests: Run unit tests:
```bash ```bash

View File

@ -20,4 +20,5 @@ install:
- "%PYTHON%/Scripts/pip.exe install -U -r requirements.txt" - "%PYTHON%/Scripts/pip.exe install -U -r requirements.txt"
test_script: test_script:
- "%PYTHON%/python.exe -m flake8"
- "%PYTHON%/Scripts/py.test.exe -sv" - "%PYTHON%/Scripts/py.test.exe -sv"

View File

@ -1,4 +1,5 @@
pip pip
flake8
pytest pytest
mock mock
pytest-mock pytest-mock

View File

@ -6,15 +6,15 @@ from thefuck.rules.brew_link import get_new_command, match
@pytest.fixture @pytest.fixture
def stderr(): def stderr():
return ("Error: Could not symlink bin/gcp\n" return ("Error: Could not symlink bin/gcp\n"
"Target /usr/local/bin/gcp\n" "Target /usr/local/bin/gcp\n"
"already exists. You may want to remove it:\n" "already exists. You may want to remove it:\n"
"rm '/usr/local/bin/gcp'\n" " rm '/usr/local/bin/gcp'\n"
"\n" "\n"
"To force the link and overwrite all conflicting files:\n" "To force the link and overwrite all conflicting files:\n"
"brew link --overwrite coreutils\n" " brew link --overwrite coreutils\n"
"\n" "\n"
"To list all files that would be deleted:\n" "To list all files that would be deleted:\n"
"brew link --overwrite --dry-run coreutils\n") " brew link --overwrite --dry-run coreutils\n")
@pytest.fixture @pytest.fixture
@ -29,7 +29,7 @@ def test_match(stderr, script):
@pytest.mark.parametrize('script', ['brew link coreutils']) @pytest.mark.parametrize('script', ['brew link coreutils'])
def test_not_match(script): def test_not_match(script):
stderr='' stderr = ''
assert not match(Command(script=script, stderr=stderr)) assert not match(Command(script=script, stderr=stderr))

View File

@ -22,7 +22,7 @@ def test_match(stdout, script):
@pytest.mark.parametrize('script', ['brew remove gnuplot']) @pytest.mark.parametrize('script', ['brew remove gnuplot'])
def test_not_match(script): def test_not_match(script):
stdout='Uninstalling /usr/local/Cellar/gnuplot/5.0.4_1... (44 files, 2.3M)\n' stdout = 'Uninstalling /usr/local/Cellar/gnuplot/5.0.4_1... (44 files, 2.3M)\n'
assert not match(Command(script=script, stdout=stdout)) assert not match(Command(script=script, stdout=stdout))

View File

@ -21,8 +21,8 @@ def test_match(brew_unknown_cmd):
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))
== ['brew list', 'brew install', 'brew uninstall'] == ['brew list', 'brew install', 'brew uninstall'])
cmds = get_new_command(Command('brew instaa', stderr=brew_unknown_cmd2)) cmds = get_new_command(Command('brew instaa', stderr=brew_unknown_cmd2))
assert 'brew install' in cmds assert 'brew install' in cmds

View File

@ -48,9 +48,9 @@ def test_match(composer_not_command, composer_not_command_one_of_this):
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)) \ stderr=composer_not_command))
== 'composer update' == 'composer update')
assert get_new_command( assert (get_new_command(Command('composer pdate',
Command('composer pdate', stderr=composer_not_command_one_of_this)) \ stderr=composer_not_command_one_of_this))
== 'composer selfupdate' == 'composer selfupdate')

View File

@ -2,7 +2,7 @@ import os
import pytest import pytest
import tarfile import tarfile
from thefuck.rules.dirty_untar import match, get_new_command, side_effect, \ from thefuck.rules.dirty_untar import match, get_new_command, side_effect, \
tar_extensions tar_extensions # noqa: E126
from tests.utils import Command from tests.utils import Command
@ -33,6 +33,7 @@ def tar_error(tmpdir):
return fixture return fixture
parametrize_extensions = pytest.mark.parametrize('ext', tar_extensions) parametrize_extensions = pytest.mark.parametrize('ext', tar_extensions)
# (filename as typed by the user, unquoted filename, quoted filename as per shells.quote) # (filename as typed by the user, unquoted filename, quoted filename as per shells.quote)

View File

@ -37,7 +37,7 @@ south.exceptions.GhostMigrations:
! I'm not trusting myself; either fix this yourself by fiddling ! I'm not trusting myself; either fix this yourself by fiddling
! with the south_migrationhistory table, or pass --delete-ghost-migrations ! with the south_migrationhistory table, or pass --delete-ghost-migrations
! to South to have it delete ALL of these records (this may not be good). ! to South to have it delete ALL of these records (this may not be good).
''' ''' # noqa
def test_match(stderr): def test_match(stderr):

View File

@ -39,5 +39,5 @@ def test_match(stderr):
def test_get_new_command(): def test_get_new_command():
assert get_new_command(Command('./manage.py migrate auth')) \ assert (get_new_command(Command('./manage.py migrate auth'))
== './manage.py migrate auth --merge' == './manage.py migrate auth --merge')

View File

@ -45,5 +45,5 @@ def test_not_match(command):
'fab prepare_extension:version=2016 deploy:beta=true -H the.fuck'), 'fab prepare_extension:version=2016 deploy:beta=true -H the.fuck'),
]) ])
def test_get_new_command(script, result): def test_get_new_command(script, result):
command = Command(script, stdout,stderr) command = Command(script, stdout, stderr)
assert get_new_command(command) == result assert get_new_command(command) == result

View File

@ -18,5 +18,5 @@ def test_match():
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'))\ assert (get_new_command(Command(u'ps -ef | grep foo'))
== 'ps -ef | grep foo' == 'ps -ef | grep foo')

View File

@ -191,7 +191,7 @@ E NameError: name 'mocker' is not defined
/home/thefuck/tests/rules/test_fix_file.py:218: NameError /home/thefuck/tests/rules/test_fix_file.py:218: NameError
""", ''), """, ''),
) ) # noqa
@pytest.mark.parametrize('test', tests) @pytest.mark.parametrize('test', tests)
@ -227,10 +227,6 @@ def test_get_new_command(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')
cmd = Command(script=test[0], stdout=test[4], stderr=test[5])
#assert (get_new_command(cmd, Settings({})) ==
# 'dummy_editor {} +{} && {}'.format(test[1], test[2], test[0]))
@pytest.mark.parametrize('test', tests) @pytest.mark.parametrize('test', tests)
@pytest.mark.usefixtures('no_memoize') @pytest.mark.usefixtures('no_memoize')
@ -243,7 +239,7 @@ def test_get_new_command_with_settings(mocker, monkeypatch, test, settings):
if test[3]: if test[3]:
assert (get_new_command(cmd) == assert (get_new_command(cmd) ==
u'dummy_editor {} +{}:{} && {}'.format(test[1], test[2], test[3], test[0])) u'dummy_editor {} +{}:{} && {}'.format(test[1], test[2], test[3], test[0]))
else: else:
assert (get_new_command(cmd) == assert (get_new_command(cmd) ==
u'dummy_editor {} +{} && {}'.format(test[1], test[2], test[0])) u'dummy_editor {} +{} && {}'.format(test[1], test[2], test[0]))

View File

@ -18,5 +18,5 @@ def test_match(stderr):
def test_get_new_command(stderr): def test_get_new_command(stderr):
assert get_new_command(Command('git add dist/*.js', stderr=stderr)) \ assert (get_new_command(Command('git add dist/*.js', stderr=stderr))
== "git add --force dist/*.js" == "git add --force dist/*.js")

View File

@ -49,9 +49,9 @@ def test_match(git_not_command, git_command, git_not_command_one_of_this):
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)) \ 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))
== ['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))
== ['git tag', 'git stage'] == ['git tag', 'git stage'])

View File

@ -25,5 +25,5 @@ def test_match(stderr):
def test_get_new_command(stderr): def test_get_new_command(stderr):
assert get_new_command(Command('git pull', stderr=stderr)) \ 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

@ -15,5 +15,5 @@ def test_match(stderr):
def test_get_new_command(stderr): def test_get_new_command(stderr):
assert get_new_command(Command('git pull', stderr=stderr)) \ assert (get_new_command(Command('git pull', stderr=stderr))
== "git stash && git pull && git stash pop" == "git stash && git pull && git stash pop")

View File

@ -15,5 +15,5 @@ def test_match(stderr):
def test_get_new_command(stderr): def test_get_new_command(stderr):
assert get_new_command(Command('git pull', stderr=stderr)) \ assert (get_new_command(Command('git pull', stderr=stderr))
== "git stash && git pull && git stash pop" == "git stash && git pull && git stash pop")

View File

@ -39,12 +39,7 @@ To /tmp/bar
@pytest.mark.parametrize('command', [ @pytest.mark.parametrize('command', [
Command(script='git push', stderr=git_err), Command(script='git push', stderr=git_err),
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):
assert match(command)
@pytest.mark.parametrize('command', [
Command(script='git push', stderr=git_err2), Command(script='git push', stderr=git_err2),
Command(script='git push nvbn', stderr=git_err2), Command(script='git push nvbn', stderr=git_err2),
Command(script='git push nvbn master', stderr=git_err2)]) Command(script='git push nvbn master', stderr=git_err2)])
@ -68,12 +63,7 @@ def test_not_match(command):
(Command(script='git push nvbn', stderr=git_err), (Command(script='git push nvbn', stderr=git_err),
'git pull nvbn && git push nvbn'), 'git pull nvbn && git push nvbn'),
(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):
assert get_new_command(command) == output
@pytest.mark.parametrize('command, output', [
(Command(script='git push', stderr=git_err2), 'git pull && git push'), (Command(script='git push', stderr=git_err2), 'git pull && git push'),
(Command(script='git push nvbn', stderr=git_err2), (Command(script='git push nvbn', stderr=git_err2),
'git pull nvbn && git push nvbn'), 'git pull nvbn && git push nvbn'),

View File

@ -14,11 +14,11 @@ def test_match(command):
Command('git remote add origin url'), Command('git remote add origin url'),
Command('git remote remove origin'), Command('git remote remove origin'),
Command('git remote prune origin'), Command('git remote prune origin'),
Command('git remote set-branches origin branch') Command('git remote set-branches origin branch')])
])
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', [
(Command('git remote set-url origin git@github.com:nvbn/thefuck.git'), (Command('git remote set-url origin git@github.com:nvbn/thefuck.git'),
'git remote add origin git@github.com:nvbn/thefuck.git')]) 'git remote add origin git@github.com:nvbn/thefuck.git')])

View File

@ -4,14 +4,14 @@ from tests.utils import Command
cherry_pick_error = ( cherry_pick_error = (
'error: Your local changes would be overwritten by cherry-pick.\n' 'error: Your local changes would be overwritten by cherry-pick.\n'
'hint: Commit your changes or stash them to proceed.\n' 'hint: Commit your changes or stash them to proceed.\n'
'fatal: cherry-pick failed') 'fatal: cherry-pick failed')
rebase_error = ( rebase_error = (
'Cannot rebase: Your index contains uncommitted changes.\n' 'Cannot rebase: Your index contains uncommitted changes.\n'
'Please commit or stash them.') 'Please commit or stash them.')
@pytest.mark.parametrize('command', [ @pytest.mark.parametrize('command', [

View File

@ -14,5 +14,5 @@ def test_match(stderr):
def test_get_new_command(stderr): def test_get_new_command(stderr):
assert get_new_command(Command('git stash pop', stderr=stderr)) \ assert (get_new_command(Command('git stash pop', stderr=stderr))
== "git add . && git stash pop && git reset ." == "git add . && git stash pop && git reset .")

View File

@ -14,5 +14,5 @@ def test_match(stderr):
def test_get_new_command(stderr): def test_get_new_command(stderr):
assert get_new_command(Command('git tag alert', stderr=stderr)) \ assert (get_new_command(Command('git tag alert', stderr=stderr))
== "git tag --force alert" == "git tag --force alert")

View File

@ -7,7 +7,7 @@ def test_match():
with patch('os.path.exists', return_value=True): with patch('os.path.exists', return_value=True):
assert match(Command(script='main', stderr='main: command not found')) assert match(Command(script='main', stderr='main: command not found'))
assert match(Command(script='main --help', assert match(Command(script='main --help',
stderr='main: command not found')) stderr='main: command not found'))
assert not match(Command(script='main', stderr='')) assert not match(Command(script='main', stderr=''))
with patch('os.path.exists', return_value=False): with patch('os.path.exists', return_value=False):

View File

@ -19,5 +19,5 @@ def test_match(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))
== ['lein repl --help', 'lein jar --help'] == ['lein repl --help', 'lein jar --help'])

View File

@ -11,16 +11,6 @@ def file_exists(mocker):
get_stderr = "ln: failed to create symbolic link '{}': File exists".format get_stderr = "ln: failed to create symbolic link '{}': File exists".format
@pytest.mark.usefixtures('file_exists')
@pytest.mark.parametrize('script', [
'ln -s dest source',
'ln dest -s source',
'ln dest source -s'])
def test_match(script):
stderr = get_stderr('source')
assert match(Command(script, stderr=stderr))
@pytest.mark.parametrize('script, stderr, exists', [ @pytest.mark.parametrize('script, stderr, exists', [
('ln dest source', get_stderr('source'), True), ('ln dest source', get_stderr('source'), True),
('ls -s dest source', get_stderr('source'), True), ('ls -s dest source', get_stderr('source'), True),
@ -38,4 +28,5 @@ def test_not_match(file_exists, script, stderr, exists):
('ln dest source -s', 'ln source -s dest')]) ('ln dest source -s', 'ln source -s dest')])
def test_match(script, result): def test_match(script, result):
stderr = get_stderr('source') stderr = get_stderr('source')
assert match(Command(script, stderr=stderr))
assert get_new_command(Command(script, stderr=stderr)) == result assert get_new_command(Command(script, stderr=stderr)) == result

View File

@ -25,7 +25,7 @@ def test_match(command):
[INFO] Finished at: Wed Aug 26 13:05:47 BST 2015 [INFO] Finished at: Wed Aug 26 13:05:47 BST 2015
[INFO] Final Memory: 6M/240M [INFO] Final Memory: 6M/240M
[INFO] ------------------------------------------------------------------------ [INFO] ------------------------------------------------------------------------
"""), """), # noqa
Command(script='mvn --help'), Command(script='mvn --help'),
Command(script='mvn -v') Command(script='mvn -v')
]) ])

View File

@ -25,7 +25,7 @@ def test_match(command):
[INFO] Finished at: Wed Aug 26 13:05:47 BST 2015 [INFO] Finished at: Wed Aug 26 13:05:47 BST 2015
[INFO] Final Memory: 6M/240M [INFO] Final Memory: 6M/240M
[INFO] ------------------------------------------------------------------------ [INFO] ------------------------------------------------------------------------
"""), """), # noqa
Command(script='mvn --help'), Command(script='mvn --help'),
Command(script='mvn -v') Command(script='mvn -v')
]) ])

View File

@ -8,5 +8,5 @@ def test_match():
def test_get_new_command(): def test_get_new_command():
assert get_new_command(Command('./test_sudo.py'))\ assert (get_new_command(Command('./test_sudo.py'))
== 'python ./test_sudo.py' == 'python ./test_sudo.py')

View File

@ -17,5 +17,5 @@ def test_not_match(command):
def test_get_new_command(): def test_get_new_command():
assert get_new_command(Command(script='rm -rf /')) \ assert (get_new_command(Command(script='rm -rf /'))
== 'rm -rf / --no-preserve-root' == 'rm -rf / --no-preserve-root')

View File

@ -18,11 +18,11 @@ def test_match(sed_unterminated_s):
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)) \ 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)) \ 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)) \ 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)) \ 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

@ -23,12 +23,12 @@ def test_not_match(command):
@pytest.mark.parametrize('command, new_command', [ @pytest.mark.parametrize('command, new_command', [
(Command('hdfs dfs ls', (Command('hdfs dfs ls',
stderr='ls: Unknown command\nDid you mean -ls? This command begins with a dash.'), ['hdfs dfs -ls']), stderr='ls: Unknown command\nDid you mean -ls? This command begins with a dash.'), ['hdfs dfs -ls']),
(Command('hdfs dfs rm /foo/bar', (Command('hdfs dfs rm /foo/bar',
stderr='rm: Unknown command\nDid you mean -rm? This command begins with a dash.'), ['hdfs dfs -rm /foo/bar']), stderr='rm: Unknown command\nDid you mean -rm? This command begins with a dash.'), ['hdfs dfs -rm /foo/bar']),
(Command('./bin/hdfs dfs ls -R /foo/bar', (Command('./bin/hdfs dfs ls -R /foo/bar',
stderr='ls: Unknown command\nDid you mean -ls? This command begins with a dash.'), ['./bin/hdfs dfs -ls -R /foo/bar']), stderr='ls: Unknown command\nDid you mean -ls? This command begins with a dash.'), ['./bin/hdfs dfs -ls -R /foo/bar']),
(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) == new_command assert get_new_command(command) == new_command

View File

@ -27,8 +27,8 @@ def test_not_match(command):
(Command(script='vagrant ssh', stderr='VM must be running to open SSH connection. Run `vagrant up`\nto start the virtual machine.'), 'vagrant up && vagrant ssh'), (Command(script='vagrant ssh', stderr='VM must be running to open SSH connection. Run `vagrant up`\nto start the virtual machine.'), 'vagrant up && vagrant ssh'),
(Command(script='vagrant ssh devbox', stderr='VM must be running to open SSH connection. Run `vagrant up`\nto start the virtual machine.'), ['vagrant up devbox && vagrant ssh devbox', 'vagrant up && vagrant ssh devbox']), (Command(script='vagrant ssh devbox', stderr='VM must be running to open SSH connection. Run `vagrant up`\nto start the virtual machine.'), ['vagrant up devbox && vagrant ssh devbox', 'vagrant up && vagrant ssh devbox']),
(Command(script='vagrant rdp', (Command(script='vagrant rdp',
stderr='VM must be created before running this command. Run `vagrant up` first.'), 'vagrant up && vagrant rdp'), stderr='VM must be created before running this command. Run `vagrant up` first.'), 'vagrant up && vagrant rdp'),
(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) == new_command assert get_new_command(command) == new_command

View File

@ -82,7 +82,7 @@ yarn_help_stdout = b'''
Run `yarn help COMMAND` for more information on specific commands. Run `yarn help COMMAND` for more information on specific commands.
Visit https://yarnpkg.com/en/docs/cli/ to learn more about Yarn. Visit https://yarnpkg.com/en/docs/cli/ to learn more about Yarn.
''' ''' # noqa
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)

View File

@ -47,8 +47,8 @@ def test_get_corrected_commands(mocker):
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)] \ assert ([cmd.script for cmd in get_corrected_commands(command)]
== ['test!', 'test@', 'test;'] == ['test!', 'test@', 'test;'])
def test_organize_commands(): def test_organize_commands():

View File

@ -13,10 +13,10 @@ from thefuck.system import Path
class TestCorrectedCommand(object): class TestCorrectedCommand(object):
def test_equality(self): def test_equality(self):
assert CorrectedCommand('ls', None, 100) == \ assert (CorrectedCommand('ls', None, 100) ==
CorrectedCommand('ls', None, 200) CorrectedCommand('ls', None, 200))
assert CorrectedCommand('ls', None, 100) != \ assert (CorrectedCommand('ls', None, 100) !=
CorrectedCommand('ls', lambda *_: _, 100) CorrectedCommand('ls', lambda *_: _, 100))
def test_hashable(self): def test_hashable(self):
assert {CorrectedCommand('ls', None, 100), assert {CorrectedCommand('ls', None, 100),
@ -41,8 +41,8 @@ class TestRule(object):
priority=900, priority=900,
requires_output=True)) requires_output=True))
rule_path = os.path.join(os.sep, 'rules', 'bash.py') rule_path = os.path.join(os.sep, 'rules', 'bash.py')
assert Rule.from_path(Path(rule_path)) \ assert (Rule.from_path(Path(rule_path))
== Rule('bash', match, get_new_command, priority=900) == Rule('bash', match, get_new_command, priority=900))
load_source.assert_called_once_with('bash', rule_path) load_source.assert_called_once_with('bash', rule_path)
@pytest.mark.parametrize('rules, exclude_rules, rule, is_enabled', [ @pytest.mark.parametrize('rules, exclude_rules, rule, is_enabled', [
@ -79,15 +79,15 @@ class TestRule(object):
def test_get_corrected_commands_with_rule_returns_list(self): def test_get_corrected_commands_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(rule.get_corrected_commands(Command(script='test'))) \ assert (list(rule.get_corrected_commands(Command(script='test')))
== [CorrectedCommand(script='test!', priority=100), == [CorrectedCommand(script='test!', priority=100),
CorrectedCommand(script='test@', priority=200)] CorrectedCommand(script='test@', priority=200)])
def test_get_corrected_commands_with_rule_returns_command(self): def test_get_corrected_commands_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(rule.get_corrected_commands(Command(script='test'))) \ assert (list(rule.get_corrected_commands(Command(script='test')))
== [CorrectedCommand(script='test!', priority=100)] == [CorrectedCommand(script='test!', priority=100)])
class TestCommand(object): class TestCommand(object):

View File

@ -30,11 +30,11 @@ def test_read_actions(patch_get_key):
const.KEY_DOWN, 'j', const.KEY_DOWN, 'j',
# Ctrl+C: # Ctrl+C:
const.KEY_CTRL_C, 'q']) const.KEY_CTRL_C, 'q'])
assert list(islice(ui.read_actions(), 8)) \ assert (list(islice(ui.read_actions(), 8))
== [const.ACTION_SELECT, const.ACTION_SELECT, == [const.ACTION_SELECT, const.ACTION_SELECT,
const.ACTION_PREVIOUS, const.ACTION_PREVIOUS, const.ACTION_PREVIOUS, const.ACTION_PREVIOUS,
const.ACTION_NEXT, const.ACTION_NEXT, const.ACTION_NEXT, const.ACTION_NEXT,
const.ACTION_ABORT, const.ACTION_ABORT] const.ACTION_ABORT, const.ACTION_ABORT])
def test_command_selector(): def test_command_selector():
@ -74,8 +74,8 @@ class TestSelectCommand(object):
def test_without_confirmation_with_side_effects( def test_without_confirmation_with_side_effects(
self, capsys, commands_with_side_effect, settings): self, capsys, commands_with_side_effect, settings):
settings.require_confirmation = False settings.require_confirmation = False
assert ui.select_command(iter(commands_with_side_effect)) \ assert (ui.select_command(iter(commands_with_side_effect))
== 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_get_key, commands): def test_with_confirmation(self, capsys, patch_get_key, commands):
@ -91,8 +91,8 @@ class TestSelectCommand(object):
def test_with_confirmation_with_side_effct(self, capsys, patch_get_key, def test_with_confirmation_with_side_effct(self, capsys, patch_get_key,
commands_with_side_effect): commands_with_side_effect):
patch_get_key(['\n']) patch_get_key(['\n'])
assert ui.select_command(iter(commands_with_side_effect)) \ assert (ui.select_command(iter(commands_with_side_effect))
== 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_get_key, commands): def test_with_confirmation_select_second(self, capsys, patch_get_key, commands):

View File

@ -18,8 +18,7 @@ from tests.utils import Command
def test_default_settings(settings, override, old, new): def test_default_settings(settings, override, old, new):
settings.clear() settings.clear()
settings.update(old) settings.update(old)
fn = lambda _: _ default_settings(override)(lambda _: _)(None)
default_settings(override)(fn)(None)
assert settings == new assert settings == new

View File

@ -3,16 +3,16 @@ from .system import init_output
init_output() init_output()
from argparse import ArgumentParser from argparse import ArgumentParser # noqa: E402
from pprint import pformat from pprint import pformat # noqa: E402
import sys import sys # noqa: E402
from . import logs, types from . import logs, types # noqa: E402
from .shells import shell from .shells import shell # noqa: E402
from .conf import settings from .conf import settings # noqa: E402
from .corrector import get_corrected_commands from .corrector import get_corrected_commands # noqa: E402
from .exceptions import EmptyCommand from .exceptions import EmptyCommand # noqa: E402
from .utils import get_installation_info, get_alias from .utils import get_installation_info, get_alias # noqa: E402
from .ui import select_command from .ui import select_command # noqa: E402
def fix_command(): def fix_command():
@ -59,11 +59,10 @@ def how_to_configure_alias():
def main(): def main():
parser = ArgumentParser(prog='thefuck') parser = ArgumentParser(prog='thefuck')
version = get_installation_info().version version = get_installation_info().version
parser.add_argument( parser.add_argument('-v', '--version',
'-v', '--version', action='version',
action='version', version='The Fuck {} using Python {}'.format(
version='The Fuck {} using Python {}'.format( version, sys.version.split()[0]))
version, sys.version.split()[0]))
parser.add_argument('-a', '--alias', parser.add_argument('-a', '--alias',
action='store_true', action='store_true',
help='[custom-alias-name] prints alias for current shell') help='[custom-alias-name] prints alias for current shell')

View File

@ -54,8 +54,8 @@ def _brew_commands():
brew_path_prefix = get_brew_path_prefix() brew_path_prefix = get_brew_path_prefix()
if brew_path_prefix: if brew_path_prefix:
try: try:
return _get_brew_commands(brew_path_prefix) \ return (_get_brew_commands(brew_path_prefix)
+ _get_brew_tap_specific_commands(brew_path_prefix) + _get_brew_tap_specific_commands(brew_path_prefix))
except OSError: except OSError:
pass pass

View File

@ -39,7 +39,7 @@ def match(command):
def get_new_command(command): def get_new_command(command):
return u'{} -d {}'.format( return u'{} -d {}'.format(
command.script, shell.quote(_zip_file(command)[:-4])) command.script, shell.quote(_zip_file(command)[:-4]))
def side_effect(old_cmd, command): def side_effect(old_cmd, command):

View File

@ -9,6 +9,7 @@ def match(command):
def get_new_command(command): def get_new_command(command):
return ' '.join(command.script_parts[1:]) return ' '.join(command.script_parts[1:])
# it should be rare enough to actually have to type twice the same word, so # it should be rare enough to actually have to type twice the same word, so
# this rule can have a higher priority to come before things like "cd cd foo" # this rule can have a higher priority to come before things like "cd cd foo"
priority = 900 priority = 900

View File

@ -40,6 +40,8 @@ def _make_pattern(pattern):
.replace('{line}', '(?P<line>[0-9]+)') \ .replace('{line}', '(?P<line>[0-9]+)') \
.replace('{col}', '(?P<col>[0-9]+)') .replace('{col}', '(?P<col>[0-9]+)')
return re.compile(pattern, re.MULTILINE) return re.compile(pattern, re.MULTILINE)
patterns = [_make_pattern(p).search for p in patterns] patterns = [_make_pattern(p).search for p in patterns]

View File

@ -10,4 +10,4 @@ def match(command):
@git_support @git_support
def get_new_command(command): def get_new_command(command):
return replace_argument(command.script, 'add', 'add --force') return replace_argument(command.script, 'add', 'add --force')

View File

@ -11,6 +11,7 @@ def match(command):
else: else:
return False return False
# git's output here is too complicated to be parsed (see the test file) # git's output here is too complicated to be parsed (see the test file)
stash_commands = ( stash_commands = (
'apply', 'apply',

View File

@ -6,7 +6,7 @@ from thefuck.specific.git import git_support
def match(command): def match(command):
return ('pull' in command.script return ('pull' in command.script
and ('You have unstaged changes' in command.stderr and ('You have unstaged changes' in command.stderr
or 'contains uncommitted changes' in command.stderr)) or 'contains uncommitted changes' in command.stderr))
@git_support @git_support

View File

@ -1,6 +1,6 @@
import subprocess import subprocess
from thefuck.utils import for_app, replace_command, eager from thefuck.utils import for_app, replace_command, eager
import sys
@for_app('ifconfig') @for_app('ifconfig')
def match(command): def match(command):
@ -21,5 +21,3 @@ def get_new_command(command):
interface = command.stderr.split(' ')[0][:-1] interface = command.stderr.split(' ')[0][:-1]
possible_interfaces = _get_possible_interfaces() possible_interfaces = _get_possible_interfaces()
return replace_command(command, interface, possible_interfaces) return replace_command(command, interface, possible_interfaces)

View File

@ -6,4 +6,5 @@ def match(command):
def get_new_command(command): def get_new_command(command):
return u'man {}'.format(command.script[3:]) return u'man {}'.format(command.script[3:])
priority = 2000 priority = 2000

View File

@ -13,4 +13,5 @@ def get_new_command(command):
return [formatme.format(pacman, package, command.script) return [formatme.format(pacman, package, command.script)
for package in packages] for package in packages]
enabled_by_default, pacman = archlinux_env() enabled_by_default, pacman = archlinux_env()

View File

@ -33,8 +33,8 @@ def match(command):
if 'not found' not in command.stderr: if 'not found' not in command.stderr:
return False return False
matched_layout = _get_matched_layout(command) matched_layout = _get_matched_layout(command)
return matched_layout and \ return (matched_layout and
_switch_command(command, matched_layout) != get_alias() _switch_command(command, matched_layout) != get_alias())
def get_new_command(command): def get_new_command(command):

View File

@ -3,8 +3,8 @@ from thefuck.utils import replace_command
def match(command): def match(command):
return (re.search(r"([^:]*): Unknown command.*", command.stderr) != None return (re.search(r"([^:]*): Unknown command.*", command.stderr) is not None
and re.search(r"Did you mean ([^?]*)?", command.stderr) != None) and re.search(r"Did you mean ([^?]*)?", command.stderr) is not None)
def get_new_command(command): def get_new_command(command):

View File

@ -26,7 +26,7 @@ def get_new_command(command):
available = _get_all_environments() available = _get_all_environments()
if available: if available:
return replace_command(command, misspelled_env, available) \ return (replace_command(command, misspelled_env, available)
+ [create_new] + [create_new])
else: else:
return create_new return create_new

View File

@ -19,9 +19,9 @@ class Tcsh(Generic):
def get_aliases(self): def get_aliases(self):
proc = Popen(['tcsh', '-ic', 'alias'], stdout=PIPE, stderr=DEVNULL) proc = Popen(['tcsh', '-ic', 'alias'], stdout=PIPE, stderr=DEVNULL)
return dict( return dict(
self._parse_alias(alias) self._parse_alias(alias)
for alias in proc.stdout.read().decode('utf-8').split('\n') for alias in proc.stdout.read().decode('utf-8').split('\n')
if alias and '\t' in alias) if alias and '\t' in alias)
def _get_history_file_name(self): def _get_history_file_name(self):
return os.environ.get("HISTFILE", return os.environ.get("HISTFILE",

View File

@ -2,6 +2,6 @@ import sys
if sys.platform == 'win32': if sys.platform == 'win32':
from .win32 import * from .win32 import * # noqa: F401,F403
else: else:
from .unix import * from .unix import * # noqa: F401,F403

View File

@ -52,5 +52,6 @@ except ImportError:
def _expanduser(self): def _expanduser(self):
return self.__class__(os.path.expanduser(str(self))) return self.__class__(os.path.expanduser(str(self)))
if not hasattr(Path, 'expanduser'): if not hasattr(Path, 'expanduser'):
Path.expanduser = _expanduser Path.expanduser = _expanduser

View File

@ -41,5 +41,6 @@ except ImportError:
def _expanduser(self): def _expanduser(self):
return self.__class__(os.path.expanduser(str(self))) return self.__class__(os.path.expanduser(str(self)))
# pathlib's expanduser fails on windows, see http://bugs.python.org/issue19776 # pathlib's expanduser fails on windows, see http://bugs.python.org/issue19776
Path.expanduser = _expanduser Path.expanduser = _expanduser

View File

@ -40,8 +40,8 @@ class Command(object):
def __eq__(self, other): def __eq__(self, other):
if isinstance(other, Command): if isinstance(other, Command):
return (self.script, self.stdout, self.stderr) \ return ((self.script, self.stdout, self.stderr)
== (other.script, other.stdout, other.stderr) == (other.script, other.stdout, other.stderr))
else: else:
return False return False
@ -159,12 +159,12 @@ class Rule(object):
def __eq__(self, other): def __eq__(self, other):
if isinstance(other, Rule): if isinstance(other, Rule):
return (self.name, self.match, self.get_new_command, return ((self.name, self.match, self.get_new_command,
self.enabled_by_default, self.side_effect, self.enabled_by_default, self.side_effect,
self.priority, self.requires_output) \ self.priority, self.requires_output)
== (other.name, other.match, other.get_new_command, == (other.name, other.match, other.get_new_command,
other.enabled_by_default, other.side_effect, other.enabled_by_default, other.side_effect,
other.priority, other.requires_output) other.priority, other.requires_output))
else: else:
return False return False
@ -172,9 +172,9 @@ class Rule(object):
return 'Rule(name={}, match={}, get_new_command={}, ' \ return 'Rule(name={}, match={}, get_new_command={}, ' \
'enabled_by_default={}, side_effect={}, ' \ 'enabled_by_default={}, side_effect={}, ' \
'priority={}, requires_output)'.format( 'priority={}, requires_output)'.format(
self.name, self.match, self.get_new_command, self.name, self.match, self.get_new_command,
self.enabled_by_default, self.side_effect, self.enabled_by_default, self.side_effect,
self.priority, self.requires_output) self.priority, self.requires_output)
@classmethod @classmethod
def from_path(cls, path): def from_path(cls, path):

View File

@ -40,6 +40,8 @@ def memoize(fn):
return value return value
return wrapper return wrapper
memoize.disabled = False memoize.disabled = False
@ -238,6 +240,8 @@ def cache(*depends_on):
return value return value
return _cache return _cache
cache.disabled = False cache.disabled = False

View File

@ -4,3 +4,7 @@ envlist = py27,py33,py34,py35,py36
[testenv] [testenv]
deps = -rrequirements.txt deps = -rrequirements.txt
commands = py.test -v --capture=sys commands = py.test -v --capture=sys
[flake8]
ignore = E501,W503
exclude = venv,build