1
0
mirror of https://github.com/nvbn/thefuck.git synced 2025-11-01 15:42:06 +00:00

Compare commits

..

1 Commits

Author SHA1 Message Date
nvbn
0fcc35c227 #380 merge cd_mkdir and cd_correction rules 2015-10-12 17:52:44 +08:00
248 changed files with 1625 additions and 6078 deletions

View File

@@ -1,51 +1,27 @@
language: python
sudo: false
matrix:
include:
- os: linux
dist: trusty
python: "3.6"
- os: linux
dist: trusty
python: "3.5"
- os: linux
dist: trusty
python: "3.4"
- os: linux
dist: trusty
python: "3.3"
- os: linux
dist: trusty
python: "2.7"
- os: osx
env: FORMULA="python"
language: generic
- os: osx
env: FORMULA="python3"
language: generic
services:
- docker
python:
- "3.5"
- "3.4"
- "3.3"
- "2.7"
addons:
apt:
sources:
- fish-shell/release-2
packages:
- python-commandnotfound
- python3-commandnotfound
before_install:
- if [[ $TRAVIS_OS_NAME == "osx" ]]; then brew update ; fi
- if [[ $TRAVIS_OS_NAME == "osx" ]]; then if brew ls --versions $FORMULA; then brew upgrade $FORMULA || echo Python is up to date; else brew install $FORMULA; fi; fi
- if [[ $TRAVIS_OS_NAME == "osx" ]]; then virtualenv venv -p $FORMULA; fi
- if [[ $TRAVIS_OS_NAME == "osx" ]]; then source venv/bin/activate; fi
- pip install -U pip
- pip install -U coveralls
- bash
- zsh
- fish
- tcsh
- pandoc
- git
install:
- pip install -Ur requirements.txt
- pip install coveralls
- pip install -r requirements.txt
- python setup.py develop
- rm -rf build
script:
- flake8
- export COVERAGE_PYTHON_VERSION=python-${TRAVIS_PYTHON_VERSION:0:1}
- export RUN_TESTS="coverage run --source=thefuck,tests -m py.test -v --capture=sys tests"
- if [[ $TRAVIS_PYTHON_VERSION == 3.6 && $TRAVIS_OS_NAME != "osx" ]]; then $RUN_TESTS --enable-functional; fi
- if [[ $TRAVIS_PYTHON_VERSION != 3.6 || $TRAVIS_OS_NAME == "osx" ]]; then $RUN_TESTS; fi
after_success:
- if [[ $TRAVIS_PYTHON_VERSION == 3.6 && $TRAVIS_OS_NAME != "osx" ]]; then coveralls; fi
- coverage run --source=thefuck,tests -m py.test -v --capture=sys --run-without-docker --enable-functional
after_success: coveralls

View File

