mirror of
				https://github.com/nvbn/thefuck.git
				synced 2025-10-30 22:54:14 +00:00 
			
		
		
		
	Merge pull request #364 from nvbn/global-settings
Don't pass `settings` explicitly
This commit is contained in:
		
							
								
								
									
										12
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								README.md
									
									
									
									
									
								
							| @@ -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: | ||||
|  | ||||
| ```python | ||||
| match(command: Command, settings: Settings) -> bool | ||||
| get_new_command(command: Command, settings: Settings) -> str | list[str] | ||||
| match(command: Command) -> bool | ||||
| get_new_command(command: Command) -> str | list[str] | ||||
| ``` | ||||
|  | ||||
| Also the rule can contain an optional function | ||||
|  | ||||
| ```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. | ||||
|  | ||||
| `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`: | ||||
|  | ||||
| @@ -264,7 +265,8 @@ requires_output = True | ||||
| ``` | ||||
|  | ||||
| [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 | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| from pathlib import Path | ||||
| import pytest | ||||
| from mock import Mock | ||||
| from thefuck import conf | ||||
|  | ||||
|  | ||||
| def pytest_addoption(parser): | ||||
| @@ -14,9 +15,20 @@ def no_memoize(monkeypatch): | ||||
|     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 | ||||
| def settings(): | ||||
|     return Mock(debug=False, no_colors=True) | ||||
| def no_colors(settings): | ||||
|     settings.no_colors = True | ||||
|  | ||||
|  | ||||
| @pytest.fixture(autouse=True) | ||||
|   | ||||
| @@ -11,7 +11,7 @@ from tests.utils import Command | ||||
| @pytest.mark.parametrize('command', [ | ||||
|     Command(script='vim', stderr='vim: command not found')]) | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|     assert match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command, return_value', [ | ||||
| @@ -24,7 +24,7 @@ def test_match(command): | ||||
| def test_match_mocked(cmdnf_mock, command, return_value): | ||||
|     get_packages = Mock(return_value=return_value) | ||||
|     cmdnf_mock.CommandNotFound.return_value = Mock(getPackages=get_packages) | ||||
|     assert match(command, None) | ||||
|     assert match(command) | ||||
|     assert cmdnf_mock.CommandNotFound.called | ||||
|     assert get_packages.called | ||||
|  | ||||
| @@ -32,7 +32,7 @@ def test_match_mocked(cmdnf_mock, command, return_value): | ||||
| @pytest.mark.parametrize('command', [ | ||||
|     Command(script='vim', stderr=''), Command()]) | ||||
| def test_not_match(command): | ||||
|     assert not match(command, None) | ||||
|     assert not match(command) | ||||
|  | ||||
|  | ||||
| # 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 convert'), 'sudo apt-get install imagemagick && sudo convert')]) | ||||
| 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', [ | ||||
| @@ -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): | ||||
|     get_packages = Mock(return_value=return_value) | ||||
|     cmdnf_mock.CommandNotFound.return_value = Mock(getPackages=get_packages) | ||||
|     assert get_new_command(command, None) == new_command | ||||
|     assert get_new_command(command) == new_command | ||||
|   | ||||
| @@ -4,7 +4,7 @@ from tests.utils import Command | ||||
|  | ||||
|  | ||||
| def test_match(): | ||||
|     assert match(Command('apt-get search foo'), None) | ||||
|     assert match(Command('apt-get search foo')) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command', [ | ||||
| @@ -18,8 +18,8 @@ def test_match(): | ||||
|     Command('apt-get update') | ||||
| ]) | ||||
| def test_not_match(command): | ||||
|     assert not match(command, None) | ||||
|     assert not match(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' | ||||
|   | ||||
| @@ -28,9 +28,9 @@ def _is_not_okay_to_test(): | ||||
| def test_match(brew_no_available_formula, brew_already_installed, | ||||
|                brew_install_no_argument): | ||||
|     assert match(Command('brew install elsticsearch', | ||||
|                          stderr=brew_no_available_formula), None) | ||||
|                          stderr=brew_no_available_formula)) | ||||
|     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), | ||||
|                      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') | ||||
| def test_get_new_command(brew_no_available_formula): | ||||
|     assert get_new_command(Command('brew install elsticsearch', | ||||
|                                    stderr=brew_no_available_formula), None)\ | ||||
|                                    stderr=brew_no_available_formula))\ | ||||
|         == 'brew install elasticsearch' | ||||
|  | ||||
|     assert get_new_command(Command('brew install aa', | ||||
|   | ||||
| @@ -15,15 +15,15 @@ def brew_unknown_cmd2(): | ||||
|  | ||||
|  | ||||
| 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(): | ||||
|         assert not match(Command('brew ' + command), None) | ||||
|         assert not match(Command('brew ' + command)) | ||||
|  | ||||
|  | ||||
| def test_get_new_command(brew_unknown_cmd, brew_unknown_cmd2): | ||||
|     assert get_new_command(Command('brew inst', stderr=brew_unknown_cmd), | ||||
|                            None) == ['brew list', 'brew install', 'brew uninstall'] | ||||
|     assert get_new_command(Command('brew inst', stderr=brew_unknown_cmd)) \ | ||||
|            == ['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 uninstall' in cmds | ||||
|   | ||||
| @@ -6,10 +6,10 @@ from tests.utils import Command | ||||
| @pytest.mark.parametrize('command', [ | ||||
|     Command(script='brew upgrade')]) | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|     assert match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command, new_command', [ | ||||
|     (Command('brew upgrade'), 'brew upgrade --all')]) | ||||
| def test_get_new_command(command, new_command): | ||||
|     assert get_new_command(command, None) == new_command | ||||
|     assert get_new_command(command) == new_command | ||||
|   | ||||
| @@ -12,10 +12,10 @@ no_such_subcommand = """No such subcommand | ||||
| @pytest.mark.parametrize('command', [ | ||||
|     Command(script='cargo buid', stderr=no_such_subcommand)]) | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|     assert match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command, new_command', [ | ||||
|     (Command('cargo buid', stderr=no_such_subcommand), 'cargo build')]) | ||||
| def test_get_new_command(command, new_command): | ||||
|     assert get_new_command(command, None) == new_command | ||||
|     assert get_new_command(command) == new_command | ||||
|   | ||||
| @@ -9,17 +9,17 @@ from tests.utils import Command | ||||
|             stderr='cd: foo: No such file or directory'), | ||||
|     Command(script='cd foo/bar/baz', stderr='cd: can\'t cd to foo/bar/baz')]) | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|     assert match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command', [ | ||||
|     Command(script='cd foo', stderr=''), Command()]) | ||||
| def test_not_match(command): | ||||
|     assert not match(command, None) | ||||
|     assert not match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command, new_command', [ | ||||
|     (Command('cd foo'), 'mkdir -p foo && cd foo'), | ||||
|     (Command('cd foo/bar/baz'), 'mkdir -p foo/bar/baz && cd foo/bar/baz')]) | ||||
| def test_get_new_command(command, new_command): | ||||
|     assert get_new_command(command, None) == new_command | ||||
|     assert get_new_command(command) == new_command | ||||
|   | ||||
| @@ -3,10 +3,10 @@ from tests.utils import Command | ||||
|  | ||||
|  | ||||
| def test_match(): | ||||
|     assert match(Command('cd..', stderr='cd..: command not found'), None) | ||||
|     assert not match(Command(), None) | ||||
|     assert match(Command('cd..', stderr='cd..: command not found')) | ||||
|     assert not match(Command()) | ||||
|  | ||||
|  | ||||
| def test_get_new_command(): | ||||
|     assert get_new_command( | ||||
|         Command('cd..'), None) == 'cd ..' | ||||
|         Command('cd..')) == 'cd ..' | ||||
|   | ||||
| @@ -41,17 +41,16 @@ def composer_not_command_one_of_this(): | ||||
|  | ||||
| def test_match(composer_not_command, composer_not_command_one_of_this): | ||||
|     assert match(Command('composer udpate', | ||||
|                          stderr=composer_not_command), None) | ||||
|                          stderr=composer_not_command)) | ||||
|     assert match(Command('composer pdate', | ||||
|                          stderr=composer_not_command_one_of_this), None) | ||||
|     assert not match(Command('ls update', stderr=composer_not_command), | ||||
|                      None) | ||||
|                          stderr=composer_not_command_one_of_this)) | ||||
|     assert not match(Command('ls update', stderr=composer_not_command)) | ||||
|  | ||||
|  | ||||
| def test_get_new_command(composer_not_command, composer_not_command_one_of_this): | ||||
|     assert get_new_command(Command('composer udpate', | ||||
|                                    stderr=composer_not_command), None) \ | ||||
|                                    stderr=composer_not_command)) \ | ||||
|            == 'composer update' | ||||
|     assert get_new_command( | ||||
|         Command('composer pdate', stderr=composer_not_command_one_of_this), | ||||
|         None) == 'composer selfupdate' | ||||
|         Command('composer pdate', stderr=composer_not_command_one_of_this)) \ | ||||
|            == 'composer selfupdate' | ||||
|   | ||||
| @@ -7,7 +7,7 @@ from tests.utils import Command | ||||
|     ('cp dir', 'cp: dor: is a directory'), | ||||
|     ('cp dir', "cp: omitting directory 'dir'")]) | ||||
| def test_match(script, stderr): | ||||
|     assert match(Command(script, stderr=stderr), None) | ||||
|     assert match(Command(script, stderr=stderr)) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('script, stderr', [ | ||||
| @@ -15,8 +15,8 @@ def test_match(script, stderr): | ||||
|     ('some dir', "cp: omitting directory 'dir'"), | ||||
|     ('cp dir', '')]) | ||||
| 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(): | ||||
|     assert get_new_command(Command(script='cp dir'), None) == 'cp -a dir' | ||||
|     assert get_new_command(Command(script='cp dir')) == 'cp -a dir' | ||||
|   | ||||
| @@ -45,14 +45,14 @@ parametrize_script = pytest.mark.parametrize('script, fixed', [ | ||||
| @parametrize_script | ||||
| def test_match(tar_error, filename, script, fixed): | ||||
|     tar_error(filename) | ||||
|     assert match(Command(script=script.format(filename)), None) | ||||
|     assert match(Command(script=script.format(filename))) | ||||
|  | ||||
|  | ||||
| @parametrize_filename | ||||
| @parametrize_script | ||||
| def test_side_effect(tar_error, filename, script, fixed): | ||||
|     tar_error(filename) | ||||
|     side_effect(Command(script=script.format(filename)), None, None) | ||||
|     side_effect(Command(script=script.format(filename)), None) | ||||
|     assert(os.listdir('.') == [filename]) | ||||
|  | ||||
|  | ||||
| @@ -60,4 +60,4 @@ def test_side_effect(tar_error, filename, script, fixed): | ||||
| @parametrize_script | ||||
| def test_get_new_command(tar_error, filename, script, fixed): | ||||
|     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) | ||||
|   | ||||
| @@ -27,14 +27,14 @@ def zip_error(tmpdir): | ||||
|     'unzip foo', | ||||
|     'unzip foo.zip']) | ||||
| def test_match(zip_error, script): | ||||
|     assert match(Command(script=script), None) | ||||
|     assert match(Command(script=script)) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('script', [ | ||||
|     'unzip foo', | ||||
|     'unzip foo.zip']) | ||||
| 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']) | ||||
|  | ||||
|  | ||||
| @@ -42,4 +42,4 @@ def test_side_effect(zip_error, script): | ||||
|     ('unzip foo', 'unzip foo -d foo'), | ||||
|     ('unzip foo.zip', 'unzip foo.zip -d foo')]) | ||||
| 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 | ||||
|   | ||||
| @@ -41,13 +41,13 @@ south.exceptions.GhostMigrations: | ||||
|  | ||||
|  | ||||
| def test_match(stderr): | ||||
|     assert match(Command('./manage.py migrate', stderr=stderr), None) | ||||
|     assert match(Command('python manage.py migrate', stderr=stderr), None) | ||||
|     assert not match(Command('./manage.py migrate'), None) | ||||
|     assert not match(Command('app migrate', stderr=stderr), None) | ||||
|     assert not match(Command('./manage.py test', stderr=stderr), None) | ||||
|     assert match(Command('./manage.py migrate', stderr=stderr)) | ||||
|     assert match(Command('python manage.py migrate', stderr=stderr)) | ||||
|     assert not match(Command('./manage.py migrate')) | ||||
|     assert not match(Command('app migrate', stderr=stderr)) | ||||
|     assert not match(Command('./manage.py test', stderr=stderr)) | ||||
|  | ||||
|  | ||||
| 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' | ||||
|   | ||||
| @@ -31,13 +31,13 @@ The following options are available: | ||||
|  | ||||
|  | ||||
| def test_match(stderr): | ||||
|     assert match(Command('./manage.py migrate', stderr=stderr), None) | ||||
|     assert match(Command('python manage.py migrate', stderr=stderr), None) | ||||
|     assert not match(Command('./manage.py migrate'), None) | ||||
|     assert not match(Command('app migrate', stderr=stderr), None) | ||||
|     assert not match(Command('./manage.py test', stderr=stderr), None) | ||||
|     assert match(Command('./manage.py migrate', stderr=stderr)) | ||||
|     assert match(Command('python manage.py migrate', stderr=stderr)) | ||||
|     assert not match(Command('./manage.py migrate')) | ||||
|     assert not match(Command('app migrate', stderr=stderr)) | ||||
|     assert not match(Command('./manage.py test', stderr=stderr)) | ||||
|  | ||||
|  | ||||
| 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' | ||||
|   | ||||
| @@ -110,14 +110,14 @@ def stderr(cmd): | ||||
|  | ||||
|  | ||||
| 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', [ | ||||
|     ('docker ps', ''), | ||||
|     ('cat pes', stderr('pes'))]) | ||||
| 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') | ||||
| @@ -126,4 +126,4 @@ def test_not_match(script, stderr): | ||||
|     ('tags', ['tag', 'stats', 'images'])]) | ||||
| def test_get_new_command(wrong, fixed): | ||||
|     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] | ||||
|   | ||||
| @@ -7,11 +7,11 @@ from tests.utils import Command | ||||
|     Command(script='cd cd foo'), | ||||
|     Command(script='git git push origin/master')]) | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|     assert match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command, new_command', [ | ||||
|     (Command('cd cd foo'), 'cd foo'), | ||||
|     (Command('git git push origin/master'), 'git push origin/master')]) | ||||
| def test_get_new_command(command, new_command): | ||||
|     assert get_new_command(command, None) == new_command | ||||
|     assert get_new_command(command) == new_command | ||||
|   | ||||
| @@ -11,12 +11,12 @@ def test_match(): | ||||
|  | ||||
|     """ | ||||
|     assert match(Command(u'ps -ef | grep foo', | ||||
|                          stderr=u'-bash:  grep: command not found'), None) | ||||
|     assert not match(Command('ps -ef | grep foo'), None) | ||||
|     assert not match(Command(), None) | ||||
|                          stderr=u'-bash:  grep: command not found')) | ||||
|     assert not match(Command('ps -ef | grep foo')) | ||||
|     assert not match(Command()) | ||||
|  | ||||
|  | ||||
| def test_get_new_command(): | ||||
|     """ 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' | ||||
|   | ||||
| @@ -184,7 +184,7 @@ E       NameError: name 'mocker' is not defined | ||||
| def test_match(mocker, monkeypatch, test): | ||||
|     mocker.patch('os.path.isfile', return_value=True) | ||||
|     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) | ||||
| @@ -194,7 +194,7 @@ def test_no_editor(mocker, monkeypatch, test): | ||||
|     if 'EDITOR' in os.environ: | ||||
|         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) | ||||
| @@ -203,7 +203,7 @@ def test_not_file(mocker, monkeypatch, test): | ||||
|     mocker.patch('os.path.isfile', return_value=False) | ||||
|     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) | ||||
| @@ -219,16 +219,16 @@ def test_get_new_command(mocker, monkeypatch, test): | ||||
|  | ||||
| @pytest.mark.parametrize('test', tests) | ||||
| @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) | ||||
|     monkeypatch.setenv('EDITOR', 'dummy_editor') | ||||
|  | ||||
|     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]: | ||||
|         assert (get_new_command(cmd, settings) == | ||||
|         assert (get_new_command(cmd) == | ||||
|             'dummy_editor {} +{}:{} && {}'.format(test[1], test[2], test[3], test[0])) | ||||
|     else: | ||||
|         assert (get_new_command(cmd, settings) == | ||||
|         assert (get_new_command(cmd) == | ||||
|             'dummy_editor {} +{} && {}'.format(test[1], test[2], test[0])) | ||||
|   | ||||
| @@ -18,7 +18,7 @@ def did_not_match(target, did_you_forget=True): | ||||
|     Command(script='git commit unknown', | ||||
|             stderr=did_not_match('unknown'))])  # Older versions of Git | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|     assert match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command', [ | ||||
| @@ -27,7 +27,7 @@ def test_match(command): | ||||
|     Command(script='git commit unknown',  # Newer versions of Git | ||||
|             stderr=did_not_match('unknown', False))]) | ||||
| def test_not_match(command): | ||||
|     assert not match(command, None) | ||||
|     assert not match(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 | ||||
|      'git add -- unknown && git commit unknown')]) | ||||
| def test_get_new_command(command, new_command): | ||||
|     assert get_new_command(command, None) == new_command | ||||
|     assert get_new_command(command) == new_command | ||||
|   | ||||
| @@ -12,11 +12,11 @@ If you are sure you want to delete it, run 'git branch -D branch'. | ||||
|  | ||||
|  | ||||
| def test_match(stderr): | ||||
|     assert match(Command('git branch -d branch', stderr=stderr), None) | ||||
|     assert not match(Command('git branch -d branch'), None) | ||||
|     assert not match(Command('ls', stderr=stderr), None) | ||||
|     assert match(Command('git branch -d branch', stderr=stderr)) | ||||
|     assert not match(Command('git branch -d branch')) | ||||
|     assert not match(Command('ls', stderr=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" | ||||
|   | ||||
| @@ -4,16 +4,16 @@ from tests.utils import Command | ||||
|  | ||||
|  | ||||
| def test_match(): | ||||
|     assert match(Command('git branch list'), None) | ||||
|     assert match(Command('git branch list')) | ||||
|  | ||||
|  | ||||
| def test_not_match(): | ||||
|     assert not match(Command(), None) | ||||
|     assert not match(Command('git commit'), None) | ||||
|     assert not match(Command('git branch'), None) | ||||
|     assert not match(Command('git stash list'), None) | ||||
|     assert not match(Command()) | ||||
|     assert not match(Command('git commit')) | ||||
|     assert not match(Command('git branch')) | ||||
|     assert not match(Command('git stash list')) | ||||
|  | ||||
|  | ||||
| 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')) | ||||
|   | ||||
| @@ -21,7 +21,7 @@ def get_branches(mocker): | ||||
|     Command(script='git checkout unknown', stderr=did_not_match('unknown')), | ||||
|     Command(script='git commit unknown', stderr=did_not_match('unknown'))]) | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|     assert match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command', [ | ||||
| @@ -30,7 +30,7 @@ def test_match(command): | ||||
|     Command(script='git checkout known', stderr=('')), | ||||
|     Command(script='git commit known', stderr=(''))]) | ||||
| def test_not_match(command): | ||||
|     assert not match(command, None) | ||||
|     assert not match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('branches, command, new_command', [ | ||||
| @@ -50,4 +50,4 @@ def test_not_match(command): | ||||
|      'git commit test-random-branch-123')]) | ||||
| def test_get_new_command(branches, command, new_command, get_branches): | ||||
|     get_branches.return_value = branches | ||||
|     assert get_new_command(command, None) == new_command | ||||
|     assert get_new_command(command) == new_command | ||||
|   | ||||
| @@ -7,7 +7,7 @@ from tests.utils import Command | ||||
|     Command(script='git diff foo'), | ||||
|     Command(script='git diff')]) | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|     assert match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command', [ | ||||
| @@ -16,11 +16,11 @@ def test_match(command): | ||||
|     Command(script='git branch'), | ||||
|     Command(script='git log')]) | ||||
| def test_not_match(command): | ||||
|     assert not match(command, None) | ||||
|     assert not match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command, new_command', [ | ||||
|     (Command('git diff'), 'git diff --staged'), | ||||
|     (Command('git diff foo'), 'git diff --staged foo')]) | ||||
| def test_get_new_command(command, new_command): | ||||
|     assert get_new_command(command, None) == new_command | ||||
|     assert get_new_command(command) == new_command | ||||
|   | ||||
| @@ -20,7 +20,7 @@ usage: git stash list [<options>] | ||||
|     'git stash Some message', | ||||
|     'git stash saev Some message']) | ||||
| 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', [ | ||||
| @@ -28,4 +28,4 @@ def test_match(wrong): | ||||
|     ('git stash Some message', 'git stash save Some message'), | ||||
|     ('git stash saev Some message', 'git stash save Some message')]) | ||||
| 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 | ||||
|   | ||||
| @@ -41,17 +41,17 @@ def git_command(): | ||||
|  | ||||
|  | ||||
| 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 st', stderr=git_not_command_one_of_this), None) | ||||
|     assert not match(Command('ls brnch', stderr=git_not_command), None) | ||||
|     assert not match(Command('git branch', stderr=git_command), None) | ||||
|     assert match(Command('git brnch', stderr=git_not_command)) | ||||
|     assert match(Command('git st', stderr=git_not_command_one_of_this)) | ||||
|     assert not match(Command('ls brnch', stderr=git_not_command)) | ||||
|     assert not match(Command('git branch', stderr=git_command)) | ||||
|  | ||||
|  | ||||
| def test_get_new_command(git_not_command, git_not_command_one_of_this, | ||||
|                          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'] | ||||
|     assert get_new_command(Command('git st', stderr=git_not_command_one_of_this), | ||||
|                            None) == ['git stats', 'git stash', 'git stage'] | ||||
|     assert get_new_command(Command('git tags', stderr=git_not_command_closest), | ||||
|                            None) == ['git tag', 'git stage'] | ||||
|     assert get_new_command(Command('git st', stderr=git_not_command_one_of_this)) \ | ||||
|            == ['git stats', 'git stash', 'git stage'] | ||||
|     assert get_new_command(Command('git tags', stderr=git_not_command_closest)) \ | ||||
|            == ['git tag', 'git stage'] | ||||
|   | ||||
| @@ -19,11 +19,11 @@ If you wish to set tracking information for this branch you can do so with: | ||||
|  | ||||
|  | ||||
| def test_match(stderr): | ||||
|     assert match(Command('git pull', stderr=stderr), None) | ||||
|     assert not match(Command('git pull'), None) | ||||
|     assert not match(Command('ls', stderr=stderr), None) | ||||
|     assert match(Command('git pull', stderr=stderr)) | ||||
|     assert not match(Command('git pull')) | ||||
|     assert not match(Command('ls', stderr=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" | ||||
|   | ||||
| @@ -12,10 +12,10 @@ Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set). | ||||
| @pytest.mark.parametrize('command', [ | ||||
|     Command(script='git pull git@github.com:mcarton/thefuck.git', stderr=git_err)]) | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|     assert match(command) | ||||
|  | ||||
|  | ||||
| @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')]) | ||||
| def test_get_new_command(command, output): | ||||
|     assert get_new_command(command, None) == output | ||||
|     assert get_new_command(command) == output | ||||
|   | ||||
| @@ -14,11 +14,11 @@ To push the current branch and set the remote as upstream, use | ||||
|  | ||||
|  | ||||
| def test_match(stderr): | ||||
|     assert match(Command('git push master', stderr=stderr), None) | ||||
|     assert not match(Command('git push master'), None) | ||||
|     assert not match(Command('ls', stderr=stderr), None) | ||||
|     assert match(Command('git push master', stderr=stderr)) | ||||
|     assert not match(Command('git push master')) | ||||
|     assert not match(Command('ls', stderr=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" | ||||
|   | ||||
| @@ -30,7 +30,7 @@ To /tmp/bar | ||||
|     Command(script='git push nvbn', stderr=git_err), | ||||
|     Command(script='git push nvbn master', stderr=git_err)]) | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|     assert match(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 master', stderr=git_uptodate)]) | ||||
| def test_not_match(command): | ||||
|     assert not match(command, None) | ||||
|     assert not match(command) | ||||
|  | ||||
|  | ||||
| @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 master', stderr=git_err), 'git push --force nvbn master')]) | ||||
| def test_get_new_command(command, output): | ||||
|     assert get_new_command(command, None) == output | ||||
|     assert get_new_command(command) == output | ||||
|   | ||||
| @@ -30,7 +30,7 @@ To /tmp/bar | ||||
|     Command(script='git push nvbn', stderr=git_err), | ||||
|     Command(script='git push nvbn master', stderr=git_err)]) | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|     assert match(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 master', stderr=git_uptodate)]) | ||||
| def test_not_match(command): | ||||
|     assert not match(command, None) | ||||
|     assert not match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command, output', [ | ||||
| @@ -51,4 +51,4 @@ def test_not_match(command): | ||||
|     (Command(script='git push nvbn master', stderr=git_err), | ||||
|      'git pull nvbn master && git push nvbn master')]) | ||||
| def test_get_new_command(command, output): | ||||
|     assert get_new_command(command, None) == output | ||||
|     assert get_new_command(command) == output | ||||
|   | ||||
| @@ -18,14 +18,14 @@ rebase_error = ( | ||||
|     Command(script='git cherry-pick a1b2c3d', stderr=cherry_pick_error), | ||||
|     Command(script='git rebase -i HEAD~7', stderr=rebase_error)]) | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|     assert match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command', [ | ||||
|     Command(script='git cherry-pick a1b2c3d', stderr=('')), | ||||
|     Command(script='git rebase -i HEAD~7', stderr=(''))]) | ||||
| def test_not_match(command): | ||||
|     assert not match(command, None) | ||||
|     assert not match(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), | ||||
|      'git stash && git rebase -i HEAD~7')]) | ||||
| def test_get_new_command(command, new_command): | ||||
|     assert get_new_command(command, None) == new_command | ||||
|     assert get_new_command(command) == new_command | ||||
|   | ||||
| @@ -7,11 +7,11 @@ from tests.utils import Command | ||||
|     Command(script='go run foo'), | ||||
|     Command(script='go run bar')]) | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|     assert match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command, new_command', [ | ||||
|     (Command('go run foo'), 'go run foo.go'), | ||||
|     (Command('go run bar'), 'go run bar.go')]) | ||||
| def test_get_new_command(command, new_command): | ||||
|     assert get_new_command(command, None) == new_command | ||||
|     assert get_new_command(command) == new_command | ||||
|   | ||||
| @@ -3,10 +3,10 @@ from tests.utils import Command | ||||
|  | ||||
|  | ||||
| def test_match(): | ||||
|     assert match(Command('grep blah .', stderr='grep: .: Is a directory'), None) | ||||
|     assert not match(Command(), None) | ||||
|     assert match(Command('grep blah .', stderr='grep: .: Is a directory')) | ||||
|     assert not match(Command()) | ||||
|  | ||||
|  | ||||
| def test_get_new_command(): | ||||
|     assert get_new_command( | ||||
|         Command('grep blah .'), None) == 'grep -r blah .' | ||||
|         Command('grep blah .')) == 'grep -r blah .' | ||||
|   | ||||
| @@ -11,18 +11,18 @@ def stdout(task): | ||||
|  | ||||
|  | ||||
| def test_match(): | ||||
|     assert match(Command('gulp srve', stdout('srve')), None) | ||||
|     assert match(Command('gulp srve', stdout('srve'))) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('script, stdout', [ | ||||
|     ('gulp serve', ''), | ||||
|     ('cat srve', stdout('srve'))]) | ||||
| 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): | ||||
|     mocker.patch('thefuck.rules.gulp_not_task.get_gulp_tasks', return_value=[ | ||||
|         'serve', 'build', 'default']) | ||||
|     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'] | ||||
|   | ||||
| @@ -4,17 +4,14 @@ from thefuck.rules.has_exists_script import match, get_new_command | ||||
|  | ||||
| def test_match(): | ||||
|     with patch('os.path.exists', return_value=True): | ||||
|         assert match(Mock(script='main', stderr='main: command not found'), | ||||
|                      None) | ||||
|         assert match(Mock(script='main', stderr='main: command not found')) | ||||
|         assert match(Mock(script='main --help', | ||||
|                           stderr='main: command not found'), | ||||
|                      None) | ||||
|         assert not match(Mock(script='main', stderr=''), None) | ||||
|                           stderr='main: command not found')) | ||||
|         assert not match(Mock(script='main', stderr='')) | ||||
|  | ||||
|     with patch('os.path.exists', return_value=False): | ||||
|         assert not match(Mock(script='main', stderr='main: command not found'), | ||||
|                          None) | ||||
|         assert not match(Mock(script='main', stderr='main: command not found')) | ||||
|  | ||||
|  | ||||
| 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' | ||||
|   | ||||
| @@ -16,14 +16,14 @@ no_suggest_stderr = ''' !    `aaaaa` is not a heroku command. | ||||
| @pytest.mark.parametrize('cmd', ['log', 'pge']) | ||||
| def test_match(cmd): | ||||
|     assert match( | ||||
|         Command('heroku {}'.format(cmd), stderr=suggest_stderr(cmd)), None) | ||||
|         Command('heroku {}'.format(cmd), stderr=suggest_stderr(cmd))) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('script, stderr', [ | ||||
|     ('cat log', suggest_stderr('log')), | ||||
|     ('heroku aaa', no_suggest_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', [ | ||||
| @@ -31,4 +31,4 @@ def test_not_match(script, stderr): | ||||
|     ('pge', ['heroku pg', 'heroku logs'])]) | ||||
| def test_get_new_command(cmd, result): | ||||
|     command = Command('heroku {}'.format(cmd), stderr=suggest_stderr(cmd)) | ||||
|     assert get_new_command(command, None) == result | ||||
|     assert get_new_command(command) == result | ||||
|   | ||||
| @@ -25,13 +25,13 @@ def callables(mocker): | ||||
| @pytest.mark.usefixtures('history', 'callables', 'no_memoize', 'alias') | ||||
| @pytest.mark.parametrize('script', ['ls cet', 'daff x']) | ||||
| 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.parametrize('script', ['apt-get', 'nocommand y']) | ||||
| 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') | ||||
| @@ -39,4 +39,4 @@ def test_not_match(script): | ||||
|     ('ls cet', 'ls cat'), | ||||
|     ('daff x', 'diff x')]) | ||||
| def test_get_new_command(script, result): | ||||
|     assert get_new_command(Command(script), None) == result | ||||
|     assert get_new_command(Command(script)) == result | ||||
|   | ||||
| @@ -7,11 +7,11 @@ from tests.utils import Command | ||||
|     Command(script='java foo.java'), | ||||
|     Command(script='java bar.java')]) | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|     assert match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command, new_command', [ | ||||
|     (Command('java foo.java'), 'java foo'), | ||||
|     (Command('java bar.java'), 'java bar')]) | ||||
| def test_get_new_command(command, new_command): | ||||
|     assert get_new_command(command, None) == new_command | ||||
|     assert get_new_command(command) == new_command | ||||
|   | ||||
| @@ -7,11 +7,11 @@ from tests.utils import Command | ||||
|     Command(script='javac foo'), | ||||
|     Command(script='javac bar')]) | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|     assert match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command, new_command', [ | ||||
|     (Command('javac foo'), 'javac foo.java'), | ||||
|     (Command('javac bar'), 'javac bar.java')]) | ||||
| def test_get_new_command(command, new_command): | ||||
|     assert get_new_command(command, None) == new_command | ||||
|     assert get_new_command(command) == new_command | ||||
|   | ||||
| @@ -14,10 +14,10 @@ Did you mean this? | ||||
|  | ||||
|  | ||||
| def test_match(is_not_task): | ||||
|     assert match(Command(script='lein rpl', stderr=is_not_task), None) | ||||
|     assert not match(Command(script='ls', 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)) | ||||
|  | ||||
|  | ||||
| def test_get_new_command(is_not_task): | ||||
|     assert get_new_command(Command(script='lein rpl --help', stderr=is_not_task), | ||||
|                            None) == ['lein repl --help', 'lein jar --help'] | ||||
|     assert get_new_command(Command(script='lein rpl --help', stderr=is_not_task)) \ | ||||
|            == ['lein repl --help', 'lein jar --help'] | ||||
|   | ||||
| @@ -3,14 +3,14 @@ from tests.utils import Command | ||||
|  | ||||
|  | ||||
| def test_match(): | ||||
|     assert match(Command(script='ls'), None) | ||||
|     assert match(Command(script='ls file.py'), None) | ||||
|     assert match(Command(script='ls /opt'), None) | ||||
|     assert not match(Command(script='ls -lah /opt'), None) | ||||
|     assert not match(Command(script='pacman -S binutils'), None) | ||||
|     assert not match(Command(script='lsof'), None) | ||||
|     assert match(Command(script='ls')) | ||||
|     assert match(Command(script='ls file.py')) | ||||
|     assert match(Command(script='ls /opt')) | ||||
|     assert not match(Command(script='ls -lah /opt')) | ||||
|     assert not match(Command(script='pacman -S binutils')) | ||||
|     assert not match(Command(script='lsof')) | ||||
|  | ||||
|  | ||||
| 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'), None) == 'ls -lah' | ||||
|     assert get_new_command(Command(script='ls file.py')) == 'ls -lah file.py' | ||||
|     assert get_new_command(Command(script='ls')) == 'ls -lah' | ||||
|   | ||||
| @@ -12,14 +12,14 @@ from tests.utils import Command | ||||
|     Command('man -s 2 read'), | ||||
|     Command('man -s 3 read')]) | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|     assert match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command', [ | ||||
|     Command('man'), | ||||
|     Command('man ')]) | ||||
| def test_not_match(command): | ||||
|     assert not match(command, None) | ||||
|     assert not match(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 3 read'), 'man -s 2 read')]) | ||||
| def test_get_new_command(command, new_command): | ||||
|     assert get_new_command(command, None) == new_command | ||||
|     assert get_new_command(command) == new_command | ||||
|   | ||||
| @@ -3,10 +3,10 @@ from tests.utils import Command | ||||
|  | ||||
|  | ||||
| def test_match(): | ||||
|     assert match(Command('mandiff', stderr='mandiff: command not found'), None) | ||||
|     assert not match(Command(), None) | ||||
|     assert match(Command('mandiff', stderr='mandiff: command not found')) | ||||
|     assert not match(Command()) | ||||
|  | ||||
|  | ||||
| def test_get_new_command(): | ||||
|     assert get_new_command( | ||||
|         Command('mandiff'), None) == 'man diff' | ||||
|         Command('mandiff')) == 'man diff' | ||||
|   | ||||
| @@ -37,7 +37,7 @@ from thefuck.rules.mercurial import ( | ||||
|     )), | ||||
| ]) | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|     assert match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command', [ | ||||
| @@ -63,7 +63,7 @@ def test_match(command): | ||||
|     )), | ||||
| ]) | ||||
| def test_not_match(command): | ||||
|     assert not match(command, None) | ||||
|     assert not match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command, possibilities', [ | ||||
| @@ -131,4 +131,4 @@ def test_extract_possibilities(command, possibilities): | ||||
|     )), 'hg rebase re'), | ||||
| ]) | ||||
| def test_get_new_command(command, new_command): | ||||
|     assert get_new_command(command, None) == new_command | ||||
|     assert get_new_command(command) == new_command | ||||
|   | ||||
| @@ -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') | ||||
|     ]) | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|     assert match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command', [ | ||||
| @@ -19,7 +19,7 @@ def test_match(command): | ||||
|     Command('./bin/hdfs dfs -mkdir foo/bar/baz'), | ||||
|     Command()]) | ||||
| def test_not_match(command): | ||||
|     assert not match(command, None) | ||||
|     assert not match(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('./bin/hdfs dfs -mkdir foo/bar/baz'), './bin/hdfs dfs -mkdir -p foo/bar/baz')]) | ||||
| def test_get_new_command(command, new_command): | ||||
|     assert get_new_command(command, None) == new_command | ||||
|     assert get_new_command(command) == new_command | ||||
|  | ||||
|   | ||||
| @@ -6,7 +6,7 @@ from tests.utils import 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]')]) | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|     assert match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command', [ | ||||
| @@ -30,11 +30,11 @@ def test_match(command): | ||||
|     Command(script='mvn -v') | ||||
| ]) | ||||
| def test_not_match(command): | ||||
|     assert not match(command, None) | ||||
|     assert not match(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 -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): | ||||
|     assert get_new_command(command, None) == new_command | ||||
|     assert get_new_command(command) == new_command | ||||
|  | ||||
|   | ||||
| @@ -6,7 +6,7 @@ from tests.utils import 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]')]) | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|     assert match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command', [ | ||||
| @@ -30,11 +30,11 @@ def test_match(command): | ||||
|     Command(script='mvn -v') | ||||
| ]) | ||||
| def test_not_match(command): | ||||
|     assert not match(command, None) | ||||
|     assert not match(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 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): | ||||
|     assert get_new_command(command, None) == new_command | ||||
|     assert get_new_command(command) == new_command | ||||
|  | ||||
|   | ||||
| @@ -11,19 +11,17 @@ def get_all_executables(mocker): | ||||
|  | ||||
| @pytest.mark.usefixtures('no_memoize') | ||||
| def test_match(): | ||||
|     assert match(Command(stderr='vom: not found', script='vom file.py'), None) | ||||
|     assert match(Command(stderr='fucck: not found', script='fucck'), None) | ||||
|     assert not match(Command(stderr='qweqwe: not found', script='qweqwe'), None) | ||||
|     assert not match(Command(stderr='some text', 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')) | ||||
|     assert not match(Command(stderr='qweqwe: not found', script='qweqwe')) | ||||
|     assert not match(Command(stderr='some text', script='vom file.py')) | ||||
|  | ||||
|  | ||||
| @pytest.mark.usefixtures('no_memoize') | ||||
| def test_get_new_command(): | ||||
|     assert get_new_command( | ||||
|         Command(stderr='vom: not found', | ||||
|                 script='vom file.py'), | ||||
|         None) == ['vim file.py'] | ||||
|                 script='vom file.py')) == ['vim file.py'] | ||||
|     assert get_new_command( | ||||
|         Command(stderr='fucck: not found', | ||||
|                 script='fucck'), | ||||
|         Command) == ['fsck'] | ||||
|                 script='fucck')) == ['fsck'] | ||||
|   | ||||
| @@ -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"), | ||||
|     ]) | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|     assert match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command', [ | ||||
| @@ -16,7 +16,7 @@ def test_match(command): | ||||
|     Command(script='mv foo bar/foo', stderr="mv: permission denied"), | ||||
|     ]) | ||||
| def test_not_match(command): | ||||
|     assert not match(command, None) | ||||
|     assert not match(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/'), | ||||
|     ]) | ||||
| def test_get_new_command(command, new_command): | ||||
|     assert get_new_command(command, None) == new_command | ||||
|     assert get_new_command(command) == new_command | ||||
|   | ||||
| @@ -14,7 +14,7 @@ from tests.utils import Command | ||||
|     Command(script='gnome-open foo.com'), | ||||
|     Command(script='kde-open foo.com')]) | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|     assert match(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('kde-open foo.io'), 'kde-open http://foo.io')]) | ||||
| def test_get_new_command(command, new_command): | ||||
|     assert get_new_command(command, None) == new_command | ||||
|     assert get_new_command(command) == new_command | ||||
|   | ||||
| @@ -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='sudo vim', stderr='sudo: vim: command not found')]) | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|     assert match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command, return_value', [ | ||||
| @@ -33,14 +33,14 @@ def test_match(command): | ||||
| @patch.multiple(pacman, create=True, pacman=pacman_cmd) | ||||
| def test_match_mocked(subp_mock, command, return_value): | ||||
|     subp_mock.check_output.return_value = return_value | ||||
|     assert match(command, None) | ||||
|     assert match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command', [ | ||||
|     Command(script='vim', stderr=''), Command(), | ||||
|     Command(script='sudo vim', stderr=''), Command()]) | ||||
| def test_not_match(command): | ||||
|     assert not match(command, None) | ||||
|     assert not match(command) | ||||
|  | ||||
|  | ||||
| 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('sudo convert'), ['{} -S extra/imagemagick && sudo convert'.format(pacman_cmd)])]) | ||||
| 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', [ | ||||
| @@ -79,4 +79,4 @@ def test_get_new_command(command, new_command, mocker): | ||||
| @patch.multiple(pacman, create=True, pacman=pacman_cmd) | ||||
| def test_get_new_command_mocked(subp_mock, command, new_command, 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 | ||||
|   | ||||
| @@ -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='sudo pacman llc', stderr='error: target not found: llc')]) | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|     assert match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command', [ | ||||
| @@ -25,7 +25,7 @@ def test_match(command): | ||||
| @patch('thefuck.specific.archlinux.subprocess') | ||||
| def test_match_mocked(subp_mock, command): | ||||
|     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), | ||||
| @@ -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='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): | ||||
|     assert get_new_command(command, None) == fixed | ||||
|     assert get_new_command(command) == fixed | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command, fixed', [ | ||||
| @@ -45,4 +45,4 @@ def test_get_new_command(command, fixed): | ||||
| @patch('thefuck.specific.archlinux.subprocess') | ||||
| def test_get_new_command_mocked(subp_mock, command, fixed): | ||||
|     subp_mock.check_output.return_value = PKGFILE_OUTPUT_LLC | ||||
|     assert get_new_command(command, None) == fixed | ||||
|     assert get_new_command(command) == fixed | ||||
|   | ||||
| @@ -14,12 +14,11 @@ def 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', | ||||
|                              stderr=pip_unknown_cmd_without_recommend), | ||||
|                      None) | ||||
|                              stderr=pip_unknown_cmd_without_recommend)) | ||||
|  | ||||
|  | ||||
| def test_get_new_command(pip_unknown_cmd): | ||||
|     assert get_new_command(Command('pip instatl', stderr=pip_unknown_cmd), | ||||
|                            None) == 'pip install' | ||||
|     assert get_new_command(Command('pip instatl', | ||||
|                                    stderr=pip_unknown_cmd)) == 'pip install' | ||||
|   | ||||
| @@ -3,10 +3,10 @@ from tests.utils import Command | ||||
|  | ||||
|  | ||||
| def test_match(): | ||||
|     assert match(Command('temp.py', stderr='Permission denied'), None) | ||||
|     assert not match(Command(), None) | ||||
|     assert match(Command('temp.py', stderr='Permission denied')) | ||||
|     assert not match(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' | ||||
|   | ||||
| @@ -7,11 +7,11 @@ from tests.utils import Command | ||||
|     Command(script='python foo'), | ||||
|     Command(script='python bar')]) | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|     assert match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command, new_command', [ | ||||
|     (Command('python foo'), 'python foo.py'), | ||||
|     (Command('python bar'), 'python bar.py')]) | ||||
| def test_get_new_command(command, new_command): | ||||
|     assert get_new_command(command, None) == new_command | ||||
|     assert get_new_command(command) == new_command | ||||
|   | ||||
| @@ -8,7 +8,7 @@ from tests.utils import Command | ||||
|     Command(script="git commit -am \"Mismatched Quotation Marks\'"), | ||||
|     Command(script="echo \"hello\'")]) | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|     assert match(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("echo \"hello\'"), "echo \"hello\"")]) | ||||
| def test_get_new_command(command, new_command): | ||||
|     assert get_new_command(command, None) == new_command | ||||
|     assert get_new_command(command) == new_command | ||||
|   | ||||
| @@ -10,7 +10,7 @@ from tests.utils import Command | ||||
|     Command('./bin/hdfs dfs -rm foo', stderr='rm: `foo`: Is a directory') | ||||
|     ]) | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|     assert match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command', [ | ||||
| @@ -19,13 +19,13 @@ def test_match(command): | ||||
|     Command('./bin/hdfs dfs -rm foo'),   | ||||
|     Command()]) | ||||
| def test_not_match(command): | ||||
|     assert not match(command, None) | ||||
|     assert not match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command, new_command', [ | ||||
|     (Command('rm foo'), 'rm -rf foo'), | ||||
|     (Command('hdfs dfs -rm foo'), 'hdfs dfs -rm -r foo')]) | ||||
| def test_get_new_command(command, new_command): | ||||
|     assert get_new_command(command, None) == new_command | ||||
|     assert get_new_command(command) == new_command | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -5,7 +5,7 @@ from tests.utils import Command | ||||
|  | ||||
| def test_match(): | ||||
|     assert match(Command(script='rm -rf /', | ||||
|                          stderr='add --no-preserve-root'), None) | ||||
|                          stderr='add --no-preserve-root')) | ||||
|  | ||||
|  | ||||
| @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 -rf /', stderr='')]) | ||||
| def test_not_match(command): | ||||
|     assert not match(command, None) | ||||
|     assert not match(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' | ||||
|   | ||||
| @@ -9,20 +9,20 @@ def 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 -es/foo/bar', stderr=sed_unterminated_s), None) | ||||
|     assert match(Command('sed -e s/foo/bar -e s/baz/quz', stderr=sed_unterminated_s), None) | ||||
|     assert not match(Command('sed -e s/foo/bar'), None) | ||||
|     assert not match(Command('sed -es/foo/bar'), None) | ||||
|     assert not match(Command('sed -e s/foo/bar -e s/baz/quz'), None) | ||||
|     assert match(Command('sed -e s/foo/bar', stderr=sed_unterminated_s)) | ||||
|     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)) | ||||
|     assert not match(Command('sed -e s/foo/bar')) | ||||
|     assert not match(Command('sed -es/foo/bar')) | ||||
|     assert not match(Command('sed -e s/foo/bar -e s/baz/quz')) | ||||
|  | ||||
|  | ||||
| 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/' | ||||
|     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/' | ||||
|     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/'" | ||||
|     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/" | ||||
|   | ||||
| @@ -4,9 +4,9 @@ from tests.utils import Command | ||||
|  | ||||
|  | ||||
| def test_match(): | ||||
|     assert match(Command('sl'), None) | ||||
|     assert not match(Command('ls'), None) | ||||
|     assert match(Command('sl')) | ||||
|     assert not match(Command('ls')) | ||||
|  | ||||
|  | ||||
| def test_get_new_command(): | ||||
|     assert get_new_command(Command('sl'), None) == 'ls' | ||||
|     assert get_new_command(Command('sl')) == 'ls' | ||||
|   | ||||
| @@ -44,23 +44,23 @@ Host key verification failed.""".format(path, '98.765.432.321') | ||||
|  | ||||
| def test_match(ssh_error): | ||||
|     errormsg, _, _, _ = ssh_error | ||||
|     assert match(Command('ssh', stderr=errormsg), None) | ||||
|     assert match(Command('ssh', stderr=errormsg), None) | ||||
|     assert match(Command('scp something something', stderr=errormsg), None) | ||||
|     assert match(Command('scp something something', stderr=errormsg), None) | ||||
|     assert not match(Command(stderr=errormsg), None) | ||||
|     assert not match(Command('notssh', stderr=errormsg), None) | ||||
|     assert not match(Command('ssh'), None) | ||||
|     assert match(Command('ssh', stderr=errormsg)) | ||||
|     assert match(Command('ssh', stderr=errormsg)) | ||||
|     assert match(Command('scp something something', stderr=errormsg)) | ||||
|     assert match(Command('scp something something', stderr=errormsg)) | ||||
|     assert not match(Command(stderr=errormsg)) | ||||
|     assert not match(Command('notssh', stderr=errormsg)) | ||||
|     assert not match(Command('ssh')) | ||||
|  | ||||
|  | ||||
| def test_side_effect(ssh_error): | ||||
|     errormsg, path, reset, known_hosts = ssh_error | ||||
|     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'] | ||||
|     assert known_hosts(path) == expected | ||||
|  | ||||
|  | ||||
| def test_get_new_command(ssh_error, monkeypatch): | ||||
|     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' | ||||
|   | ||||
| @@ -14,11 +14,11 @@ from tests.utils import Command | ||||
|     ('You don\'t have access to the history DB.', ''), | ||||
|     ('', "error: [Errno 13] Permission denied: '/usr/local/lib/python2.7/dist-packages/ipaddr.py'")]) | ||||
| def test_match(stderr, stdout): | ||||
|     assert match(Command(stderr=stderr, stdout=stdout), None) | ||||
|     assert match(Command(stderr=stderr, stdout=stdout)) | ||||
|  | ||||
|  | ||||
| def test_not_match(): | ||||
|     assert not match(Command(), None) | ||||
|     assert not match(Command()) | ||||
|  | ||||
|  | ||||
| @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"')]) | ||||
| def test_get_new_command(before, after): | ||||
|     assert get_new_command(Command(before), None) == after | ||||
|     assert get_new_command(Command(before)) == after | ||||
|   | ||||
| @@ -9,7 +9,7 @@ from tests.utils import Command | ||||
|     Command(stderr='command not found: фзе-пуе', script=u'фзе-пуе'), | ||||
|     Command(stderr='command not found: λσ', script=u'λσ')]) | ||||
| def test_match(command): | ||||
|     assert switch_lang.match(command, None) | ||||
|     assert switch_lang.match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command', [ | ||||
| @@ -18,11 +18,11 @@ def test_match(command): | ||||
|     Command(stderr='command not found: агсл', script=u'агсл'), | ||||
|     Command(stderr='some info', script=u'фзе-пуе')]) | ||||
| def test_not_match(command): | ||||
|     assert not switch_lang.match(command, None) | ||||
|     assert not switch_lang.match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command, new_command', [ | ||||
|     (Command(u'фзе-пуе штыефдд мшь'), 'apt-get install vim'), | ||||
|     (Command(u'λσ -λα'), 'ls -la')]) | ||||
| 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 | ||||
|   | ||||
| @@ -4,15 +4,15 @@ from tests.utils import Command | ||||
|  | ||||
|  | ||||
| def test_match(): | ||||
|     assert match(Command('systemctl nginx start', stderr='Unknown operation \'nginx\'.'), None) | ||||
|     assert match(Command('sudo systemctl nginx start', stderr='Unknown operation \'nginx\'.'), None) | ||||
|     assert not match(Command('systemctl start nginx'), None) | ||||
|     assert not match(Command('systemctl start nginx'), None) | ||||
|     assert not match(Command('sudo systemctl nginx', stderr='Unknown operation \'nginx\'.'), None) | ||||
|     assert not match(Command('systemctl nginx', stderr='Unknown operation \'nginx\'.'), 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.'), None) | ||||
|     assert match(Command('systemctl nginx start', stderr='Unknown operation \'nginx\'.')) | ||||
|     assert match(Command('sudo systemctl nginx start', stderr='Unknown operation \'nginx\'.')) | ||||
|     assert not match(Command('systemctl start nginx')) | ||||
|     assert not match(Command('systemctl start nginx')) | ||||
|     assert not match(Command('sudo systemctl nginx', stderr='Unknown operation \'nginx\'.')) | ||||
|     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.')) | ||||
|  | ||||
|  | ||||
| def test_get_new_command(): | ||||
|     assert get_new_command(Command('systemctl nginx start'), None) == "systemctl start nginx" | ||||
|     assert get_new_command(Command('sudo systemctl nginx start'), None) == "sudo systemctl start nginx" | ||||
|     assert get_new_command(Command('systemctl nginx start')) == "systemctl start nginx" | ||||
|     assert get_new_command(Command('sudo systemctl nginx start')) == "sudo systemctl start nginx" | ||||
|   | ||||
| @@ -11,9 +11,9 @@ def 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): | ||||
|     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'] | ||||
|   | ||||
| @@ -15,7 +15,7 @@ error_msg = ( | ||||
|     Command(script='tsuru app-log -f', stderr=error_msg[1]), | ||||
| ]) | ||||
| def test_match(command): | ||||
|     assert match(command, {}) | ||||
|     assert match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command', [ | ||||
| @@ -24,7 +24,7 @@ def test_match(command): | ||||
|     Command(script='tsuru app-log -f', stderr=('Error: unparseable data')), | ||||
| ]) | ||||
| def test_not_match(command): | ||||
|     assert not match(command, {}) | ||||
|     assert not match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command, new_command', [ | ||||
| @@ -34,4 +34,4 @@ def test_not_match(command): | ||||
|      'tsuru login && tsuru app-log -f'), | ||||
| ]) | ||||
| def test_get_new_command(command, new_command): | ||||
|     assert get_new_command(command, {}) == new_command | ||||
|     assert get_new_command(command) == new_command | ||||
|   | ||||
| @@ -30,7 +30,7 @@ from thefuck.rules.tsuru_not_command import match, get_new_command | ||||
|     )), | ||||
| ]) | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|     assert match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command', [ | ||||
| @@ -58,7 +58,7 @@ def test_match(command): | ||||
|     Command('tsuru env-get', stderr='Error: App thefuck not found.'), | ||||
| ]) | ||||
| def test_not_match(command): | ||||
|     assert not match(command, None) | ||||
|     assert not match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command, new_commands', [ | ||||
| @@ -87,4 +87,4 @@ def test_not_match(command): | ||||
|     )), ['tsuru target-list']), | ||||
| ]) | ||||
| def test_get_new_command(command, new_commands): | ||||
|     assert get_new_command(command, None) == new_commands | ||||
|     assert get_new_command(command) == new_commands | ||||
|   | ||||
| @@ -9,7 +9,7 @@ from tests.utils import Command | ||||
|             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): | ||||
|     assert match(command, None) | ||||
|     assert match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command', [ | ||||
| @@ -18,7 +18,7 @@ def test_match(command): | ||||
|     Command(script='hdfs dfs -ls -R /foo/bar', stderr=''),   | ||||
|     Command()]) | ||||
| def test_not_match(command): | ||||
|     assert not match(command, None) | ||||
|     assert not match(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', | ||||
|         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): | ||||
|     assert get_new_command(command, None) == new_command | ||||
|     assert get_new_command(command) == new_command | ||||
|  | ||||
|   | ||||
| @@ -11,7 +11,7 @@ from tests.utils import Command | ||||
|     Command(script='vagrant rdp devbox', | ||||
|             stderr='VM must be created before running this command. Run `vagrant up` first.')]) | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|     assert match(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()]) | ||||
| def test_not_match(command): | ||||
|     assert not match(command, None) | ||||
|     assert not match(command) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('command, new_command', [ | ||||
| @@ -31,5 +31,5 @@ def test_not_match(command): | ||||
|     (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'])]) | ||||
| def test_get_new_command(command, new_command): | ||||
|     assert get_new_command(command, None) == new_command | ||||
|     assert get_new_command(command) == new_command | ||||
|  | ||||
|   | ||||
| @@ -8,11 +8,11 @@ from tests.utils import Command | ||||
|     Command(script='whois https://en.wikipedia.org/'), | ||||
|     Command(script='whois meta.unix.stackexchange.com')]) | ||||
| def test_match(command): | ||||
|     assert match(command, None) | ||||
|     assert match(command) | ||||
|  | ||||
|  | ||||
| def test_not_match(): | ||||
|     assert not match(Command(script='whois'), None) | ||||
|     assert not match(Command(script='whois')) | ||||
|  | ||||
|  | ||||
| # `whois com` actually makes sense | ||||
| @@ -23,4 +23,4 @@ def test_not_match(): | ||||
|                                                     'whois stackexchange.com', | ||||
|                                                     'whois com'])]) | ||||
| def test_get_new_command(command, new_command): | ||||
|     assert get_new_command(command, None) == new_command | ||||
|     assert get_new_command(command) == new_command | ||||
|   | ||||
| @@ -9,9 +9,10 @@ from tests.utils import Command | ||||
|      "19:23:25.470911 git.c:282   trace: alias expansion: com => 'commit' '--verbose'")]) | ||||
| def test_git_support(called, command, stderr): | ||||
|     @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', [ | ||||
| @@ -24,6 +25,7 @@ def test_git_support(called, command, stderr): | ||||
|     ('cat hub', False)]) | ||||
| def test_git_support_match(command, is_git): | ||||
|     @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 | ||||
|   | ||||
| @@ -13,8 +13,8 @@ from tests.utils import Command | ||||
|     (False, 'sudo ls', 'ls', False), | ||||
|     (False, 'ls', 'ls', False)]) | ||||
| def test_sudo_support(return_value, command, called, result): | ||||
|     def fn(command, settings): | ||||
|     def fn(command): | ||||
|         assert command == Command(called) | ||||
|         return return_value | ||||
|  | ||||
|     assert sudo_support(fn)(Command(command), None) == result | ||||
|     assert sudo_support(fn)(Command(command)) == result | ||||
|   | ||||
| @@ -26,22 +26,23 @@ def environ(monkeypatch): | ||||
|  | ||||
|  | ||||
| @pytest.mark.usefixture('environ') | ||||
| def test_settings_defaults(load_source): | ||||
| def test_settings_defaults(load_source, settings): | ||||
|     load_source.return_value = object() | ||||
|     conf.init_settings(Mock()) | ||||
|     for key, val in conf.DEFAULT_SETTINGS.items(): | ||||
|         assert getattr(conf.get_settings(Mock()), key) == val | ||||
|         assert getattr(settings, key) == val | ||||
|  | ||||
|  | ||||
| @pytest.mark.usefixture('environ') | ||||
| class TestSettingsFromFile(object): | ||||
|     def test_from_file(self, load_source): | ||||
|     def test_from_file(self, load_source, settings): | ||||
|         load_source.return_value = Mock(rules=['test'], | ||||
|                                         wait_command=10, | ||||
|                                         require_confirmation=True, | ||||
|                                         no_colors=True, | ||||
|                                         priority={'vim': 100}, | ||||
|                                         exclude_rules=['git']) | ||||
|         settings = conf.get_settings(Mock()) | ||||
|         conf.init_settings(Mock()) | ||||
|         assert settings.rules == ['test'] | ||||
|         assert settings.wait_command == 10 | ||||
|         assert settings.require_confirmation is True | ||||
| @@ -49,26 +50,26 @@ class TestSettingsFromFile(object): | ||||
|         assert settings.priority == {'vim': 100} | ||||
|         assert settings.exclude_rules == ['git'] | ||||
|  | ||||
|     def test_from_file_with_DEFAULT(self, load_source): | ||||
|     def test_from_file_with_DEFAULT(self, load_source, settings): | ||||
|         load_source.return_value = Mock(rules=conf.DEFAULT_RULES + ['test'], | ||||
|                                         wait_command=10, | ||||
|                                         exclude_rules=[], | ||||
|                                         require_confirmation=True, | ||||
|                                         no_colors=True) | ||||
|         settings = conf.get_settings(Mock()) | ||||
|         conf.init_settings(Mock()) | ||||
|         assert settings.rules == conf.DEFAULT_RULES + ['test'] | ||||
|  | ||||
|  | ||||
| @pytest.mark.usefixture('load_source') | ||||
| class TestSettingsFromEnv(object): | ||||
|     def test_from_env(self, environ): | ||||
|     def test_from_env(self, environ, settings): | ||||
|         environ.update({'THEFUCK_RULES': 'bash:lisp', | ||||
|                         'THEFUCK_EXCLUDE_RULES': 'git:vim', | ||||
|                         'THEFUCK_WAIT_COMMAND': '55', | ||||
|                         'THEFUCK_REQUIRE_CONFIRMATION': 'true', | ||||
|                         'THEFUCK_NO_COLORS': 'false', | ||||
|                         'THEFUCK_PRIORITY': 'bash=10:lisp=wrong:vim=15'}) | ||||
|         settings = conf.get_settings(Mock()) | ||||
|         conf.init_settings(Mock()) | ||||
|         assert settings.rules == ['bash', 'lisp'] | ||||
|         assert settings.exclude_rules == ['git', 'vim'] | ||||
|         assert settings.wait_command == 55 | ||||
| @@ -76,9 +77,9 @@ class TestSettingsFromEnv(object): | ||||
|         assert settings.no_colors is False | ||||
|         assert settings.priority == {'bash': 10, 'vim': 15} | ||||
|  | ||||
|     def test_from_env_with_DEFAULT(self, environ): | ||||
|     def test_from_env_with_DEFAULT(self, environ, settings): | ||||
|         environ.update({'THEFUCK_RULES': 'DEFAULT_RULES:bash:lisp'}) | ||||
|         settings = conf.get_settings(Mock()) | ||||
|         conf.init_settings(Mock()) | ||||
|         assert settings.rules == conf.DEFAULT_RULES + ['bash', 'lisp'] | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -16,7 +16,7 @@ def test_load_rule(mocker): | ||||
|                           enabled_by_default=True, | ||||
|                           priority=900, | ||||
|                           requires_output=True)) | ||||
|     assert corrector.load_rule(Path('/rules/bash.py'), settings=Mock(priority={})) \ | ||||
|     assert corrector.load_rule(Path('/rules/bash.py')) \ | ||||
|            == Rule('bash', match, get_new_command, priority=900) | ||||
|     load_source.assert_called_once_with('bash', '/rules/bash.py') | ||||
|  | ||||
| @@ -25,7 +25,7 @@ class TestGetRules(object): | ||||
|     @pytest.fixture | ||||
|     def glob(self, mocker): | ||||
|         results = {} | ||||
|         mocker.patch('thefuck.corrector.Path.glob', | ||||
|         mocker.patch('pathlib.Path.glob', | ||||
|                      new_callable=lambda: lambda *_: results.pop('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'], conf.DEFAULT_RULES, ['git'], ['bash']), | ||||
|         (['git.py', 'bash.py'], ['git'], ['git'], [])]) | ||||
|     def test_get_rules(self, glob, paths, conf_rules, exclude_rules, loaded_rules): | ||||
|     def test_get_rules(self, glob, settings, paths, conf_rules, exclude_rules, | ||||
|                        loaded_rules): | ||||
|         glob([PosixPath(path) for path in paths]) | ||||
|         settings = Mock(rules=self._prepare_rules(conf_rules), | ||||
|         settings.update(rules=self._prepare_rules(conf_rules), | ||||
|                         priority={}, | ||||
|                         exclude_rules=self._prepare_rules(exclude_rules)) | ||||
|         rules = corrector.get_rules(Path('~'), settings) | ||||
|         rules = corrector.get_rules() | ||||
|         self._compare_names(rules, loaded_rules) | ||||
|  | ||||
|  | ||||
| class TestIsRuleMatch(object): | ||||
|     def test_no_match(self, settings): | ||||
|     def test_no_match(self): | ||||
|         assert not corrector.is_rule_match( | ||||
|             Command('ls'), Rule('', lambda *_: False), settings) | ||||
|             Command('ls'), Rule('', lambda _: False)) | ||||
|  | ||||
|     def test_match(self, settings): | ||||
|         rule = Rule('', lambda x, _: x.script == 'cd ..') | ||||
|         assert corrector.is_rule_match(Command('cd ..'), rule, settings) | ||||
|     def test_match(self): | ||||
|         rule = Rule('', lambda x: x.script == 'cd ..') | ||||
|         assert corrector.is_rule_match(Command('cd ..'), rule) | ||||
|  | ||||
|     def test_when_rule_failed(self, capsys, settings): | ||||
|     @pytest.mark.usefixtures('no_colors') | ||||
|     def test_when_rule_failed(self, capsys): | ||||
|         rule = Rule('test', Mock(side_effect=OSError('Denied')), | ||||
|                     requires_output=False) | ||||
|         assert not corrector.is_rule_match( | ||||
|             Command('ls'), rule, settings) | ||||
|         assert not corrector.is_rule_match(Command('ls'), rule) | ||||
|         assert capsys.readouterr()[1].split('\n')[0] == '[WARN] Rule test:' | ||||
|  | ||||
|  | ||||
| class TestMakeCorrectedCommands(object): | ||||
|     def test_with_rule_returns_list(self): | ||||
|         rule = Rule(get_new_command=lambda x, _: [x.script + '!', x.script + '@'], | ||||
|         rule = Rule(get_new_command=lambda x: [x.script + '!', x.script + '@'], | ||||
|                     priority=100) | ||||
|         assert list(make_corrected_commands(Command(script='test'), rule, None)) \ | ||||
|         assert list(make_corrected_commands(Command(script='test'), rule)) \ | ||||
|                == [CorrectedCommand(script='test!', priority=100), | ||||
|                    CorrectedCommand(script='test@', priority=200)] | ||||
|  | ||||
|     def test_with_rule_returns_command(self): | ||||
|         rule = Rule(get_new_command=lambda x, _: x.script + '!', | ||||
|         rule = Rule(get_new_command=lambda x: x.script + '!', | ||||
|                     priority=100) | ||||
|         assert list(make_corrected_commands(Command(script='test'), rule, None)) \ | ||||
|         assert list(make_corrected_commands(Command(script='test'), rule)) \ | ||||
|                == [CorrectedCommand(script='test!', priority=100)] | ||||
|  | ||||
| def test_get_corrected_commands(mocker): | ||||
|     command = Command('test', 'test', 'test') | ||||
|     rules = [Rule(match=lambda *_: False), | ||||
|              Rule(match=lambda *_: True, | ||||
|                   get_new_command=lambda x, _: x.script + '!', priority=100), | ||||
|              Rule(match=lambda *_: True, | ||||
|                   get_new_command=lambda x, _: [x.script + '@', x.script + ';'], | ||||
|     rules = [Rule(match=lambda _: False), | ||||
|              Rule(match=lambda _: True, | ||||
|                   get_new_command=lambda x: x.script + '!', priority=100), | ||||
|              Rule(match=lambda _: True, | ||||
|                   get_new_command=lambda x: [x.script + '@', x.script + ';'], | ||||
|                   priority=60)] | ||||
|     mocker.patch('thefuck.corrector.get_rules', return_value=rules) | ||||
|     assert [cmd.script for cmd in get_corrected_commands(command, None, Mock(debug=False))] \ | ||||
|     assert [cmd.script for cmd in get_corrected_commands(command)] \ | ||||
|            == ['test!', 'test@', 'test;'] | ||||
|   | ||||
| @@ -1,14 +1,20 @@ | ||||
| import pytest | ||||
| from mock import Mock | ||||
| from thefuck import logs | ||||
|  | ||||
|  | ||||
| def test_color(): | ||||
|     assert logs.color('red', Mock(no_colors=False)) == 'red' | ||||
|     assert logs.color('red', Mock(no_colors=True)) == '' | ||||
| def test_color(settings): | ||||
|     settings.no_colors = False | ||||
|     assert logs.color('red') == 'red' | ||||
|     settings.no_colors = True | ||||
|     assert logs.color('red') == '' | ||||
|  | ||||
|  | ||||
| def test_debug(capsys): | ||||
|     logs.debug('test', Mock(no_colors=True, debug=True)) | ||||
|     assert capsys.readouterr() == ('', 'DEBUG: test\n') | ||||
|     logs.debug('test', Mock(no_colors=True, debug=False)) | ||||
|     assert capsys.readouterr() == ('', '') | ||||
| @pytest.mark.usefixtures('no_colors') | ||||
| @pytest.mark.parametrize('debug, stderr', [ | ||||
|     (True, 'DEBUG: test\n'), | ||||
|     (False, '')]) | ||||
| def test_debug(capsys, settings, debug, stderr): | ||||
|     settings.debug = debug | ||||
|     logs.debug('test') | ||||
|     assert capsys.readouterr() == ('', stderr) | ||||
|   | ||||
| @@ -24,9 +24,9 @@ class TestGetCommand(object): | ||||
|         monkeypatch.setattr('thefuck.shells.from_shell', lambda x: x) | ||||
|         monkeypatch.setattr('thefuck.shells.to_shell', lambda x: x) | ||||
|  | ||||
|     def test_get_command_calls(self, Popen): | ||||
|         assert main.get_command(Mock(env={}), | ||||
|                                 ['thefuck', 'apt-get', 'search', 'vim']) \ | ||||
|     def test_get_command_calls(self, Popen, settings): | ||||
|         settings.env = {} | ||||
|         assert main.get_command(['thefuck', 'apt-get', 'search', 'vim']) \ | ||||
|                == Command('apt-get search vim', 'stdout', 'stderr') | ||||
|         Popen.assert_called_once_with('apt-get search vim', | ||||
|                                       shell=True, | ||||
| @@ -41,6 +41,6 @@ class TestGetCommand(object): | ||||
|         (['thefuck', 'ls'], 'ls')]) | ||||
|     def test_get_command_script(self, args, result): | ||||
|         if result: | ||||
|             assert main.get_command(Mock(env={}), args).script == result | ||||
|             assert main.get_command(args).script == result | ||||
|         else: | ||||
|             assert main.get_command(Mock(env={}), args) is None | ||||
|             assert main.get_command(args) is None | ||||
|   | ||||
| @@ -10,14 +10,6 @@ def test_rules_names_list(): | ||||
|     assert Rule('bash') not in RulesNamesList(['lisp']) | ||||
|  | ||||
|  | ||||
| def test_update_settings(): | ||||
|     settings = Settings({'key': 'val'}) | ||||
|     new_settings = settings.update(key='new-val', unset='unset-value') | ||||
|     assert new_settings.key == 'val' | ||||
|     assert new_settings.unset == 'unset-value' | ||||
|     assert settings.key == 'val' | ||||
|  | ||||
|  | ||||
| class TestSortedCorrectedCommandsSequence(object): | ||||
|     def test_realises_generator_only_on_demand(self, settings): | ||||
|         should_realise = False | ||||
| @@ -28,24 +20,23 @@ class TestSortedCorrectedCommandsSequence(object): | ||||
|             assert should_realise | ||||
|             yield CorrectedCommand('git checkout', priority=100) | ||||
|  | ||||
|         commands = SortedCorrectedCommandsSequence(gen(), settings) | ||||
|         commands = SortedCorrectedCommandsSequence(gen()) | ||||
|         assert commands[0] == CorrectedCommand('git commit') | ||||
|         should_realise = True | ||||
|         assert commands[1] == CorrectedCommand('git checkout', priority=100) | ||||
|         assert commands[2] == CorrectedCommand('git branch', priority=200) | ||||
|  | ||||
|     def test_remove_duplicates(self, settings): | ||||
|     def test_remove_duplicates(self): | ||||
|         side_effect = lambda *_: None | ||||
|         seq = SortedCorrectedCommandsSequence( | ||||
|             iter([CorrectedCommand('ls', priority=100), | ||||
|                   CorrectedCommand('ls', priority=200), | ||||
|                   CorrectedCommand('ls', side_effect, 300)]), | ||||
|             settings) | ||||
|                   CorrectedCommand('ls', side_effect, 300)])) | ||||
|         assert set(seq) == {CorrectedCommand('ls', priority=100), | ||||
|                             CorrectedCommand('ls', side_effect, 300)} | ||||
|  | ||||
|     def test_with_blank(self, settings): | ||||
|         seq = SortedCorrectedCommandsSequence(iter([]), settings) | ||||
|     def test_with_blank(self): | ||||
|         seq = SortedCorrectedCommandsSequence(iter([])) | ||||
|         assert list(seq) == [] | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -56,66 +56,55 @@ def test_command_selector(): | ||||
|     assert changes == [1, 2, 3, 1, 3] | ||||
|  | ||||
|  | ||||
| @pytest.mark.usefixtures('no_colors') | ||||
| class TestSelectCommand(object): | ||||
|     @pytest.fixture | ||||
|     def commands_with_side_effect(self, settings): | ||||
|     def commands_with_side_effect(self): | ||||
|         return SortedCorrectedCommandsSequence( | ||||
|             iter([CorrectedCommand('ls', lambda *_: None, 100), | ||||
|                   CorrectedCommand('cd', lambda *_: None, 100)]), | ||||
|             settings) | ||||
|                   CorrectedCommand('cd', lambda *_: None, 100)])) | ||||
|  | ||||
|     @pytest.fixture | ||||
|     def commands(self, settings): | ||||
|     def commands(self): | ||||
|         return SortedCorrectedCommandsSequence( | ||||
|             iter([CorrectedCommand('ls', None, 100), | ||||
|                   CorrectedCommand('cd', None, 100)]), | ||||
|             settings) | ||||
|                   CorrectedCommand('cd', None, 100)])) | ||||
|  | ||||
|     def test_without_commands(self, capsys): | ||||
|         assert ui.select_command([], Mock(debug=False, no_color=True)) is None | ||||
|         assert ui.select_command([]) is None | ||||
|         assert capsys.readouterr() == ('', 'No fucks given\n') | ||||
|  | ||||
|     def test_without_confirmation(self, capsys, commands): | ||||
|         assert ui.select_command(commands, | ||||
|                                  Mock(debug=False, no_color=True, | ||||
|                                       require_confirmation=False)) == commands[0] | ||||
|     def test_without_confirmation(self, capsys, commands, settings): | ||||
|         settings.require_confirmation = False | ||||
|         assert ui.select_command(commands) == commands[0] | ||||
|         assert capsys.readouterr() == ('', 'ls\n') | ||||
|  | ||||
|     def test_without_confirmation_with_side_effects(self, capsys, | ||||
|                                                     commands_with_side_effect): | ||||
|         assert ui.select_command(commands_with_side_effect, | ||||
|                                  Mock(debug=False, no_color=True, | ||||
|                                       require_confirmation=False)) \ | ||||
|     def test_without_confirmation_with_side_effects( | ||||
|             self, capsys, commands_with_side_effect, settings): | ||||
|         settings.require_confirmation = False | ||||
|         assert ui.select_command(commands_with_side_effect) \ | ||||
|                == commands_with_side_effect[0] | ||||
|         assert capsys.readouterr() == ('', 'ls (+side effect)\n') | ||||
|  | ||||
|     def test_with_confirmation(self, capsys, patch_getch, commands): | ||||
|         patch_getch(['\n']) | ||||
|         assert ui.select_command(commands, | ||||
|                                  Mock(debug=False, no_color=True, | ||||
|                                       require_confirmation=True)) == commands[0] | ||||
|         assert ui.select_command(commands) == commands[0] | ||||
|         assert capsys.readouterr() == ('', u'\x1b[1K\rls [enter/↑/↓/ctrl+c]\n') | ||||
|  | ||||
|     def test_with_confirmation_abort(self, capsys, patch_getch, commands): | ||||
|         patch_getch([KeyboardInterrupt]) | ||||
|         assert ui.select_command(commands, | ||||
|                                  Mock(debug=False, no_color=True, | ||||
|                                       require_confirmation=True)) is None | ||||
|         assert ui.select_command(commands) is None | ||||
|         assert capsys.readouterr() == ('', u'\x1b[1K\rls [enter/↑/↓/ctrl+c]\nAborted\n') | ||||
|  | ||||
|     def test_with_confirmation_with_side_effct(self, capsys, patch_getch, | ||||
|                                                commands_with_side_effect): | ||||
|         patch_getch(['\n']) | ||||
|         assert ui.select_command(commands_with_side_effect, | ||||
|                                  Mock(debug=False, no_color=True, | ||||
|                                       require_confirmation=True))\ | ||||
|         assert ui.select_command(commands_with_side_effect)\ | ||||
|                == commands_with_side_effect[0] | ||||
|         assert capsys.readouterr() == ('', u'\x1b[1K\rls (+side effect) [enter/↑/↓/ctrl+c]\n') | ||||
|  | ||||
|     def test_with_confirmation_select_second(self, capsys, patch_getch, commands): | ||||
|         patch_getch(['\x1b', '[', 'B', '\n']) | ||||
|         assert ui.select_command(commands, | ||||
|                                  Mock(debug=False, no_color=True, | ||||
|                                       require_confirmation=True)) == commands[1] | ||||
|         assert ui.select_command(commands) == commands[1] | ||||
|         assert capsys.readouterr() == ( | ||||
|             '', u'\x1b[1K\rls [enter/↑/↓/ctrl+c]\x1b[1K\rcd [enter/↑/↓/ctrl+c]\n') | ||||
|   | ||||
| @@ -1,10 +1,9 @@ | ||||
| import pytest | ||||
| from mock import Mock | ||||
| import six | ||||
| from thefuck.utils import wrap_settings, \ | ||||
| from thefuck.utils import default_settings, \ | ||||
|     memoize, get_closest, get_all_executables, replace_argument, \ | ||||
|     get_all_matched_commands, is_app, for_app, cache | ||||
| from thefuck.types import Settings | ||||
|     get_all_matched_commands, is_app, for_app, cache, compatibility_call | ||||
| from tests.utils import Command | ||||
|  | ||||
|  | ||||
| @@ -12,9 +11,12 @@ from tests.utils import Command | ||||
|     ({'key': 'val'}, {}, {'key': 'val'}), | ||||
|     ({'key': 'new-val'}, {'key': 'val'}, {'key': 'val'}), | ||||
|     ({'key': 'new-val', 'unset': 'unset'}, {'key': 'val'}, {'key': 'val', 'unset': 'unset'})]) | ||||
| def test_wrap_settings(override, old, new): | ||||
|     fn = lambda _, settings: settings | ||||
|     assert wrap_settings(override)(fn)(None, Settings(old)) == new | ||||
| def test_default_settings(settings, override, old, new): | ||||
|     settings.clear() | ||||
|     settings.update(old) | ||||
|     fn = lambda _: _ | ||||
|     default_settings(override)(fn)(None) | ||||
|     assert settings == new | ||||
|  | ||||
|  | ||||
| def test_memoize(): | ||||
| @@ -112,10 +114,10 @@ def test_is_app(script, names, result): | ||||
|     ('hg diff', ['git', 'hub'], False)]) | ||||
| def test_for_app(script, names, result): | ||||
|     @for_app(*names) | ||||
|     def match(command, settings): | ||||
|     def match(command): | ||||
|         return True | ||||
|  | ||||
|     assert match(Command(script), None) == result | ||||
|     assert match(Command(script)) == result | ||||
|  | ||||
|  | ||||
| class TestCache(object): | ||||
| @@ -180,3 +182,50 @@ class TestCache(object): | ||||
|         shelve.update({key: {'etag': '-1', 'value': 'old-value'}}) | ||||
|         assert fn() == '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()) | ||||
|   | ||||
| @@ -1,12 +1,11 @@ | ||||
| from copy import copy | ||||
| from imp import load_source | ||||
| import os | ||||
| import sys | ||||
| 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): | ||||
|         return _DefaultRulesNames(list(self) + items) | ||||
|  | ||||
| @@ -24,7 +23,6 @@ class _DefaultRulesNames(types.RulesNamesList): | ||||
| DEFAULT_RULES = _DefaultRulesNames([]) | ||||
| DEFAULT_PRIORITY = 1000 | ||||
|  | ||||
|  | ||||
| DEFAULT_SETTINGS = {'rules': DEFAULT_RULES, | ||||
|                     'exclude_rules': [], | ||||
|                     'wait_command': 3, | ||||
| @@ -42,7 +40,6 @@ ENV_TO_ATTR = {'THEFUCK_RULES': 'rules', | ||||
|                'THEFUCK_PRIORITY': 'priority', | ||||
|                'THEFUCK_DEBUG': 'debug'} | ||||
|  | ||||
|  | ||||
| SETTINGS_HEADER = u"""# ~/.thefuck/settings.py: The Fuck settings file | ||||
| # | ||||
| # The rules are defined as in the example bellow: | ||||
| @@ -105,30 +102,30 @@ def _settings_from_env(): | ||||
|             if env in os.environ} | ||||
|  | ||||
|  | ||||
| def get_settings(user_dir): | ||||
|     """Returns settings filled with values from `settings.py` and env.""" | ||||
|     conf = copy(DEFAULT_SETTINGS) | ||||
|     try: | ||||
|         conf.update(_settings_from_file(user_dir)) | ||||
|     except Exception: | ||||
|         logs.exception("Can't load settings from file", | ||||
|                        sys.exc_info(), | ||||
|                        types.Settings(conf)) | ||||
| settings = Settings(DEFAULT_SETTINGS) | ||||
|  | ||||
|  | ||||
| def init_settings(user_dir): | ||||
|     """Fills `settings` with values from `settings.py` and env.""" | ||||
|     from .logs import exception | ||||
|  | ||||
|     settings.user_dir = user_dir | ||||
|  | ||||
|     try: | ||||
|         conf.update(_settings_from_env()) | ||||
|         settings.update(_settings_from_file(user_dir)) | ||||
|     except Exception: | ||||
|         logs.exception("Can't load settings from env", | ||||
|                        sys.exc_info(), | ||||
|                        types.Settings(conf)) | ||||
|         exception("Can't load settings from file", sys.exc_info()) | ||||
|  | ||||
|     if not isinstance(conf['rules'], types.RulesNamesList): | ||||
|         conf['rules'] = types.RulesNamesList(conf['rules']) | ||||
|     try: | ||||
|         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): | ||||
|         conf['exclude_rules'] = types.RulesNamesList(conf['exclude_rules']) | ||||
|     if not isinstance(settings['rules'], RulesNamesList): | ||||
|         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): | ||||
|   | ||||
| @@ -1,16 +1,19 @@ | ||||
| import sys | ||||
| from imp import load_source | ||||
| 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.""" | ||||
|     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)) | ||||
|         priority = getattr(rule_module, 'priority', conf.DEFAULT_PRIORITY) | ||||
|     return types.Rule(name, rule_module.match, | ||||
|         priority = getattr(rule_module, 'priority', DEFAULT_PRIORITY) | ||||
|     return Rule(name, rule_module.match, | ||||
|                 rule_module.get_new_command, | ||||
|                 getattr(rule_module, 'enabled_by_default', True), | ||||
|                 getattr(rule_module, 'side_effect', None), | ||||
| @@ -18,27 +21,27 @@ def load_rule(rule, settings): | ||||
|                 getattr(rule_module, 'requires_output', True)) | ||||
|  | ||||
|  | ||||
| def get_loaded_rules(rules, settings): | ||||
| def get_loaded_rules(rules): | ||||
|     """Yields all available rules.""" | ||||
|     for rule in rules: | ||||
|         if rule.name != '__init__.py': | ||||
|             loaded_rule = load_rule(rule, settings) | ||||
|             loaded_rule = load_rule(rule) | ||||
|             if loaded_rule in settings.rules and \ | ||||
|                             loaded_rule not in settings.exclude_rules: | ||||
|                 yield loaded_rule | ||||
|  | ||||
|  | ||||
| def get_rules(user_dir, settings): | ||||
| def get_rules(): | ||||
|     """Returns all enabled rules.""" | ||||
|     bundled = Path(__file__).parent \ | ||||
|         .joinpath('rules') \ | ||||
|         .glob('*.py') | ||||
|     user = user_dir.joinpath('rules').glob('*.py') | ||||
|     return sorted(get_loaded_rules(sorted(bundled) + sorted(user), settings), | ||||
|     user = settings.user_dir.joinpath('rules').glob('*.py') | ||||
|     return sorted(get_loaded_rules(sorted(bundled) + sorted(user)), | ||||
|                   key=lambda rule: rule.priority) | ||||
|  | ||||
|  | ||||
| def is_rule_match(command, rule, settings): | ||||
| def is_rule_match(command, rule): | ||||
|     """Returns first matched rule for command.""" | ||||
|     script_only = command.stdout is None and command.stderr is None | ||||
|  | ||||
| @@ -46,27 +49,26 @@ def is_rule_match(command, rule, settings): | ||||
|         return False | ||||
|  | ||||
|     try: | ||||
|         with logs.debug_time(u'Trying rule: {};'.format(rule.name), | ||||
|                              settings): | ||||
|             if rule.match(command, settings): | ||||
|         with logs.debug_time(u'Trying rule: {};'.format(rule.name)): | ||||
|             if compatibility_call(rule.match, command): | ||||
|                 return True | ||||
|     except Exception: | ||||
|         logs.rule_failed(rule, sys.exc_info(), settings) | ||||
|         logs.rule_failed(rule, sys.exc_info()) | ||||
|  | ||||
|  | ||||
| def make_corrected_commands(command, rule, settings): | ||||
|     new_commands = rule.get_new_command(command, settings) | ||||
| def make_corrected_commands(command, rule): | ||||
|     new_commands = compatibility_call(rule.get_new_command, command) | ||||
|     if not isinstance(new_commands, list): | ||||
|         new_commands = (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, | ||||
|                                priority=(n + 1) * rule.priority) | ||||
|  | ||||
|  | ||||
| def get_corrected_commands(command, user_dir, settings): | ||||
| def get_corrected_commands(command): | ||||
|     corrected_commands = ( | ||||
|         corrected for rule in get_rules(user_dir, settings) | ||||
|         if is_rule_match(command, rule, settings) | ||||
|         for corrected in make_corrected_commands(command, rule, settings)) | ||||
|     return types.SortedCorrectedCommandsSequence(corrected_commands, settings) | ||||
|         corrected for rule in get_rules() | ||||
|         if is_rule_match(command, rule) | ||||
|         for corrected in make_corrected_commands(command, rule)) | ||||
|     return SortedCorrectedCommandsSequence(corrected_commands) | ||||
|   | ||||
| @@ -5,9 +5,10 @@ from datetime import datetime | ||||
| import sys | ||||
| from traceback import format_exception | ||||
| import colorama | ||||
| from .conf import settings | ||||
|  | ||||
|  | ||||
| def color(color_, settings): | ||||
| def color(color_): | ||||
|     """Utility for ability to disabling colored output.""" | ||||
|     if settings.no_colors: | ||||
|         return '' | ||||
| @@ -15,37 +16,37 @@ def color(color_, settings): | ||||
|         return color_ | ||||
|  | ||||
|  | ||||
| def exception(title, exc_info, settings): | ||||
| def exception(title, exc_info): | ||||
|     sys.stderr.write( | ||||
|         u'{warn}[WARN] {title}:{reset}\n{trace}' | ||||
|         u'{warn}----------------------------{reset}\n\n'.format( | ||||
|             warn=color(colorama.Back.RED + colorama.Fore.WHITE | ||||
|                        + colorama.Style.BRIGHT, settings), | ||||
|             reset=color(colorama.Style.RESET_ALL, settings), | ||||
|                        + colorama.Style.BRIGHT), | ||||
|             reset=color(colorama.Style.RESET_ALL), | ||||
|             title=title, | ||||
|             trace=''.join(format_exception(*exc_info)))) | ||||
|  | ||||
|  | ||||
| def rule_failed(rule, exc_info, settings): | ||||
|     exception('Rule {}'.format(rule.name), exc_info, settings) | ||||
| def rule_failed(rule, exc_info): | ||||
|     exception('Rule {}'.format(rule.name), exc_info) | ||||
|  | ||||
|  | ||||
| def failed(msg, settings): | ||||
| def failed(msg): | ||||
|     sys.stderr.write('{red}{msg}{reset}\n'.format( | ||||
|         msg=msg, | ||||
|         red=color(colorama.Fore.RED, settings), | ||||
|         reset=color(colorama.Style.RESET_ALL, settings))) | ||||
|         red=color(colorama.Fore.RED), | ||||
|         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( | ||||
|         script=corrected_command.script, | ||||
|         side_effect=' (+side effect)' if corrected_command.side_effect else '', | ||||
|         bold=color(colorama.Style.BRIGHT, settings), | ||||
|         reset=color(colorama.Style.RESET_ALL, settings))) | ||||
|         bold=color(colorama.Style.BRIGHT), | ||||
|         reset=color(colorama.Style.RESET_ALL))) | ||||
|  | ||||
|  | ||||
| def confirm_text(corrected_command, settings): | ||||
| def confirm_text(corrected_command): | ||||
|     sys.stderr.write( | ||||
|         ('{clear}{bold}{script}{reset}{side_effect} ' | ||||
|          '[{green}enter{reset}/{blue}↑{reset}/{blue}↓{reset}' | ||||
| @@ -53,42 +54,42 @@ def confirm_text(corrected_command, settings): | ||||
|             script=corrected_command.script, | ||||
|             side_effect=' (+side effect)' if corrected_command.side_effect else '', | ||||
|             clear='\033[1K\r', | ||||
|             bold=color(colorama.Style.BRIGHT, settings), | ||||
|             green=color(colorama.Fore.GREEN, settings), | ||||
|             red=color(colorama.Fore.RED, settings), | ||||
|             reset=color(colorama.Style.RESET_ALL, settings), | ||||
|             blue=color(colorama.Fore.BLUE, settings))) | ||||
|             bold=color(colorama.Style.BRIGHT), | ||||
|             green=color(colorama.Fore.GREEN), | ||||
|             red=color(colorama.Fore.RED), | ||||
|             reset=color(colorama.Style.RESET_ALL), | ||||
|             blue=color(colorama.Fore.BLUE))) | ||||
|  | ||||
|  | ||||
| def debug(msg, settings): | ||||
| def debug(msg): | ||||
|     if settings.debug: | ||||
|         sys.stderr.write(u'{blue}{bold}DEBUG:{reset} {msg}\n'.format( | ||||
|             msg=msg, | ||||
|             reset=color(colorama.Style.RESET_ALL, settings), | ||||
|             blue=color(colorama.Fore.BLUE, settings), | ||||
|             bold=color(colorama.Style.BRIGHT, settings))) | ||||
|             reset=color(colorama.Style.RESET_ALL), | ||||
|             blue=color(colorama.Fore.BLUE), | ||||
|             bold=color(colorama.Style.BRIGHT))) | ||||
|  | ||||
|  | ||||
| @contextmanager | ||||
| def debug_time(msg, settings): | ||||
| def debug_time(msg): | ||||
|     started = datetime.now() | ||||
|     try: | ||||
|         yield | ||||
|     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( | ||||
|         bold=color(colorama.Style.BRIGHT, settings), | ||||
|         reset=color(colorama.Style.RESET_ALL, settings))) | ||||
|         bold=color(colorama.Style.BRIGHT), | ||||
|         reset=color(colorama.Style.RESET_ALL))) | ||||
|     if configuration_details: | ||||
|         content, path = configuration_details | ||||
|         print( | ||||
|             "Please put {bold}{content}{reset} in your " | ||||
|             "{bold}{path}{reset}.".format( | ||||
|                 bold=color(colorama.Style.BRIGHT, settings), | ||||
|                 reset=color(colorama.Style.RESET_ALL, settings), | ||||
|                 bold=color(colorama.Style.BRIGHT), | ||||
|                 reset=color(colorama.Style.RESET_ALL), | ||||
|                 path=path, | ||||
|                 content=content)) | ||||
|     print('More details - https://github.com/nvbn/thefuck#manual-installation') | ||||
|   | ||||
| @@ -10,8 +10,10 @@ import sys | ||||
| from psutil import Process, TimeoutExpired | ||||
| import colorama | ||||
| 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 .utils import compatibility_call | ||||
| from .ui import select_command | ||||
|  | ||||
|  | ||||
| @@ -21,11 +23,11 @@ def setup_user_dir(): | ||||
|     rules_dir = user_dir.joinpath('rules') | ||||
|     if not rules_dir.is_dir(): | ||||
|         rules_dir.mkdir(parents=True) | ||||
|     conf.initialize_settings_file(user_dir) | ||||
|     initialize_settings_file(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 | ||||
|     `settings.wait_command` time. | ||||
|  | ||||
| @@ -43,7 +45,7 @@ def wait_output(settings, popen): | ||||
|         return False | ||||
|  | ||||
|  | ||||
| def get_command(settings, args): | ||||
| def get_command(args): | ||||
|     """Creates command from `args` and executes it.""" | ||||
|     if six.PY2: | ||||
|         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.update(settings.env) | ||||
|  | ||||
|     with logs.debug_time(u'Call: {}; with env: {};'.format(script, env), | ||||
|                          settings): | ||||
|     with logs.debug_time(u'Call: {}; with env: {};'.format(script, 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') | ||||
|             stderr = result.stderr.read().decode('utf-8') | ||||
|  | ||||
|             logs.debug(u'Received stdout: {}'.format(stdout), settings) | ||||
|             logs.debug(u'Received stderr: {}'.format(stderr), settings) | ||||
|             logs.debug(u'Received stdout: {}'.format(stdout)) | ||||
|             logs.debug(u'Received stderr: {}'.format(stderr)) | ||||
|  | ||||
|             return types.Command(script, stdout, stderr) | ||||
|         else: | ||||
|             logs.debug(u'Execution timed out!', settings) | ||||
|             logs.debug(u'Execution timed out!') | ||||
|             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.""" | ||||
|     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) | ||||
|     print(command.script) | ||||
|  | ||||
| @@ -87,20 +88,20 @@ def run_command(old_cmd, command, settings): | ||||
| def fix_command(): | ||||
|     colorama.init() | ||||
|     user_dir = setup_user_dir() | ||||
|     settings = conf.get_settings(user_dir) | ||||
|     with logs.debug_time('Total', settings): | ||||
|         logs.debug(u'Run with settings: {}'.format(pformat(settings)), settings) | ||||
|     init_settings(user_dir) | ||||
|     with logs.debug_time('Total'): | ||||
|         logs.debug(u'Run with settings: {}'.format(pformat(settings))) | ||||
|  | ||||
|         command = get_command(settings, sys.argv) | ||||
|         command = get_command(sys.argv) | ||||
|  | ||||
|         if not command: | ||||
|             logs.debug('Empty command, nothing to do', settings) | ||||
|             logs.debug('Empty command, nothing to do') | ||||
|             return | ||||
|  | ||||
|         corrected_commands = get_corrected_commands(command, user_dir, settings) | ||||
|         selected_command = select_command(corrected_commands, settings) | ||||
|         corrected_commands = get_corrected_commands(command) | ||||
|         selected_command = select_command(corrected_commands) | ||||
|         if selected_command: | ||||
|             run_command(command, selected_command, settings) | ||||
|             run_command(command, selected_command) | ||||
|  | ||||
|  | ||||
| def _get_current_version(): | ||||
| @@ -128,8 +129,8 @@ def how_to_configure_alias(): | ||||
|     """ | ||||
|     colorama.init() | ||||
|     user_dir = setup_user_dir() | ||||
|     settings = conf.get_settings(user_dir) | ||||
|     logs.how_to_configure_alias(shells.how_to_configure(), settings) | ||||
|     init_settings(user_dir) | ||||
|     logs.how_to_configure_alias(shells.how_to_configure()) | ||||
|  | ||||
|  | ||||
| def main(): | ||||
|   | ||||
| @@ -20,11 +20,11 @@ def get_package(command): | ||||
|         return None | ||||
|  | ||||
|  | ||||
| def match(command, settings): | ||||
| def match(command): | ||||
|     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) | ||||
|     formatme = shells.and_('sudo apt-get install {}', '{}') | ||||
|     return formatme.format(name, command.script) | ||||
|   | ||||
| @@ -3,9 +3,9 @@ from thefuck.utils import for_app | ||||
|  | ||||
|  | ||||
| @for_app('apt-get') | ||||
| def match(command, settings): | ||||
| def match(command): | ||||
|     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) | ||||
|   | ||||
| @@ -24,7 +24,7 @@ def _get_similar_formula(formula_name): | ||||
|     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 | ||||
|                          'No available formula' in command.stderr) | ||||
|  | ||||
| @@ -35,7 +35,7 @@ def match(command, settings): | ||||
|     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]+)', | ||||
|                                    command.stderr)[0] | ||||
|     exist_formula = _get_similar_formula(not_exist_formula) | ||||
|   | ||||
| @@ -63,7 +63,7 @@ def _brew_commands(): | ||||
|             'doctor', 'create', 'edit'] | ||||
|  | ||||
|  | ||||
| def match(command, settings): | ||||
| def match(command): | ||||
|     is_proper_command = ('brew' in command.script and | ||||
|                          'Unknown command' in command.stderr) | ||||
|  | ||||
| @@ -74,7 +74,7 @@ def match(command, settings): | ||||
|     return False | ||||
|  | ||||
|  | ||||
| def get_new_command(command, settings): | ||||
| def get_new_command(command): | ||||
|     broken_cmd = re.findall(r'Error: Unknown command: ([a-z]+)', | ||||
|                             command.stderr)[0] | ||||
|     return replace_command(command, broken_cmd, _brew_commands()) | ||||
|   | ||||
| @@ -6,9 +6,9 @@ | ||||
| # 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' | ||||
|  | ||||
|  | ||||
| def get_new_command(command, settings): | ||||
| def get_new_command(command): | ||||
|     return command.script + ' --all' | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| def match(command, settings): | ||||
| def match(command): | ||||
|     return command.script == 'cargo' | ||||
|  | ||||
|  | ||||
| def get_new_command(command, settings): | ||||
| def get_new_command(command): | ||||
|     return 'cargo build' | ||||
|   | ||||
| @@ -3,12 +3,12 @@ from thefuck.utils import replace_argument, for_app | ||||
|  | ||||
|  | ||||
| @for_app('cargo') | ||||
| def match(command, settings): | ||||
| def match(command): | ||||
|     return ('No such subcommand' 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] | ||||
|     fix = re.findall(r'Did you mean `([^`]*)`', command.stderr)[0] | ||||
|  | ||||
|   | ||||
| @@ -18,7 +18,7 @@ def _get_sub_dirs(parent): | ||||
|  | ||||
| @sudo_support | ||||
| @for_app('cd') | ||||
| def match(command, settings): | ||||
| def match(command): | ||||
|     """Match function copied from cd_mkdir.py""" | ||||
|     return (command.script.startswith('cd ') | ||||
|             and ('no such file or directory' in command.stderr.lower() | ||||
| @@ -26,7 +26,7 @@ def match(command, settings): | ||||
|  | ||||
|  | ||||
| @sudo_support | ||||
| def get_new_command(command, settings): | ||||
| def get_new_command(command): | ||||
|     """ | ||||
|     Attempt to rebuild the path string by spellchecking the directories. | ||||
|     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: | ||||
|             cwd = os.path.join(cwd, best_matches[0]) | ||||
|         else: | ||||
|             return cd_mkdir.get_new_command(command, settings) | ||||
|             return cd_mkdir.get_new_command(command) | ||||
|     return 'cd "{0}"'.format(cwd) | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -6,12 +6,12 @@ from thefuck.specific.sudo import sudo_support | ||||
|  | ||||
| @sudo_support | ||||
| @for_app('cd') | ||||
| def match(command, settings): | ||||
| def match(command): | ||||
|     return (('no such file or directory' in command.stderr.lower() | ||||
|              or 'cd: can\'t cd to' in command.stderr.lower())) | ||||
|  | ||||
|  | ||||
| @sudo_support | ||||
| def get_new_command(command, settings): | ||||
| def get_new_command(command): | ||||
|     repl = shells.and_('mkdir -p \\1', 'cd \\1') | ||||
|     return re.sub(r'^cd (.*)', repl, command.script) | ||||
|   | ||||
| @@ -8,9 +8,9 @@ | ||||
| # cd..: command not found | ||||
|  | ||||
|  | ||||
| def match(command, settings): | ||||
| def match(command): | ||||
|     return command.script == 'cd..' | ||||
|  | ||||
|  | ||||
| def get_new_command(command, settings): | ||||
| def get_new_command(command): | ||||
|     return 'cd ..' | ||||
|   | ||||
| @@ -3,12 +3,12 @@ from thefuck.utils import replace_argument, for_app | ||||
|  | ||||
|  | ||||
| @for_app('composer') | ||||
| def match(command, settings): | ||||
| def match(command): | ||||
|     return (('did you mean this?' 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] | ||||
|     new_cmd = re.findall(r'Did you mean this\?[^\n]*\n\s*([^\n]*)', command.stderr) | ||||
|     if not new_cmd: | ||||
|   | ||||
| @@ -5,11 +5,11 @@ from thefuck.utils import for_app | ||||
|  | ||||
| @sudo_support | ||||
| @for_app('cp') | ||||
| def match(command, settings): | ||||
| def match(command): | ||||
|     stderr = command.stderr.lower() | ||||
|     return 'omitting directory' in stderr or 'is a directory' in stderr | ||||
|  | ||||
|  | ||||
| @sudo_support | ||||
| def get_new_command(command, settings): | ||||
| def get_new_command(command): | ||||
|     return re.sub(r'^cp', 'cp -a', command.script) | ||||
|   | ||||
| @@ -2,11 +2,11 @@ from thefuck.utils import for_app | ||||
|  | ||||
|  | ||||
| @for_app(['g++', 'clang++']) | ||||
| def match(command, settings): | ||||
| def match(command): | ||||
|     return ('This file requires compiler and library support for the ' | ||||
|             'ISO C++ 2011 standard.' in command.stderr or | ||||
|             '-Wc++11-extensions' in command.stderr) | ||||
|  | ||||
|  | ||||
| def get_new_command(command, settings): | ||||
| def get_new_command(command): | ||||
|     return command.script + ' -std=c++11' | ||||
|   | ||||
| @@ -25,18 +25,18 @@ def _tar_file(cmd): | ||||
|  | ||||
|  | ||||
| @for_app('tar') | ||||
| def match(command, settings): | ||||
| def match(command): | ||||
|     return ('-C' not in command.script | ||||
|             and _is_tar_extract(command.script) | ||||
|             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}') \ | ||||
|         .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: | ||||
|         for file in archive.getnames(): | ||||
|             os.remove(file) | ||||
|   | ||||
| @@ -22,16 +22,16 @@ def _zip_file(command): | ||||
|  | ||||
|  | ||||
| @for_app('unzip') | ||||
| def match(command, settings): | ||||
| def match(command): | ||||
|     return ('-d' not in command.script | ||||
|             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]) | ||||
|  | ||||
|  | ||||
| def side_effect(old_cmd, command, settings): | ||||
| def side_effect(old_cmd, command): | ||||
|     with zipfile.ZipFile(_zip_file(old_cmd), 'r') as archive: | ||||
|         for file in archive.namelist(): | ||||
|             os.remove(file) | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user