@@ -1,25 +0,0 @@
# Report issues
If you have any issue with The Fuck, sorry about that, but we will do what we
can to fix that. Actually, maybe we already have, so first thing to do is to
update The Fuck and see if the bug is still there.
If it is (sorry again), check if the problem has not already been reported and
if not, just open an issue on [GitHub](https://github.com/nvbn/thefuck) with
the following basic information:
- the output of `thefuck --version` (something like `The Fuck 3.1 using
Python 3.5.0`);
- your shell and its version (`bash`, `zsh`, *Windows PowerShell*, etc.);
- your system (Debian 7, ArchLinux, Windows, etc.);
- how to reproduce the bug;
- the output of The Fuck with `THEFUCK_DEBUG=true` exported (typically execute
`export THEFUCK_DEBUG=true` in your shell before The Fuck);
- if the bug only appears with a specific application, the output of that
application and its version;
- anything else you think is relevant.
It's only with enough information that we can do something to fix the problem.
# Make a pull request
We gladly accept pull request on the [official
repository](https://github.com/nvbn/thefuck) for new rules, new features, bug
fixes, etc.

147
README.md
View File

@@ -1,10 +1,10 @@
# The Fuck [![Version][version-badge]][version-link] [![Build Status][travis-badge]][travis-link] [![Windows Build Status][appveyor-badge]][appveyor-link] [![Coverage][coverage-badge]][coverage-link] [![MIT License][license-badge]](LICENSE.md)
# The Fuck [![Build Status](https://travis-ci.org/nvbn/thefuck.svg?branch=master)](https://travis-ci.org/nvbn/thefuck)
Magnificent app which corrects your previous console command,
inspired by a [@liamosaur](https://twitter.com/liamosaur/)
[tweet](https://twitter.com/liamosaur/status/506975850596536320).
[![gif with examples][examples-link]][examples-link]
[![gif with examples](https://raw.githubusercontent.com/nvbn/thefuck/master/example.gif)](https://raw.githubusercontent.com/nvbn/thefuck/master/example.gif)
Few more examples:
@@ -52,7 +52,7 @@ Python 3.4.2 (default, Oct 8 2014, 13:08:17)
git: 'brnch' is not a git command. See 'git --help'.
Did you mean this?
branch
branch
➜ fuck
git branch [enter/↑/↓/ctrl+c]
@@ -94,25 +94,20 @@ Reading package lists... Done
- pip
- python-dev
## Installation
On OS X you can install `The Fuck` with [Homebrew][homebrew]:
## Installation [*experimental*]
On Ubuntu and OS X you can install `The Fuck` with installation script:
```bash
brew install thefuck
wget -O - https://raw.githubusercontent.com/nvbn/thefuck/master/install.sh | sh - && $0
```
On Ubuntu you can install `The Fuck` with:
```bash
sudo apt update
sudo apt install python3-dev python3-pip
pip3 install --user thefuck
```
## Manual installation
On other systems you can install `The Fuck` with `pip`:
Install `The Fuck` with `pip`:
```bash
pip install --user thefuck
sudo pip install thefuck
```
[Or using an OS package manager (OS X, Ubuntu, Arch).](https://github.com/nvbn/thefuck/wiki/Installation)
@@ -120,9 +115,9 @@ pip install --user thefuck
You should place this command in your `.bash_profile`, `.bashrc`, `.zshrc` or other startup script:
```bash
eval $(thefuck --alias)
eval "$(thefuck --alias)"
# You can use whatever you want as an alias, like for Mondays:
eval $(thefuck --alias FUCK)
eval "$(thefuck --alias FUCK)"
```
[Or in your shell config (Bash, Zsh, Fish, Powershell, tcsh).](https://github.com/nvbn/thefuck/wiki/Shell-aliases)
@@ -130,16 +125,11 @@ eval $(thefuck --alias FUCK)
Changes will be available only in a new shell session.
To make them available immediately, run `source ~/.bashrc` (or your shell config file like `.zshrc`).
If you want separate alias for running fixed command without confirmation you can use alias like:
```bash
alias fuck-it='export THEFUCK_REQUIRE_CONFIRMATION=False; fuck; export THEFUCK_REQUIRE_CONFIRMATION=True'
```
## Update
```bash
pip install --user thefuck --upgrade
sudo pip install thefuck --upgrade
```
**Aliases changed in 1.34.**
@@ -149,14 +139,11 @@ pip install --user thefuck --upgrade
The Fuck tries to match a rule for the previous command, creates a new command
using the matched rule and runs it. Rules enabled by default are as follows:
* `ag_literal` – adds `-Q` to `ag` when suggested;
* `aws_cli` – fixes misspelled commands like `aws dynamdb scan`;
* `cargo` – runs `cargo build` instead of `cargo`;
* `cargo_no_command` – fixes wrongs commands like `cargo buid`;
* `cd_correction` – spellchecks and correct failed cd commands;
* `cd_mkdir` – creates directories before cd'ing into them;
* `cd_correction` – spellchecks and correct failed cd commands, when it's not possible
creates directories before cd'ing into them;
* `cd_parent` – changes `cd..` to `cd ..`;
* `chmod_x` – add execution bit;
* `composer_not_command` – fixes composer command name;
* `cp_omitting_directory` – adds `-a` when you `cp` directory;
* `cpp11` – adds missing `-std=c++11` to `g++` or `clang++`;
@@ -166,85 +153,48 @@ using the matched rule and runs it. Rules enabled by default are as follows:
* `django_south_merge` – adds `--merge` to inconsistent django south migration;
* `docker_not_command` – fixes wrong docker commands like `docker tags`;
* `dry` – fixes repetitions like `git git push`;
* `fab_command_not_found` – fix misspelled fabric commands;
* `fix_alt_space` – replaces Alt+Space with Space character;
* `fix_file` – opens a file with an error in your `$EDITOR`;
* `gem_unknown_command` – fixes wrong `gem` commands;
* `git_add` – fixes *"pathspec 'foo' did not match any file(s) known to git."*;
* `git_add_force` &ndash; adds `--force` to `git add <pathspec>...` when paths are .gitignore'd;
* `git_bisect_usage` &ndash; fixes `git bisect strt`, `git bisect goood`, `git bisect rset`, etc. when bisecting;
* `git_add` &ndash; fixes *"Did you forget to 'git add'?"*;
* `git_branch_delete` &ndash; changes `git branch -d` to `git branch -D`;
* `git_branch_exists` &ndash; offers `git branch -d foo`, `git branch -D foo` or `git checkout foo` when creating a branch that already exists;
* `git_branch_list` &ndash; catches `git branch list` in place of `git branch` and removes created branch;
* `git_checkout` &ndash; fixes branch name or creates new branch;
* `git_diff_no_index` &ndash; adds `--no-index` to previous `git diff` on untracked files;
* `git_diff_staged` &ndash; adds `--staged` to previous `git diff` with unexpected output;
* `git_fix_stash` &ndash; fixes `git stash` commands (misspelled subcommand and missing `save`);
* `git_flag_after_filename` &ndash; fixes `fatal: bad flag '...' after filename`
* `git_help_aliased` &ndash; fixes `git help <alias>` commands replacing <alias> with the aliased command;
* `git_not_command` &ndash; fixes wrong git commands like `git brnch`;
* `git_pull` &ndash; sets upstream before executing previous `git pull`;
* `git_pull_clone` &ndash; clones instead of pulling when the repo does not exist;
* `git_pull_uncommitted_changes` &ndash; stashes changes before pulling and pops them afterwards;
* `git_push` &ndash; adds `--set-upstream origin $branch` to previous failed `git push`;
* `git_push_pull` &ndash; runs `git pull` when `push` was rejected;
* `git_rebase_no_changes` &ndash; runs `git rebase --skip` instead of `git rebase --continue` when there are no changes;
* `git_rm_local_modifications` &ndash; adds `-f` or `--cached` when you try to `rm` a locally modified file;
* `git_rm_recursive` &ndash; adds `-r` when you try to `rm` a directory;
* `git_rm_staged` &ndash; adds `-f` or `--cached` when you try to `rm` a file with staged changes
* `git_rebase_merge_dir` &ndash; offers `git rebase (--continue | --abort | --skip)` or removing the `.git/rebase-merge` dir when a rebase is in progress;
* `git_remote_seturl_add` &ndash; runs `git remote add` when `git remote set_url` on nonexistant remote;
* `git_stash` &ndash; stashes your local modifications before rebasing or switching branch;
* `git_stash_pop` &ndash; adds your local modifications before popping stash, then resets;
* `git_tag_force` &ndash; adds `--force` to `git tag <tagname>` when the tag already exists;
* `git_two_dashes` &ndash; adds a missing dash to commands like `git commit -amend` or `git rebase -continue`;
* `go_run` &ndash; appends `.go` extension when compiling/running Go programs;
* `gradle_no_task` &ndash; fixes not found or ambiguous `gradle` task;
* `gradle_wrapper` &ndash; replaces `gradle` with `./gradlew`;
* `grep_arguments_order` &ndash; fixes grep arguments order for situations like `grep -lir . test`;
* `git_stash` &ndash; stashes you local modifications before rebasing or switching branch;
* `go_run` &ndash; appends `.go` extension when compiling/running Go programs
* `grep_recursive` &ndash; adds `-r` when you trying to `grep` directory;
* `grunt_task_not_found` &ndash; fixes misspelled `grunt` commands;
* `gulp_not_task` &ndash; fixes misspelled `gulp` tasks;
* `has_exists_script` &ndash; prepends `./` when script/binary exists;
* `heroku_not_command` &ndash; fixes wrong `heroku` commands like `heroku log`;
* `history` &ndash; tries to replace command with most similar command from history;
* `hostscli` &ndash; tries to fix `hostscli` usage;
* `ifconfig_device_not_found` &ndash; fixes wrong device names like `wlan0` to `wlp2s0`;
* `java` &ndash; removes `.java` extension when running Java programs;
* `javac` &ndash; appends missing `.java` when compiling Java files;
* `lein_not_task` &ndash; fixes wrong `lein` tasks like `lein rpl`;
* `ln_no_hard_link` &ndash; catches hard link creation on directories, suggest symbolic link;
* `ln_s_order` &ndash; fixes `ln -s` arguments order;
* `ls_all` &ndash; adds `-A` to `ls` when output is empty;
* `ls_lah` &ndash; adds `-lah` to `ls`;
* `man` &ndash; changes manual section;
* `man_no_space` &ndash; fixes man commands without spaces, for example `mandiff`;
* `mercurial` &ndash; fixes wrong `hg` commands;
* `missing_space_before_subcommand` &ndash; fixes command with missing space like `npminstall`;
* `mkdir_p` &ndash; adds `-p` when you trying to create directory without parent;
* `mvn_no_command` &ndash; adds `clean package` to `mvn`;
* `mvn_unknown_lifecycle_phase` &ndash; fixes misspelled lifecycle phases with `mvn`;
* `npm_missing_script` &ndash; fixes `npm` custom script name in `npm run-script <script>`;
* `npm_run_script` &ndash; adds missing `run-script` for custom `npm` scripts;
* `npm_wrong_command` &ndash; fixes wrong npm commands like `npm urgrade`;
* `no_command` &ndash; fixes wrong console commands, for example `vom/vim`;
* `no_such_file` &ndash; creates missing directories with `mv` and `cp` commands;
* `open` &ndash; either prepends `http://` to address passed to `open` or create a new file or directory and passes it to `open`;
* `open` &ndash; prepends `http` to address passed to `open`;
* `pip_unknown_command` &ndash; fixes wrong `pip` commands, for example `pip instatl/pip install`;
* `port_already_in_use` &ndash; kills process that bound port;
* `python_command` &ndash; prepends `python` when you trying to run not executable/without `./` python script;
* `python_execute` &ndash; appends missing `.py` when executing Python files;
* `quotation_marks` &ndash; fixes uneven usage of `'` and `"` when containing args';
* `path_from_history` &ndash; replaces not found path with similar absolute path from history;
* `react_native_command_unrecognized` &ndash; fixes unrecognized `react-native` commands;
* `remove_trailing_cedilla` &ndash; remove trailling cedillas `ç`, a common typo for european keyboard layouts;
* `rm_dir` &ndash; adds `-rf` when you trying to remove directory;
* `scm_correction` &ndash; corrects wrong scm like `hg log` to `git log`;
* `sed_unterminated_s` &ndash; adds missing '/' to `sed`'s `s` commands;
* `sl_ls` &ndash; changes `sl` to `ls`;
* `ssh_known_hosts` &ndash; removes host from `known_hosts` on warning;
* `sudo` &ndash; prepends `sudo` to previous command if it failed because of permissions;
* `sudo_command_from_user_path` &ndash; runs commands from users `$PATH` with `sudo`;
* `switch_lang` &ndash; switches command from your local layout to en;
* `systemctl` &ndash; correctly orders parameters of confusing `systemctl`;
* `test.py` &ndash; runs `py.test` instead of `test.py`;
@@ -254,35 +204,27 @@ using the matched rule and runs it. Rules enabled by default are as follows:
* `tmux` &ndash; fixes `tmux` commands;
* `unknown_command` &ndash; fixes hadoop hdfs-style "unknown command", for example adds missing '-' to the command on `hdfs dfs ls`;
* `vagrant_up` &ndash; starts up the vagrant instance;
* `whois` &ndash; fixes `whois` command;
* `workon_doesnt_exists` &ndash; fixes `virtualenvwrapper` env name os suggests to create new.
* `yarn_alias` &ndash; fixes aliased `yarn` commands like `yarn ls`;
* `yarn_command_not_found` &ndash; fixes misspelled `yarn` commands;
* `yarn_help` &ndash; makes it easier to open `yarn` documentation;
* `whois` &ndash; fixes `whois` command.
Enabled by default only on specific platforms:
* `apt_get` &ndash; installs app from apt if it not installed (requires `python-commandnotfound` / `python3-commandnotfound`);
* `apt_get_search` &ndash; changes trying to search using `apt-get` with searching using `apt-cache`;
* `apt_invalid_operation` &ndash; fixes invalid `apt` and `apt-get` calls, like `apt-get isntall vim`;
* `brew_install` &ndash; fixes formula name for `brew install`;
* `brew_link` &ndash; adds `--overwrite --dry-run` if linking fails;
* `brew_uninstall` &ndash; adds `--force` to `brew uninstall` if multiple versions were installed;
* `brew_unknown_command` &ndash; fixes wrong brew commands, for example `brew docto/brew doctor`;
* `brew_update_formula` &ndash; turns `brew update <formula>` into `brew upgrade <formula>`;
* `brew_upgrade` &ndash; appends `--all` to `brew upgrade` as per Homebrew's new behaviour;
* `pacman` &ndash; installs app with `pacman` if it is not installed (uses `yaourt` if available);
* `pacman_not_found` &ndash; fixes package name with `pacman` or `yaourt`.
Bundled, but not enabled by default:
* `git_push_force` &ndash; adds `--force-with-lease` to a `git push` (may conflict with `git_push_pull`);
* `git_push_force` &ndash; adds `--force` to a `git push` (may conflict with `git_push_pull`);
* `rm_root` &ndash; adds `--no-preserve-root` to `rm -rf /` command.
## Creating your own rules
For adding your own rule you should create `your-rule-name.py`
in `~/.config/thefuck/rules`. The rule should contain two functions:
in `~/.thefuck/rules`. The rule should contain two functions:
```python
match(command: Command) -> bool
@@ -296,12 +238,10 @@ 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`, `stderr` and `script_parts`.
Rule shouldn't change `Command`.
`Command` has three attributes: `script`, `stdout` and `stderr`.
*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 `~/.config/thefuck/settings.py` and values from env ([see more below](#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`:
@@ -331,7 +271,7 @@ requires_output = True
## Settings
The Fuck has a few settings parameters which can be changed in `$XDG_CONFIG_HOME/thefuck/settings.py` (`$XDG_CONFIG_HOME` defaults to `~/.config`):
The Fuck has a few settings parameters which can be changed in `~/.thefuck/settings.py`:
* `rules` &ndash; list of enabled rules, by default `thefuck.conf.DEFAULT_RULES`;
* `exclude_rules` &ndash; list of disabled rules, by default `[]`;
@@ -339,11 +279,7 @@ The Fuck has a few settings parameters which can be changed in `$XDG_CONFIG_HOME
* `wait_command` &ndash; max amount of time in seconds for getting previous command output;
* `no_colors` &ndash; disable colored output;
* `priority` &ndash; dict with rules priorities, rule with lower `priority` will be matched first;
* `debug` &ndash; enables debug output, by default `False`;
* `history_limit` &ndash; numeric value of how many history commands will be scanned, like `2000`;
* `alter_history` &ndash; push fixed command to history, by default `True`;
* `wait_slow_command` &ndash; max amount of time in seconds for getting previous command output if it in `slow_commands` list;
* `slow_commands` &ndash; list of slow commands.
* `debug` &ndash; enables debug output, by default `False`.
Example of `settings.py`:
@@ -355,25 +291,18 @@ wait_command = 10
no_colors = False
priority = {'sudo': 100, 'no_command': 9999}
debug = False
history_limit = 9999
wait_slow_command = 20
slow_commands = ['react-native', 'gradle']
```
Or via environment variables:
* `THEFUCK_RULES` &ndash; list of enabled rules, like `DEFAULT_RULES:rm_root` or `sudo:no_command`;
* `THEFUCK_EXCLUDE_RULES` &ndash; list of disabled rules, like `git_pull:git_push`;
* `THEFUCK_EXCLUDE_RULES` &ndash; list of disabled rules, like `git_pull:git_push`;
* `THEFUCK_REQUIRE_CONFIRMATION` &ndash; require confirmation before running new command, `true/false`;
* `THEFUCK_WAIT_COMMAND` &ndash; max amount of time in seconds for getting previous command output;
* `THEFUCK_NO_COLORS` &ndash; disable colored output, `true/false`;
* `THEFUCK_PRIORITY` &ndash; priority of the rules, like `no_command=9999:apt_get=100`,
rule with lower `priority` will be matched first;
* `THEFUCK_DEBUG` &ndash; enables debug output, `true/false`;
* `THEFUCK_HISTORY_LIMIT` &ndash; how many history commands will be scanned, like `2000`;
* `THEFUCK_ALTER_HISTORY` &ndash; push fixed command to history `true/false`;
* `THEFUCK_WAIT_SLOW_COMMAND` &ndash; max amount of time in seconds for getting previous command output if it in `slow_commands` list;
* `THEFUCK_SLOW_COMMANDS` &ndash; list of slow commands, like `lein:gradle`.
* `THEFUCK_DEBUG` &ndash; enables debug output, `true/false`.
For example:
@@ -384,7 +313,6 @@ export THEFUCK_REQUIRE_CONFIRMATION='true'
export THEFUCK_WAIT_COMMAND=10
export THEFUCK_NO_COLORS='false'
export THEFUCK_PRIORITY='no_command=9999:apt_get=100'
export THEFUCK_HISTORY_LIMIT='2000'
```
## Developing
@@ -396,12 +324,6 @@ pip install -r requirements.txt
python setup.py develop
```
Run code style checks:
```bash
flake8
```
Run unit tests:
```bash
@@ -423,16 +345,3 @@ sudo apt-get install pandoc
## License MIT
Project License can be found [here](LICENSE.md).
[version-badge]: https://img.shields.io/pypi/v/thefuck.svg?label=version
[version-link]: https://pypi.python.org/pypi/thefuck/
[travis-badge]: https://img.shields.io/travis/nvbn/thefuck.svg
[travis-link]: https://travis-ci.org/nvbn/thefuck
[appveyor-badge]: https://img.shields.io/appveyor/ci/nvbn/thefuck.svg?label=windows%20build
[appveyor-link]: https://ci.appveyor.com/project/nvbn/thefuck
[coverage-badge]: https://img.shields.io/coveralls/nvbn/thefuck.svg
[coverage-link]: https://coveralls.io/github/nvbn/thefuck
[license-badge]: https://img.shields.io/badge/license-MIT-007EC7.svg
[examples-link]: https://raw.githubusercontent.com/nvbn/thefuck/master/example.gif
[homebrew]: http://brew.sh/

View File

@@ -1,24 +0,0 @@
build: false
environment:
matrix:
- PYTHON: "C:/Python27"
- PYTHON: "C:/Python33"
- PYTHON: "C:/Python34"
- PYTHON: "C:/Python35"
- PYTHON: "C:/Python36"
init:
- "ECHO %PYTHON%"
- ps: "ls C:/Python*"
install:
- ps: (new-object net.webclient).DownloadFile('https://bootstrap.pypa.io/get-pip.py', 'C:/get-pip.py')
- "%PYTHON%/python.exe C:/get-pip.py"
- "%PYTHON%/Scripts/pip.exe install -U setuptools"
- "%PYTHON%/python.exe setup.py develop"
- "%PYTHON%/Scripts/pip.exe install -U -r requirements.txt"
test_script:
- "%PYTHON%/python.exe -m flake8"
- "%PYTHON%/Scripts/py.test.exe -sv"

View File

@@ -1,4 +1,57 @@
#!/bin/sh
echo "Installation script is deprecated!"
echo "For installation instruction please visit https://github.com/nvbn/thefuck"
should_add_alias () {
[ -f $1 ] && ! grep -q thefuck $1
}
installed () {
hash $1 2>/dev/null
}
# Install os dependencies:
if installed apt-get; then
# Debian/ubuntu:
sudo apt-get update -yy
sudo apt-get install -yy python-pip python-dev command-not-found
if [[ -n $(apt-cache search python-commandnotfound) ]]; then
# In case of different python versions:
sudo apt-get install -yy python-commandnotfound
fi
else
if installed brew; then
# OS X:
brew update
brew install python
else
# Genreic way:
wget https://bootstrap.pypa.io/get-pip.py
sudo python get-pip.py
rm get-pip.py
fi
fi
# thefuck requires fresh versions of setuptools and pip:
sudo pip install -U pip setuptools
sudo pip install -U thefuck
# Setup aliases:
if should_add_alias ~/.bashrc; then
echo 'eval $(thefuck --alias)' >> ~/.bashrc
fi
if should_add_alias ~/.bash_profile; then
echo 'eval $(thefuck --alias)' >> ~/.bash_profile
fi
if should_add_alias ~/.zshrc; then
echo 'eval $(thefuck --alias)' >> ~/.zshrc
fi
if should_add_alias ~/.config/fish/config.fish; then
thefuck --alias >> ~/.config/fish/config.fish
fi
if should_add_alias ~/.tcshrc; then
echo 'eval `thefuck --alias`' >> ~/.tcshrc
fi

View File

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

View File

@@ -1,17 +1,8 @@
#!/usr/bin/env python
from setuptools import setup, find_packages
import pkg_resources
import sys
import os
try:
if int(pkg_resources.get_distribution("pip").version.split('.')[0]) < 6:
print('pip older than 6.0 not supported, please upgrade pip with:\n\n'
' pip install -U pip')
sys.exit(-1)
except pkg_resources.DistributionNotFound:
pass
if os.environ.get('CONVERT_README'):
import pypandoc
@@ -29,11 +20,10 @@ elif (3, 0) < version < (3, 3):
' ({}.{} detected).'.format(*version))
sys.exit(-1)
VERSION = '3.15'
VERSION = '3.1'
install_requires = ['psutil', 'colorama', 'six', 'decorator']
extras_require = {':python_version<"3.4"': ['pathlib2'],
":sys_platform=='win32'": ['win_unicode_console']}
extras_require = {':python_version<"3.4"': ['pathlib']}
setup(name='thefuck',
version=VERSION,
@@ -44,11 +34,12 @@ setup(name='thefuck',
url='https://github.com/nvbn/thefuck',
license='MIT',
packages=find_packages(exclude=['ez_setup', 'examples',
'tests', 'tests.*', 'release']),
'tests', 'release']),
include_package_data=True,
zip_safe=False,
install_requires=install_requires,
extras_require=extras_require,
entry_points={'console_scripts': [
'thefuck = thefuck.main:main',
'fuck = thefuck.not_configured:main']})
'thefuck-alias = thefuck.main:print_alias',
'fuck = thefuck.main:how_to_configure_alias']})

View File

@@ -1,9 +1,6 @@
from pathlib import Path
import pytest
from thefuck import shells
from thefuck import conf, const
from thefuck.system import Path
shells.shell = shells.Generic()
from thefuck import conf
def pytest_addoption(parser):
@@ -22,7 +19,7 @@ def no_memoize(monkeypatch):
def settings(request):
def _reset_settings():
conf.settings.clear()
conf.settings.update(const.DEFAULT_SETTINGS)
conf.settings.update(conf.DEFAULT_SETTINGS)
request.addfinalizer(_reset_settings)
conf.settings.user_dir = Path('~/.thefuck')
@@ -49,14 +46,3 @@ def functional(request):
@pytest.fixture
def source_root():
return Path(__file__).parent.parent.resolve()
@pytest.fixture
def set_shell(monkeypatch, request):
def _set(cls):
shell = cls()
monkeypatch.setattr('thefuck.shells.shell', shell)
request.addfinalizer()
return shell
return _set

View File

@@ -3,19 +3,26 @@ from tests.functional.plots import with_confirmation, without_confirmation, \
refuse_with_confirmation, history_changed, history_not_changed, \
select_command_with_arrows, how_to_configure
containers = ((u'thefuck/python3-bash',
u'FROM python:3',
containers = ((u'thefuck/ubuntu-python3-bash',
u'''FROM ubuntu:latest
RUN apt-get update
RUN apt-get install -yy python3 python3-pip python3-dev git
RUN pip3 install -U setuptools
RUN ln -s /usr/bin/pip3 /usr/bin/pip''',
u'bash'),
(u'thefuck/python2-bash',
u'FROM python:2',
(u'thefuck/ubuntu-python2-bash',
u'''FROM ubuntu:latest
RUN apt-get update
RUN apt-get install -yy python python-pip python-dev git
RUN pip2 install -U pip setuptools''',
u'bash'))
@pytest.fixture(params=containers)
def proc(request, spawnu, TIMEOUT):
def proc(request, spawnu, run_without_docker):
proc = spawnu(*request.param)
proc.sendline(u"pip install /src")
assert proc.expect([TIMEOUT, u'Successfully installed'])
if not run_without_docker:
proc.sendline(u"pip install /src")
proc.sendline(u"export PS1='$ '")
proc.sendline(u'eval $(thefuck --alias)')
proc.sendline(u'echo > $HISTFILE')
@@ -23,29 +30,38 @@ def proc(request, spawnu, TIMEOUT):
@pytest.mark.functional
def test_with_confirmation(proc, TIMEOUT):
@pytest.mark.once_without_docker
def test_with_confirmation(proc, TIMEOUT, run_without_docker):
with_confirmation(proc, TIMEOUT)
history_changed(proc, TIMEOUT, u'echo test')
if not run_without_docker:
history_changed(proc, TIMEOUT, u'echo test')
@pytest.mark.functional
def test_select_command_with_arrows(proc, TIMEOUT):
@pytest.mark.once_without_docker
def test_select_command_with_arrows(proc, TIMEOUT, run_without_docker):
select_command_with_arrows(proc, TIMEOUT)
history_changed(proc, TIMEOUT, u'git help')
if not run_without_docker:
history_changed(proc, TIMEOUT, u'git help')
@pytest.mark.functional
def test_refuse_with_confirmation(proc, TIMEOUT):
@pytest.mark.once_without_docker
def test_refuse_with_confirmation(proc, TIMEOUT, run_without_docker):
refuse_with_confirmation(proc, TIMEOUT)
history_not_changed(proc, TIMEOUT)
if not run_without_docker:
history_not_changed(proc, TIMEOUT)
@pytest.mark.functional
def test_without_confirmation(proc, TIMEOUT):
@pytest.mark.once_without_docker
def test_without_confirmation(proc, TIMEOUT, run_without_docker):
without_confirmation(proc, TIMEOUT)
history_changed(proc, TIMEOUT, u'echo test')
if not run_without_docker:
history_changed(proc, TIMEOUT, u'echo test')
@pytest.mark.functional
@pytest.mark.once_without_docker
def test_how_to_configure_alias(proc, TIMEOUT):
how_to_configure(proc, TIMEOUT)

View File

@@ -2,50 +2,52 @@ import pytest
from tests.functional.plots import with_confirmation, without_confirmation, \
refuse_with_confirmation, select_command_with_arrows
containers = (('thefuck/python3-fish',
u'''FROM python:3
# Use jessie-backports since it has the fish package. See here for details:
# https://github.com/tianon/docker-brew-debian/blob/88ae21052affd8a14553bb969f9d41c464032122/jessie/backports/Dockerfile
RUN awk '$1 ~ "^deb" { $3 = $3 "-backports"; print; exit }' /etc/apt/sources.list > /etc/apt/sources.list.d/backports.list
containers = (('thefuck/ubuntu-python3-fish',
u'''FROM ubuntu:latest
RUN apt-get update
RUN apt-get install -yy python3 python3-pip python3-dev fish git
RUN pip3 install -U setuptools
RUN ln -s /usr/bin/pip3 /usr/bin/pip
RUN apt-get install -yy fish''',
u'fish'),
('thefuck/python2-fish',
u'''FROM python:2
# Use jessie-backports since it has the fish package. See here for details:
# https://github.com/tianon/docker-brew-debian/blob/88ae21052affd8a14553bb969f9d41c464032122/jessie/backports/Dockerfile
RUN awk '$1 ~ "^deb" { $3 = $3 "-backports"; print; exit }' /etc/apt/sources.list > /etc/apt/sources.list.d/backports.list
('thefuck/ubuntu-python2-fish',
u'''FROM ubuntu:latest
RUN apt-get update
RUN apt-get install -yy python python-pip python-dev git
RUN pip2 install -U pip setuptools
RUN apt-get install -yy fish''',
u'fish'))
@pytest.fixture(params=containers)
def proc(request, spawnu, TIMEOUT):
def proc(request, spawnu):
proc = spawnu(*request.param)
proc.sendline(u"pip install /src")
assert proc.expect([TIMEOUT, u'Successfully installed'])
proc.sendline(u'thefuck --alias > ~/.config/fish/config.fish')
proc.sendline(u'fish')
return proc
@pytest.mark.functional
@pytest.mark.skip_without_docker
def test_with_confirmation(proc, TIMEOUT):
with_confirmation(proc, TIMEOUT)
@pytest.mark.functional
@pytest.mark.skip_without_docker
def test_select_command_with_arrows(proc, TIMEOUT):
select_command_with_arrows(proc, TIMEOUT)
@pytest.mark.functional
@pytest.mark.skip_without_docker
def test_refuse_with_confirmation(proc, TIMEOUT):
refuse_with_confirmation(proc, TIMEOUT)
@pytest.mark.functional
@pytest.mark.skip_without_docker
def test_without_confirmation(proc, TIMEOUT):
without_confirmation(proc, TIMEOUT)

View File

@@ -0,0 +1,25 @@
import pytest
from thefuck.utils import get_installation_info
envs = ((u'bash', 'thefuck/ubuntu-bash', u'''
FROM ubuntu:latest
RUN apt-get update
RUN apt-get install -yy bash
'''), (u'bash', 'thefuck/generic-bash', u'''
FROM fedora:latest
RUN dnf install -yy python-devel sudo wget gcc
'''))
@pytest.mark.functional
@pytest.mark.skip_without_docker
@pytest.mark.parametrize('shell, tag, dockerfile', envs)
def test_installation(spawnu, shell, TIMEOUT, tag, dockerfile):
proc = spawnu(tag, dockerfile, shell)
proc.sendline(u'cat /src/install.sh | sh - && $0')
proc.sendline(u'thefuck --version')
version = get_installation_info().version
assert proc.expect([TIMEOUT, u'thefuck {}'.format(version)],
timeout=600)
proc.sendline(u'fuck')
assert proc.expect([TIMEOUT, u'No fucks given'])

View File

@@ -2,7 +2,11 @@ import pytest
import time
dockerfile = u'''
FROM python:3
FROM ubuntu:latest
RUN apt-get update
RUN apt-get install -yy python3 python3-pip python3-dev git
RUN pip3 install -U setuptools
RUN ln -s /usr/bin/pip3 /usr/bin/pip
RUN adduser --disabled-password --gecos '' test
ENV SEED "{seed}"
WORKDIR /src
@@ -36,9 +40,10 @@ def plot(proc, TIMEOUT):
@pytest.mark.functional
@pytest.mark.skip_without_docker
@pytest.mark.benchmark(min_rounds=10)
def test_performance(spawnu, TIMEOUT, benchmark):
proc = spawnu(u'thefuck/python3-bash-performance',
proc = spawnu(u'thefuck/ubuntu-python3-bash-performance',
dockerfile, u'bash')
proc.sendline(u'pip install /src')
proc.sendline(u'su test')

View File

@@ -2,45 +2,53 @@ import pytest
from tests.functional.plots import with_confirmation, without_confirmation, \
refuse_with_confirmation, select_command_with_arrows
containers = (('thefuck/python3-tcsh',
u'''FROM python:3
containers = (('thefuck/ubuntu-python3-tcsh',
u'''FROM ubuntu:latest
RUN apt-get update
RUN apt-get install -yy python3 python3-pip python3-dev git
RUN pip3 install -U setuptools
RUN ln -s /usr/bin/pip3 /usr/bin/pip
RUN apt-get install -yy tcsh''',
u'tcsh'),
('thefuck/python2-tcsh',
u'''FROM python:2
('thefuck/ubuntu-python2-tcsh',
u'''FROM ubuntu:latest
RUN apt-get update
RUN apt-get install -yy python python-pip python-dev git
RUN pip2 install -U pip setuptools
RUN apt-get install -yy tcsh''',
u'tcsh'))
@pytest.fixture(params=containers)
def proc(request, spawnu, TIMEOUT):
def proc(request, spawnu, run_without_docker):
proc = spawnu(*request.param)
proc.sendline(u'pip install /src')
assert proc.expect([TIMEOUT, u'Successfully installed'])
if not run_without_docker:
proc.sendline(u'pip install /src')
proc.sendline(u'tcsh')
proc.sendline(u'setenv PYTHONIOENCODING utf8')
proc.sendline(u'eval `thefuck --alias`')
return proc
@pytest.mark.functional
@pytest.mark.once_without_docker
def test_with_confirmation(proc, TIMEOUT):
with_confirmation(proc, TIMEOUT)
@pytest.mark.functional
@pytest.mark.once_without_docker
def test_select_command_with_arrows(proc, TIMEOUT):
select_command_with_arrows(proc, TIMEOUT)
@pytest.mark.functional
@pytest.mark.once_without_docker
def test_refuse_with_confirmation(proc, TIMEOUT):
refuse_with_confirmation(proc, TIMEOUT)
@pytest.mark.functional
@pytest.mark.once_without_docker
def test_without_confirmation(proc, TIMEOUT):
without_confirmation(proc, TIMEOUT)

View File

@@ -3,23 +3,28 @@ from tests.functional.plots import with_confirmation, without_confirmation, \
refuse_with_confirmation, history_changed, history_not_changed, \
select_command_with_arrows, how_to_configure
containers = (('thefuck/python3-zsh',
u'''FROM python:3
containers = (('thefuck/ubuntu-python3-zsh',
u'''FROM ubuntu:latest
RUN apt-get update
RUN apt-get install -yy python3 python3-pip python3-dev git
RUN pip3 install -U setuptools
RUN ln -s /usr/bin/pip3 /usr/bin/pip
RUN apt-get install -yy zsh''',
u'zsh'),
('thefuck/python2-zsh',
u'''FROM python:2
('thefuck/ubuntu-python2-zsh',
u'''FROM ubuntu:latest
RUN apt-get update
RUN apt-get install -yy python python-pip python-dev git
RUN pip2 install -U pip setuptools
RUN apt-get install -yy zsh''',
u'zsh'))
@pytest.fixture(params=containers)
def proc(request, spawnu, TIMEOUT):
def proc(request, spawnu, run_without_docker):
proc = spawnu(*request.param)
proc.sendline(u'pip install /src')
assert proc.expect([TIMEOUT, u'Successfully installed'])
if not run_without_docker:
proc.sendline(u'pip install /src')
proc.sendline(u'eval $(thefuck --alias)')
proc.sendline(u'export HISTFILE=~/.zsh_history')
proc.sendline(u'echo > $HISTFILE')
@@ -30,29 +35,34 @@ def proc(request, spawnu, TIMEOUT):
@pytest.mark.functional
@pytest.mark.once_without_docker
def test_with_confirmation(proc, TIMEOUT):
with_confirmation(proc, TIMEOUT)
history_changed(proc, TIMEOUT, u'echo test')
@pytest.mark.functional
@pytest.mark.once_without_docker
def test_select_command_with_arrows(proc, TIMEOUT):
select_command_with_arrows(proc, TIMEOUT)
history_changed(proc, TIMEOUT, u'git help')
@pytest.mark.functional
@pytest.mark.once_without_docker
def test_refuse_with_confirmation(proc, TIMEOUT):
refuse_with_confirmation(proc, TIMEOUT)
history_not_changed(proc, TIMEOUT)
@pytest.mark.functional
@pytest.mark.once_without_docker
def test_without_confirmation(proc, TIMEOUT):
without_confirmation(proc, TIMEOUT)
history_changed(proc, TIMEOUT, u'echo test')
@pytest.mark.functional
@pytest.mark.once_without_docker
def test_how_to_configure_alias(proc, TIMEOUT):
how_to_configure(proc, TIMEOUT)

6
tests/rules/conftest.py Normal file
View File

@@ -0,0 +1,6 @@
import pytest
@pytest.fixture(autouse=True)
def generic_shell(monkeypatch):
monkeypatch.setattr('thefuck.shells.and_', lambda *x: ' && '.join(x))

View File

@@ -1,25 +0,0 @@
import pytest
from thefuck.rules.ag_literal import get_new_command, match
from tests.utils import Command
@pytest.fixture
def stderr():
return ('ERR: Bad regex! pcre_compile() failed at position 1: missing )\n'
'If you meant to search for a literal string, run ag with -Q\n')
@pytest.mark.parametrize('script', ['ag \('])
def test_match(script, stderr):
assert match(Command(script=script, stderr=stderr))
@pytest.mark.parametrize('script', ['ag foo'])
def test_not_match(script):
assert not match(Command(script=script))
@pytest.mark.parametrize('script, new_cmd', [
('ag \(', 'ag -Q \(')])
def test_get_new_command(script, new_cmd, stderr):
assert get_new_command((Command(script=script, stderr=stderr))) == new_cmd

View File

@@ -1,43 +1,53 @@
import pytest
from mock import Mock, patch
from thefuck.rules import apt_get
from thefuck.rules.apt_get import match, get_new_command
from tests.utils import Command
@pytest.mark.parametrize('command, packages', [
(Command(script='vim', stderr='vim: command not found'),
[('vim', 'main'), ('vim-tiny', 'main')]),
(Command(script='sudo vim', stderr='vim: command not found'),
[('vim', 'main'), ('vim-tiny', 'main')]),
(Command(script='vim', stderr="The program 'vim' is currently not installed. You can install it by typing: sudo apt install vim"),
[('vim', 'main'), ('vim-tiny', 'main')])])
def test_match(mocker, command, packages):
mocker.patch('thefuck.rules.apt_get.which', return_value=None)
mock = mocker.patch('thefuck.rules.apt_get.command_not_found',
create=True)
mock.getPackages.return_value = packages
# python-commandnotfound is available in ubuntu 14.04+
@pytest.mark.skipif(not getattr(apt_get, 'enabled_by_default', True),
reason='Skip if python-commandnotfound is not available')
@pytest.mark.parametrize('command', [
Command(script='vim', stderr='vim: command not found')])
def test_match(command):
assert match(command)
@pytest.mark.parametrize('command, packages, which', [
(Command(script='a_bad_cmd', stderr='a_bad_cmd: command not found'),
[], None),
(Command(script='vim', stderr=''), [], None),
(Command(), [], None),
@pytest.mark.parametrize('command, return_value', [
(Command(script='vim', stderr='vim: command not found'),
['vim'], '/usr/bin/vim'),
[('vim', 'main'), ('vim-tiny', 'main')]),
(Command(script='sudo vim', stderr='vim: command not found'),
['vim'], '/usr/bin/vim')])
def test_not_match(mocker, command, packages, which):
mocker.patch('thefuck.rules.apt_get.which', return_value=which)
mock = mocker.patch('thefuck.rules.apt_get.command_not_found',
create=True)
mock.getPackages.return_value = packages
[('vim', 'main'), ('vim-tiny', 'main')])])
@patch('thefuck.rules.apt_get.CommandNotFound', create=True)
@patch.multiple(apt_get, create=True, apt_get='apt_get')
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)
assert cmdnf_mock.CommandNotFound.called
assert get_packages.called
@pytest.mark.parametrize('command', [
Command(script='vim', stderr=''), Command()])
def test_not_match(command):
assert not match(command)
@pytest.mark.parametrize('command, new_command, packages', [
# python-commandnotfound is available in ubuntu 14.04+
@pytest.mark.skipif(not getattr(apt_get, 'enabled_by_default', True),
reason='Skip if python-commandnotfound is not available')
@pytest.mark.parametrize('command, new_command', [
(Command('vim'), 'sudo apt-get install vim && vim'),
(Command('convert'), 'sudo apt-get install imagemagick && convert'),
(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) == new_command
@pytest.mark.parametrize('command, new_command, return_value', [
(Command('vim'), 'sudo apt-get install vim && vim',
[('vim', 'main'), ('vim-tiny', 'main')]),
(Command('convert'), 'sudo apt-get install imagemagick && convert',
@@ -48,8 +58,9 @@ def test_not_match(mocker, command, packages, which):
(Command('sudo convert'), 'sudo apt-get install imagemagick && sudo convert',
[('imagemagick', 'main'),
('graphicsmagick-imagemagick-compat', 'universe')])])
def test_get_new_command(mocker, command, new_command, packages):
mock = mocker.patch('thefuck.rules.apt_get.command_not_found',
create=True)
mock.getPackages.return_value = packages
@patch('thefuck.rules.apt_get.CommandNotFound', create=True)
@patch.multiple(apt_get, create=True, apt_get='apt_get')
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) == new_command

View File

@@ -1,122 +0,0 @@
from io import BytesIO
import pytest
from tests.utils import Command
from thefuck.rules.apt_invalid_operation import match, get_new_command, \
_get_operations
invalid_operation = 'E: Invalid operation {}'.format
apt_help = b'''apt 1.0.10.2ubuntu1 for amd64 compiled on Oct 5 2015 15:55:05
Usage: apt [options] command
CLI for apt.
Basic commands:
list - list packages based on package names
search - search in package descriptions
show - show package details
update - update list of available packages
install - install packages
remove - remove packages
upgrade - upgrade the system by installing/upgrading packages
full-upgrade - upgrade the system by removing/installing/upgrading packages
edit-sources - edit the source information file
'''
apt_operations = ['list', 'search', 'show', 'update', 'install', 'remove',
'upgrade', 'full-upgrade', 'edit-sources']
apt_get_help = b'''apt 1.0.10.2ubuntu1 for amd64 compiled on Oct 5 2015 15:55:05
Usage: apt-get [options] command
apt-get [options] install|remove pkg1 [pkg2 ...]
apt-get [options] source pkg1 [pkg2 ...]
apt-get is a simple command line interface for downloading and
installing packages. The most frequently used commands are update
and install.
Commands:
update - Retrieve new lists of packages
upgrade - Perform an upgrade
install - Install new packages (pkg is libc6 not libc6.deb)
remove - Remove packages
autoremove - Remove automatically all unused packages
purge - Remove packages and config files
source - Download source archives
build-dep - Configure build-dependencies for source packages
dist-upgrade - Distribution upgrade, see apt-get(8)
dselect-upgrade - Follow dselect selections
clean - Erase downloaded archive files
autoclean - Erase old downloaded archive files
check - Verify that there are no broken dependencies
changelog - Download and display the changelog for the given package
download - Download the binary package into the current directory
Options:
-h This help text.
-q Loggable output - no progress indicator
-qq No output except for errors
-d Download only - do NOT install or unpack archives
-s No-act. Perform ordering simulation
-y Assume Yes to all queries and do not prompt
-f Attempt to correct a system with broken dependencies in place
-m Attempt to continue if archives are unlocatable
-u Show a list of upgraded packages as well
-b Build the source package after fetching it
-V Show verbose version numbers
-c=? Read this configuration file
-o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp
See the apt-get(8), sources.list(5) and apt.conf(5) manual
pages for more information and options.
This APT has Super Cow Powers.
'''
apt_get_operations = ['update', 'upgrade', 'install', 'remove', 'autoremove',
'purge', 'source', 'build-dep', 'dist-upgrade',
'dselect-upgrade', 'clean', 'autoclean', 'check',
'changelog', 'download']
@pytest.mark.parametrize('script, stderr', [
('apt', invalid_operation('saerch')),
('apt-get', invalid_operation('isntall')),
('apt-cache', invalid_operation('rumove'))])
def test_match(script, stderr):
assert match(Command(script, stderr=stderr))
@pytest.mark.parametrize('script, stderr', [
('vim', invalid_operation('vim')),
('apt-get', "")])
def test_not_match(script, stderr):
assert not match(Command(script, stderr=stderr))
@pytest.fixture
def set_help(mocker):
mock = mocker.patch('subprocess.Popen')
def _set_text(text):
mock.return_value.stdout = BytesIO(text)
return _set_text
@pytest.mark.parametrize('app, help_text, operations', [
('apt', apt_help, apt_operations),
('apt-get', apt_get_help, apt_get_operations)
])
def test_get_operations(set_help, app, help_text, operations):
set_help(help_text)
assert _get_operations(app) == operations
@pytest.mark.parametrize('script, stderr, help_text, result', [
('apt-get isntall vim', invalid_operation('isntall'),
apt_get_help, 'apt-get install vim'),
('apt saerch vim', invalid_operation('saerch'),
apt_help, 'apt search vim'),
])
def test_get_new_command(set_help, stderr, script, help_text, result):
set_help(help_text)
assert get_new_command(Command(script, stderr=stderr))[0] == result

View File

@@ -1,101 +0,0 @@
import pytest
from thefuck.rules.aws_cli import match, get_new_command
from tests.utils import Command
no_suggestions = '''\
usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
To see help text, you can run:
aws help
aws <command> help
aws <command> <subcommand> help
aws: error: argument command: Invalid choice, valid choices are:
dynamodb | dynamodbstreams
ec2 | ecr
'''
misspelled_command = '''\
usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
To see help text, you can run:
aws help
aws <command> help
aws <command> <subcommand> help
aws: error: argument command: Invalid choice, valid choices are:
dynamodb | dynamodbstreams
ec2 | ecr
Invalid choice: 'dynamdb', maybe you meant:
* dynamodb
'''
misspelled_subcommand = '''\
usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
To see help text, you can run:
aws help
aws <command> help
aws <command> <subcommand> help
aws: error: argument operation: Invalid choice, valid choices are:
query | scan
update-item | update-table
Invalid choice: 'scn', maybe you meant:
* scan
'''
misspelled_subcommand_with_multiple_options = '''\
usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
To see help text, you can run:
aws help
aws <command> help
aws <command> <subcommand> help
aws: error: argument operation: Invalid choice, valid choices are:
describe-table | get-item
list-tables | put-item
Invalid choice: 't-item', maybe you meant:
* put-item
* get-item
'''
@pytest.mark.parametrize('command', [
Command('aws dynamdb scan', stderr=misspelled_command),
Command('aws dynamodb scn', stderr=misspelled_subcommand),
Command('aws dynamodb t-item',
stderr=misspelled_subcommand_with_multiple_options)])
def test_match(command):
assert match(command)
def test_not_match():
assert not match(Command('aws dynamodb invalid', stderr=no_suggestions))
@pytest.mark.parametrize('command, result', [
(Command('aws dynamdb scan', stderr=misspelled_command),
['aws dynamodb scan']),
(Command('aws dynamodb scn', stderr=misspelled_subcommand),
['aws dynamodb scan']),
(Command('aws dynamodb t-item',
stderr=misspelled_subcommand_with_multiple_options),
['aws dynamodb put-item', 'aws dynamodb get-item'])])
def test_get_new_command(command, result):
assert get_new_command(command) == result

View File

@@ -31,7 +31,8 @@ def test_match(brew_no_available_formula, brew_already_installed,
stderr=brew_no_available_formula))
assert not match(Command('brew install git',
stderr=brew_already_installed))
assert not match(Command('brew install', stderr=brew_install_no_argument))
assert not match(Command('brew install', stderr=brew_install_no_argument),
None)
@pytest.mark.skipif(_is_not_okay_to_test(),
@@ -42,5 +43,5 @@ def test_get_new_command(brew_no_available_formula):
== 'brew install elasticsearch'
assert get_new_command(Command('brew install aa',
stderr=brew_no_available_formula))\
!= 'brew install aha'
stderr=brew_no_available_formula),
None) != 'brew install aha'

View File

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

View File

@@ -1,31 +0,0 @@
import pytest
from tests.utils import Command
from thefuck.rules.brew_uninstall import get_new_command, match
@pytest.fixture
def stdout():
return ("Uninstalling /usr/local/Cellar/tbb/4.4-20160916... (118 files, 1.9M)\n"
"tbb 4.4-20160526, 4.4-20160722 are still installed.\n"
"Remove all versions with `brew uninstall --force tbb`.\n")
@pytest.fixture
def new_command(formula):
return 'brew uninstall --force {}'.format(formula)
@pytest.mark.parametrize('script', ['brew uninstall tbb', 'brew rm tbb', 'brew remove tbb'])
def test_match(stdout, script):
assert match(Command(script=script, stdout=stdout))
@pytest.mark.parametrize('script', ['brew remove gnuplot'])
def test_not_match(script):
stdout = 'Uninstalling /usr/local/Cellar/gnuplot/5.0.4_1... (44 files, 2.3M)\n'
assert not match(Command(script=script, stdout=stdout))
@pytest.mark.parametrize('script, formula, ', [('brew uninstall tbb', 'tbb')])
def test_get_new_command(stdout, new_command, script, formula):
assert get_new_command(Command(script=script, stdout=stdout)) == new_command

View File

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

View File

@@ -1,30 +0,0 @@
import pytest
from tests.utils import Command
from thefuck.rules.brew_update_formula import get_new_command, match
@pytest.fixture
def stderr():
return ("Error: This command updates brew itself, and does not take formula"
" names.\nUse 'brew upgrade <formula>'.")
@pytest.fixture
def new_command(formula):
return 'brew upgrade {}'.format(formula)
@pytest.mark.parametrize('script', ['brew update foo', 'brew update bar zap'])
def test_match(stderr, script):
assert match(Command(script=script, stderr=stderr))
@pytest.mark.parametrize('script', ['brew upgrade foo', 'brew update'])
def test_not_match(script):
assert not match(Command(script=script, stderr=''))
@pytest.mark.parametrize('script, formula, ', [
('brew update foo', 'foo'), ('brew update bar zap', 'bar zap')])
def test_get_new_command(stderr, new_command, script, formula):
assert get_new_command(Command(script=script, stderr=stderr)) == new_command

View File

@@ -3,26 +3,19 @@ from thefuck.rules.cargo_no_command import match, get_new_command
from tests.utils import Command
no_such_subcommand_old = """No such subcommand
no_such_subcommand = """No such subcommand
Did you mean `build`?
"""
no_such_subcommand = """error: no such subcommand
\tDid you mean `build`?
"""
@pytest.mark.parametrize('command', [
Command(script='cargo buid', stderr=no_such_subcommand_old),
Command(script='cargo buils', stderr=no_such_subcommand)])
Command(script='cargo buid', stderr=no_such_subcommand)])
def test_match(command):
assert match(command)
@pytest.mark.parametrize('command, new_command', [
(Command('cargo buid', stderr=no_such_subcommand_old), 'cargo build'),
(Command('cargo buils', stderr=no_such_subcommand), 'cargo build')])
(Command('cargo buid', stderr=no_such_subcommand), 'cargo build')])
def test_get_new_command(command, new_command):
assert get_new_command(command) == new_command

View File

@@ -1,5 +1,5 @@
import pytest
from thefuck.rules.cd_mkdir import match, get_new_command
from thefuck.rules.cd_correction import match, get_new_command
from tests.utils import Command

View File

@@ -1,39 +0,0 @@
import pytest
from tests.utils import Command
from thefuck.rules.chmod_x import match, get_new_command
@pytest.fixture
def file_exists(mocker):
return mocker.patch('os.path.exists', return_value=True)
@pytest.fixture
def file_access(mocker):
return mocker.patch('os.access', return_value=False)
@pytest.mark.usefixtures('file_exists', 'file_access')
@pytest.mark.parametrize('script, stderr', [
('./gradlew build', 'gradlew: Permission denied'),
('./install.sh --help', 'install.sh: permission denied')])
def test_match(script, stderr):
assert match(Command(script, stderr=stderr))
@pytest.mark.parametrize('script, stderr, exists, callable', [
('./gradlew build', 'gradlew: Permission denied', True, True),
('./gradlew build', 'gradlew: Permission denied', False, False),
('./gradlew build', 'gradlew: error', True, False),
('gradlew build', 'gradlew: Permission denied', True, False)])
def test_not_match(file_exists, file_access, script, stderr, exists, callable):
file_exists.return_value = exists
file_access.return_value = callable
assert not match(Command(script, stderr=stderr))
@pytest.mark.parametrize('script, result', [
('./gradlew build', 'chmod +x gradlew && ./gradlew build'),
('./install.sh --help', 'chmod +x install.sh && ./install.sh --help')])
def test_get_new_command(script, result):
assert get_new_command(Command(script)) == result

View File

@@ -48,9 +48,9 @@ def test_match(composer_not_command, composer_not_command_one_of_this):
def test_get_new_command(composer_not_command, composer_not_command_one_of_this):
assert (get_new_command(Command('composer udpate',
stderr=composer_not_command))
== 'composer update')
assert (get_new_command(Command('composer pdate',
stderr=composer_not_command_one_of_this))
== 'composer selfupdate')
assert get_new_command(Command('composer udpate',
stderr=composer_not_command)) \
== 'composer update'
assert get_new_command(
Command('composer pdate', stderr=composer_not_command_one_of_this)) \
== 'composer selfupdate'

View File

@@ -1,8 +1,7 @@
import os
import pytest
import tarfile
from thefuck.rules.dirty_untar import match, get_new_command, side_effect, \
tar_extensions # noqa: E126
from thefuck.rules.dirty_untar import match, get_new_command, side_effect
from tests.utils import Command
@@ -33,42 +32,34 @@ def tar_error(tmpdir):
return fixture
parametrize_extensions = pytest.mark.parametrize('ext', tar_extensions)
# (filename as typed by the user, unquoted filename, quoted filename as per shells.quote)
parametrize_filename = pytest.mark.parametrize('filename, unquoted, quoted', [
('foo{}', 'foo{}', 'foo{}'),
('foo\ bar{}', 'foo bar{}', "'foo bar{}'"),
('"foo bar{}"', 'foo bar{}', "'foo bar{}'")])
parametrize_filename = pytest.mark.parametrize('filename', [
'foo.tar',
'foo.tar.gz',
'foo.tgz'])
parametrize_script = pytest.mark.parametrize('script, fixed', [
('tar xvf {}', 'mkdir -p {dir} && tar xvf {filename} -C {dir}'),
('tar -xvf {}', 'mkdir -p {dir} && tar -xvf {filename} -C {dir}'),
('tar --extract -f {}', 'mkdir -p {dir} && tar --extract -f {filename} -C {dir}')])
('tar xvf {}', 'mkdir -p foo && tar xvf {} -C foo'),
('tar -xvf {}', 'mkdir -p foo && tar -xvf {} -C foo'),
('tar --extract -f {}', 'mkdir -p foo && tar --extract -f {} -C foo')])
@parametrize_extensions
@parametrize_filename
@parametrize_script
def test_match(ext, tar_error, filename, unquoted, quoted, script, fixed):
tar_error(unquoted.format(ext))
assert match(Command(script=script.format(filename.format(ext))))
def test_match(tar_error, filename, script, fixed):
tar_error(filename)
assert match(Command(script=script.format(filename)))
@parametrize_extensions
@parametrize_filename
@parametrize_script
def test_side_effect(ext, tar_error, filename, unquoted, quoted, script, fixed):
tar_error(unquoted.format(ext))
side_effect(Command(script=script.format(filename.format(ext))), None)
assert set(os.listdir('.')) == {unquoted.format(ext), 'd'}
def test_side_effect(tar_error, filename, script, fixed):
tar_error(filename)
side_effect(Command(script=script.format(filename)), None)
assert set(os.listdir('.')) == {filename, 'd'}
@parametrize_extensions
@parametrize_filename
@parametrize_script
def test_get_new_command(ext, tar_error, filename, unquoted, quoted, script, fixed):
tar_error(unquoted.format(ext))
assert (get_new_command(Command(script=script.format(filename.format(ext))))
== fixed.format(dir=quoted.format(''), filename=filename.format(ext)))
def test_get_new_command(tar_error, filename, script, fixed):
tar_error(filename)
assert get_new_command(Command(script=script.format(filename))) == fixed.format(filename)

View File

@@ -1,72 +1,48 @@
# -*- coding: utf-8 -*-
import os
import pytest
import zipfile
from thefuck.rules.dirty_unzip import match, get_new_command, side_effect
from tests.utils import Command
from unicodedata import normalize
@pytest.fixture
def zip_error(tmpdir):
def zip_error_inner(filename):
path = os.path.join(str(tmpdir), filename)
path = os.path.join(str(tmpdir), 'foo.zip')
def reset(path):
with zipfile.ZipFile(path, 'w') as archive:
archive.writestr('a', '1')
archive.writestr('b', '2')
archive.writestr('c', '3')
def reset(path):
with zipfile.ZipFile(path, 'w') as archive:
archive.writestr('a', '1')
archive.writestr('b', '2')
archive.writestr('c', '3')
archive.writestr('d/e', '4')
archive.writestr('d/e', '4')
archive.extractall()
archive.extractall()
os.chdir(str(tmpdir))
reset(path)
os.chdir(str(tmpdir))
reset(path)
dir_list = os.listdir(u'.')
if filename not in dir_list:
filename = normalize('NFD', filename)
assert set(dir_list) == {filename, 'a', 'b', 'c', 'd'}
assert set(os.listdir('./d')) == {'e'}
return zip_error_inner
assert set(os.listdir('.')) == {'foo.zip', 'a', 'b', 'c', 'd'}
assert set(os.listdir('./d')) == {'e'}
@pytest.mark.parametrize('script,filename', [
(u'unzip café', u'café.zip'),
(u'unzip café.zip', u'café.zip'),
(u'unzip foo', u'foo.zip'),
(u'unzip foo.zip', u'foo.zip')])
def test_match(zip_error, script, filename):
zip_error(filename)
@pytest.mark.parametrize('script', [
'unzip foo',
'unzip foo.zip'])
def test_match(zip_error, script):
assert match(Command(script=script))
@pytest.mark.parametrize('script,filename', [
(u'unzip café', u'café.zip'),
(u'unzip café.zip', u'café.zip'),
(u'unzip foo', u'foo.zip'),
(u'unzip foo.zip', u'foo.zip')])
def test_side_effect(zip_error, script, filename):
zip_error(filename)
@pytest.mark.parametrize('script', [
'unzip foo',
'unzip foo.zip'])
def test_side_effect(zip_error, script):
side_effect(Command(script=script), None)
dir_list = os.listdir(u'.')
if filename not in set(dir_list):
filename = normalize('NFD', filename)
assert set(dir_list) == {filename, 'd'}
assert set(os.listdir('.')) == {'foo.zip', 'd'}
@pytest.mark.parametrize('script,fixed,filename', [
(u'unzip café', u"unzip café -d 'café'", u'café.zip'),
(u'unzip foo', u'unzip foo -d foo', u'foo.zip'),
(u"unzip foo\\ bar.zip", u"unzip foo\\ bar.zip -d 'foo bar'", u'foo.zip'),
(u"unzip 'foo bar.zip'", u"unzip 'foo bar.zip' -d 'foo bar'", u'foo.zip'),
(u'unzip foo.zip', u'unzip foo.zip -d foo', u'foo.zip')])
def test_get_new_command(zip_error, script, fixed, filename):
zip_error(filename)
@pytest.mark.parametrize('script,fixed', [
('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)) == fixed

View File

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

View File

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

View File

@@ -1,49 +0,0 @@
import pytest
from thefuck.rules.fab_command_not_found import match, get_new_command
from tests.utils import Command
stderr = '''
Warning: Command(s) not found:
extenson
deloyp
'''
stdout = '''
Available commands:
update_config
prepare_extension
Template A string class for supporting $-substitutions.
deploy
glob Return a list of paths matching a pathname pattern.
install_web
set_version
'''
@pytest.mark.parametrize('command', [
Command('fab extenson', stderr=stderr),
Command('fab deloyp', stderr=stderr),
Command('fab extenson deloyp', stderr=stderr)])
def test_match(command):
assert match(command)
@pytest.mark.parametrize('command', [
Command('gulp extenson', stderr=stderr),
Command('fab deloyp')])
def test_not_match(command):
assert not match(command)
@pytest.mark.parametrize('script, result', [
('fab extenson', 'fab prepare_extension'),
('fab extenson:version=2016',
'fab prepare_extension:version=2016'),
('fab extenson:version=2016 install_web set_version:val=0.5.0',
'fab prepare_extension:version=2016 install_web set_version:val=0.5.0'),
('fab extenson:version=2016 deloyp:beta=true -H the.fuck',
'fab prepare_extension:version=2016 deploy:beta=true -H the.fuck'),
])
def test_get_new_command(script, result):
command = Command(script, stdout, stderr)
assert get_new_command(command) == result

View File

@@ -18,5 +18,5 @@ def test_match():
def test_get_new_command():
""" Replace the Alt+Space character by a simple space """
assert (get_new_command(Command(u'ps -ef | grep foo'))
== 'ps -ef | grep foo')
assert get_new_command(Command(u'ps -ef | grep foo'))\
== 'ps -ef | grep foo'

View File

@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
import pytest
import os
from thefuck.rules.fix_file import match, get_new_command
@@ -89,20 +87,6 @@ Traceback (most recent call last):
TypeError: first argument must be string or compiled pattern
"""),
(u'python café.py', u'café.py', 8, None, '',
u"""
Traceback (most recent call last):
File "café.py", line 8, in <module>
match("foo")
File "café.py", line 5, in match
m = re.search(None, command)
File "/usr/lib/python3.4/re.py", line 170, in search
return _compile(pattern, flags).search(string)
File "/usr/lib/python3.4/re.py", line 293, in _compile
raise TypeError("first argument must be string or compiled pattern")
TypeError: first argument must be string or compiled pattern
"""),
('ruby a.rb', 'a.rb', 3, None, '',
"""
a.rb:3: syntax error, unexpected keyword_end
@@ -191,7 +175,7 @@ E NameError: name 'mocker' is not defined
/home/thefuck/tests/rules/test_fix_file.py:218: NameError
""", ''),
) # noqa
)
@pytest.mark.parametrize('test', tests)
@@ -227,6 +211,10 @@ def test_get_new_command(mocker, monkeypatch, test):
mocker.patch('os.path.isfile', return_value=True)
monkeypatch.setenv('EDITOR', 'dummy_editor')
cmd = Command(script=test[0], stdout=test[4], stderr=test[5])
#assert (get_new_command(cmd, Settings({})) ==
# 'dummy_editor {} +{} && {}'.format(test[1], test[2], test[0]))
@pytest.mark.parametrize('test', tests)
@pytest.mark.usefixtures('no_memoize')
@@ -239,7 +227,7 @@ def test_get_new_command_with_settings(mocker, monkeypatch, test, settings):
if test[3]:
assert (get_new_command(cmd) ==
u'dummy_editor {} +{}:{} && {}'.format(test[1], test[2], test[3], test[0]))
'dummy_editor {} +{}:{} && {}'.format(test[1], test[2], test[3], test[0]))
else:
assert (get_new_command(cmd) ==
u'dummy_editor {} +{} && {}'.format(test[1], test[2], test[0]))
'dummy_editor {} +{} && {}'.format(test[1], test[2], test[0]))

View File

@@ -1,82 +0,0 @@
import pytest
from six import BytesIO
from thefuck.rules.gem_unknown_command import match, get_new_command
from tests.utils import Command
stderr = '''
ERROR: While executing gem ... (Gem::CommandLineError)
Unknown command {}
'''
gem_help_commands_stdout = b'''
GEM commands are:
build Build a gem from a gemspec
cert Manage RubyGems certificates and signing settings
check Check a gem repository for added or missing files
cleanup Clean up old versions of installed gems
contents Display the contents of the installed gems
dependency Show the dependencies of an installed gem
environment Display information about the RubyGems environment
fetch Download a gem and place it in the current directory
generate_index Generates the index files for a gem server directory
help Provide help on the 'gem' command
install Install a gem into the local repository
list Display local gems whose name matches REGEXP
lock Generate a lockdown list of gems
mirror Mirror all gem files (requires rubygems-mirror)
open Open gem sources in editor
outdated Display all gems that need updates
owner Manage gem owners of a gem on the push server
pristine Restores installed gems to pristine condition from files
located in the gem cache
push Push a gem up to the gem server
query Query gem information in local or remote repositories
rdoc Generates RDoc for pre-installed gems
search Display remote gems whose name matches REGEXP
server Documentation and gem repository HTTP server
sources Manage the sources and cache file RubyGems uses to search
for gems
specification Display gem specification (in yaml)
stale List gems along with access times
uninstall Uninstall gems from the local repository
unpack Unpack an installed gem to the current directory
update Update installed gems to the latest version
which Find the location of a library file you can require
yank Remove a pushed gem from the index
For help on a particular command, use 'gem help COMMAND'.
Commands may be abbreviated, so long as they are unambiguous.
e.g. 'gem i rake' is short for 'gem install rake'.
'''
@pytest.fixture(autouse=True)
def gem_help_commands(mocker):
patch = mocker.patch('subprocess.Popen')
patch.return_value.stdout = BytesIO(gem_help_commands_stdout)
return patch
@pytest.mark.parametrize('script, command', [
('gem isntall jekyll', 'isntall'),
('gem last --local', 'last')])
def test_match(script, command):
assert match(Command(script, stderr=stderr.format(command)))
@pytest.mark.parametrize('script, stderr', [
('gem install jekyll', ''),
('git log', stderr.format('log'))])
def test_not_match(script, stderr):
assert not match(Command(script, stderr=stderr))
@pytest.mark.parametrize('script, stderr, result', [
('gem isntall jekyll', stderr.format('isntall'), 'gem install jekyll'),
('gem last --local', stderr.format('last'), 'gem list --local')])
def test_get_new_command(script, stderr, result):
new_command = get_new_command(Command(script, stderr=stderr))
assert new_command[0] == result

View File

@@ -3,38 +3,37 @@ from thefuck.rules.git_add import match, get_new_command
from tests.utils import Command
@pytest.fixture(autouse=True)
def path_exists(mocker):
return mocker.patch('thefuck.rules.git_add.Path.exists',
return_value=True)
@pytest.fixture
def stderr(target):
return ("error: pathspec '{}' did not match any "
'file(s) known to git.'.format(target))
def did_not_match(target, did_you_forget=True):
error = ("error: pathspec '{}' did not match any "
"file(s) known to git.".format(target))
if did_you_forget:
error = ("{}\nDid you forget to 'git add'?'".format(error))
return error
@pytest.mark.parametrize('script, target', [
('git submodule update unknown', 'unknown'),
('git commit unknown', 'unknown')])
def test_match(stderr, script, target):
assert match(Command(script=script, stderr=stderr))
@pytest.mark.parametrize('command', [
Command(script='git submodule update unknown',
stderr=did_not_match('unknown')),
Command(script='git commit unknown',
stderr=did_not_match('unknown'))]) # Older versions of Git
def test_match(command):
assert match(command)
@pytest.mark.parametrize('script, target, exists', [
('git submodule update known', '', True),
('git commit known', '', True),
('git submodule update known', stderr, False)])
def test_not_match(path_exists, stderr, script, target, exists):
path_exists.return_value = exists
assert not match(Command(script=script, stderr=stderr))
@pytest.mark.parametrize('command', [
Command(script='git submodule update known', stderr=('')),
Command(script='git commit known', stderr=('')),
Command(script='git commit unknown', # Newer versions of Git
stderr=did_not_match('unknown', False))])
def test_not_match(command):
assert not match(command)
@pytest.mark.parametrize('script, target, new_command', [
('git submodule update unknown', 'unknown',
@pytest.mark.parametrize('command, new_command', [
(Command('git submodule update unknown', stderr=did_not_match('unknown')),
'git add -- unknown && git submodule update unknown'),
('git commit unknown', 'unknown',
(Command('git commit unknown', stderr=did_not_match('unknown')), # Old Git
'git add -- unknown && git commit unknown')])
def test_get_new_command(stderr, script, target, new_command):
assert get_new_command(Command(script=script, stderr=stderr)) == new_command
def test_get_new_command(command, new_command):
assert get_new_command(command) == new_command

View File

@@ -1,22 +0,0 @@
import pytest
from thefuck.rules.git_add_force import match, get_new_command
from tests.utils import Command
@pytest.fixture
def stderr():
return ('The following paths are ignored by one of your .gitignore files:\n'
'dist/app.js\n'
'dist/background.js\n'
'dist/options.js\n'
'Use -f if you really want to add them.\n')
def test_match(stderr):
assert match(Command('git add dist/*.js', stderr=stderr))
assert not match(Command('git add dist/*.js'))
def test_get_new_command(stderr):
assert (get_new_command(Command('git add dist/*.js', stderr=stderr))
== "git add --force dist/*.js")

View File

@@ -1,30 +0,0 @@
import pytest
from tests.utils import Command
from thefuck.rules.git_bisect_usage import match, get_new_command
@pytest.fixture
def stderr():
return ("usage: git bisect [help|start|bad|good|new|old"
"|terms|skip|next|reset|visualize|replay|log|run]")
@pytest.mark.parametrize('script', [
'git bisect strt', 'git bisect rset', 'git bisect goood'])
def test_match(stderr, script):
assert match(Command(script=script, stderr=stderr))
@pytest.mark.parametrize('script', [
'git bisect', 'git bisect start', 'git bisect good'])
def test_not_match(script):
assert not match(Command(script=script, stderr=''))
@pytest.mark.parametrize('script, new_cmd, ', [
('git bisect goood', ['good', 'old', 'log']),
('git bisect strt', ['start', 'terms', 'reset']),
('git bisect rset', ['reset', 'next', 'start'])])
def test_get_new_command(stderr, script, new_cmd):
new_cmd = ['git bisect %s' % cmd for cmd in new_cmd]
assert get_new_command(Command(script=script, stderr=stderr)) == new_cmd

View File

@@ -1,34 +0,0 @@
import pytest
from thefuck.rules.git_branch_exists import match, get_new_command
from tests.utils import Command
@pytest.fixture
def stderr(branch_name):
return "fatal: A branch named '{}' already exists.".format(branch_name)
@pytest.fixture
def new_command(branch_name):
return [cmd.format(branch_name) for cmd in [
'git branch -d {0} && git branch {0}',
'git branch -d {0} && git checkout -b {0}',
'git branch -D {0} && git branch {0}',
'git branch -D {0} && git checkout -b {0}', 'git checkout {0}']]
@pytest.mark.parametrize('script, branch_name', [
('git branch foo', 'foo'), ('git checkout bar', 'bar')])
def test_match(stderr, script, branch_name):
assert match(Command(script=script, stderr=stderr))
@pytest.mark.parametrize('script', ['git branch foo', 'git checkout bar'])
def test_not_match(script):
assert not match(Command(script=script, stderr=''))
@pytest.mark.parametrize('script, branch_name, ', [
('git branch foo', 'foo'), ('git checkout bar', 'bar')])
def test_get_new_command(stderr, new_command, script, branch_name):
assert get_new_command(Command(script=script, stderr=stderr)) == new_command

View File

@@ -1,5 +1,5 @@
from thefuck import shells
from thefuck.rules.git_branch_list import match, get_new_command
from thefuck.shells import shell
from tests.utils import Command
@@ -16,4 +16,4 @@ def test_not_match():
def test_get_new_command():
assert (get_new_command(Command('git branch list')) ==
shell.and_('git branch --delete list', 'git branch'))
shells.and_('git branch --delete list', 'git branch'))

View File

@@ -1,6 +1,5 @@
import pytest
from io import BytesIO
from thefuck.rules.git_checkout import match, get_branches, get_new_command
from thefuck.rules.git_checkout import match, get_new_command
from tests.utils import Command
@@ -14,10 +13,8 @@ def did_not_match(target, did_you_forget=False):
@pytest.fixture
def git_branch(mocker, branches):
mock = mocker.patch('subprocess.Popen')
mock.return_value.stdout = BytesIO(branches)
return mock
def get_branches(mocker):
return mocker.patch('thefuck.rules.git_checkout.get_branches')
@pytest.mark.parametrize('command', [
@@ -36,34 +33,21 @@ def test_not_match(command):
assert not match(command)
@pytest.mark.parametrize('branches, branch_list', [
(b'', []),
(b'* master', ['master']),
(b' remotes/origin/master', ['master']),
(b' just-another-branch', ['just-another-branch']),
(b'* master\n just-another-branch', ['master', 'just-another-branch']),
(b'* master\n remotes/origin/master\n just-another-branch',
['master', 'master', 'just-another-branch'])])
def test_get_branches(branches, branch_list, git_branch):
git_branch(branches)
assert list(get_branches()) == branch_list
@pytest.mark.parametrize('branches, command, new_command', [
(b'',
([],
Command(script='git checkout unknown', stderr=did_not_match('unknown')),
'git branch unknown && git checkout unknown'),
(b'',
([],
Command('git commit unknown', stderr=did_not_match('unknown')),
'git branch unknown && git commit unknown'),
(b' test-random-branch-123',
(['test-random-branch-123'],
Command(script='git checkout tst-rdm-brnch-123',
stderr=did_not_match('tst-rdm-brnch-123')),
'git checkout test-random-branch-123'),
(b' test-random-branch-123',
(['test-random-branch-123'],
Command(script='git commit tst-rdm-brnch-123',
stderr=did_not_match('tst-rdm-brnch-123')),
'git commit test-random-branch-123')])
def test_get_new_command(branches, command, new_command, git_branch):
git_branch(branches)
def test_get_new_command(branches, command, new_command, get_branches):
get_branches.return_value = branches
assert get_new_command(command) == new_command

View File

@@ -1,23 +0,0 @@
import pytest
from thefuck.rules.git_diff_no_index import match, get_new_command
from tests.utils import Command
@pytest.mark.parametrize('command', [
Command(script='git diff foo bar')])
def test_match(command):
assert match(command)
@pytest.mark.parametrize('command', [
Command(script='git diff --no-index foo bar'),
Command(script='git diff foo'),
Command(script='git diff foo bar baz')])
def test_not_match(command):
assert not match(command)
@pytest.mark.parametrize('command, new_command', [
(Command('git diff foo bar'), 'git diff --no-index foo bar')])
def test_get_new_command(command, new_command):
assert get_new_command(command) == new_command

View File

@@ -1,31 +0,0 @@
import pytest
from thefuck.rules.git_flag_after_filename import match, get_new_command
from tests.utils import Command
command1 = Command('git log README.md -p',
stderr="fatal: bad flag '-p' used after filename")
command2 = Command('git log README.md -p CONTRIBUTING.md',
stderr="fatal: bad flag '-p' used after filename")
command3 = Command('git log -p README.md --name-only',
stderr="fatal: bad flag '--name-only' used after filename")
@pytest.mark.parametrize('command', [
command1, command2, command3])
def test_match(command):
assert match(command)
@pytest.mark.parametrize('command', [
Command('git log README.md'),
Command('git log -p README.md')])
def test_not_match(command):
assert not match(command)
@pytest.mark.parametrize('command, result', [
(command1, "git log -p README.md"),
(command2, "git log -p README.md CONTRIBUTING.md"),
(command3, "git log -p --name-only README.md")])
def test_get_new_command(command, result):
assert get_new_command(command) == result

View File

@@ -1,24 +0,0 @@
import pytest
from thefuck.rules.git_help_aliased import match, get_new_command
from tests.utils import Command
@pytest.mark.parametrize('script, stdout', [
('git help st', "`git st' is aliased to `status'"),
('git help ds', "`git ds' is aliased to `diff --staged'")])
def test_match(script, stdout):
assert match(Command(script=script, stdout=stdout))
@pytest.mark.parametrize('script, stdout', [
('git help status', "GIT-STATUS(1)...Git Manual...GIT-STATUS(1)"),
('git help diff', "GIT-DIFF(1)...Git Manual...GIT-DIFF(1)")])
def test_not_match(script, stdout):
assert not match(Command(script=script, stdout=stdout))
@pytest.mark.parametrize('script, stdout, new_command', [
('git help st', "`git st' is aliased to `status'", 'git help status'),
('git help ds', "`git ds' is aliased to `diff --staged'", 'git help diff')])
def test_get_new_command(script, stdout, new_command):
assert get_new_command(Command(script=script, stdout=stdout)) == new_command

View File

@@ -49,9 +49,9 @@ def test_match(git_not_command, git_command, git_not_command_one_of_this):
def test_get_new_command(git_not_command, git_not_command_one_of_this,
git_not_command_closest):
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))
== ['git stats', 'git stash', 'git stage'])
assert (get_new_command(Command('git tags', stderr=git_not_command_closest))
== ['git tag', 'git stage'])
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)) \
== ['git stats', 'git stash', 'git stage']
assert get_new_command(Command('git tags', stderr=git_not_command_closest)) \
== ['git tag', 'git stage']

View File

@@ -25,5 +25,5 @@ def test_match(stderr):
def test_get_new_command(stderr):
assert (get_new_command(Command('git pull', stderr=stderr))
== "git branch --set-upstream-to=origin/master master && git pull")
assert get_new_command(Command('git pull', stderr=stderr)) \
== "git branch --set-upstream-to=origin/master master && git pull"

View File

@@ -1,19 +0,0 @@
import pytest
from thefuck.rules.git_pull_uncommitted_changes import match, get_new_command
from tests.utils import Command
@pytest.fixture
def stderr():
return '''error: Cannot pull with rebase: You have unstaged changes.'''
def test_match(stderr):
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))
== "git stash && git pull && git stash pop")

View File

@@ -1,19 +0,0 @@
import pytest
from thefuck.rules.git_pull_uncommitted_changes import match, get_new_command
from tests.utils import Command
@pytest.fixture
def stderr():
return '''error: Cannot pull with rebase: Your index contains uncommitted changes.'''
def test_match(stderr):
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))
== "git stash && git pull && git stash pop")

View File

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

View File

@@ -45,8 +45,8 @@ def test_not_match(command):
@pytest.mark.parametrize('command, output', [
(Command(script='git push', stderr=git_err), 'git push --force-with-lease'),
(Command(script='git push nvbn', stderr=git_err), 'git push --force-with-lease nvbn'),
(Command(script='git push nvbn master', stderr=git_err), 'git push --force-with-lease nvbn master')])
(Command(script='git push', stderr=git_err), 'git push --force'),
(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) == output

View File

@@ -13,17 +13,6 @@ To /tmp/foo
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
'''
git_err2 = '''
To /tmp/foo
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to '/tmp/bar'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
'''
git_uptodate = 'Everything up-to-date'
git_ok = '''
Counting objects: 3, done.
@@ -39,10 +28,7 @@ To /tmp/bar
@pytest.mark.parametrize('command', [
Command(script='git push', stderr=git_err),
Command(script='git push nvbn', stderr=git_err),
Command(script='git push nvbn master', stderr=git_err),
Command(script='git push', stderr=git_err2),
Command(script='git push nvbn', stderr=git_err2),
Command(script='git push nvbn master', stderr=git_err2)])
Command(script='git push nvbn master', stderr=git_err)])
def test_match(command):
assert match(command)
@@ -63,11 +49,6 @@ def test_not_match(command):
(Command(script='git push nvbn', stderr=git_err),
'git pull nvbn && git push nvbn'),
(Command(script='git push nvbn master', stderr=git_err),
'git pull nvbn master && git push nvbn master'),
(Command(script='git push', stderr=git_err2), 'git pull && git push'),
(Command(script='git push nvbn', stderr=git_err2),
'git pull nvbn && git push nvbn'),
(Command(script='git push nvbn master', stderr=git_err2),
'git pull nvbn master && git push nvbn master')])
def test_get_new_command(command, output):
assert get_new_command(command) == output

View File

@@ -1,40 +0,0 @@
import pytest
from thefuck.rules.git_rebase_merge_dir import match, get_new_command
from tests.utils import Command
@pytest.fixture
def stderr():
return ('\n\nIt seems that there is already a rebase-merge directory, and\n'
'I wonder if you are in the middle of another rebase. If that is the\n'
'case, please try\n'
'\tgit rebase (--continue | --abort | --skip)\n'
'If that is not the case, please\n'
'\trm -fr "/foo/bar/baz/egg/.git/rebase-merge"\n'
'and run me again. I am stopping in case you still have something\n'
'valuable there.\n')
@pytest.mark.parametrize('script', [
('git rebase master'), ('git rebase -skip'), ('git rebase')])
def test_match(stderr, script):
assert match(Command(script=script, stderr=stderr))
@pytest.mark.parametrize('script', ['git rebase master', 'git rebase -abort'])
def test_not_match(script):
assert not match(Command(script=script))
@pytest.mark.parametrize('script, result', [
('git rebase master', [
'git rebase --abort', 'git rebase --skip', 'git rebase --continue',
'rm -fr "/foo/bar/baz/egg/.git/rebase-merge"']),
('git rebase -skip', [
'git rebase --skip', 'git rebase --abort', 'git rebase --continue',
'rm -fr "/foo/bar/baz/egg/.git/rebase-merge"']),
('git rebase', [
'git rebase --skip', 'git rebase --abort', 'git rebase --continue',
'rm -fr "/foo/bar/baz/egg/.git/rebase-merge"'])])
def test_get_new_command(stderr, script, result):
assert get_new_command(Command(script=script, stderr=stderr)) == result

View File

@@ -1,28 +0,0 @@
import pytest
from thefuck.rules.git_rebase_no_changes import match, get_new_command
from tests.utils import Command
@pytest.fixture
def stdout():
return '''Applying: Test commit
No changes - did you forget to use 'git add'?
If there is nothing left to stage, chances are that something else
already introduced the same changes; you might want to skip this patch.
When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".
'''
def test_match(stdout):
assert match(Command('git rebase --continue', stdout=stdout))
assert not match(Command('git rebase --continue'))
assert not match(Command('git rebase --skip'))
def test_get_new_command(stdout):
assert (get_new_command(Command('git rebase --continue', stdout=stdout)) ==
'git rebase --skip')

View File

@@ -1,26 +0,0 @@
import pytest
from thefuck.rules.git_remote_seturl_add import match, get_new_command
from tests.utils import Command
@pytest.mark.parametrize('command', [
Command(script='git remote set-url origin url', stderr="fatal: No such remote")])
def test_match(command):
assert match(command)
@pytest.mark.parametrize('command', [
Command('git remote set-url origin url', stderr=""),
Command('git remote add origin url'),
Command('git remote remove origin'),
Command('git remote prune origin'),
Command('git remote set-branches origin branch')])
def test_not_match(command):
assert not match(command)
@pytest.mark.parametrize('command, new_command', [
(Command('git remote set-url origin git@github.com:nvbn/thefuck.git'),
'git remote add origin git@github.com:nvbn/thefuck.git')])
def test_get_new_command(command, new_command):
assert get_new_command(command) == new_command

View File

@@ -1,28 +0,0 @@
import pytest
from thefuck.rules.git_rm_local_modifications import match, get_new_command
from tests.utils import Command
@pytest.fixture
def stderr(target):
return ('error: the following file has local modifications:\n {}\n(use '
'--cached to keep the file, or -f to force removal)').format(target)
@pytest.mark.parametrize('script, target', [
('git rm foo', 'foo'),
('git rm foo bar', 'bar')])
def test_match(stderr, script, target):
assert match(Command(script=script, stderr=stderr))
@pytest.mark.parametrize('script', ['git rm foo', 'git rm foo bar', 'git rm'])
def test_not_match(script):
assert not match(Command(script=script, stderr=''))
@pytest.mark.parametrize('script, target, new_command', [
('git rm foo', 'foo', ['git rm --cached foo', 'git rm -f foo']),
('git rm foo bar', 'bar', ['git rm --cached foo bar', 'git rm -f foo bar'])])
def test_get_new_command(stderr, script, target, new_command):
assert get_new_command(Command(script=script, stderr=stderr)) == new_command

View File

@@ -1,27 +0,0 @@
import pytest
from thefuck.rules.git_rm_recursive import match, get_new_command
from tests.utils import Command
@pytest.fixture
def stderr(target):
return "fatal: not removing '{}' recursively without -r".format(target)
@pytest.mark.parametrize('script, target', [
('git rm foo', 'foo'),
('git rm foo bar', 'foo bar')])
def test_match(stderr, script, target):
assert match(Command(script=script, stderr=stderr))
@pytest.mark.parametrize('script', ['git rm foo', 'git rm foo bar'])
def test_not_match(script):
assert not match(Command(script=script, stderr=''))
@pytest.mark.parametrize('script, target, new_command', [
('git rm foo', 'foo', 'git rm -r foo'),
('git rm foo bar', 'foo bar', 'git rm -r foo bar')])
def test_get_new_command(stderr, script, target, new_command):
assert get_new_command(Command(script=script, stderr=stderr)) == new_command

View File

@@ -1,28 +0,0 @@
import pytest
from thefuck.rules.git_rm_staged import match, get_new_command
from tests.utils import Command
@pytest.fixture
def stderr(target):
return ('error: the following file has changes staged in the index:\n {}\n(use '
'--cached to keep the file, or -f to force removal)').format(target)
@pytest.mark.parametrize('script, target', [
('git rm foo', 'foo'),
('git rm foo bar', 'bar')])
def test_match(stderr, script, target):
assert match(Command(script=script, stderr=stderr))
@pytest.mark.parametrize('script', ['git rm foo', 'git rm foo bar', 'git rm'])
def test_not_match(script):
assert not match(Command(script=script, stderr=''))
@pytest.mark.parametrize('script, target, new_command', [
('git rm foo', 'foo', ['git rm --cached foo', 'git rm -f foo']),
('git rm foo bar', 'bar', ['git rm --cached foo bar', 'git rm -f foo bar'])])
def test_get_new_command(stderr, script, target, new_command):
assert get_new_command(Command(script=script, stderr=stderr)) == new_command

View File

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

View File

@@ -1,18 +0,0 @@
import pytest
from thefuck.rules.git_stash_pop import match, get_new_command
from tests.utils import Command
@pytest.fixture
def stderr():
return '''error: Your local changes to the following files would be overwritten by merge:'''
def test_match(stderr):
assert match(Command('git stash pop', stderr=stderr))
assert not match(Command('git stash'))
def test_get_new_command(stderr):
assert (get_new_command(Command('git stash pop', stderr=stderr))
== "git add . && git stash pop && git reset .")

View File

@@ -1,18 +0,0 @@
import pytest
from thefuck.rules.git_tag_force import match, get_new_command
from tests.utils import Command
@pytest.fixture
def stderr():
return '''fatal: tag 'alert' already exists'''
def test_match(stderr):
assert match(Command('git tag alert', stderr=stderr))
assert not match(Command('git tag alert'))
def test_get_new_command(stderr):
assert (get_new_command(Command('git tag alert', stderr=stderr))
== "git tag --force alert")

View File

@@ -1,47 +0,0 @@
import pytest
from thefuck.rules.git_two_dashes import match, get_new_command
from tests.utils import Command
@pytest.fixture
def stderr(meant):
return 'error: did you mean `%s` (with two dashes ?)' % meant
@pytest.mark.parametrize('command', [
Command(script='git add -patch', stderr=stderr('--patch')),
Command(script='git checkout -patch', stderr=stderr('--patch')),
Command(script='git commit -amend', stderr=stderr('--amend')),
Command(script='git push -tags', stderr=stderr('--tags')),
Command(script='git rebase -continue', stderr=stderr('--continue'))])
def test_match(command):
assert match(command)
@pytest.mark.parametrize('command', [
Command(script='git add --patch'),
Command(script='git checkout --patch'),
Command(script='git commit --amend'),
Command(script='git push --tags'),
Command(script='git rebase --continue')])
def test_not_match(command):
assert not match(command)
@pytest.mark.parametrize('command, output', [
(Command(script='git add -patch', stderr=stderr('--patch')),
'git add --patch'),
(Command(script='git checkout -patch', stderr=stderr('--patch')),
'git checkout --patch'),
(Command(script='git checkout -patch', stderr=stderr('--patch')),
'git checkout --patch'),
(Command(script='git init -bare', stderr=stderr('--bare')),
'git init --bare'),
(Command(script='git commit -amend', stderr=stderr('--amend')),
'git commit --amend'),
(Command(script='git push -tags', stderr=stderr('--tags')),
'git push --tags'),
(Command(script='git rebase -continue', stderr=stderr('--continue')),
'git rebase --continue')])
def test_get_new_command(command, output):
assert get_new_command(command) == output

View File

@@ -1,158 +0,0 @@
import pytest
from io import BytesIO
from thefuck.rules.gradle_no_task import match, get_new_command
from tests.utils import Command
gradle_tasks = b'''
:tasks
------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------
Android tasks
-------------
androidDependencies - Displays the Android dependencies of the project.
signingReport - Displays the signing info for each variant.
sourceSets - Prints out all the source sets defined in this project.
Build tasks
-----------
assemble - Assembles all variants of all applications and secondary packages.
assembleAndroidTest - Assembles all the Test applications.
assembleDebug - Assembles all Debug builds.
assembleRelease - Assembles all Release builds.
build - Assembles and tests this project.
buildDependents - Assembles and tests this project and all projects that depend on it.
buildNeeded - Assembles and tests this project and all projects it depends on.
compileDebugAndroidTestSources
compileDebugSources
compileDebugUnitTestSources
compileReleaseSources
compileReleaseUnitTestSources
extractDebugAnnotations - Extracts Android annotations for the debug variant into the archive file
extractReleaseAnnotations - Extracts Android annotations for the release variant into the archive file
mockableAndroidJar - Creates a version of android.jar that's suitable for unit tests.
Build Setup tasks
-----------------
init - Initializes a new Gradle build. [incubating]
wrapper - Generates Gradle wrapper files. [incubating]
Help tasks
----------
components - Displays the components produced by root project 'org.rerenderer_example.snake'. [incubating]
dependencies - Displays all dependencies declared in root project 'org.rerenderer_example.snake'.
dependencyInsight - Displays the insight into a specific dependency in root project 'org.rerenderer_example.snake'.
help - Displays a help message.
model - Displays the configuration model of root project 'org.rerenderer_example.snake'. [incubating]
projects - Displays the sub-projects of root project 'org.rerenderer_example.snake'.
properties - Displays the properties of root project 'org.rerenderer_example.snake'.
tasks - Displays the tasks runnable from root project 'org.rerenderer_example.snake' (some of the displayed tasks may belong to subprojects).
Install tasks
-------------
installDebug - Installs the Debug build.
installDebugAndroidTest - Installs the android (on device) tests for the Debug build.
installRelease - Installs the Release build.
uninstallAll - Uninstall all applications.
uninstallDebug - Uninstalls the Debug build.
uninstallDebugAndroidTest - Uninstalls the android (on device) tests for the Debug build.
uninstallRelease - Uninstalls the Release build.
React tasks
-----------
bundleDebugJsAndAssets - bundle JS and assets for Debug.
bundleReleaseJsAndAssets - bundle JS and assets for Release.
Verification tasks
------------------
check - Runs all checks.
clean - Deletes the build directory.
connectedAndroidTest - Installs and runs instrumentation tests for all flavors on connected devices.
connectedCheck - Runs all device checks on currently connected devices.
connectedDebugAndroidTest - Installs and runs the tests for debug on connected devices.
deviceAndroidTest - Installs and runs instrumentation tests using all Device Providers.
deviceCheck - Runs all device checks using Device Providers and Test Servers.
lint - Runs lint on all variants.
lintDebug - Runs lint on the Debug build.
lintRelease - Runs lint on the Release build.
test - Run unit tests for all variants.
testDebugUnitTest - Run unit tests for the debug build.
testReleaseUnitTest - Run unit tests for the release build.
Other tasks
-----------
assembleDefault
copyDownloadableDepsToLibs
jarDebugClasses
jarReleaseClasses
To see all tasks and more detail, run gradlew tasks --all
To see more detail about a task, run gradlew help --task <task>
BUILD SUCCESSFUL
Total time: 1.936 secs
'''
stderr_not_found = '''
FAILURE: Build failed with an exception.
* What went wrong:
Task '{}' not found in root project 'org.rerenderer_example.snake'.
* Try:
Run gradlew tasks to get a list of available tasks. Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
'''.format
stderr_ambiguous = '''
FAILURE: Build failed with an exception.
* What went wrong:
Task '{}' is ambiguous in root project 'org.rerenderer_example.snake'. Candidates are: 'assembleRelease', 'assembleReleaseUnitTest'.
* Try:
Run gradlew tasks to get a list of available tasks. Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
'''.format
@pytest.fixture(autouse=True)
def tasks(mocker):
patch = mocker.patch('thefuck.rules.gradle_no_task.Popen')
patch.return_value.stdout = BytesIO(gradle_tasks)
return patch
@pytest.mark.parametrize('command', [
Command('./gradlew assembler', stderr=stderr_ambiguous('assembler')),
Command('./gradlew instar', stderr=stderr_not_found('instar')),
Command('gradle assembler', stderr=stderr_ambiguous('assembler')),
Command('gradle instar', stderr=stderr_not_found('instar'))])
def test_match(command):
assert match(command)
@pytest.mark.parametrize('command', [
Command('./gradlew assemble'),
Command('gradle assemble'),
Command('npm assembler', stderr=stderr_ambiguous('assembler')),
Command('npm instar', stderr=stderr_not_found('instar'))])
def test_not_match(command):
assert not match(command)
@pytest.mark.parametrize('command, result', [
(Command('./gradlew assembler', stderr=stderr_ambiguous('assembler')),
'./gradlew assemble'),
(Command('./gradlew instardebug', stderr=stderr_not_found('instardebug')),
'./gradlew installDebug'),
(Command('gradle assembler', stderr=stderr_ambiguous('assembler')),
'gradle assemble'),
(Command('gradle instardebug', stderr=stderr_not_found('instardebug')),
'gradle installDebug')])
def test_get_new_command(command, result):
assert get_new_command(command)[0] == result

View File

@@ -1,38 +0,0 @@
import pytest
from thefuck.rules.gradle_wrapper import match, get_new_command
from tests.utils import Command
@pytest.fixture(autouse=True)
def exists(mocker):
return mocker.patch('thefuck.rules.gradle_wrapper.os.path.isfile',
return_value=True)
@pytest.mark.parametrize('command', [
Command('gradle tasks', stderr='gradle: not found'),
Command('gradle build', stderr='gradle: not found')])
def test_match(mocker, command):
mocker.patch('thefuck.rules.gradle_wrapper.which', return_value=None)
assert match(command)
@pytest.mark.parametrize('command, gradlew, which', [
(Command('gradle tasks', stderr='gradle: not found'), False, None),
(Command('gradle tasks', stderr='command not found'), True, '/usr/bin/gradle'),
(Command('npm tasks', stderr='npm: not found'), True, None)])
def test_not_match(mocker, exists, command, gradlew, which):
mocker.patch('thefuck.rules.gradle_wrapper.which', return_value=which)
exists.return_value = gradlew
assert not match(command)
@pytest.mark.parametrize('script, result', [
('gradle assemble', './gradlew assemble'),
('gradle --help', './gradlew --help'),
('gradle build -c', './gradlew build -c')])
def test_get_new_command(script, result):
command = Command(script)
assert get_new_command(command) == result

View File

@@ -1,40 +0,0 @@
import pytest
from thefuck.rules.grep_arguments_order import get_new_command, match
from tests.utils import Command
stderr = 'grep: {}: No such file or directory'.format
@pytest.fixture(autouse=True)
def os_path(monkeypatch):
monkeypatch.setattr('os.path.isfile', lambda x: not x.startswith('-'))
@pytest.mark.parametrize('script, file', [
('grep test.py test', 'test'),
('grep -lir . test', 'test'),
('egrep test.py test', 'test'),
('egrep -lir . test', 'test')])
def test_match(script, file):
assert match(Command(script, stderr=stderr(file)))
@pytest.mark.parametrize('script, stderr', [
('cat test.py', stderr('test')),
('grep test test.py', ''),
('grep -lir test .', ''),
('egrep test test.py', ''),
('egrep -lir test .', '')])
def test_not_match(script, stderr):
assert not match(Command(script, stderr=stderr))
@pytest.mark.parametrize('script, stderr, result', [
('grep test.py test', stderr('test'), 'grep test test.py'),
('grep -lir . test', stderr('test'), 'grep -lir test .'),
('grep . test -lir', stderr('test'), 'grep test -lir .'),
('egrep test.py test', stderr('test'), 'egrep test test.py'),
('egrep -lir . test', stderr('test'), 'egrep -lir test .'),
('egrep . test -lir', stderr('test'), 'egrep test -lir .')])
def test_get_new_command(script, stderr, result):
assert get_new_command(Command(script, stderr=stderr)) == result

View File

@@ -1,15 +1,12 @@
# -*- coding: utf-8 -*-
from thefuck.rules.grep_recursive import match, get_new_command
from tests.utils import Command
def test_match():
assert match(Command('grep blah .', stderr='grep: .: Is a directory'))
assert match(Command(u'grep café .', stderr='grep: .: Is a directory'))
assert not match(Command())
def test_get_new_command():
assert get_new_command(Command('grep blah .')) == 'grep -r blah .'
assert get_new_command(Command(u'grep café .')) == u'grep -r café .'
assert get_new_command(
Command('grep blah .')) == 'grep -r blah .'

View File

@@ -1,129 +0,0 @@
# -*- encoding: utf-8 -*-
from io import BytesIO
import pytest
from tests.utils import Command
from thefuck.rules.grunt_task_not_found import match, get_new_command
stdout = '''
Warning: Task "{}" not found. Use --force to continue.
Aborted due to warnings.
Execution Time (2016-08-13 21:01:40 UTC+3)
loading tasks 11ms ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 92%
Total 12ms
'''.format
grunt_help_stdout = b'''
Grunt: The JavaScript Task Runner (v0.4.5)
Usage
grunt [options] [task [task ...]]
Options
--help, -h Display this help text.
--base Specify an alternate base path. By default, all file paths are
relative to the Gruntfile. (grunt.file.setBase) *
--no-color Disable colored output.
--gruntfile Specify an alternate Gruntfile. By default, grunt looks in the
current or parent directories for the nearest Gruntfile.js or
Gruntfile.coffee file.
--debug, -d Enable debugging mode for tasks that support it.
--stack Print a stack trace when exiting with a warning or fatal error.
--force, -f A way to force your way past warnings. Want a suggestion? Don't
use this option, fix your code.
--tasks Additional directory paths to scan for task and "extra" files.
(grunt.loadTasks) *
--npm Npm-installed grunt plugins to scan for task and "extra" files.
(grunt.loadNpmTasks) *
--no-write Disable writing files (dry run).
--verbose, -v Verbose mode. A lot more information output.
--version, -V Print the grunt version. Combine with --verbose for more info.
--completion Output shell auto-completion rules. See the grunt-cli
documentation for more information.
Options marked with * have methods exposed via the grunt API and should instead
be specified inside the Gruntfile wherever possible.
Available tasks
autoprefixer Prefix CSS files. *
concurrent Run grunt tasks concurrently *
clean Clean files and folders. *
compass Compile Sass to CSS using Compass *
concat Concatenate files. *
connect Start a connect web server. *
copy Copy files. *
cssmin Minify CSS *
htmlmin Minify HTML *
imagemin Minify PNG, JPEG, GIF and SVG images *
jshint Validate files with JSHint. *
uglify Minify files with UglifyJS. *
watch Run predefined tasks whenever watched files change.
filerev File revisioning based on content hashing *
cdnify Replace scripts with refs to the Google CDN *
karma run karma. *
newer Run a task with only those source files that have been modified
since the last successful run.
any-newer DEPRECATED TASK. Use the "newer" task instead
newer-postrun Internal task.
newer-clean Remove cached timestamps.
ngAnnotate Add, remove and rebuild AngularJS dependency injection
annotations *
ngconstant Dynamic angular constant generator task. *
svgmin Minify SVG *
usemin Replaces references to non-minified scripts / stylesheets *
useminPrepare Using HTML markup as the primary source of information *
wiredep Inject Bower components into your source code. *
serve Compile then start a connect web server
server DEPRECATED TASK. Use the "serve" task instead
test Alias for "clean:server", "ngconstant:test", "wiredep",
"concurrent:test", "autoprefixer", "connect:test", "karma"
tasks.
build Alias for "ngconstant:production", "clean:dist", "wiredep",
"useminPrepare", "concurrent:dist", "autoprefixer", "concat",
"ngAnnotate", "copy:dist", "cdnify", "cssmin", "uglify",
"filerev", "usemin", "htmlmin" tasks.
default Alias for "newer:jshint", "test", "build" tasks.
Tasks run in the order specified. Arguments may be passed to tasks that accept
them by using colons, like "lint:files". Tasks marked with * are "multi tasks"
and will iterate over all sub-targets if no argument is specified.
The list of available tasks may change based on tasks directories or grunt
plugins specified in the Gruntfile or via command-line options.
For more information, see http://gruntjs.com/
'''
@pytest.fixture(autouse=True)
def grunt_help(mocker):
patch = mocker.patch('thefuck.rules.grunt_task_not_found.Popen')
patch.return_value.stdout = BytesIO(grunt_help_stdout)
return patch
@pytest.mark.parametrize('command', [
Command('grunt defualt', stdout('defualt')),
Command('grunt buld:css', stdout('buld:css'))])
def test_match(command):
assert match(command)
@pytest.mark.parametrize('command', [
Command('npm nuild', stdout('nuild')),
Command('grunt rm')])
def test_not_match(command):
assert not match(command)
@pytest.mark.parametrize('command, result', [
(Command('grunt defualt', stdout('defualt')), 'grunt default'),
(Command('grunt cmpass:all', stdout('cmpass:all')), 'grunt compass:all'),
(Command('grunt cmpass:all --color', stdout('cmpass:all')),
'grunt compass:all --color')])
def test_get_new_command(command, result):
assert get_new_command(command) == result

View File

@@ -1,5 +1,4 @@
import pytest
from io import BytesIO
from tests.utils import Command
from thefuck.rules.gulp_not_task import match, get_new_command
@@ -23,7 +22,7 @@ def test_not_march(script, stdout):
def test_get_new_command(mocker):
mock = mocker.patch('subprocess.Popen')
mock.return_value.stdout = BytesIO(b'serve \nbuild \ndefault \n')
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) == ['gulp serve', 'gulp default']

View File

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

View File

@@ -3,23 +3,38 @@ from thefuck.rules.history import match, get_new_command
from tests.utils import Command
@pytest.fixture(autouse=True)
def history_without_current(mocker):
return mocker.patch(
'thefuck.rules.history.get_valid_history_without_current',
return_value=['ls cat', 'diff x'])
@pytest.fixture
def history(mocker):
return mocker.patch('thefuck.rules.history.get_history',
return_value=['le cat', 'fuck', 'ls cat',
'diff x', 'nocommand x'])
@pytest.fixture
def alias(mocker):
return mocker.patch('thefuck.rules.history.thefuck_alias',
return_value='fuck')
@pytest.fixture
def callables(mocker):
return mocker.patch('thefuck.rules.history.get_all_executables',
return_value=['diff', 'ls'])
@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))
@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))
@pytest.mark.usefixtures('history', 'callables', 'no_memoize', 'alias')
@pytest.mark.parametrize('script, result', [
('ls cet', 'ls cat'),
('daff x', 'diff x')])

View File

@@ -1,29 +0,0 @@
import pytest
from thefuck.rules.hostscli import no_website, get_new_command, match
from tests.utils import Command
no_website_long = '''
{}:
No Domain list found for website: a_website_that_does_not_exist
Please raise a Issue here: https://github.com/dhilipsiva/hostscli/issues/new
if you think we should add domains for this website.
type `hostscli websites` to see a list of websites that you can block/unblock
'''.format(no_website)
@pytest.mark.parametrize('command', [
Command('hostscli block a_website_that_does_not_exist',
stderr=no_website_long)])
def test_match(command):
assert match(command)
@pytest.mark.parametrize('command, result', [(
Command('hostscli block a_website_that_does_not_exist',
stderr=no_website_long),
['hostscli websites'])])
def test_get_new_command(command, result):
assert get_new_command(command) == result

View File

@@ -1,53 +0,0 @@
import pytest
from six import BytesIO
from thefuck.rules.ifconfig_device_not_found import match, get_new_command
from tests.utils import Command
stderr = '{}: error fetching interface information: Device not found'
stdout = b'''
wlp2s0 Link encap:Ethernet HWaddr 5c:51:4f:7c:58:5d
inet addr:192.168.0.103 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: fe80::be23:69b9:96d2:6d39/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:23581604 errors:0 dropped:0 overruns:0 frame:0
TX packets:17017655 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:16148429061 (16.1 GB) TX bytes:7067533695 (7.0 GB)
'''
@pytest.fixture(autouse=True)
def ifconfig(mocker):
mock = mocker.patch(
'thefuck.rules.ifconfig_device_not_found.subprocess.Popen')
mock.return_value.stdout = BytesIO(stdout)
return mock
@pytest.mark.parametrize('script, stderr', [
('ifconfig wlan0', stderr.format('wlan0')),
('ifconfig -s eth0', stderr.format('eth0')),
])
def test_match(script, stderr):
assert match(Command(script, stderr=stderr))
@pytest.mark.parametrize('script, stderr', [
('config wlan0',
'wlan0: error fetching interface information: Device not found'),
('ifconfig eth0', ''),
])
def test_not_match(script, stderr):
assert not match(Command(script, stderr=stderr))
@pytest.mark.parametrize('script, result', [
('ifconfig wlan0', ['ifconfig wlp2s0']),
('ifconfig -s wlan0', ['ifconfig -s wlp2s0']),
])
def test_get_new_comman(script, result):
new_command = get_new_command(
Command(script, stderr=stderr.format('wlan0')))
assert new_command == result

View File

@@ -19,5 +19,5 @@ def test_match(is_not_task):
def test_get_new_command(is_not_task):
assert (get_new_command(Command(script='lein rpl --help', stderr=is_not_task))
== ['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']

View File

@@ -1,37 +0,0 @@
# -*- coding: utf-8 -*-
import pytest
from thefuck.rules.ln_no_hard_link import match, get_new_command
from tests.utils import Command
error = "hard link not allowed for directory"
@pytest.mark.parametrize('script, stderr', [
("ln barDir barLink", "ln: barDir: {}"),
("sudo ln a b", "ln: a: {}"),
("sudo ln -nbi a b", "ln: a: {}")])
def test_match(script, stderr):
command = Command(script, stderr=stderr.format(error))
assert match(command)
@pytest.mark.parametrize('script, stderr', [
('', ''),
("ln a b", "... hard link"),
("sudo ln a b", "... hard link"),
("a b", error)])
def test_not_match(script, stderr):
command = Command(script, stderr=stderr)
assert not match(command)
@pytest.mark.parametrize('script, result', [
("ln barDir barLink", "ln -s barDir barLink"),
("sudo ln barDir barLink", "sudo ln -s barDir barLink"),
("sudo ln -nbi a b", "sudo ln -s -nbi a b"),
("ln -nbi a b && ls", "ln -s -nbi a b && ls"),
("ln a ln", "ln -s a ln"),
("sudo ln a ln", "sudo ln -s a ln")])
def test_get_new_command(script, result):
command = Command(script)
assert get_new_command(command) == result

View File

@@ -1,32 +0,0 @@
import pytest
from thefuck.rules.ln_s_order import match, get_new_command
from tests.utils import Command
@pytest.fixture
def file_exists(mocker):
return mocker.patch('os.path.exists', return_value=True)
get_stderr = "ln: failed to create symbolic link '{}': File exists".format
@pytest.mark.parametrize('script, stderr, exists', [
('ln dest source', get_stderr('source'), True),
('ls -s dest source', get_stderr('source'), True),
('ln -s dest source', '', True),
('ln -s dest source', get_stderr('source'), False)])
def test_not_match(file_exists, script, stderr, exists):
file_exists.return_value = exists
assert not match(Command(script, stderr=stderr))
@pytest.mark.usefixtures('file_exists')
@pytest.mark.parametrize('script, result', [
('ln -s dest source', 'ln -s source dest'),
('ln dest -s source', 'ln -s source dest'),
('ln dest source -s', 'ln source -s dest')])
def test_match(script, result):
stderr = get_stderr('source')
assert match(Command(script, stderr=stderr))
assert get_new_command(Command(script, stderr=stderr)) == result

View File

@@ -1,12 +0,0 @@
from thefuck.rules.ls_all import match, get_new_command
from tests.utils import Command
def test_match():
assert match(Command(script='ls'))
assert not match(Command(script='ls', stdout='file.py\n'))
def test_get_new_command():
assert get_new_command(Command(script='ls empty_dir')) == 'ls -A empty_dir'
assert get_new_command(Command(script='ls')) == 'ls -A'

View File

@@ -23,8 +23,7 @@ def test_not_match(command):
@pytest.mark.parametrize('command, new_command', [
(Command('man read'), ['man 3 read', 'man 2 read', 'read --help']),
(Command('man missing', stderr="No manual entry for missing\n"), ['missing --help']),
(Command('man read'), ['man 3 read', 'man 2 read']),
(Command('man 2 read'), 'man 3 read'),
(Command('man 3 read'), 'man 2 read'),
(Command('man -s2 read'), 'man -s3 read'),

View File

@@ -1,39 +0,0 @@
import pytest
from thefuck.rules.missing_space_before_subcommand import (
match, get_new_command)
from tests.utils import Command
@pytest.fixture(autouse=True)
def which(mocker):
return mocker.patch('thefuck.rules.missing_space_before_subcommand.which',
return_value=None)
@pytest.fixture(autouse=True)
def all_executables(mocker):
return mocker.patch(
'thefuck.rules.missing_space_before_subcommand.get_all_executables',
return_value=['git', 'ls', 'npm'])
@pytest.mark.parametrize('script', [
'gitbranch', 'ls-la', 'npminstall'])
def test_match(script):
assert match(Command(script))
@pytest.mark.parametrize('script, which_result', [
('git branch', '/usr/bin/git'),
('vimfile', None)])
def test_not_match(script, which_result, which):
which.return_value = which_result
assert not match(Command(script))
@pytest.mark.parametrize('script, result', [
('gitbranch', 'git branch'),
('ls-la', 'ls -la'),
('npminstall webpack', 'npm install webpack')])
def test_get_new_command(script, result):
assert get_new_command(Command(script)) == result

View File

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

View File

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

View File

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

View File

@@ -6,42 +6,22 @@ from tests.utils import Command
@pytest.fixture(autouse=True)
def get_all_executables(mocker):
mocker.patch('thefuck.rules.no_command.get_all_executables',
return_value=['vim', 'fsck', 'git', 'go'])
@pytest.fixture(autouse=True)
def history_without_current(mocker):
return mocker.patch(
'thefuck.rules.no_command.get_valid_history_without_current',
return_value=['git commit'])
return_value=['vim', 'apt-get', 'fsck'])
@pytest.mark.usefixtures('no_memoize')
@pytest.mark.parametrize('script, stderr', [
('vom file.py', 'vom: not found'),
('fucck', 'fucck: not found'),
('got commit', 'got: command not found')])
def test_match(mocker, script, stderr):
mocker.patch('thefuck.rules.no_command.which', return_value=None)
assert match(Command(script, stderr=stderr))
def test_match():
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')
@pytest.mark.parametrize('script, stderr, which', [
('qweqwe', 'qweqwe: not found', None),
('vom file.py', 'some text', None),
('vim file.py', 'vim: not found', 'vim')])
def test_not_match(mocker, script, stderr, which):
mocker.patch('thefuck.rules.no_command.which', return_value=which)
assert not match(Command(script, stderr=stderr))
@pytest.mark.usefixtures('no_memoize')
@pytest.mark.parametrize('script, result', [
('vom file.py', ['vim file.py']),
('fucck', ['fsck']),
('got commit', ['git commit', 'go commit'])])
def test_get_new_command(script, result):
assert get_new_command(Command(script)) == result
def test_get_new_command():
assert get_new_command(
Command(stderr='vom: not found',
script='vom file.py')) == ['vim file.py']
assert get_new_command(
Command(stderr='fucck: not found',
script='fucck')) == ['fsck']

View File

@@ -6,7 +6,7 @@ from tests.utils import Command
@pytest.mark.parametrize('command', [
Command(script='mv foo bar/foo', stderr="mv: cannot move 'foo' to 'bar/foo': No such file or directory"),
Command(script='mv foo bar/', stderr="mv: cannot move 'foo' to 'bar/': No such file or directory"),
])
])
def test_match(command):
assert match(command)
@@ -14,7 +14,7 @@ def test_match(command):
@pytest.mark.parametrize('command', [
Command(script='mv foo bar/', stderr=""),
Command(script='mv foo bar/foo', stderr="mv: permission denied"),
])
])
def test_not_match(command):
assert not match(command)
@@ -22,6 +22,6 @@ def test_not_match(command):
@pytest.mark.parametrize('command, new_command', [
(Command(script='mv foo bar/foo', stderr="mv: cannot move 'foo' to 'bar/foo': No such file or directory"), 'mkdir -p bar && mv foo bar/foo'),
(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) == new_command

View File

@@ -1,69 +0,0 @@
import pytest
from io import BytesIO
from tests.utils import Command
from thefuck.rules.npm_missing_script import match, get_new_command
stderr = '''
npm ERR! Linux 4.4.0-31-generic
npm ERR! argv "/opt/node/bin/node" "/opt/node/bin/npm" "run" "dvelop"
npm ERR! node v4.4.7
npm ERR! npm v2.15.8
npm ERR! missing script: {}
npm ERR!
npm ERR! If you need help, you may report this error at:
npm ERR! <https://github.com/npm/npm/issues>
npm ERR! Please include the following file with any support request:
npm ERR! /home/nvbn/exp/code_view/client_web/npm-debug.log
'''.format
run_script_stdout = b'''
Lifecycle scripts included in code-view-web:
test
jest
available via `npm run-script`:
build
cp node_modules/ace-builds/src-min/ -a resources/ace/ && webpack --progress --colors -p --config ./webpack.production.config.js
develop
cp node_modules/ace-builds/src/ -a resources/ace/ && webpack-dev-server --progress --colors
watch-test
jest --verbose --watch
'''
@pytest.fixture(autouse=True)
def run_script(mocker):
patch = mocker.patch('thefuck.specific.npm.Popen')
patch.return_value.stdout = BytesIO(run_script_stdout)
return patch.return_value
@pytest.mark.parametrize('command', [
Command('npm ru wach', stderr=stderr('wach')),
Command('npm run live-tes', stderr=stderr('live-tes')),
Command('npm run-script sahare', stderr=stderr('sahare'))])
def test_match(command):
assert match(command)
@pytest.mark.parametrize('command', [
Command('npm wach', stderr=stderr('wach')),
Command('vim live-tes', stderr=stderr('live-tes')),
Command('npm run-script sahare')])
def test_not_match(command):
assert not match(command)
@pytest.mark.parametrize('script, stderr, result', [
('npm ru wach-tests', stderr('wach-tests'), 'npm ru watch-test'),
('npm -i run-script dvelop', stderr('dvelop'),
'npm -i run-script develop'),
('npm -i run-script buld -X POST', stderr('buld'),
'npm -i run-script build -X POST')])
def test_get_new_command(script, stderr, result):
command = Command(script, stderr=stderr)
assert get_new_command(command)[0] == result

View File

@@ -1,84 +0,0 @@
import pytest
from io import BytesIO
from thefuck.rules.npm_run_script import match, get_new_command
from tests.utils import Command
stdout = '''
Usage: npm <command>
where <command> is one of:
access, add-user, adduser, apihelp, author, bin, bugs, c,
cache, completion, config, ddp, dedupe, deprecate, dist-tag,
dist-tags, docs, edit, explore, faq, find, find-dupes, get,
help, help-search, home, i, info, init, install, issues, la,
link, list, ll, ln, login, logout, ls, outdated, owner,
pack, ping, prefix, prune, publish, r, rb, rebuild, remove,
repo, restart, rm, root, run-script, s, se, search, set,
show, shrinkwrap, star, stars, start, stop, t, tag, team,
test, tst, un, uninstall, unlink, unpublish, unstar, up,
update, upgrade, v, version, view, whoami
npm <cmd> -h quick help on <cmd>
npm -l display full usage info
npm faq commonly asked questions
npm help <term> search for help on <term>
npm help npm involved overview
Specify configs in the ini-formatted file:
/home/nvbn/.npmrc
or on the command line via: npm <command> --key value
Config info can be viewed via: npm help config
'''
run_script_stdout = b'''
Lifecycle scripts included in code-view-web:
test
jest
available via `npm run-script`:
build
cp node_modules/ace-builds/src-min/ -a resources/ace/ && webpack --progress --colors -p --config ./webpack.production.config.js
develop
cp node_modules/ace-builds/src/ -a resources/ace/ && webpack-dev-server --progress --colors
watch-test
jest --verbose --watch
'''
@pytest.fixture(autouse=True)
def run_script(mocker):
patch = mocker.patch('thefuck.specific.npm.Popen')
patch.return_value.stdout = BytesIO(run_script_stdout)
return patch.return_value
@pytest.mark.usefixtures('no_memoize')
@pytest.mark.parametrize('script', [
'npm watch-test', 'npm develop'])
def test_match(script):
command = Command(script, stdout)
assert match(command)
@pytest.mark.usefixtures('no_memoize')
@pytest.mark.parametrize('command, run_script_out', [
(Command('npm test', 'TEST FAIL'), run_script_stdout),
(Command('npm watch-test', 'TEST FAIL'), run_script_stdout),
(Command('npm test', stdout), run_script_stdout),
(Command('vim watch-test', stdout), run_script_stdout)])
def test_not_match(run_script, command, run_script_out):
run_script.stdout = BytesIO(run_script_out)
assert not match(command)
@pytest.mark.usefixtures('no_memoize')
@pytest.mark.parametrize('script, result', [
('npm watch-test', 'npm run-script watch-test'),
('npm -i develop', 'npm run-script -i develop'),
('npm -i watch-script --path ..',
'npm run-script -i watch-script --path ..')])
def test_get_new_command(script, result):
command = Command(script, stdout)
assert get_new_command(command) == result

View File

@@ -1,58 +0,0 @@
import pytest
from thefuck.rules.npm_wrong_command import match, get_new_command
from tests.utils import Command
stdout = '''
Usage: npm <command>
where <command> is one of:
access, add-user, adduser, apihelp, author, bin, bugs, c,
cache, completion, config, ddp, dedupe, deprecate, dist-tag,
dist-tags, docs, edit, explore, faq, find, find-dupes, get,
help, help-search, home, i, info, init, install, issues, la,
link, list, ll, ln, login, logout, ls, outdated, owner,
pack, ping, prefix, prune, publish, r, rb, rebuild, remove,
repo, restart, rm, root, run-script, s, se, search, set,
show, shrinkwrap, star, stars, start, stop, t, tag, team,
test, tst, un, uninstall, unlink, unpublish, unstar, up,
update, upgrade, v, verison, version, view, whoami
npm <cmd> -h quick help on <cmd>
npm -l display full usage info
npm faq commonly asked questions
npm help <term> search for help on <term>
npm help npm involved overview
Specify configs in the ini-formatted file:
/home/nvbn/.npmrc
or on the command line via: npm <command> --key value
Config info can be viewed via: npm help config
npm@2.14.7 /opt/node/lib/node_modules/npm
'''
@pytest.mark.parametrize('script', [
'npm urgrdae',
'npm urgrade -g',
'npm -f urgrade -g',
'npm urg'])
def test_match(script):
assert match(Command(script, stdout))
@pytest.mark.parametrize('script, stdout', [
('npm urgrade', ''),
('npm', stdout),
('test urgrade', stdout),
('npm -e', stdout)])
def test_not_match(script, stdout):
assert not match(Command(script, stdout))
@pytest.mark.parametrize('script, result', [
('npm urgrade', 'npm upgrade'),
('npm -g isntall gulp', 'npm -g install gulp'),
('npm isntall -g gulp', 'npm install -g gulp')])
def test_get_new_command(script, result):
assert get_new_command(Command(script, stdout)) == result

View File

@@ -1,49 +1,31 @@
import pytest
from thefuck.rules.open import is_arg_url, match, get_new_command
from thefuck.rules.open import match, get_new_command
from tests.utils import Command
@pytest.fixture
def stderr(script):
return 'The file {} does not exist.\n'.format(script.split(' ', 1)[1])
@pytest.mark.parametrize('command', [
Command(script='open foo.com'),
Command(script='open foo.ly'),
Command(script='open foo.org'),
Command(script='open foo.net'),
Command(script='open foo.se'),
Command(script='open foo.io'),
Command(script='xdg-open foo.com'),
Command(script='gnome-open foo.com'),
Command(script='kde-open foo.com')])
def test_match(command):
assert match(command)
@pytest.mark.parametrize('script', [
'open foo.com',
'open foo.edu',
'open foo.info',
'open foo.io',
'open foo.ly',
'open foo.me',
'open foo.net',
'open foo.org',
'open foo.se',
'open www.foo.ru'])
def test_is_arg_url(script):
assert is_arg_url(Command(script))
@pytest.mark.parametrize('script', ['open foo', 'open bar.txt', 'open egg.doc'])
def test_not_is_arg_url(script):
assert not is_arg_url(Command(script))
@pytest.mark.parametrize('script', [
'open foo.com',
'xdg-open foo.com',
'gnome-open foo.com',
'kde-open foo.com',
'open nonest'])
def test_match(script, stderr):
assert match(Command(script, stderr=stderr))
@pytest.mark.parametrize('script, new_command', [
('open foo.io', ['open http://foo.io']),
('xdg-open foo.io', ['xdg-open http://foo.io']),
('gnome-open foo.io', ['gnome-open http://foo.io']),
('kde-open foo.io', ['kde-open http://foo.io']),
('open nonest', ['touch nonest && open nonest',
'mkdir nonest && open nonest'])])
def test_get_new_command(script, new_command, stderr):
assert get_new_command(Command(script, stderr=stderr)) == new_command
@pytest.mark.parametrize('command, new_command', [
(Command('open foo.com'), 'open http://foo.com'),
(Command('open foo.ly'), 'open http://foo.ly'),
(Command('open foo.org'), 'open http://foo.org'),
(Command('open foo.net'), 'open http://foo.net'),
(Command('open foo.se'), 'open http://foo.se'),
(Command('open foo.io'), 'open http://foo.io'),
(Command('xdg-open foo.io'), 'xdg-open http://foo.io'),
(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) == new_command

View File

@@ -1,43 +0,0 @@
import pytest
from thefuck.rules.path_from_history import match, get_new_command
from tests.utils import Command
@pytest.fixture(autouse=True)
def history(mocker):
return mocker.patch(
'thefuck.rules.path_from_history.get_valid_history_without_current',
return_value=['cd /opt/java', 'ls ~/work/project/'])
@pytest.fixture(autouse=True)
def path_exists(mocker):
path_mock = mocker.patch('thefuck.rules.path_from_history.Path')
exists_mock = path_mock.return_value.expanduser.return_value.exists
exists_mock.return_value = True
return exists_mock
@pytest.mark.parametrize('script, stderr', [
('ls project', 'no such file or directory: project'),
('cd project', "can't cd to project"),
])
def test_match(script, stderr):
assert match(Command(script, stderr=stderr))
@pytest.mark.parametrize('script, stderr', [
('myapp cats', 'no such file or directory: project'),
('cd project', ""),
])
def test_not_match(script, stderr):
assert not match(Command(script, stderr=stderr))
@pytest.mark.parametrize('script, stderr, result', [
('ls project', 'no such file or directory: project', 'ls ~/work/project'),
('cd java', "can't cd to java", 'cd /opt/java'),
])
def test_get_new_command(script, stderr, result):
new_command = get_new_command(Command(script, stderr=stderr))
assert new_command[0] == result

View File

@@ -1,101 +0,0 @@
from io import BytesIO
import pytest
from thefuck.rules.port_already_in_use import match, get_new_command
from tests.utils import Command
outputs = [
'''
DE 70% 1/1 build modulesevents.js:141
throw er; // Unhandled 'error' event
^
Error: listen EADDRINUSE 127.0.0.1:8080
at Object.exports._errnoException (util.js:873:11)
at exports._exceptionWithHostPort (util.js:896:20)
at Server._listen2 (net.js:1250:14)
at listen (net.js:1286:10)
at net.js:1395:9
at GetAddrInfoReqWrap.asyncCallback [as callback] (dns.js:64:16)
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:83:10)
''',
'''
[6:40:01 AM] <START> Building Dependency Graph
[6:40:01 AM] <START> Crawling File System
ERROR Packager can't listen on port 8080
Most likely another process is already using this port
Run the following command to find out which process:
lsof -n -i4TCP:8080
You can either shut down the other process:
kill -9 <PID>
or run packager on different port.
''',
'''
Traceback (most recent call last):
File "/usr/lib/python3.5/runpy.py", line 184, in _run_module_as_main
"__main__", mod_spec)
File "/usr/lib/python3.5/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/home/nvbn/exp/code_view/server/code_view/main.py", line 14, in <module>
web.run_app(app)
File "/home/nvbn/.virtualenvs/code_view/lib/python3.5/site-packages/aiohttp/web.py", line 310, in run_app
backlog=backlog))
File "/usr/lib/python3.5/asyncio/base_events.py", line 373, in run_until_complete
return future.result()
File "/usr/lib/python3.5/asyncio/futures.py", line 274, in result
raise self._exception
File "/usr/lib/python3.5/asyncio/tasks.py", line 240, in _step
result = coro.send(None)
File "/usr/lib/python3.5/asyncio/base_events.py", line 953, in create_server
% (sa, err.strerror.lower()))
OSError: [Errno 98] error while attempting to bind on address ('0.0.0.0', 8080): address already in use
Task was destroyed but it is pending!
task: <Task pending coro=<RedisProtocol._reader_coroutine() running at /home/nvbn/.virtualenvs/code_view/lib/python3.5/site-packages/asyncio_redis/protocol.py:921> wait_for=<Future pending cb=[Task._wakeup()]>>
'''
]
lsof_stdout = b'''COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 18233 nvbn 16u IPv4 557134 0t0 TCP localhost:http-alt (LISTEN)
'''
@pytest.fixture(autouse=True)
def lsof(mocker):
patch = mocker.patch('thefuck.rules.port_already_in_use.Popen')
patch.return_value.stdout = BytesIO(lsof_stdout)
return patch
@pytest.mark.usefixtures('no_memoize')
@pytest.mark.parametrize(
'command',
[Command('./app', stdout=output) for output in outputs]
+ [Command('./app', stderr=output) for output in outputs])
def test_match(command):
assert match(command)
@pytest.mark.usefixtures('no_memoize')
@pytest.mark.parametrize('command, lsof_output', [
(Command('./app'), lsof_stdout),
(Command('./app', stdout=outputs[1]), b''),
(Command('./app', stderr=outputs[2]), b'')])
def test_not_match(lsof, command, lsof_output):
lsof.return_value.stdout = BytesIO(lsof_output)
assert not match(command)
@pytest.mark.parametrize(
'command',
[Command('./app', stdout=output) for output in outputs]
+ [Command('./app', stderr=output) for output in outputs])
def test_get_new_command(command):
assert get_new_command(command) == 'kill 18233 && ./app'

View File

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

View File

@@ -1,46 +0,0 @@
import pytest
from thefuck.rules.react_native_command_unrecognized import match, \
get_new_command
from tests.utils import Command
stderr = 'Command `{}` unrecognized'.format
stdout = '''
Usage: react-native <command>
Commands:
- start: starts the webserver
- bundle: builds the javascript bundle for offline use
- unbundle: builds javascript as "unbundle" for offline use
- new-library: generates a native library bridge
- android: generates an Android project for your app
- run-android: builds your app and starts it on a connected Android emulator or device
- log-android: print Android logs
- run-ios: builds your app and starts it on iOS simulator
- log-ios: print iOS logs
- upgrade: upgrade your app's template files to the latest version; run this after updating the react-native version in your package.json and running npm install
- link: link a library
'''
@pytest.mark.parametrize('command', [
Command('react-native star', stderr=stderr('star')),
Command('react-native android-logs', stderr=stderr('android-logs'))])
def test_match(command):
assert match(command)
@pytest.mark.parametrize('command', [
Command('gradle star', stderr=stderr('star')),
Command('react-native start')])
def test_not_match(command):
assert not match(command)
@pytest.mark.parametrize('command, result', [
(Command('react-native star', stdout, stderr('star')),
'react-native start'),
(Command('react-native logsandroid -f', stdout, stderr('logsandroid')),
'react-native log-android -f')])
def test_get_new_command(command, result):
assert get_new_command(command)[0] == result

View File

@@ -1,17 +0,0 @@
import pytest
from thefuck.rules.remove_trailing_cedilla import match, get_new_command, CEDILLA
from tests.utils import Command
@pytest.mark.parametrize('command', [
Command(script='wrong' + CEDILLA),
Command(script='wrong with args' + CEDILLA)])
def test_match(command):
assert match(command)
@pytest.mark.parametrize('command, new_command', [
(Command('wrong' + CEDILLA), 'wrong'),
(Command('wrong with args' + CEDILLA), 'wrong with args')])
def test_get_new_command(command, new_command):
assert get_new_command(command) == new_command

View File

@@ -7,25 +7,25 @@ from tests.utils import Command
Command('rm foo', stderr='rm: foo: is a directory'),
Command('rm foo', stderr='rm: foo: Is a directory'),
Command('hdfs dfs -rm foo', stderr='rm: `foo`: Is a directory'),
Command('./bin/hdfs dfs -rm foo', stderr='rm: `foo`: Is a directory'),
])
Command('./bin/hdfs dfs -rm foo', stderr='rm: `foo`: Is a directory')
])
def test_match(command):
assert match(command)
@pytest.mark.parametrize('command', [
Command('rm foo'),
Command('rm foo'),
Command('hdfs dfs -rm foo'),
Command('./bin/hdfs dfs -rm foo'),
Command(),
])
Command('./bin/hdfs dfs -rm foo'),
Command()])
def test_not_match(command):
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'),
])
(Command('hdfs dfs -rm foo'), 'hdfs dfs -rm -r foo')])
def test_get_new_command(command, new_command):
assert get_new_command(command) == new_command

View File

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

View File

@@ -1,46 +0,0 @@
import pytest
from thefuck.rules.scm_correction import match, get_new_command
from tests.utils import Command
@pytest.fixture
def get_actual_scm_mock(mocker):
return mocker.patch('thefuck.rules.scm_correction._get_actual_scm',
return_value=None)
@pytest.mark.parametrize('script, stderr, actual_scm', [
('git log', 'fatal: Not a git repository '
'(or any of the parent directories): .git',
'hg'),
('hg log', "abort: no repository found in '/home/nvbn/exp/thefuck' "
"(.hg not found)!",
'git')])
def test_match(get_actual_scm_mock, script, stderr, actual_scm):
get_actual_scm_mock.return_value = actual_scm
assert match(Command(script, stderr=stderr))
@pytest.mark.parametrize('script, stderr, actual_scm', [
('git log', '', 'hg'),
('git log', 'fatal: Not a git repository '
'(or any of the parent directories): .git',
None),
('hg log', "abort: no repository found in '/home/nvbn/exp/thefuck' "
"(.hg not found)!",
None),
('not-scm log', "abort: no repository found in '/home/nvbn/exp/thefuck' "
"(.hg not found)!",
'git')])
def test_not_match(get_actual_scm_mock, script, stderr, actual_scm):
get_actual_scm_mock.return_value = actual_scm
assert not match(Command(script, stderr=stderr))
@pytest.mark.parametrize('script, actual_scm, result', [
('git log', 'hg', 'hg log'),
('hg log', 'git', 'git log')])
def test_get_new_command(get_actual_scm_mock, script, actual_scm, result):
get_actual_scm_mock.return_value = actual_scm
new_command = get_new_command(Command(script))
assert new_command == result

View File

@@ -18,11 +18,11 @@ def test_match(sed_unterminated_s):
def test_get_new_command(sed_unterminated_s):
assert (get_new_command(Command('sed -e s/foo/bar', stderr=sed_unterminated_s))
== 'sed -e s/foo/bar/')
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))
== r"sed -e 's/\/foo/bar/'")
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/")
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)) \
== 'sed -es/foo/bar/'
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)) \
== r"sed -e s/foo/bar/ -es/baz/quz/"

View File

@@ -1,5 +1,6 @@
import os
import pytest
from mock import Mock
from thefuck.rules.ssh_known_hosts import match, get_new_command,\
side_effect
from tests.utils import Command
@@ -52,7 +53,6 @@ def test_match(ssh_error):
assert not match(Command('ssh'))
@pytest.mark.skipif(os.name == 'nt', reason='Skip if testing on Windows')
def test_side_effect(ssh_error):
errormsg, path, reset, known_hosts = ssh_error
command = Command('ssh user@host', stderr=errormsg)

View File

@@ -19,13 +19,11 @@ def test_match(stderr, stdout):
def test_not_match():
assert not match(Command())
assert not match(Command(script='sudo ls', stderr='Permission denied'))
@pytest.mark.parametrize('before, after', [
('ls', 'sudo ls'),
('echo a > b', 'sudo sh -c "echo a > b"'),
('echo "a" >> b', 'sudo sh -c "echo \\"a\\" >> b"'),
('mkdir && touch a', 'sudo sh -c "mkdir && touch a"')])
('echo "a" >> b', 'sudo sh -c "echo \\"a\\" >> b"')])
def test_get_new_command(before, after):
assert get_new_command(Command(before)) == after

View File

@@ -1,39 +0,0 @@
import pytest
from thefuck.rules.sudo_command_from_user_path import match, get_new_command
from tests.utils import Command
stderr = 'sudo: {}: command not found'
@pytest.fixture(autouse=True)
def which(mocker):
return mocker.patch('thefuck.rules.sudo_command_from_user_path.which',
return_value='/usr/bin/app')
@pytest.mark.parametrize('script, stderr', [
('sudo npm install -g react-native-cli', stderr.format('npm')),
('sudo -u app appcfg update .', stderr.format('appcfg'))])
def test_match(script, stderr):
assert match(Command(script, stderr=stderr))
@pytest.mark.parametrize('script, stderr, which_result', [
('npm --version', stderr.format('npm'), '/usr/bin/npm'),
('sudo npm --version', '', '/usr/bin/npm'),
('sudo npm --version', stderr.format('npm'), None)])
def test_not_match(which, script, stderr, which_result):
which.return_value = which_result
assert not match(Command(script, stderr=stderr))
@pytest.mark.parametrize('script, stderr, result', [
('sudo npm install -g react-native-cli',
stderr.format('npm'),
'sudo env "PATH=$PATH" npm install -g react-native-cli'),
('sudo -u app appcfg update .',
stderr.format('appcfg'),
'sudo -u app env "PATH=$PATH" appcfg update .')])
def test_get_new_command(script, stderr, result):
assert get_new_command(Command(script, stderr=stderr)) == result

View File

@@ -1,3 +1,4 @@
import pytest
from thefuck.rules.systemctl import match, get_new_command
from tests.utils import Command

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