mirror of
				https://github.com/nvbn/thefuck.git
				synced 2025-11-03 08:32:03 +00:00 
			
		
		
		
	Compare commits
	
		
			586 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					a65f90813b | ||
| 
						 | 
					a778ea6203 | ||
| 
						 | 
					03a828d586 | ||
| 
						 | 
					4a0d71c1c4 | ||
| 
						 | 
					a6f63c0568 | ||
| 
						 | 
					d1b9492085 | ||
| 
						 | 
					993a661c60 | ||
| 
						 | 
					bc9121cb13 | ||
| 
						 | 
					7db140c456 | ||
| 
						 | 
					e313ff73a9 | ||
| 
						 | 
					8c62706db4 | ||
| 
						 | 
					6baa7f650e | ||
| 
						 | 
					4ae32cf4ee | ||
| 
						 | 
					385746850e | ||
| 
						 | 
					4f87141f0c | ||
| 
						 | 
					dbedcc7aa6 | ||
| 
						 | 
					e0b5d47fa5 | ||
| 
						 | 
					ca44ee0640 | ||
| 
						 | 
					892e8a8e65 | ||
| 
						 | 
					a947259eef | ||
| 
						 | 
					785cb83ff3 | ||
| 
						 | 
					aec8fe3233 | ||
| 
						 | 
					c21dbd2be3 | ||
| 
						 | 
					6173913291 | ||
| 
						 | 
					6f0d1e287d | ||
| 
						 | 
					756044e087 | ||
| 
						 | 
					ddd8788353 | ||
| 
						 | 
					76c0e7bc70 | ||
| 
						 | 
					4865bdd81f | ||
| 
						 | 
					fa169c686c | ||
| 
						 | 
					9cae0bffff | ||
| 
						 | 
					b519d317f7 | ||
| 
						 | 
					5b420204c9 | ||
| 
						 | 
					07005b591a | ||
| 
						 | 
					cb99e42e02 | ||
| 
						 | 
					51f77964c6 | ||
| 
						 | 
					30b1c44f91 | ||
| 
						 | 
					af28f0334a | ||
| 
						 | 
					5ee5439c1e | ||
| 
						 | 
					cf006dac2c | ||
| 
						 | 
					5b535077bf | ||
| 
						 | 
					cf3acbfa2e | ||
| 
						 | 
					4d714994a3 | ||
| 
						 | 
					02f717a0e8 | ||
| 
						 | 
					8f4f2f03a7 | ||
| 
						 | 
					feb36ede5c | ||
| 
						 | 
					16a440cb9d | ||
| 
						 | 
					10b20574d1 | ||
| 
						 | 
					91fceb401a | ||
| 
						 | 
					4b79e23ba7 | ||
| 
						 | 
					f915a6ed0c | ||
| 
						 | 
					a964af7e95 | ||
| 
						 | 
					77fc021a6c | ||
| 
						 | 
					4822ceb87a | ||
| 
						 | 
					b2947aba8d | ||
| 
						 | 
					d2e0a19aae | ||
| 
						 | 
					0c84eefa55 | ||
| 
						 | 
					8bd6c5da67 | ||
| 
						 | 
					ce6b82c92d | ||
| 
						 | 
					5dbbb3b1ed | ||
| 
						 | 
					db4b37910d | ||
| 
						 | 
					2b88ea11ea | ||
| 
						 | 
					db7dffdb44 | ||
| 
						 | 
					92f3c8fb52 | ||
| 
						 | 
					7c4f0d2e55 | ||
| 
						 | 
					d05eb0a6dc | ||
| 
						 | 
					cf352fd788 | ||
| 
						 | 
					3c1cce6bd2 | ||
| 
						 | 
					5d3a727d1a | ||
| 
						 | 
					ea87d55771 | ||
| 
						 | 
					aa6b18d0ce | ||
| 
						 | 
					934eeaf4fc | ||
| 
						 | 
					3ad8d52a84 | ||
| 
						 | 
					bb5c7c576f | ||
| 
						 | 
					17c3935078 | ||
| 
						 | 
					a734b94fec | ||
| 
						 | 
					7bf405e9c3 | ||
| 
						 | 
					c3bcdd7dee | ||
| 
						 | 
					ad53023860 | ||
| 
						 | 
					8938323229 | ||
| 
						 | 
					92133f77d6 | ||
| 
						 | 
					64eaf96eb8 | ||
| 
						 | 
					c9264aff10 | ||
| 
						 | 
					9660ec7813 | ||
| 
						 | 
					9ac47d8f78 | ||
| 
						 | 
					6e2b82911f | ||
| 
						 | 
					af9d34c299 | ||
| 
						 | 
					bcc11219e6 | ||
| 
						 | 
					495a66088b | ||
| 
						 | 
					4fe64e3dfa | ||
| 
						 | 
					cae76eb55f | ||
| 
						 | 
					afd2ed4e51 | ||
| 
						 | 
					1a4d74d487 | ||
| 
						 | 
					0bd3e85e08 | ||
| 
						 | 
					faeeef7666 | ||
| 
						 | 
					4d65d6a1df | ||
| 
						 | 
					cfa51506fb | ||
| 
						 | 
					5df350254e | ||
| 
						 | 
					612c393ec4 | ||
| 
						 | 
					4d89b3499e | ||
| 
						 | 
					070bb2ff28 | ||
| 
						 | 
					71025dff17 | ||
| 
						 | 
					621b455334 | ||
| 
						 | 
					176924c18d | ||
| 
						 | 
					1f75fc1ea9 | ||
| 
						 | 
					46cb87615e | ||
| 
						 | 
					c63e0d1582 | ||
| 
						 | 
					a3eb124033 | ||
| 
						 | 
					a1f115eb19 | ||
| 
						 | 
					56851e8d31 | ||
| 
						 | 
					a8c3c2d728 | ||
| 
						 | 
					844d3af8ae | ||
| 
						 | 
					a2693bd737 | ||
| 
						 | 
					ae3e231a5f | ||
| 
						 | 
					21bb439d7c | ||
| 
						 | 
					efcf7da7db | ||
| 
						 | 
					5f79217e97 | ||
| 
						 | 
					fdfbfc80c0 | ||
| 
						 | 
					b09a4e394e | ||
| 
						 | 
					34973fe97e | ||
| 
						 | 
					379d2953c9 | ||
| 
						 | 
					065b350ada | ||
| 
						 | 
					ca787a1cba | ||
| 
						 | 
					4c2fc490f2 | ||
| 
						 | 
					0c2083485d | ||
| 
						 | 
					bc78c83224 | ||
| 
						 | 
					b2a5009116 | ||
| 
						 | 
					087584a1e0 | ||
| 
						 | 
					b6b15bf0d1 | ||
| 
						 | 
					a169575b0f | ||
| 
						 | 
					fbea803a9b | ||
| 
						 | 
					51415a5cb1 | ||
| 
						 | 
					237bc57999 | ||
| 
						 | 
					2af65071d8 | ||
| 
						 | 
					c93b547624 | ||
| 
						 | 
					837ca73f50 | ||
| 
						 | 
					a3b2e6872b | ||
| 
						 | 
					29ed1800e1 | ||
| 
						 | 
					965c05bfdf | ||
| 
						 | 
					a7d1c725e4 | ||
| 
						 | 
					99e828d15d | ||
| 
						 | 
					ae2b767a4d | ||
| 
						 | 
					3893e0cdca | ||
| 
						 | 
					2988e4871f | ||
| 
						 | 
					d5e333b727 | ||
| 
						 | 
					1755bcd1b5 | ||
| 
						 | 
					f773b57bea | ||
| 
						 | 
					5866ea8433 | ||
| 
						 | 
					729508e581 | ||
| 
						 | 
					1b7c8b5498 | ||
| 
						 | 
					9b6cd0cd7b | ||
| 
						 | 
					77ea630d84 | ||
| 
						 | 
					917c6ac887 | ||
| 
						 | 
					8bea63eb23 | ||
| 
						 | 
					2bf21d9f0e | ||
| 
						 | 
					e2f66cb26b | ||
| 
						 | 
					ff1ee979f0 | ||
| 
						 | 
					25343dbfb4 | ||
| 
						 | 
					ea3671f98c | ||
| 
						 | 
					4584903beb | ||
| 
						 | 
					990ba57159 | ||
| 
						 | 
					16c110823d | ||
| 
						 | 
					01418526b4 | ||
| 
						 | 
					d2845a0d2e | ||
| 
						 | 
					2c1666abc4 | ||
| 
						 | 
					42853f41bb | ||
| 
						 | 
					5f11ecc4f8 | ||
| 
						 | 
					4bd4c0f731 | ||
| 
						 | 
					b8c5433dc4 | ||
| 
						 | 
					e2883430bc | ||
| 
						 | 
					a4b690369c | ||
| 
						 | 
					6bbd680e56 | ||
| 
						 | 
					e5f8e9c0de | ||
| 
						 | 
					ebf1ea88f5 | ||
| 
						 | 
					d2b0b6e8ec | ||
| 
						 | 
					561eb12c08 | ||
| 
						 | 
					ed38fedf26 | ||
| 
						 | 
					15bcd7f03f | ||
| 
						 | 
					9e39bcd55c | ||
| 
						 | 
					cfa73f10d6 | ||
| 
						 | 
					c3709682d5 | ||
| 
						 | 
					96f7e53aa2 | ||
| 
						 | 
					d1f55603fe | ||
| 
						 | 
					f74bbb7a9a | ||
| 
						 | 
					d6c2c7266d | ||
| 
						 | 
					51839e65cd | ||
| 
						 | 
					d5ae3a6b41 | ||
| 
						 | 
					9f421a17e5 | ||
| 
						 | 
					9d9820676a | ||
| 
						 | 
					5ec4909d2f | ||
| 
						 | 
					c6d2766553 | ||
| 
						 | 
					c6af8409d9 | ||
| 
						 | 
					95e7d00aec | ||
| 
						 | 
					cdccf1881e | ||
| 
						 | 
					db6053b301 | ||
| 
						 | 
					183b70c8b8 | ||
| 
						 | 
					5e0cc8c703 | ||
| 
						 | 
					1aa2ec1795 | ||
| 
						 | 
					0c98053f74 | ||
| 
						 | 
					17b2fba48d | ||
| 
						 | 
					43886c38ff | ||
| 
						 | 
					9070748a86 | ||
| 
						 | 
					61de6f4a51 | ||
| 
						 | 
					d102af41d9 | ||
| 
						 | 
					b7002bb9f9 | ||
| 
						 | 
					18b4f5df6a | ||
| 
						 | 
					28153db4a8 | ||
| 
						 | 
					047a1a6072 | ||
| 
						 | 
					69db5c70e6 | ||
| 
						 | 
					fa1edd4bae | ||
| 
						 | 
					333c4b2a3f | ||
| 
						 | 
					b1f10642fa | ||
| 
						 | 
					047efd5575 | ||
| 
						 | 
					f604756cb7 | ||
| 
						 | 
					a27115bff1 | ||
| 
						 | 
					5d00b3bc25 | ||
| 
						 | 
					0cf4f5e8b0 | ||
| 
						 | 
					41707b80c6 | ||
| 
						 | 
					3a39deb485 | ||
| 
						 | 
					d4bc8cebf1 | ||
| 
						 | 
					6daf687237 | ||
| 
						 | 
					2207dd2668 | ||
| 
						 | 
					d1ab08a797 | ||
| 
						 | 
					51e89a36ef | ||
| 
						 | 
					39f7cc37eb | ||
| 
						 | 
					251b69b5a0 | ||
| 
						 | 
					8b1f078e27 | ||
| 
						 | 
					a47e84fa6b | ||
| 
						 | 
					bcab700215 | ||
| 
						 | 
					4fb99fd7a8 | ||
| 
						 | 
					bb5f6bb705 | ||
| 
						 | 
					d92765d5df | ||
| 
						 | 
					d8de5cfd20 | ||
| 
						 | 
					d73b14ce4b | ||
| 
						 | 
					04b83cf7e8 | ||
| 
						 | 
					019f0abf67 | ||
| 
						 | 
					c8d3dcd1bf | ||
| 
						 | 
					4f5b382df4 | ||
| 
						 | 
					77ad68b04b | ||
| 
						 | 
					6b0311181d | ||
| 
						 | 
					48808f93ac | ||
| 
						 | 
					7ce4307c87 | ||
| 
						 | 
					f7f0660114 | ||
| 
						 | 
					46f2351907 | ||
| 
						 | 
					e9de01fa41 | ||
| 
						 | 
					9b260eb239 | ||
| 
						 | 
					f20d4dbf85 | ||
| 
						 | 
					4af7dc2748 | ||
| 
						 | 
					c8e9606c7d | ||
| 
						 | 
					d71b9c2e62 | ||
| 
						 | 
					60497b9d04 | ||
| 
						 | 
					619af2638a | ||
| 
						 | 
					a1f15bfe5f | ||
| 
						 | 
					ce959b2a8b | ||
| 
						 | 
					3cc4940842 | ||
| 
						 | 
					470c0ef699 | ||
| 
						 | 
					4f95b3365a | ||
| 
						 | 
					bbfd53d718 | ||
| 
						 | 
					28d078708b | ||
| 
						 | 
					778d5f3e6e | ||
| 
						 | 
					c5acee54ea | ||
| 
						 | 
					c3e9c1bfc1 | ||
| 
						 | 
					6c25b33b9e | ||
| 
						 | 
					052f415d94 | ||
| 
						 | 
					3438d6dde7 | ||
| 
						 | 
					af0fe66a9f | ||
| 
						 | 
					fe07fcaa62 | ||
| 
						 | 
					b5dc7aab6d | ||
| 
						 | 
					a2ec5aa3ff | ||
| 
						 | 
					0b2bda9e85 | ||
| 
						 | 
					68c882cf1a | ||
| 
						 | 
					abe8fb84c6 | ||
| 
						 | 
					86b17eb570 | ||
| 
						 | 
					dcc0ce7ff3 | ||
| 
						 | 
					fee874cddc | ||
| 
						 | 
					2ce1c6bf90 | ||
| 
						 | 
					9b129fad08 | ||
| 
						 | 
					20adefbe7d | ||
| 
						 | 
					52ef1fa47d | ||
| 
						 | 
					94f8652175 | ||
| 
						 | 
					abe287a52b | ||
| 
						 | 
					60e19a054a | ||
| 
						 | 
					45add1e3d6 | ||
| 
						 | 
					934870f650 | ||
| 
						 | 
					738cc0c9a8 | ||
| 
						 | 
					cb6f964a30 | ||
| 
						 | 
					9c9a7343de | ||
| 
						 | 
					3803452980 | ||
| 
						 | 
					a19833d0c7 | ||
| 
						 | 
					084b907ac0 | ||
| 
						 | 
					bd5cf38271 | ||
| 
						 | 
					3c3d17e0ea | ||
| 
						 | 
					2f353498de | ||
| 
						 | 
					f0f49c1865 | ||
| 
						 | 
					20fff3142c | ||
| 
						 | 
					6e22b9ec6c | ||
| 
						 | 
					d53240b777 | ||
| 
						 | 
					cab933e7e6 | ||
| 
						 | 
					8b05f6d46f | ||
| 
						 | 
					ec64fbd5ea | ||
| 
						 | 
					4f9fb796c4 | ||
| 
						 | 
					be744f20ba | ||
| 
						 | 
					1b12cd85e9 | ||
| 
						 | 
					47df80f6b8 | ||
| 
						 | 
					a0ef0efe46 | ||
| 
						 | 
					25662ad737 | ||
| 
						 | 
					42b344676e | ||
| 
						 | 
					a3e1cb6718 | ||
| 
						 | 
					f249098336 | ||
| 
						 | 
					c3b1ba7637 | ||
| 
						 | 
					b65a9a0a4f | ||
| 
						 | 
					29c1d1efcf | ||
| 
						 | 
					0560f4ba8e | ||
| 
						 | 
					f9aa0e7c6b | ||
| 
						 | 
					b18a049886 | ||
| 
						 | 
					9192b555b5 | ||
| 
						 | 
					d750d3d6d1 | ||
| 
						 | 
					3ad953001d | ||
| 
						 | 
					3b4b87d8ed | ||
| 
						 | 
					6c3d67763a | ||
| 
						 | 
					959680d24d | ||
| 
						 | 
					b0adc7f2ca | ||
| 
						 | 
					fc05364233 | ||
| 
						 | 
					ad3db4ac67 | ||
| 
						 | 
					4a7b335d7c | ||
| 
						 | 
					465f6191b0 | ||
| 
						 | 
					b2836319ad | ||
| 
						 | 
					b3e9b36bd1 | ||
| 
						 | 
					ae2949cfa2 | ||
| 
						 | 
					1bb04b41eb | ||
| 
						 | 
					acd0b3e024 | ||
| 
						 | 
					7c5676491a | ||
| 
						 | 
					8feb722ed0 | ||
| 
						 | 
					c3ea2fd0c7 | ||
| 
						 | 
					b55464b2ea | ||
| 
						 | 
					8ddb61ae89 | ||
| 
						 | 
					fe91008a9c | ||
| 
						 | 
					7f777213c5 | ||
| 
						 | 
					89f868c115 | ||
| 
						 | 
					81f6a25abc | ||
| 
						 | 
					cc9af78787 | ||
| 
						 | 
					1fc3f1b5bf | ||
| 
						 | 
					45574d06c9 | ||
| 
						 | 
					dc23d67a42 | ||
| 
						 | 
					2fea0d4c60 | ||
| 
						 | 
					8c8abca8d5 | ||
| 
						 | 
					bd6ee68c03 | ||
| 
						 | 
					16533e85a7 | ||
| 
						 | 
					b3a19fe439 | ||
| 
						 | 
					959b96cf6e | ||
| 
						 | 
					f20311fa89 | ||
| 
						 | 
					a4c391096a | ||
| 
						 | 
					e71a3e0cdb | ||
| 
						 | 
					2d995d464f | ||
| 
						 | 
					280751b36e | ||
| 
						 | 
					0a6a3db65d | ||
| 
						 | 
					ecfc180280 | ||
| 
						 | 
					dae58211ba | ||
| 
						 | 
					5e9b2c56da | ||
| 
						 | 
					192ab0bfb0 | ||
| 
						 | 
					372e983459 | ||
| 
						 | 
					346cb99217 | ||
| 
						 | 
					bbfedb861f | ||
| 
						 | 
					f5b0e96747 | ||
| 
						 | 
					12a33f56bc | ||
| 
						 | 
					590fdba2aa | ||
| 
						 | 
					f374142bf8 | ||
| 
						 | 
					540ff7e16d | ||
| 
						 | 
					806dad18bf | ||
| 
						 | 
					8b416f269f | ||
| 
						 | 
					5e44fb22be | ||
| 
						 | 
					5389d0c106 | ||
| 
						 | 
					c970f190d2 | ||
| 
						 | 
					8f25c95f06 | ||
| 
						 | 
					4a48108c69 | ||
| 
						 | 
					f5e8fe954e | ||
| 
						 | 
					3da26192cb | ||
| 
						 | 
					11c133523a | ||
| 
						 | 
					4b3e6a1448 | ||
| 
						 | 
					09d9f63c98 | ||
| 
						 | 
					e8883429c6 | ||
| 
						 | 
					c1b67f2514 | ||
| 
						 | 
					3d6e7b17db | ||
| 
						 | 
					75ef866214 | ||
| 
						 | 
					5021d16cea | ||
| 
						 | 
					af259846b4 | ||
| 
						 | 
					213791d3c2 | ||
| 
						 | 
					71dc2666cc | ||
| 
						 | 
					3e66a294c4 | ||
| 
						 | 
					3e8db28a73 | ||
| 
						 | 
					6e886c6b4f | ||
| 
						 | 
					3fc2efee0f | ||
| 
						 | 
					cb14aded6b | ||
| 
						 | 
					08af616e3d | ||
| 
						 | 
					dfa22bc92b | ||
| 
						 | 
					eb17e696c3 | ||
| 
						 | 
					b8ce95ad68 | ||
| 
						 | 
					1173f9f59c | ||
| 
						 | 
					a8dbc48fd4 | ||
| 
						 | 
					4a27595e97 | ||
| 
						 | 
					bf80d97062 | ||
| 
						 | 
					1fb6dd925b | ||
| 
						 | 
					b2be0b3cad | ||
| 
						 | 
					122541b7d8 | ||
| 
						 | 
					488c1dad79 | ||
| 
						 | 
					c3fe7e5e68 | ||
| 
						 | 
					3d56204f92 | ||
| 
						 | 
					293f16c3c8 | ||
| 
						 | 
					7339a97b90 | ||
| 
						 | 
					f3525e9fe0 | ||
| 
						 | 
					df4d2cc88d | ||
| 
						 | 
					382eb8b86c | ||
| 
						 | 
					105d3d8137 | ||
| 
						 | 
					191a2e588d | ||
| 
						 | 
					f964c65f16 | ||
| 
						 | 
					dd0667ea8f | ||
| 
						 | 
					4392872568 | ||
| 
						 | 
					f7ce0fda25 | ||
| 
						 | 
					2f9db24ed1 | ||
| 
						 | 
					4ae2e9bbc4 | ||
| 
						 | 
					5cfd493d05 | ||
| 
						 | 
					22eac045c8 | ||
| 
						 | 
					cdd5f21e88 | ||
| 
						 | 
					8cc19daaaa | ||
| 
						 | 
					8bf4182f86 | ||
| 
						 | 
					6df772ba05 | ||
| 
						 | 
					e2e8b6fc86 | ||
| 
						 | 
					faa7ee6030 | ||
| 
						 | 
					6321f25533 | ||
| 
						 | 
					9a02e821cd | ||
| 
						 | 
					4129ff2717 | ||
| 
						 | 
					ea6600be8b | ||
| 
						 | 
					b0195a8748 | ||
| 
						 | 
					fc35ee657e | ||
| 
						 | 
					50207d8180 | ||
| 
						 | 
					b6855587fa | ||
| 
						 | 
					45d849b1ac | ||
| 
						 | 
					d8027bb499 | ||
| 
						 | 
					4932122f71 | ||
| 
						 | 
					8a4f4eea45 | ||
| 
						 | 
					ff8d61a4fb | ||
| 
						 | 
					6dcf9a3a14 | ||
| 
						 | 
					8b62959fe3 | ||
| 
						 | 
					21103d1b50 | ||
| 
						 | 
					61937e9e8f | ||
| 
						 | 
					5d74344994 | ||
| 
						 | 
					12394ca842 | ||
| 
						 | 
					ebe53f0d18 | ||
| 
						 | 
					0c283ff2b8 | ||
| 
						 | 
					bc78f1bbee | ||
| 
						 | 
					f2a7364e8c | ||
| 
						 | 
					9103c1ffd5 | ||
| 
						 | 
					edf77a90ad | ||
| 
						 | 
					27c14a44af | ||
| 
						 | 
					514bb7df81 | ||
| 
						 | 
					3bd2c8d4c8 | ||
| 
						 | 
					e5ce000399 | ||
| 
						 | 
					9fc2bc904c | ||
| 
						 | 
					51f1f44162 | ||
| 
						 | 
					b0702d309f | ||
| 
						 | 
					2b750bac8b | ||
| 
						 | 
					8c02658a32 | ||
| 
						 | 
					301de75aee | ||
| 
						 | 
					0d86fce9be | ||
| 
						 | 
					7be71a0121 | ||
| 
						 | 
					354ae119c6 | ||
| 
						 | 
					a2b2e5b5b8 | ||
| 
						 | 
					b21c9ebb43 | ||
| 
						 | 
					2e002f666b | ||
| 
						 | 
					4163fb5f2e | ||
| 
						 | 
					e72c88e344 | ||
| 
						 | 
					f4eebbaaf9 | ||
| 
						 | 
					5e5a8e4dfa | ||
| 
						 | 
					8cbe236845 | ||
| 
						 | 
					2b3e8dc62a | ||
| 
						 | 
					5ab2cf646e | ||
| 
						 | 
					c5b4628c5c | ||
| 
						 | 
					d4cec3e850 | ||
| 
						 | 
					564638c171 | ||
| 
						 | 
					c6171a85e9 | ||
| 
						 | 
					ee610032b8 | ||
| 
						 | 
					6754ebe20d | ||
| 
						 | 
					15d19fdf9c | ||
| 
						 | 
					967e30d914 | ||
| 
						 | 
					38ee31ebcb | ||
| 
						 | 
					7315958ea9 | ||
| 
						 | 
					cce25b1ea4 | ||
| 
						 | 
					1a57ef03c8 | ||
| 
						 | 
					298c04f89c | ||
| 
						 | 
					42a8b4f639 | ||
| 
						 | 
					336d8b7b4b | ||
| 
						 | 
					feb3eee2a0 | ||
| 
						 | 
					7cb0388ed0 | ||
| 
						 | 
					004c0d06eb | ||
| 
						 | 
					abbbd1f8eb | ||
| 
						 | 
					700d9ac7e9 | ||
| 
						 | 
					8037a17b73 | ||
| 
						 | 
					49917ce6b4 | ||
| 
						 | 
					c5e1139879 | ||
| 
						 | 
					1becd92b12 | ||
| 
						 | 
					bc6b107066 | ||
| 
						 | 
					9b30ae0424 | ||
| 
						 | 
					88831c424f | ||
| 
						 | 
					4a2f869c6d | ||
| 
						 | 
					7f0f9a966f | ||
| 
						 | 
					85647794dc | ||
| 
						 | 
					8c9416e57f | ||
| 
						 | 
					95607557d6 | ||
| 
						 | 
					e9ffe2ea9d | ||
| 
						 | 
					c08a8bddc9 | ||
| 
						 | 
					ca8222e764 | ||
| 
						 | 
					986bbb30a7 | ||
| 
						 | 
					2cdfe105fb | ||
| 
						 | 
					b494c4e273 | ||
| 
						 | 
					0ad70a1edc | ||
| 
						 | 
					285d57eb01 | ||
| 
						 | 
					d20205249b | ||
| 
						 | 
					b29113c229 | ||
| 
						 | 
					41a0a766ce | ||
| 
						 | 
					6222985491 | ||
| 
						 | 
					e09e5a9683 | ||
| 
						 | 
					6883d2dbeb | ||
| 
						 | 
					215c64d924 | ||
| 
						 | 
					ab76f87e01 | ||
| 
						 | 
					fd759ea2ac | ||
| 
						 | 
					213e7bf74b | ||
| 
						 | 
					1a2c1aa4e9 | ||
| 
						 | 
					fc48e69921 | ||
| 
						 | 
					88732a608e | ||
| 
						 | 
					8374be0872 | ||
| 
						 | 
					3ae01ac65d | ||
| 
						 | 
					4d467cce95 | ||
| 
						 | 
					8be353941f | ||
| 
						 | 
					d442f959e9 | ||
| 
						 | 
					cb2cddbdd9 | ||
| 
						 | 
					8632a29edc | ||
| 
						 | 
					36a0a669b0 | ||
| 
						 | 
					214acf56c5 | ||
| 
						 | 
					da3bc60942 | ||
| 
						 | 
					70c89164b0 | ||
| 
						 | 
					1a76bfd2a3 | ||
| 
						 | 
					b16de9c7c2 | ||
| 
						 | 
					43fead02d3 | ||
| 
						 | 
					de513cacb1 | ||
| 
						 | 
					e4b97af73e | ||
| 
						 | 
					9d91b96780 | ||
| 
						 | 
					8962cf2ec1 | ||
| 
						 | 
					d6e80b7835 | ||
| 
						 | 
					4bc1cc7849 | ||
| 
						 | 
					e6af00ef97 | ||
| 
						 | 
					c8550a0ce5 | ||
| 
						 | 
					0a40e7f0a9 | ||
| 
						 | 
					9c649c05a9 | ||
| 
						 | 
					7933e963d8 | ||
| 
						 | 
					4fc18cb4e7 | ||
| 
						 | 
					5d1dd70652 | ||
| 
						 | 
					65a25d5448 | ||
| 
						 | 
					4e854a575e | ||
| 
						 | 
					742200a500 | ||
| 
						 | 
					44cd1fd7e1 | ||
| 
						 | 
					dc16600871 | ||
| 
						 | 
					af40ad84d8 | ||
| 
						 | 
					63e62fcba3 | ||
| 
						 | 
					368be788d7 | ||
| 
						 | 
					cd1468489f | ||
| 
						 | 
					fbce86b92a | ||
| 
						 | 
					3f6652df66 | ||
| 
						 | 
					cf82af8978 | ||
| 
						 | 
					20f51f5ffe | ||
| 
						 | 
					8f6d8b1dd1 | ||
| 
						 | 
					c0002fe6e0 | ||
| 
						 | 
					6609b8d06a | ||
| 
						 | 
					5b5df9361d | ||
| 
						 | 
					fa234fde70 | ||
| 
						 | 
					867aec83c3 | ||
| 
						 | 
					2117659c40 | ||
| 
						 | 
					4985f75d74 | ||
| 
						 | 
					959d20df78 | ||
| 
						 | 
					8529461742 | ||
| 
						 | 
					3173ef10c6 | ||
| 
						 | 
					1c5fef3a34 | ||
| 
						 | 
					386e6bf0c3 | ||
| 
						 | 
					1146ab654c | ||
| 
						 | 
					4e7eceaa3a | ||
| 
						 | 
					71bb1994c3 | ||
| 
						 | 
					bfa3c905a3 | 
							
								
								
									
										57
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										57
									
								
								.travis.yml
									
									
									
									
									
								
							@@ -1,25 +1,50 @@
 | 
			
		||||
language: python
 | 
			
		||||
python:
 | 
			
		||||
  - "3.4"
 | 
			
		||||
  - "3.3"
 | 
			
		||||
  - "2.7"
 | 
			
		||||
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
 | 
			
		||||
addons:
 | 
			
		||||
  apt:
 | 
			
		||||
    sources:
 | 
			
		||||
      - fish-shell/release-2
 | 
			
		||||
    packages:
 | 
			
		||||
      - bash
 | 
			
		||||
      - zsh
 | 
			
		||||
      - fish
 | 
			
		||||
      - tcsh
 | 
			
		||||
env:
 | 
			
		||||
  - FUNCTIONAL=true BARE=true
 | 
			
		||||
      - 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
 | 
			
		||||
install:
 | 
			
		||||
  - pip install coveralls
 | 
			
		||||
  - pip install -r requirements.txt
 | 
			
		||||
  - pip install -Ur requirements.txt
 | 
			
		||||
  - python setup.py develop
 | 
			
		||||
  - rm -rf build
 | 
			
		||||
script:
 | 
			
		||||
  - export COVERAGE_PYTHON_VERSION=python-${TRAVIS_PYTHON_VERSION:0:1}
 | 
			
		||||
  - coverage run --source=thefuck,tests -m py.test -v --capture=sys
 | 
			
		||||
after_success: coveralls
 | 
			
		||||
  - 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:
 | 
			
		||||
  - coveralls
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										25
									
								
								CONTRIBUTING.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								CONTRIBUTING.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
# 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.
 | 
			
		||||
							
								
								
									
										185
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										185
									
								
								README.md
									
									
									
									
									
								
							@@ -1,10 +1,10 @@
 | 
			
		||||
# The Fuck [](https://travis-ci.org/nvbn/thefuck) 
 | 
			
		||||
# 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)
 | 
			
		||||
 | 
			
		||||
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]
 | 
			
		||||
 | 
			
		||||
Few more examples:
 | 
			
		||||
 | 
			
		||||
@@ -14,7 +14,7 @@ E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied)
 | 
			
		||||
E: Unable to lock the administration directory (/var/lib/dpkg/), are you root?
 | 
			
		||||
 | 
			
		||||
➜ fuck
 | 
			
		||||
sudo apt-get install vim [enter/ctrl+c]
 | 
			
		||||
sudo apt-get install vim [enter/↑/↓/ctrl+c]
 | 
			
		||||
[sudo] password for nvbn:
 | 
			
		||||
Reading package lists... Done
 | 
			
		||||
...
 | 
			
		||||
@@ -29,7 +29,7 @@ To push the current branch and set the remote as upstream, use
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
➜ fuck
 | 
			
		||||
git push --set-upstream origin master [enter/ctrl+c]
 | 
			
		||||
git push --set-upstream origin master [enter/↑/↓/ctrl+c]
 | 
			
		||||
Counting objects: 9, done.
 | 
			
		||||
...
 | 
			
		||||
```
 | 
			
		||||
@@ -42,7 +42,7 @@ No command 'puthon' found, did you mean:
 | 
			
		||||
zsh: command not found: puthon
 | 
			
		||||
 | 
			
		||||
➜ fuck
 | 
			
		||||
python [enter/ctrl+c]
 | 
			
		||||
python [enter/↑/↓/ctrl+c]
 | 
			
		||||
Python 3.4.2 (default, Oct  8 2014, 13:08:17)
 | 
			
		||||
...
 | 
			
		||||
```
 | 
			
		||||
@@ -52,10 +52,10 @@ 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]
 | 
			
		||||
git branch [enter/↑/↓/ctrl+c]
 | 
			
		||||
* master
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
@@ -67,7 +67,7 @@ Did you mean this?
 | 
			
		||||
         repl
 | 
			
		||||
 | 
			
		||||
➜ fuck
 | 
			
		||||
lein repl [enter/ctrl+c]
 | 
			
		||||
lein repl [enter/↑/↓/ctrl+c]
 | 
			
		||||
nREPL server started on port 54848 on host 127.0.0.1 - nrepl://127.0.0.1:54848
 | 
			
		||||
REPL-y 0.3.1
 | 
			
		||||
...
 | 
			
		||||
@@ -96,10 +96,23 @@ Reading package lists... Done
 | 
			
		||||
 | 
			
		||||
## Installation
 | 
			
		||||
 | 
			
		||||
Install `The Fuck` with `pip`:
 | 
			
		||||
On OS X you can install `The Fuck` with [Homebrew][homebrew]:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
sudo pip install thefuck
 | 
			
		||||
brew install thefuck
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
On Ubuntu you can install `The Fuck` with:
 | 
			
		||||
```bash
 | 
			
		||||
sudo apt update
 | 
			
		||||
sudo apt install python3-dev python3-pip
 | 
			
		||||
sudo -H pip3 install thefuck
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
On other systems you can install `The Fuck` with `pip`:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
sudo -H pip install thefuck
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[Or using an OS package manager (OS X, Ubuntu, Arch).](https://github.com/nvbn/thefuck/wiki/Installation)
 | 
			
		||||
@@ -107,9 +120,9 @@ sudo pip install 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)
 | 
			
		||||
@@ -121,7 +134,7 @@ To make them available immediately, run `source ~/.bashrc` (or your shell config
 | 
			
		||||
## Update
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
sudo pip install thefuck --upgrade
 | 
			
		||||
sudo -H pip install thefuck --upgrade
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
**Aliases changed in 1.34.**
 | 
			
		||||
@@ -131,156 +144,230 @@ sudo pip install 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_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++`;
 | 
			
		||||
* `dirty_untar` – fixes `tar x` command that untarred in the current directory;
 | 
			
		||||
* `dirty_unzip` – fixes `unzip` command that unzipped in the current directory;
 | 
			
		||||
* `django_south_ghost` – adds `--delete-ghost-migrations` to failed because ghosts django south migration;
 | 
			
		||||
* `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;
 | 
			
		||||
* `git_add` – fixes *"Did you forget to 'git add'?"*;
 | 
			
		||||
* `fix_file` – opens a file with an error in your `$EDITOR`;
 | 
			
		||||
* `git_add` – fixes *"pathspec 'foo' did not match any file(s) known to git."*;
 | 
			
		||||
* `git_bisect_usage` – fixes `git bisect strt`, `git bisect goood`, `git bisect rset`, etc. when bisecting;
 | 
			
		||||
* `git_branch_delete` – changes `git branch -d` to `git branch -D`;
 | 
			
		||||
* `git_branch_exists` – offers `git branch -d foo`, `git branch -D foo` or `git checkout foo` when creating a branch that already exists;
 | 
			
		||||
* `git_branch_list` – catches `git branch list` in place of `git branch` and removes created branch;
 | 
			
		||||
* `git_checkout` – fixes branch name or creates new branch;
 | 
			
		||||
* `git_diff_no_index` – adds `--no-index` to previous `git diff` on untracked files;
 | 
			
		||||
* `git_diff_staged` – adds `--staged` to previous `git diff` with unexpected output;
 | 
			
		||||
* `git_fix_stash` – fixes `git stash` commands (misspelled subcommand and missing `save`);
 | 
			
		||||
* `git_flag_after_filename` – fixes `fatal: bad flag '...' after filename`
 | 
			
		||||
* `git_help_aliased` – fixes `git help <alias>` commands replacing <alias> with the aliased command;
 | 
			
		||||
* `git_not_command` – fixes wrong git commands like `git brnch`;
 | 
			
		||||
* `git_pull` – sets upstream before executing previous `git pull`;
 | 
			
		||||
* `git_pull_clone` – clones instead of pulling when the repo does not exist;
 | 
			
		||||
* `git_pull_uncommitted_changes` – stashes changes before pulling and pops them afterwards;
 | 
			
		||||
* `git_push` – adds `--set-upstream origin $branch` to previous failed `git push`;
 | 
			
		||||
* `git_push_pull` – runs `git pull` when `push` was rejected;
 | 
			
		||||
* `git_rebase_no_changes` – runs `git rebase --skip` instead of `git rebase --continue` when there are no changes;
 | 
			
		||||
* `git_rm_local_modifications` –  adds `-f` or `--cached` when you try to `rm` a locally modified file;
 | 
			
		||||
* `git_rm_recursive` – adds `-r` when you try to `rm` a directory;
 | 
			
		||||
* `git_rebase_merge_dir` – offers `git rebase (--continue | --abort | --skip)` or removing the `.git/rebase-merge` dir when a rebase is in progress;
 | 
			
		||||
* `git_remote_seturl_add` – runs `git remote add` when `git remote set_url` on nonexistant remote;
 | 
			
		||||
* `git_stash` – stashes you local modifications before rebasing or switching branch;
 | 
			
		||||
* `go_run` – appends `.go` extension when compiling/running Go programs
 | 
			
		||||
* `git_stash_pop` – adds your local modifications before popping stash, then resets;
 | 
			
		||||
* `git_two_dashes` – adds a missing dash to commands like `git commit -amend` or `git rebase -continue`;
 | 
			
		||||
* `go_run` – appends `.go` extension when compiling/running Go programs;
 | 
			
		||||
* `gradle_no_task` – fixes not found or ambiguous `gradle` task;
 | 
			
		||||
* `gradle_wrapper` – replaces `gradle` with `./gradlew`;
 | 
			
		||||
* `grep_arguments_order` – fixes grep arguments order for situations like `grep -lir . test`;
 | 
			
		||||
* `grep_recursive` – adds `-r` when you trying to `grep` directory;
 | 
			
		||||
* `gulp_not_task` – fixes misspelled gulp tasks;
 | 
			
		||||
* `grunt_task_not_found` – fixes misspelled `grunt` commands;
 | 
			
		||||
* `gulp_not_task` – fixes misspelled `gulp` tasks;
 | 
			
		||||
* `has_exists_script` – prepends `./` when script/binary exists;
 | 
			
		||||
* `heroku_no_command` – fixes wrong `heroku` commands like `heroku log`;
 | 
			
		||||
* `heroku_not_command` – fixes wrong `heroku` commands like `heroku log`;
 | 
			
		||||
* `history` – tries to replace command with most similar command from history;
 | 
			
		||||
* `ifconfig_device_not_found` – fixes wrong device names like `wlan0` to `wlp2s0`;
 | 
			
		||||
* `java` – removes `.java` extension when running Java programs;
 | 
			
		||||
* `javac` – appends missing `.java` when compiling Java files;
 | 
			
		||||
* `lein_not_task` – fixes wrong `lein` tasks like `lein rpl`;
 | 
			
		||||
* `ln_no_hard_link` – catches hard link creation on directories, suggest symbolic link;
 | 
			
		||||
* `ln_s_order` – fixes `ln -s` arguments order;
 | 
			
		||||
* `ls_all` – adds `-A` to `ls` when output is empty;
 | 
			
		||||
* `ls_lah` – adds `-lah` to `ls`;
 | 
			
		||||
* `man` – changes manual section;
 | 
			
		||||
* `man_no_space` – fixes man commands without spaces, for example `mandiff`;
 | 
			
		||||
* `mercurial` – fixes wrong `hg` commands;
 | 
			
		||||
* `mkdir_p` – adds `-p` when you trying to create directory without parent;
 | 
			
		||||
* `mvn_no_command` – adds `clean package` to `mvn`;
 | 
			
		||||
* `mvn_unknown_lifecycle_phase` – fixes misspelled lifecycle phases with `mvn`;
 | 
			
		||||
* `npm_missing_script` – fixes `npm` custom script name in `npm run-script <script>`;
 | 
			
		||||
* `npm_run_script` – adds missing `run-script` for custom `npm` scripts;
 | 
			
		||||
* `npm_wrong_command` – fixes wrong npm commands like `npm urgrade`;
 | 
			
		||||
* `no_command` – fixes wrong console commands, for example `vom/vim`;
 | 
			
		||||
* `no_such_file` – creates missing directories with `mv` and `cp` commands;
 | 
			
		||||
* `open` – prepends `http` to address passed to `open`;
 | 
			
		||||
* `open` – either prepends `http://` to address passed to `open` or create a new file or directory and passes it to `open`;
 | 
			
		||||
* `pip_unknown_command` – fixes wrong `pip` commands, for example `pip instatl/pip install`;
 | 
			
		||||
* `port_already_in_use` – kills process that bound port;
 | 
			
		||||
* `python_command` – prepends `python` when you trying to run not executable/without `./` python script;
 | 
			
		||||
* `python_execute` – appends missing `.py` when executing Python files;
 | 
			
		||||
* `quotation_marks` – fixes uneven usage of `'` and `"` when containing args'
 | 
			
		||||
* `quotation_marks` – fixes uneven usage of `'` and `"` when containing args';
 | 
			
		||||
* `react_native_command_unrecognized` – fixes unrecognized `react-native` commands;
 | 
			
		||||
* `remove_trailing_cedilla` – remove trailling cedillas `ç`, a common typo for european keyboard layouts;
 | 
			
		||||
* `rm_dir` – adds `-rf` when you trying to remove directory;
 | 
			
		||||
* `sed_unterminated_s` – adds missing '/' to `sed`'s `s` commands;
 | 
			
		||||
* `sl_ls` – changes `sl` to `ls`;
 | 
			
		||||
* `ssh_known_hosts` – removes host from `known_hosts` on warning;
 | 
			
		||||
* `sudo` – prepends `sudo` to previous command if it failed because of permissions;
 | 
			
		||||
* `switch_layout` – switches command from your local layout to en;
 | 
			
		||||
* `switch_lang` – switches command from your local layout to en;
 | 
			
		||||
* `systemctl` – correctly orders parameters of confusing `systemctl`;
 | 
			
		||||
* `test.py` – runs `py.test` instead of `test.py`;
 | 
			
		||||
* `touch` – creates missing directories before "touching";
 | 
			
		||||
* `tsuru_login` – runs `tsuru login` if not authenticated or session expired;
 | 
			
		||||
* `tsuru_not_command` – fixes wrong `tsuru` commands like `tsuru shell`;
 | 
			
		||||
* `tmux` – fixes `tmux` commands;
 | 
			
		||||
* `whois` – fixes `whois` command.
 | 
			
		||||
* `unknown_command` – fixes hadoop hdfs-style "unknown command", for example adds missing '-' to the command on `hdfs dfs ls`;
 | 
			
		||||
* `vagrant_up` – starts up the vagrant instance;
 | 
			
		||||
* `whois` – fixes `whois` command;
 | 
			
		||||
* `workon_doesnt_exists` – fixes `virtualenvwrapper` env name os suggests to create new.
 | 
			
		||||
 | 
			
		||||
Enabled by default only on specific platforms:
 | 
			
		||||
 | 
			
		||||
* `apt_get` – installs app from apt if it not installed;
 | 
			
		||||
* `apt_get` – installs app from apt if it not installed (requires `python-commandnotfound` / `python3-commandnotfound`);
 | 
			
		||||
* `apt_get_search` – changes trying to search using `apt-get` with searching using `apt-cache`;
 | 
			
		||||
* `apt_invalid_operation` – fixes invalid `apt` and `apt-get` calls, like `apt-get isntall vim`;
 | 
			
		||||
* `brew_install` – fixes formula name for `brew install`;
 | 
			
		||||
* `brew_link` – adds `--overwrite --dry-run` if linking fails;
 | 
			
		||||
* `brew_uninstall` – adds `--force` to `brew uninstall` if multiple versions were installed;
 | 
			
		||||
* `brew_unknown_command` – fixes wrong brew commands, for example `brew docto/brew doctor`;
 | 
			
		||||
* `brew_update_formula` – turns `brew update <formula>` into `brew upgrade <formula>`;
 | 
			
		||||
* `brew_upgrade` – appends `--all` to `brew upgrade` as per Homebrew's new behaviour;
 | 
			
		||||
* `pacman` – installs app with `pacman` or `yaourt` if it is not installed.
 | 
			
		||||
* `pacman` – installs app with `pacman` if it is not installed (uses `yaourt` if available);
 | 
			
		||||
* `pacman_not_found` – fixes package name with `pacman` or `yaourt`.
 | 
			
		||||
 | 
			
		||||
Bundled, but not enabled by default:
 | 
			
		||||
 | 
			
		||||
* `git_push_force` – adds `--force` to a `git push` (may conflict with `git_push_pull`);
 | 
			
		||||
* `git_push_force` – adds `--force-with-lease` to a `git push` (may conflict with `git_push_pull`);
 | 
			
		||||
* `rm_root` – 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 `~/.thefuck/rules`. The rule should contain two functions:
 | 
			
		||||
in `~/.config/thefuck/rules`. The rule should contain two functions:
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
match(command: Command, settings: Settings) -> bool
 | 
			
		||||
get_new_command(command: Command, settings: Settings) -> str
 | 
			
		||||
match(command: Command) -> bool
 | 
			
		||||
get_new_command(command: Command) -> str | list[str]
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Also the rule can contain an optional function
 | 
			
		||||
`side_effect(command: Command, settings: Settings) -> None` and an
 | 
			
		||||
optional boolean `enabled_by_default`.
 | 
			
		||||
 | 
			
		||||
`Command` has three attributes: `script`, `stdout` and `stderr`.
 | 
			
		||||
```python
 | 
			
		||||
side_effect(old_command: Command, fixed_command: str) -> None
 | 
			
		||||
```
 | 
			
		||||
and optional `enabled_by_default`, `requires_output` and `priority` variables.
 | 
			
		||||
 | 
			
		||||
`Settings` is a special object filled with `~/.thefuck/settings.py` and values from env ([see more below](#settings)).
 | 
			
		||||
`Command` has three attributes: `script`, `stdout`, `stderr` and `script_parts`.
 | 
			
		||||
Rule shouldn't change `Command`.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
*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)).
 | 
			
		||||
 | 
			
		||||
Simple example of the rule for running script with `sudo`:
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
def match(command, settings):
 | 
			
		||||
def match(command):
 | 
			
		||||
    return ('permission denied' in command.stderr.lower()
 | 
			
		||||
            or 'EACCES' in command.stderr)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_new_command(command, settings):
 | 
			
		||||
def get_new_command(command):
 | 
			
		||||
    return 'sudo {}'.format(command.script)
 | 
			
		||||
 | 
			
		||||
# Optional:
 | 
			
		||||
enabled_by_default = True
 | 
			
		||||
 | 
			
		||||
def side_effect(command, settings):
 | 
			
		||||
def side_effect(command, fixed_command):
 | 
			
		||||
    subprocess.call('chmod 777 .', shell=True)
 | 
			
		||||
 | 
			
		||||
priority = 1000  # Lower first, default is 1000
 | 
			
		||||
 | 
			
		||||
requires_output = True
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[More examples of rules](https://github.com/nvbn/thefuck/tree/master/thefuck/rules),
 | 
			
		||||
[utility functions for rules](https://github.com/nvbn/thefuck/tree/master/thefuck/utils.py).
 | 
			
		||||
[utility functions for rules](https://github.com/nvbn/thefuck/tree/master/thefuck/utils.py),
 | 
			
		||||
[app/os-specific helpers](https://github.com/nvbn/thefuck/tree/master/thefuck/specific/).
 | 
			
		||||
 | 
			
		||||
## Settings
 | 
			
		||||
 | 
			
		||||
The Fuck has a few settings parameters which can be changed in `~/.thefuck/settings.py`:
 | 
			
		||||
The Fuck has a few settings parameters which can be changed in `$XDG_CONFIG_HOME/thefuck/settings.py` (`$XDG_CONFIG_HOME` defaults to `~/.config`):
 | 
			
		||||
 | 
			
		||||
* `rules` – list of enabled rules, by default `thefuck.conf.DEFAULT_RULES`;
 | 
			
		||||
* `exclude_rules` – list of disabled rules, by default `[]`;
 | 
			
		||||
* `require_confirmation` – requires confirmation before running new command, by default `True`;
 | 
			
		||||
* `wait_command` – max amount of time in seconds for getting previous command output;
 | 
			
		||||
* `no_colors` – disable colored output;
 | 
			
		||||
* `priority` – dict with rules priorities, rule with lower `priority` will be matched first;
 | 
			
		||||
* `debug` – enables debug output, by default `False`.
 | 
			
		||||
* `debug` – enables debug output, by default `False`;
 | 
			
		||||
* `history_limit` – numeric value of how many history commands will be scanned, like `2000`;
 | 
			
		||||
* `alter_history` – push fixed command to history, by default `True`;
 | 
			
		||||
* `wait_slow_command` – max amount of time in seconds for getting previous command output if it in `slow_commands` list;
 | 
			
		||||
* `slow_commands` – list of slow commands.
 | 
			
		||||
 | 
			
		||||
Example of `settings.py`:
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
rules = ['sudo', 'no_command']
 | 
			
		||||
exclude_rules = ['git_push']
 | 
			
		||||
require_confirmation = True
 | 
			
		||||
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` – list of enabled rules, like `DEFAULT_RULES:rm_root` or `sudo:no_command`;
 | 
			
		||||
* `THEFUCK_EXCLUDE_RULES` – list of disabled rules, like `git_pull:git_push`;
 | 
			
		||||
* `THEFUCK_REQUIRE_CONFIRMATION` – require confirmation before running new command, `true/false`;
 | 
			
		||||
* `THEFUCK_WAIT_COMMAND` – max amount of time in seconds for getting previous command output;
 | 
			
		||||
* `THEFUCK_NO_COLORS` – disable colored output, `true/false`;
 | 
			
		||||
* `THEFUCK_PRIORITY` – priority of the rules, like `no_command=9999:apt_get=100`,
 | 
			
		||||
rule with lower `priority` will be matched first;
 | 
			
		||||
* `THEFUCK_DEBUG` – enables debug output, `true/false`.
 | 
			
		||||
* `THEFUCK_DEBUG` – enables debug output, `true/false`;
 | 
			
		||||
* `THEFUCK_HISTORY_LIMIT` – how many history commands will be scanned, like `2000`;
 | 
			
		||||
* `THEFUCK_ALTER_HISTORY` – push fixed command to history `true/false`;
 | 
			
		||||
* `THEFUCK_WAIT_SLOW_COMMAND` – max amount of time in seconds for getting previous command output if it in `slow_commands` list;
 | 
			
		||||
* `THEFUCK_SLOW_COMMANDS` – list of slow commands, like `lein:gradle`.
 | 
			
		||||
 | 
			
		||||
For example:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
export THEFUCK_RULES='sudo:no_command'
 | 
			
		||||
export THEFUCK_EXCLUDE_RULES='git_pull:git_push'
 | 
			
		||||
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
 | 
			
		||||
@@ -301,8 +388,28 @@ py.test
 | 
			
		||||
Run unit and functional tests (requires docker):
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
FUNCTIONAL=true py.test
 | 
			
		||||
py.test --enable-functional
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
For sending package to pypi:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
sudo apt-get install pandoc
 | 
			
		||||
./release.py
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## 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/
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										23
									
								
								appveyor.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								appveyor.yml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
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%/Scripts/py.test.exe -sv"
 | 
			
		||||
							
								
								
									
										4
									
								
								install.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										4
									
								
								install.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
echo "Installation script is deprecated!"
 | 
			
		||||
echo "For installation instruction please visit https://github.com/nvbn/thefuck"
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
#!/usr/bin/env python
 | 
			
		||||
from subprocess import call
 | 
			
		||||
import os
 | 
			
		||||
import re
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -28,4 +29,7 @@ call('git commit -am "Bump to {}"'.format(version), shell=True)
 | 
			
		||||
call('git tag {}'.format(version), shell=True)
 | 
			
		||||
call('git push', shell=True)
 | 
			
		||||
call('git push --tags', shell=True)
 | 
			
		||||
call('python setup.py sdist bdist_wheel upload', shell=True)
 | 
			
		||||
 | 
			
		||||
env = os.environ
 | 
			
		||||
env['CONVERT_README'] = 'true'
 | 
			
		||||
call('python setup.py sdist bdist_wheel upload', shell=True, env=env)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,10 @@
 | 
			
		||||
pip
 | 
			
		||||
pytest
 | 
			
		||||
mock
 | 
			
		||||
pytest-mock
 | 
			
		||||
wheel
 | 
			
		||||
setuptools>=17.1
 | 
			
		||||
pexpect
 | 
			
		||||
pypandoc
 | 
			
		||||
pytest-benchmark
 | 
			
		||||
pytest-docker-pexpect
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,2 @@
 | 
			
		||||
[bdist_wheel]
 | 
			
		||||
universal = 1
 | 
			
		||||
[metadata]
 | 
			
		||||
description-file = README.md
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										38
									
								
								setup.py
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								setup.py
									
									
									
									
									
								
							@@ -1,34 +1,54 @@
 | 
			
		||||
#!/usr/bin/env python
 | 
			
		||||
from setuptools import setup, find_packages
 | 
			
		||||
import pkg_resources
 | 
			
		||||
import sys
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
if sys.version_info < (2, 7):
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
    long_description = pypandoc.convert('README.md', 'rst')
 | 
			
		||||
else:
 | 
			
		||||
    long_description = ''
 | 
			
		||||
 | 
			
		||||
version = sys.version_info[:2]
 | 
			
		||||
if version < (2, 7):
 | 
			
		||||
    print('thefuck requires Python version 2.7 or later' +
 | 
			
		||||
          ' ({}.{} detected).'.format(*sys.version_info[:2]))
 | 
			
		||||
          ' ({}.{} detected).'.format(*version))
 | 
			
		||||
    sys.exit(-1)
 | 
			
		||||
elif (3, 0) < sys.version_info < (3, 3):
 | 
			
		||||
elif (3, 0) < version < (3, 3):
 | 
			
		||||
    print('thefuck requires Python version 3.3 or later' +
 | 
			
		||||
          ' ({}.{} detected).'.format(*sys.version_info[:2]))
 | 
			
		||||
          ' ({}.{} detected).'.format(*version))
 | 
			
		||||
    sys.exit(-1)
 | 
			
		||||
 | 
			
		||||
VERSION = '2.4'
 | 
			
		||||
VERSION = '3.13'
 | 
			
		||||
 | 
			
		||||
install_requires = ['psutil', 'colorama', 'six']
 | 
			
		||||
extras_require = {':python_version<"3.4"': ['pathlib']}
 | 
			
		||||
install_requires = ['psutil', 'colorama', 'six', 'decorator']
 | 
			
		||||
extras_require = {':python_version<"3.4"': ['pathlib2'],
 | 
			
		||||
                  ":sys_platform=='win32'": ['win_unicode_console']}
 | 
			
		||||
 | 
			
		||||
setup(name='thefuck',
 | 
			
		||||
      version=VERSION,
 | 
			
		||||
      description="Magnificent app which corrects your previous console command",
 | 
			
		||||
      long_description=long_description,
 | 
			
		||||
      author='Vladimir Iakovlev',
 | 
			
		||||
      author_email='nvbn.rm@gmail.com',
 | 
			
		||||
      url='https://github.com/nvbn/thefuck',
 | 
			
		||||
      license='MIT',
 | 
			
		||||
      packages=find_packages(exclude=['ez_setup', 'examples',
 | 
			
		||||
                                      'tests', 'release']),
 | 
			
		||||
                                      'tests', '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',
 | 
			
		||||
          'thefuck-alias = thefuck.main:print_alias']})
 | 
			
		||||
          'fuck = thefuck.main:how_to_configure_alias']})
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,62 @@
 | 
			
		||||
import pytest
 | 
			
		||||
from thefuck import shells
 | 
			
		||||
from thefuck import conf, const
 | 
			
		||||
from thefuck.system import Path
 | 
			
		||||
 | 
			
		||||
shells.shell = shells.Generic()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def pytest_addoption(parser):
 | 
			
		||||
    """Adds `--run-without-docker` argument."""
 | 
			
		||||
    group = parser.getgroup("thefuck")
 | 
			
		||||
    group.addoption('--enable-functional', action="store_true", default=False,
 | 
			
		||||
                    help="Enable functional tests")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture
 | 
			
		||||
def no_memoize(monkeypatch):
 | 
			
		||||
    monkeypatch.setattr('thefuck.utils.memoize.disabled', True)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(autouse=True)
 | 
			
		||||
def settings(request):
 | 
			
		||||
    def _reset_settings():
 | 
			
		||||
        conf.settings.clear()
 | 
			
		||||
        conf.settings.update(const.DEFAULT_SETTINGS)
 | 
			
		||||
 | 
			
		||||
    request.addfinalizer(_reset_settings)
 | 
			
		||||
    conf.settings.user_dir = Path('~/.thefuck')
 | 
			
		||||
    return conf.settings
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture
 | 
			
		||||
def no_colors(settings):
 | 
			
		||||
    settings.no_colors = True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(autouse=True)
 | 
			
		||||
def no_cache(monkeypatch):
 | 
			
		||||
    monkeypatch.setattr('thefuck.utils.cache.disabled', True)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(autouse=True)
 | 
			
		||||
def functional(request):
 | 
			
		||||
    if request.node.get_marker('functional') \
 | 
			
		||||
            and not request.config.getoption('enable_functional'):
 | 
			
		||||
        pytest.skip('functional tests are disabled')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@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
 | 
			
		||||
 
 | 
			
		||||
@@ -1,42 +1,86 @@
 | 
			
		||||
def with_confirmation(proc):
 | 
			
		||||
    """Ensures that command can be fixed when confirmation enabled."""
 | 
			
		||||
def _set_confirmation(proc, require):
 | 
			
		||||
    proc.sendline(u'mkdir -p ~/.thefuck')
 | 
			
		||||
    proc.sendline(u'echo "require_confirmation = True" > ~/.thefuck/settings.py')
 | 
			
		||||
    proc.sendline(
 | 
			
		||||
        u'echo "require_confirmation = {}" > ~/.thefuck/settings.py'.format(
 | 
			
		||||
            require))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def with_confirmation(proc, TIMEOUT):
 | 
			
		||||
    """Ensures that command can be fixed when confirmation enabled."""
 | 
			
		||||
    _set_confirmation(proc, True)
 | 
			
		||||
 | 
			
		||||
    proc.sendline(u'ehco test')
 | 
			
		||||
 | 
			
		||||
    proc.sendline(u'fuck')
 | 
			
		||||
    proc.expect(u'echo test')
 | 
			
		||||
    proc.expect(u'enter')
 | 
			
		||||
    proc.expect_exact(u'ctrl+c')
 | 
			
		||||
    assert proc.expect([TIMEOUT, u'echo test'])
 | 
			
		||||
    assert proc.expect([TIMEOUT, u'enter'])
 | 
			
		||||
    assert proc.expect_exact([TIMEOUT, u'ctrl+c'])
 | 
			
		||||
    proc.send('\n')
 | 
			
		||||
 | 
			
		||||
    proc.expect(u'test')
 | 
			
		||||
    assert proc.expect([TIMEOUT, u'test'])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def refuse_with_confirmation(proc):
 | 
			
		||||
def history_changed(proc, TIMEOUT, to):
 | 
			
		||||
    """Ensures that history changed."""
 | 
			
		||||
    proc.send('\033[A')
 | 
			
		||||
    assert proc.expect([TIMEOUT, to])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def history_not_changed(proc, TIMEOUT):
 | 
			
		||||
    """Ensures that history not changed."""
 | 
			
		||||
    proc.send('\033[A')
 | 
			
		||||
    assert proc.expect([TIMEOUT, u'fuck'])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def select_command_with_arrows(proc, TIMEOUT):
 | 
			
		||||
    """Ensures that command can be selected with arrow keys."""
 | 
			
		||||
    _set_confirmation(proc, True)
 | 
			
		||||
 | 
			
		||||
    proc.sendline(u'git h')
 | 
			
		||||
    assert proc.expect([TIMEOUT, u"git: 'h' is not a git command."])
 | 
			
		||||
 | 
			
		||||
    proc.sendline(u'fuck')
 | 
			
		||||
    assert proc.expect([TIMEOUT, u'git show'])
 | 
			
		||||
    proc.send('\033[B')
 | 
			
		||||
    assert proc.expect([TIMEOUT, u'git push'])
 | 
			
		||||
    proc.send('\033[B')
 | 
			
		||||
    assert proc.expect([TIMEOUT, u'git help'])
 | 
			
		||||
    proc.send('\033[A')
 | 
			
		||||
    assert proc.expect([TIMEOUT, u'git push'])
 | 
			
		||||
    proc.send('\033[B')
 | 
			
		||||
    assert proc.expect([TIMEOUT, u'git help'])
 | 
			
		||||
    proc.send('\n')
 | 
			
		||||
 | 
			
		||||
    assert proc.expect([TIMEOUT, u'usage'])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def refuse_with_confirmation(proc, TIMEOUT):
 | 
			
		||||
    """Ensures that fix can be refused when confirmation enabled."""
 | 
			
		||||
    proc.sendline(u'mkdir -p ~/.thefuck')
 | 
			
		||||
    proc.sendline(u'echo "require_confirmation = True" > ~/.thefuck/settings.py')
 | 
			
		||||
    _set_confirmation(proc, True)
 | 
			
		||||
 | 
			
		||||
    proc.sendline(u'ehco test')
 | 
			
		||||
 | 
			
		||||
    proc.sendline(u'fuck')
 | 
			
		||||
    proc.expect(u'echo test')
 | 
			
		||||
    proc.expect(u'enter')
 | 
			
		||||
    proc.expect_exact(u'ctrl+c')
 | 
			
		||||
    assert proc.expect([TIMEOUT, u'echo test'])
 | 
			
		||||
    assert proc.expect([TIMEOUT, u'enter'])
 | 
			
		||||
    assert proc.expect_exact([TIMEOUT, u'ctrl+c'])
 | 
			
		||||
    proc.send('\003')
 | 
			
		||||
 | 
			
		||||
    proc.expect(u'Aborted')
 | 
			
		||||
    assert proc.expect([TIMEOUT, u'Aborted'])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def without_confirmation(proc):
 | 
			
		||||
def without_confirmation(proc, TIMEOUT):
 | 
			
		||||
    """Ensures that command can be fixed when confirmation disabled."""
 | 
			
		||||
    proc.sendline(u'mkdir -p ~/.thefuck')
 | 
			
		||||
    proc.sendline(u'echo "require_confirmation = False" > ~/.thefuck/settings.py')
 | 
			
		||||
    _set_confirmation(proc, False)
 | 
			
		||||
 | 
			
		||||
    proc.sendline(u'ehco test')
 | 
			
		||||
 | 
			
		||||
    proc.sendline(u'fuck')
 | 
			
		||||
    proc.expect(u'echo test')
 | 
			
		||||
    proc.expect(u'test')
 | 
			
		||||
    assert proc.expect([TIMEOUT, u'echo test'])
 | 
			
		||||
    assert proc.expect([TIMEOUT, u'test'])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def how_to_configure(proc, TIMEOUT):
 | 
			
		||||
    proc.sendline(u'unalias fuck')
 | 
			
		||||
    proc.sendline(u'fuck')
 | 
			
		||||
    assert proc.expect([TIMEOUT, u"alias isn't configured"])
 | 
			
		||||
 
 | 
			
		||||
@@ -1,42 +1,51 @@
 | 
			
		||||
import pytest
 | 
			
		||||
from tests.functional.plots import with_confirmation, without_confirmation, \
 | 
			
		||||
    refuse_with_confirmation
 | 
			
		||||
from tests.functional.utils import spawn, functional, images
 | 
			
		||||
    refuse_with_confirmation, history_changed, history_not_changed, \
 | 
			
		||||
    select_command_with_arrows, how_to_configure
 | 
			
		||||
 | 
			
		||||
containers = images(('ubuntu-python3-bash', u'''
 | 
			
		||||
FROM ubuntu:latest
 | 
			
		||||
RUN apt-get update
 | 
			
		||||
RUN apt-get install -yy python3 python3-pip python3-dev
 | 
			
		||||
RUN pip3 install -U setuptools
 | 
			
		||||
RUN ln -s /usr/bin/pip3 /usr/bin/pip
 | 
			
		||||
'''),
 | 
			
		||||
                    ('ubuntu-python2-bash', u'''
 | 
			
		||||
FROM ubuntu:latest
 | 
			
		||||
RUN apt-get update
 | 
			
		||||
RUN apt-get install -yy python python-pip python-dev
 | 
			
		||||
RUN pip2 install -U pip setuptools
 | 
			
		||||
'''))
 | 
			
		||||
containers = ((u'thefuck/python3-bash',
 | 
			
		||||
               u'FROM python:3',
 | 
			
		||||
               u'bash'),
 | 
			
		||||
              (u'thefuck/python2-bash',
 | 
			
		||||
               u'FROM python:2',
 | 
			
		||||
               u'bash'))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@functional
 | 
			
		||||
@pytest.mark.parametrize('tag, dockerfile', containers)
 | 
			
		||||
def test_with_confirmation(tag, dockerfile):
 | 
			
		||||
    with spawn(tag, dockerfile, u'bash') as proc:
 | 
			
		||||
        proc.sendline(u'eval $(thefuck-alias)')
 | 
			
		||||
        with_confirmation(proc)
 | 
			
		||||
@pytest.fixture(params=containers)
 | 
			
		||||
def proc(request, spawnu, TIMEOUT):
 | 
			
		||||
    proc = spawnu(*request.param)
 | 
			
		||||
    proc.sendline(u"pip install /src")
 | 
			
		||||
    assert proc.expect([TIMEOUT, u'Successfully installed'])
 | 
			
		||||
    proc.sendline(u"export PS1='$ '")
 | 
			
		||||
    proc.sendline(u'eval $(thefuck --alias)')
 | 
			
		||||
    proc.sendline(u'echo > $HISTFILE')
 | 
			
		||||
    return proc
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@functional
 | 
			
		||||
@pytest.mark.parametrize('tag, dockerfile', containers)
 | 
			
		||||
def test_refuse_with_confirmation(tag, dockerfile):
 | 
			
		||||
    with spawn(tag, dockerfile, u'bash') as proc:
 | 
			
		||||
        proc.sendline(u'eval $(thefuck-alias)')
 | 
			
		||||
        refuse_with_confirmation(proc)
 | 
			
		||||
@pytest.mark.functional
 | 
			
		||||
def test_with_confirmation(proc, TIMEOUT):
 | 
			
		||||
    with_confirmation(proc, TIMEOUT)
 | 
			
		||||
    history_changed(proc, TIMEOUT, u'echo test')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@functional
 | 
			
		||||
@pytest.mark.parametrize('tag, dockerfile', containers)
 | 
			
		||||
def test_without_confirmation(tag, dockerfile):
 | 
			
		||||
    with spawn(tag, dockerfile, u'bash') as proc:
 | 
			
		||||
        proc.sendline(u'eval $(thefuck-alias)')
 | 
			
		||||
        without_confirmation(proc)
 | 
			
		||||
@pytest.mark.functional
 | 
			
		||||
def test_select_command_with_arrows(proc, TIMEOUT):
 | 
			
		||||
    select_command_with_arrows(proc, TIMEOUT)
 | 
			
		||||
    history_changed(proc, TIMEOUT, u'git help')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.functional
 | 
			
		||||
def test_refuse_with_confirmation(proc, TIMEOUT):
 | 
			
		||||
    refuse_with_confirmation(proc, TIMEOUT)
 | 
			
		||||
    history_not_changed(proc, TIMEOUT)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.functional
 | 
			
		||||
def test_without_confirmation(proc, TIMEOUT):
 | 
			
		||||
    without_confirmation(proc, TIMEOUT)
 | 
			
		||||
    history_changed(proc, TIMEOUT, u'echo test')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.functional
 | 
			
		||||
def test_how_to_configure_alias(proc, TIMEOUT):
 | 
			
		||||
    how_to_configure(proc, TIMEOUT)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,51 +1,52 @@
 | 
			
		||||
import pytest
 | 
			
		||||
from tests.functional.plots import with_confirmation, without_confirmation, \
 | 
			
		||||
    refuse_with_confirmation
 | 
			
		||||
from tests.functional.utils import spawn, functional, images, bare
 | 
			
		||||
    refuse_with_confirmation, select_command_with_arrows
 | 
			
		||||
 | 
			
		||||
containers = images(('ubuntu-python3-fish', u'''
 | 
			
		||||
FROM ubuntu:latest
 | 
			
		||||
RUN apt-get update
 | 
			
		||||
RUN apt-get install -yy python3 python3-pip python3-dev fish
 | 
			
		||||
RUN pip3 install -U setuptools
 | 
			
		||||
RUN ln -s /usr/bin/pip3 /usr/bin/pip
 | 
			
		||||
'''),
 | 
			
		||||
                    ('ubuntu-python2-fish', u'''
 | 
			
		||||
FROM ubuntu:latest
 | 
			
		||||
RUN apt-get update
 | 
			
		||||
RUN apt-get install -yy python python-pip python-dev fish
 | 
			
		||||
RUN pip2 install -U pip setuptools
 | 
			
		||||
'''))
 | 
			
		||||
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
 | 
			
		||||
                   RUN apt-get update
 | 
			
		||||
                   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
 | 
			
		||||
                   RUN apt-get update
 | 
			
		||||
                   RUN apt-get install -yy fish''',
 | 
			
		||||
               u'fish'))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@functional
 | 
			
		||||
@pytest.mark.skipif(
 | 
			
		||||
    bool(bare), reason='https://github.com/travis-ci/apt-source-whitelist/issues/71')
 | 
			
		||||
@pytest.mark.parametrize('tag, dockerfile', containers)
 | 
			
		||||
def test_with_confirmation(tag, dockerfile):
 | 
			
		||||
    with spawn(tag, dockerfile, u'fish') as proc:
 | 
			
		||||
        proc.sendline(u'thefuck-alias > ~/.config/fish/config.fish')
 | 
			
		||||
        proc.sendline(u'fish')
 | 
			
		||||
        with_confirmation(proc)
 | 
			
		||||
@pytest.fixture(params=containers)
 | 
			
		||||
def proc(request, spawnu, TIMEOUT):
 | 
			
		||||
    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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@functional
 | 
			
		||||
@pytest.mark.skipif(
 | 
			
		||||
    bool(bare), reason='https://github.com/travis-ci/apt-source-whitelist/issues/71')
 | 
			
		||||
@pytest.mark.parametrize('tag, dockerfile', containers)
 | 
			
		||||
def test_refuse_with_confirmation(tag, dockerfile):
 | 
			
		||||
    with spawn(tag, dockerfile, u'fish') as proc:
 | 
			
		||||
        proc.sendline(u'thefuck-alias > ~/.config/fish/config.fish')
 | 
			
		||||
        proc.sendline(u'fish')
 | 
			
		||||
        refuse_with_confirmation(proc)
 | 
			
		||||
@pytest.mark.functional
 | 
			
		||||
def test_with_confirmation(proc, TIMEOUT):
 | 
			
		||||
    with_confirmation(proc, TIMEOUT)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@functional
 | 
			
		||||
@pytest.mark.skipif(
 | 
			
		||||
    bool(bare), reason='https://github.com/travis-ci/apt-source-whitelist/issues/71')
 | 
			
		||||
@pytest.mark.parametrize('tag, dockerfile', containers)
 | 
			
		||||
def test_without_confirmation(tag, dockerfile):
 | 
			
		||||
    with spawn(tag, dockerfile, u'fish') as proc:
 | 
			
		||||
        proc.sendline(u'thefuck-alias > ~/.config/fish/config.fish')
 | 
			
		||||
        proc.sendline(u'fish')
 | 
			
		||||
        without_confirmation(proc)
 | 
			
		||||
@pytest.mark.functional
 | 
			
		||||
def test_select_command_with_arrows(proc, TIMEOUT):
 | 
			
		||||
    select_command_with_arrows(proc, TIMEOUT)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.functional
 | 
			
		||||
def test_refuse_with_confirmation(proc, TIMEOUT):
 | 
			
		||||
    refuse_with_confirmation(proc, TIMEOUT)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.functional
 | 
			
		||||
def test_without_confirmation(proc, TIMEOUT):
 | 
			
		||||
    without_confirmation(proc, TIMEOUT)
 | 
			
		||||
 | 
			
		||||
# TODO: ensure that history changes.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										45
									
								
								tests/functional/test_performance.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								tests/functional/test_performance.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
import pytest
 | 
			
		||||
import time
 | 
			
		||||
 | 
			
		||||
dockerfile = u'''
 | 
			
		||||
FROM python:3
 | 
			
		||||
RUN adduser --disabled-password --gecos '' test
 | 
			
		||||
ENV SEED "{seed}"
 | 
			
		||||
WORKDIR /src
 | 
			
		||||
USER test
 | 
			
		||||
RUN echo 'eval $(thefuck --alias)' > /home/test/.bashrc
 | 
			
		||||
RUN echo > /home/test/.bash_history
 | 
			
		||||
RUN git config --global user.email "you@example.com"
 | 
			
		||||
RUN git config --global user.name "Your Name"
 | 
			
		||||
USER root
 | 
			
		||||
'''.format(seed=time.time())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def plot(proc, TIMEOUT):
 | 
			
		||||
    proc.sendline(u'cd /home/test/')
 | 
			
		||||
    proc.sendline(u'fuck')
 | 
			
		||||
    assert proc.expect([TIMEOUT, u'No fucks given'])
 | 
			
		||||
    proc.sendline(u'git init')
 | 
			
		||||
    proc.sendline(u'git add .')
 | 
			
		||||
    proc.sendline(u'git commit -a -m init')
 | 
			
		||||
    proc.sendline(u'git brnch')
 | 
			
		||||
    proc.sendline(u'fuck')
 | 
			
		||||
    assert proc.expect([TIMEOUT, u'git branch'])
 | 
			
		||||
    proc.send('\n')
 | 
			
		||||
    assert proc.expect([TIMEOUT, u'master'])
 | 
			
		||||
    proc.sendline(u'echo test')
 | 
			
		||||
    proc.sendline(u'echo tst')
 | 
			
		||||
    proc.sendline(u'fuck')
 | 
			
		||||
    assert proc.expect([TIMEOUT, u'echo test'])
 | 
			
		||||
    proc.send('\n')
 | 
			
		||||
    assert proc.expect([TIMEOUT, u'test'])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.functional
 | 
			
		||||
@pytest.mark.benchmark(min_rounds=10)
 | 
			
		||||
def test_performance(spawnu, TIMEOUT, benchmark):
 | 
			
		||||
    proc = spawnu(u'thefuck/python3-bash-performance',
 | 
			
		||||
                  dockerfile, u'bash')
 | 
			
		||||
    proc.sendline(u'pip install /src')
 | 
			
		||||
    proc.sendline(u'su test')
 | 
			
		||||
    assert benchmark(plot, proc, TIMEOUT) is None
 | 
			
		||||
@@ -1,45 +1,47 @@
 | 
			
		||||
import pytest
 | 
			
		||||
from tests.functional.utils import spawn, functional, images
 | 
			
		||||
from tests.functional.plots import with_confirmation, without_confirmation, \
 | 
			
		||||
    refuse_with_confirmation
 | 
			
		||||
    refuse_with_confirmation, select_command_with_arrows
 | 
			
		||||
 | 
			
		||||
containers = images(('ubuntu-python3-tcsh', u'''
 | 
			
		||||
FROM ubuntu:latest
 | 
			
		||||
RUN apt-get update
 | 
			
		||||
RUN apt-get install -yy python3 python3-pip python3-dev tcsh
 | 
			
		||||
RUN pip3 install -U setuptools
 | 
			
		||||
RUN ln -s /usr/bin/pip3 /usr/bin/pip
 | 
			
		||||
'''),
 | 
			
		||||
                    ('ubuntu-python2-tcsh', u'''
 | 
			
		||||
FROM ubuntu:latest
 | 
			
		||||
RUN apt-get update
 | 
			
		||||
RUN apt-get install -yy python python-pip python-dev tcsh
 | 
			
		||||
RUN pip2 install -U pip setuptools
 | 
			
		||||
'''))
 | 
			
		||||
containers = (('thefuck/python3-tcsh',
 | 
			
		||||
               u'''FROM python:3
 | 
			
		||||
                   RUN apt-get update
 | 
			
		||||
                   RUN apt-get install -yy tcsh''',
 | 
			
		||||
               u'tcsh'),
 | 
			
		||||
              ('thefuck/python2-tcsh',
 | 
			
		||||
               u'''FROM python:2
 | 
			
		||||
                   RUN apt-get update
 | 
			
		||||
                   RUN apt-get install -yy tcsh''',
 | 
			
		||||
               u'tcsh'))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@functional
 | 
			
		||||
@pytest.mark.parametrize('tag, dockerfile', containers)
 | 
			
		||||
def test_with_confirmation(tag, dockerfile):
 | 
			
		||||
    with spawn(tag, dockerfile, u'tcsh') as proc:
 | 
			
		||||
        proc.sendline(u'tcsh')
 | 
			
		||||
        proc.sendline(u'eval `thefuck-alias`')
 | 
			
		||||
        with_confirmation(proc)
 | 
			
		||||
@pytest.fixture(params=containers)
 | 
			
		||||
def proc(request, spawnu, TIMEOUT):
 | 
			
		||||
    proc = spawnu(*request.param)
 | 
			
		||||
    proc.sendline(u'pip install /src')
 | 
			
		||||
    assert proc.expect([TIMEOUT, u'Successfully installed'])
 | 
			
		||||
    proc.sendline(u'tcsh')
 | 
			
		||||
    proc.sendline(u'setenv PYTHONIOENCODING utf8')
 | 
			
		||||
    proc.sendline(u'eval `thefuck --alias`')
 | 
			
		||||
    return proc
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@functional
 | 
			
		||||
@pytest.mark.parametrize('tag, dockerfile', containers)
 | 
			
		||||
def test_refuse_with_confirmation(tag, dockerfile):
 | 
			
		||||
    with spawn(tag, dockerfile, u'tcsh') as proc:
 | 
			
		||||
        proc.sendline(u'tcsh')
 | 
			
		||||
        proc.sendline(u'eval `thefuck-alias`')
 | 
			
		||||
        refuse_with_confirmation(proc)
 | 
			
		||||
@pytest.mark.functional
 | 
			
		||||
def test_with_confirmation(proc, TIMEOUT):
 | 
			
		||||
    with_confirmation(proc, TIMEOUT)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@functional
 | 
			
		||||
@pytest.mark.parametrize('tag, dockerfile', containers)
 | 
			
		||||
def test_without_confirmation(tag, dockerfile):
 | 
			
		||||
    with spawn(tag, dockerfile, u'tcsh') as proc:
 | 
			
		||||
        proc.sendline(u'tcsh')
 | 
			
		||||
        proc.sendline(u'eval `thefuck-alias`')
 | 
			
		||||
        without_confirmation(proc)
 | 
			
		||||
@pytest.mark.functional
 | 
			
		||||
def test_select_command_with_arrows(proc, TIMEOUT):
 | 
			
		||||
    select_command_with_arrows(proc, TIMEOUT)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.functional
 | 
			
		||||
def test_refuse_with_confirmation(proc, TIMEOUT):
 | 
			
		||||
    refuse_with_confirmation(proc, TIMEOUT)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.functional
 | 
			
		||||
def test_without_confirmation(proc, TIMEOUT):
 | 
			
		||||
    without_confirmation(proc, TIMEOUT)
 | 
			
		||||
 | 
			
		||||
# TODO: ensure that history changes.
 | 
			
		||||
 
 | 
			
		||||
@@ -1,42 +1,58 @@
 | 
			
		||||
import pytest
 | 
			
		||||
from tests.functional.utils import spawn, functional, images
 | 
			
		||||
from tests.functional.plots import with_confirmation, without_confirmation, \
 | 
			
		||||
    refuse_with_confirmation
 | 
			
		||||
    refuse_with_confirmation, history_changed, history_not_changed, \
 | 
			
		||||
    select_command_with_arrows, how_to_configure
 | 
			
		||||
 | 
			
		||||
containers = images(('ubuntu-python3-zsh', u'''
 | 
			
		||||
FROM ubuntu:latest
 | 
			
		||||
RUN apt-get update
 | 
			
		||||
RUN apt-get install -yy python3 python3-pip python3-dev zsh
 | 
			
		||||
RUN pip3 install -U setuptools
 | 
			
		||||
RUN ln -s /usr/bin/pip3 /usr/bin/pip
 | 
			
		||||
'''),
 | 
			
		||||
                    ('ubuntu-python2-zsh', u'''
 | 
			
		||||
FROM ubuntu:latest
 | 
			
		||||
RUN apt-get update
 | 
			
		||||
RUN apt-get install -yy python python-pip python-dev zsh
 | 
			
		||||
RUN pip2 install -U pip setuptools
 | 
			
		||||
'''))
 | 
			
		||||
containers = (('thefuck/python3-zsh',
 | 
			
		||||
               u'''FROM python:3
 | 
			
		||||
                   RUN apt-get update
 | 
			
		||||
                   RUN apt-get install -yy zsh''',
 | 
			
		||||
               u'zsh'),
 | 
			
		||||
              ('thefuck/python2-zsh',
 | 
			
		||||
               u'''FROM python:2
 | 
			
		||||
                   RUN apt-get update
 | 
			
		||||
                   RUN apt-get install -yy zsh''',
 | 
			
		||||
               u'zsh'))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@functional
 | 
			
		||||
@pytest.mark.parametrize('tag, dockerfile', containers)
 | 
			
		||||
def test_with_confirmation(tag, dockerfile):
 | 
			
		||||
    with spawn(tag, dockerfile, u'zsh') as proc:
 | 
			
		||||
        proc.sendline(u'eval $(thefuck-alias)')
 | 
			
		||||
        with_confirmation(proc)
 | 
			
		||||
@pytest.fixture(params=containers)
 | 
			
		||||
def proc(request, spawnu, TIMEOUT):
 | 
			
		||||
    proc = spawnu(*request.param)
 | 
			
		||||
    proc.sendline(u'pip install /src')
 | 
			
		||||
    assert proc.expect([TIMEOUT, u'Successfully installed'])
 | 
			
		||||
    proc.sendline(u'eval $(thefuck --alias)')
 | 
			
		||||
    proc.sendline(u'export HISTFILE=~/.zsh_history')
 | 
			
		||||
    proc.sendline(u'echo > $HISTFILE')
 | 
			
		||||
    proc.sendline(u'export SAVEHIST=100')
 | 
			
		||||
    proc.sendline(u'export HISTSIZE=100')
 | 
			
		||||
    proc.sendline(u'setopt INC_APPEND_HISTORY')
 | 
			
		||||
    return proc
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@functional
 | 
			
		||||
@pytest.mark.parametrize('tag, dockerfile', containers)
 | 
			
		||||
def test_refuse_with_confirmation(tag, dockerfile):
 | 
			
		||||
    with spawn(tag, dockerfile, u'zsh') as proc:
 | 
			
		||||
        proc.sendline(u'eval $(thefuck-alias)')
 | 
			
		||||
        refuse_with_confirmation(proc)
 | 
			
		||||
@pytest.mark.functional
 | 
			
		||||
def test_with_confirmation(proc, TIMEOUT):
 | 
			
		||||
    with_confirmation(proc, TIMEOUT)
 | 
			
		||||
    history_changed(proc, TIMEOUT, u'echo test')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@functional
 | 
			
		||||
@pytest.mark.parametrize('tag, dockerfile', containers)
 | 
			
		||||
def test_without_confirmation(tag, dockerfile):
 | 
			
		||||
    with spawn(tag, dockerfile, u'zsh') as proc:
 | 
			
		||||
        proc.sendline(u'eval $(thefuck-alias)')
 | 
			
		||||
        without_confirmation(proc)
 | 
			
		||||
@pytest.mark.functional
 | 
			
		||||
def test_select_command_with_arrows(proc, TIMEOUT):
 | 
			
		||||
    select_command_with_arrows(proc, TIMEOUT)
 | 
			
		||||
    history_changed(proc, TIMEOUT, u'git help')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.functional
 | 
			
		||||
def test_refuse_with_confirmation(proc, TIMEOUT):
 | 
			
		||||
    refuse_with_confirmation(proc, TIMEOUT)
 | 
			
		||||
    history_not_changed(proc, TIMEOUT)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.functional
 | 
			
		||||
def test_without_confirmation(proc, TIMEOUT):
 | 
			
		||||
    without_confirmation(proc, TIMEOUT)
 | 
			
		||||
    history_changed(proc, TIMEOUT, u'echo test')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.functional
 | 
			
		||||
def test_how_to_configure_alias(proc, TIMEOUT):
 | 
			
		||||
    how_to_configure(proc, TIMEOUT)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,54 +0,0 @@
 | 
			
		||||
import os
 | 
			
		||||
from contextlib import contextmanager
 | 
			
		||||
import subprocess
 | 
			
		||||
import shutil
 | 
			
		||||
from tempfile import mkdtemp
 | 
			
		||||
from pathlib import Path
 | 
			
		||||
import sys
 | 
			
		||||
import pexpect
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
root = str(Path(__file__).parent.parent.parent.resolve())
 | 
			
		||||
bare = os.environ.get('BARE')
 | 
			
		||||
enabled = os.environ.get('FUNCTIONAL')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def build_container(tag, dockerfile):
 | 
			
		||||
    tmpdir = mkdtemp()
 | 
			
		||||
    with Path(tmpdir).joinpath('Dockerfile').open('w') as file:
 | 
			
		||||
        file.write(dockerfile)
 | 
			
		||||
    if subprocess.call(['docker', 'build', '--tag={}'.format(tag), tmpdir],
 | 
			
		||||
                       cwd=root) != 0:
 | 
			
		||||
        raise Exception("Can't build a container")
 | 
			
		||||
    shutil.rmtree(tmpdir)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@contextmanager
 | 
			
		||||
def spawn(tag, dockerfile, cmd):
 | 
			
		||||
    if bare:
 | 
			
		||||
        proc = pexpect.spawnu(cmd)
 | 
			
		||||
    else:
 | 
			
		||||
        tag = 'thefuck/{}'.format(tag)
 | 
			
		||||
        build_container(tag, dockerfile)
 | 
			
		||||
        proc = pexpect.spawnu('docker run --volume {}:/src --tty=true '
 | 
			
		||||
                              '--interactive=true {} {}'.format(root, tag, cmd))
 | 
			
		||||
        proc.sendline('pip install /src')
 | 
			
		||||
 | 
			
		||||
    proc.logfile = sys.stdout
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        yield proc
 | 
			
		||||
    finally:
 | 
			
		||||
        proc.terminate(force=bare)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def images(*items):
 | 
			
		||||
    if bare:
 | 
			
		||||
        return [items[0]]
 | 
			
		||||
    else:
 | 
			
		||||
        return items
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
functional = pytest.mark.skipif(
 | 
			
		||||
    not enabled,
 | 
			
		||||
    reason='Functional tests are disabled by default.')
 | 
			
		||||
@@ -1,6 +0,0 @@
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(autouse=True)
 | 
			
		||||
def generic_shell(monkeypatch):
 | 
			
		||||
    monkeypatch.setattr('thefuck.shells.and_', lambda *x: ' && '.join(x))
 | 
			
		||||
							
								
								
									
										25
									
								
								tests/rules/test_ag_literal.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								tests/rules/test_ag_literal.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
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
 | 
			
		||||
@@ -1,59 +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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 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, None)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command, return_value', [
 | 
			
		||||
@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')])])
 | 
			
		||||
@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, None)
 | 
			
		||||
    assert cmdnf_mock.CommandNotFound.called
 | 
			
		||||
    assert get_packages.called
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
    assert match(command)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command', [
 | 
			
		||||
    Command(script='vim', stderr=''), Command()])
 | 
			
		||||
def test_not_match(command):
 | 
			
		||||
    assert not match(command, None)
 | 
			
		||||
@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),
 | 
			
		||||
    (Command(script='vim', stderr='vim: command not found'),
 | 
			
		||||
     ['vim'], '/usr/bin/vim'),
 | 
			
		||||
    (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
 | 
			
		||||
 | 
			
		||||
    assert not match(command)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 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')])
 | 
			
		||||
def test_get_new_command(command, new_command):
 | 
			
		||||
    assert get_new_command(command, None) == new_command
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command, new_command, return_value', [
 | 
			
		||||
@pytest.mark.parametrize('command, new_command, packages', [
 | 
			
		||||
    (Command('vim'), 'sudo apt-get install vim && vim',
 | 
			
		||||
     [('vim', 'main'), ('vim-tiny', 'main')]),
 | 
			
		||||
    (Command('convert'), 'sudo apt-get install imagemagick && convert',
 | 
			
		||||
     [('imagemagick', 'main'),
 | 
			
		||||
      ('graphicsmagick-imagemagick-compat', 'universe')]),
 | 
			
		||||
    (Command('sudo vim'), 'sudo apt-get install vim && sudo vim',
 | 
			
		||||
     [('vim', 'main'), ('vim-tiny', 'main')]),
 | 
			
		||||
    (Command('sudo convert'), 'sudo apt-get install imagemagick && sudo convert',
 | 
			
		||||
     [('imagemagick', 'main'),
 | 
			
		||||
      ('graphicsmagick-imagemagick-compat', 'universe')])])
 | 
			
		||||
@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, None) == new_command
 | 
			
		||||
    assert cmdnf_mock.CommandNotFound.called
 | 
			
		||||
    assert get_packages.called
 | 
			
		||||
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
 | 
			
		||||
    assert get_new_command(command) == new_command
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										25
									
								
								tests/rules/test_apt_get_search.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								tests/rules/test_apt_get_search.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
import pytest
 | 
			
		||||
from thefuck.rules.apt_get_search import get_new_command, match
 | 
			
		||||
from tests.utils import Command
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_match():
 | 
			
		||||
    assert match(Command('apt-get search foo'))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command', [
 | 
			
		||||
    Command('apt-cache search foo'),
 | 
			
		||||
    Command('aptitude search foo'),
 | 
			
		||||
    Command('apt search foo'),
 | 
			
		||||
    Command('apt-get install foo'),
 | 
			
		||||
    Command('apt-get source foo'),
 | 
			
		||||
    Command('apt-get clean'),
 | 
			
		||||
    Command('apt-get remove'),
 | 
			
		||||
    Command('apt-get update')
 | 
			
		||||
])
 | 
			
		||||
def test_not_match(command):
 | 
			
		||||
    assert not match(command)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_get_new_command():
 | 
			
		||||
    assert get_new_command(Command('apt-get search foo')) == 'apt-cache search foo'
 | 
			
		||||
							
								
								
									
										122
									
								
								tests/rules/test_apt_invalid_operation.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								tests/rules/test_apt_invalid_operation.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,122 @@
 | 
			
		||||
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
 | 
			
		||||
							
								
								
									
										101
									
								
								tests/rules/test_aws_cli.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								tests/rules/test_aws_cli.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,101 @@
 | 
			
		||||
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
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
import pytest
 | 
			
		||||
from thefuck.rules.brew_install import match, get_new_command
 | 
			
		||||
from thefuck.rules.brew_install import brew_formulas
 | 
			
		||||
from thefuck.rules.brew_install import _get_formulas
 | 
			
		||||
from tests.utils import Command
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -20,9 +20,7 @@ def brew_already_installed():
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def _is_not_okay_to_test():
 | 
			
		||||
    if 'elasticsearch' not in brew_formulas:
 | 
			
		||||
        return True
 | 
			
		||||
    return False
 | 
			
		||||
    return 'elasticsearch' not in _get_formulas()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.skipif(_is_not_okay_to_test(),
 | 
			
		||||
@@ -30,20 +28,19 @@ def _is_not_okay_to_test():
 | 
			
		||||
def test_match(brew_no_available_formula, brew_already_installed,
 | 
			
		||||
               brew_install_no_argument):
 | 
			
		||||
    assert match(Command('brew install elsticsearch',
 | 
			
		||||
                         stderr=brew_no_available_formula), None)
 | 
			
		||||
                         stderr=brew_no_available_formula))
 | 
			
		||||
    assert not match(Command('brew install git',
 | 
			
		||||
                             stderr=brew_already_installed), None)
 | 
			
		||||
    assert not match(Command('brew install', stderr=brew_install_no_argument),
 | 
			
		||||
                     None)
 | 
			
		||||
                             stderr=brew_already_installed))
 | 
			
		||||
    assert not match(Command('brew install', stderr=brew_install_no_argument))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.skipif(_is_not_okay_to_test(),
 | 
			
		||||
                    reason='No need to run if there\'s no formula')
 | 
			
		||||
def test_get_new_command(brew_no_available_formula):
 | 
			
		||||
    assert get_new_command(Command('brew install elsticsearch',
 | 
			
		||||
                                   stderr=brew_no_available_formula), None)\
 | 
			
		||||
                                   stderr=brew_no_available_formula))\
 | 
			
		||||
        == 'brew install elasticsearch'
 | 
			
		||||
 | 
			
		||||
    assert get_new_command(Command('brew install aa',
 | 
			
		||||
                                   stderr=brew_no_available_formula),
 | 
			
		||||
                           None) != 'brew install aha'
 | 
			
		||||
                                   stderr=brew_no_available_formula))\
 | 
			
		||||
        != 'brew install aha'
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										38
									
								
								tests/rules/test_brew_link.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								tests/rules/test_brew_link.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
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
 | 
			
		||||
							
								
								
									
										31
									
								
								tests/rules/test_brew_uninstall.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								tests/rules/test_brew_uninstall.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
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
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
import pytest
 | 
			
		||||
from thefuck.rules.brew_unknown_command import match, get_new_command
 | 
			
		||||
from thefuck.rules.brew_unknown_command import brew_commands
 | 
			
		||||
from thefuck.rules.brew_unknown_command import _brew_commands
 | 
			
		||||
from tests.utils import Command
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -15,14 +15,15 @@ def brew_unknown_cmd2():
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_match(brew_unknown_cmd):
 | 
			
		||||
    assert match(Command('brew inst', stderr=brew_unknown_cmd), None)
 | 
			
		||||
    for command in brew_commands:
 | 
			
		||||
        assert not match(Command('brew ' + command), None)
 | 
			
		||||
    assert match(Command('brew inst', stderr=brew_unknown_cmd))
 | 
			
		||||
    for command in _brew_commands():
 | 
			
		||||
        assert not match(Command('brew ' + command))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_get_new_command(brew_unknown_cmd, brew_unknown_cmd2):
 | 
			
		||||
    assert get_new_command(Command('brew inst', stderr=brew_unknown_cmd),
 | 
			
		||||
                           None) == 'brew list'
 | 
			
		||||
    assert get_new_command(Command('brew inst', stderr=brew_unknown_cmd)) \
 | 
			
		||||
           == ['brew list', 'brew install', 'brew uninstall']
 | 
			
		||||
 | 
			
		||||
    assert get_new_command(Command('brew instaa', stderr=brew_unknown_cmd2),
 | 
			
		||||
                           None) == 'brew install'
 | 
			
		||||
    cmds = get_new_command(Command('brew instaa', stderr=brew_unknown_cmd2))
 | 
			
		||||
    assert 'brew install' in cmds
 | 
			
		||||
    assert 'brew uninstall' in cmds
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										30
									
								
								tests/rules/test_brew_update_formula.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								tests/rules/test_brew_update_formula.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
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
 | 
			
		||||
@@ -6,10 +6,10 @@ from tests.utils import Command
 | 
			
		||||
@pytest.mark.parametrize('command', [
 | 
			
		||||
    Command(script='brew upgrade')])
 | 
			
		||||
def test_match(command):
 | 
			
		||||
    assert match(command, None)
 | 
			
		||||
    assert match(command)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command, new_command', [
 | 
			
		||||
    (Command('brew upgrade'), 'brew upgrade --all')])
 | 
			
		||||
def test_get_new_command(command, new_command):
 | 
			
		||||
    assert get_new_command(command, None) == new_command
 | 
			
		||||
    assert get_new_command(command) == new_command
 | 
			
		||||
 
 | 
			
		||||
@@ -3,19 +3,26 @@ from thefuck.rules.cargo_no_command import match, get_new_command
 | 
			
		||||
from tests.utils import Command
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
no_such_subcommand = """No such subcommand
 | 
			
		||||
no_such_subcommand_old = """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)])
 | 
			
		||||
    Command(script='cargo buid', stderr=no_such_subcommand_old),
 | 
			
		||||
    Command(script='cargo buils', stderr=no_such_subcommand)])
 | 
			
		||||
def test_match(command):
 | 
			
		||||
    assert match(command, None)
 | 
			
		||||
    assert match(command)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command, new_command', [
 | 
			
		||||
    (Command('cargo buid', stderr=no_such_subcommand), 'cargo build')])
 | 
			
		||||
    (Command('cargo buid', stderr=no_such_subcommand_old), 'cargo build'),
 | 
			
		||||
    (Command('cargo buils', stderr=no_such_subcommand), 'cargo build')])
 | 
			
		||||
def test_get_new_command(command, new_command):
 | 
			
		||||
    assert get_new_command(command, None) == new_command
 | 
			
		||||
    assert get_new_command(command) == new_command
 | 
			
		||||
 
 | 
			
		||||
@@ -9,17 +9,17 @@ from tests.utils import Command
 | 
			
		||||
            stderr='cd: foo: No such file or directory'),
 | 
			
		||||
    Command(script='cd foo/bar/baz', stderr='cd: can\'t cd to foo/bar/baz')])
 | 
			
		||||
def test_match(command):
 | 
			
		||||
    assert match(command, None)
 | 
			
		||||
    assert match(command)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command', [
 | 
			
		||||
    Command(script='cd foo', stderr=''), Command()])
 | 
			
		||||
def test_not_match(command):
 | 
			
		||||
    assert not match(command, None)
 | 
			
		||||
    assert not match(command)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command, new_command', [
 | 
			
		||||
    (Command('cd foo'), 'mkdir -p foo && cd foo'),
 | 
			
		||||
    (Command('cd foo/bar/baz'), 'mkdir -p foo/bar/baz && cd foo/bar/baz')])
 | 
			
		||||
def test_get_new_command(command, new_command):
 | 
			
		||||
    assert get_new_command(command, None) == new_command
 | 
			
		||||
    assert get_new_command(command) == new_command
 | 
			
		||||
 
 | 
			
		||||
@@ -3,10 +3,10 @@ from tests.utils import Command
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_match():
 | 
			
		||||
    assert match(Command('cd..', stderr='cd..: command not found'), None)
 | 
			
		||||
    assert not match(Command(), None)
 | 
			
		||||
    assert match(Command('cd..', stderr='cd..: command not found'))
 | 
			
		||||
    assert not match(Command())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_get_new_command():
 | 
			
		||||
    assert get_new_command(
 | 
			
		||||
        Command('cd..'), None) == 'cd ..'
 | 
			
		||||
        Command('cd..')) == 'cd ..'
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										39
									
								
								tests/rules/test_chmod_x.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								tests/rules/test_chmod_x.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
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
 | 
			
		||||
@@ -5,49 +5,52 @@ from tests.utils import Command
 | 
			
		||||
 | 
			
		||||
@pytest.fixture
 | 
			
		||||
def composer_not_command():
 | 
			
		||||
    return """
 | 
			
		||||
 | 
			
		||||
                                    
 | 
			
		||||
  [InvalidArgumentException]        
 | 
			
		||||
  Command "udpate" is not defined.  
 | 
			
		||||
  Did you mean this?                
 | 
			
		||||
      update
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
    # that weird spacing is part of the actual command output
 | 
			
		||||
    return (
 | 
			
		||||
        '\n'
 | 
			
		||||
        '\n'
 | 
			
		||||
        '                                    \n'
 | 
			
		||||
        '  [InvalidArgumentException]        \n'
 | 
			
		||||
        '  Command "udpate" is not defined.  \n'
 | 
			
		||||
        '  Did you mean this?                \n'
 | 
			
		||||
        '      update                        \n'
 | 
			
		||||
        '                                    \n'
 | 
			
		||||
        '\n'
 | 
			
		||||
        '\n'
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture
 | 
			
		||||
def composer_not_command_one_of_this():
 | 
			
		||||
    return """
 | 
			
		||||
                            
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  [InvalidArgumentException]       
 | 
			
		||||
  Command "pdate" is not defined.  
 | 
			
		||||
  Did you mean one of these?       
 | 
			
		||||
      selfupdate                   
 | 
			
		||||
      self-update                  
 | 
			
		||||
      update                       
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
    # that weird spacing is part of the actual command output
 | 
			
		||||
    return (
 | 
			
		||||
        '\n'
 | 
			
		||||
        '\n'
 | 
			
		||||
        '                                   \n'
 | 
			
		||||
        '  [InvalidArgumentException]       \n'
 | 
			
		||||
        '  Command "pdate" is not defined.  \n'
 | 
			
		||||
        '  Did you mean one of these?       \n'
 | 
			
		||||
        '      selfupdate                   \n'
 | 
			
		||||
        '      self-update                  \n'
 | 
			
		||||
        '      update                       \n'
 | 
			
		||||
        '                                   \n'
 | 
			
		||||
        '\n'
 | 
			
		||||
        '\n'
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_match(composer_not_command, composer_not_command_one_of_this):
 | 
			
		||||
    assert match(Command('composer udpate',
 | 
			
		||||
                         stderr=composer_not_command), None)
 | 
			
		||||
                         stderr=composer_not_command))
 | 
			
		||||
    assert match(Command('composer pdate',
 | 
			
		||||
                         stderr=composer_not_command_one_of_this), None)
 | 
			
		||||
    assert not match(Command('ls update', stderr=composer_not_command),
 | 
			
		||||
                     None)
 | 
			
		||||
                         stderr=composer_not_command_one_of_this))
 | 
			
		||||
    assert not match(Command('ls update', stderr=composer_not_command))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_get_new_command(composer_not_command, composer_not_command_one_of_this):
 | 
			
		||||
    assert get_new_command(Command('composer udpate',
 | 
			
		||||
                                   stderr=composer_not_command), None) \
 | 
			
		||||
                                   stderr=composer_not_command)) \
 | 
			
		||||
           == 'composer update'
 | 
			
		||||
    assert get_new_command(
 | 
			
		||||
        Command('composer pdate', stderr=composer_not_command_one_of_this),
 | 
			
		||||
        None) == 'composer selfupdate'
 | 
			
		||||
        Command('composer pdate', stderr=composer_not_command_one_of_this)) \
 | 
			
		||||
           == 'composer selfupdate'
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ from tests.utils import Command
 | 
			
		||||
    ('cp dir', 'cp: dor: is a directory'),
 | 
			
		||||
    ('cp dir', "cp: omitting directory 'dir'")])
 | 
			
		||||
def test_match(script, stderr):
 | 
			
		||||
    assert match(Command(script, stderr=stderr), None)
 | 
			
		||||
    assert match(Command(script, stderr=stderr))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('script, stderr', [
 | 
			
		||||
@@ -15,8 +15,8 @@ def test_match(script, stderr):
 | 
			
		||||
    ('some dir', "cp: omitting directory 'dir'"),
 | 
			
		||||
    ('cp dir', '')])
 | 
			
		||||
def test_not_match(script, stderr):
 | 
			
		||||
    assert not match(Command(script, stderr=stderr), None)
 | 
			
		||||
    assert not match(Command(script, stderr=stderr))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_get_new_command():
 | 
			
		||||
    assert get_new_command(Command(script='cp dir'), None) == 'cp -a dir'
 | 
			
		||||
    assert get_new_command(Command(script='cp dir')) == 'cp -a dir'
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										73
									
								
								tests/rules/test_dirty_untar.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								tests/rules/test_dirty_untar.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,73 @@
 | 
			
		||||
import os
 | 
			
		||||
import pytest
 | 
			
		||||
import tarfile
 | 
			
		||||
from thefuck.rules.dirty_untar import match, get_new_command, side_effect, \
 | 
			
		||||
                                      tar_extensions
 | 
			
		||||
from tests.utils import Command
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture
 | 
			
		||||
def tar_error(tmpdir):
 | 
			
		||||
    def fixture(filename):
 | 
			
		||||
        path = os.path.join(str(tmpdir), filename)
 | 
			
		||||
 | 
			
		||||
        def reset(path):
 | 
			
		||||
            os.mkdir('d')
 | 
			
		||||
            with tarfile.TarFile(path, 'w') as archive:
 | 
			
		||||
                for file in ('a', 'b', 'c', 'd/e'):
 | 
			
		||||
                    with open(file, 'w') as f:
 | 
			
		||||
                        f.write('*')
 | 
			
		||||
 | 
			
		||||
                    archive.add(file)
 | 
			
		||||
 | 
			
		||||
                    os.remove(file)
 | 
			
		||||
 | 
			
		||||
            with tarfile.TarFile(path, 'r') as archive:
 | 
			
		||||
                archive.extractall()
 | 
			
		||||
 | 
			
		||||
        os.chdir(str(tmpdir))
 | 
			
		||||
        reset(path)
 | 
			
		||||
 | 
			
		||||
        assert set(os.listdir('.')) == {filename, 'a', 'b', 'c', 'd'}
 | 
			
		||||
        assert set(os.listdir('./d')) == {'e'}
 | 
			
		||||
 | 
			
		||||
    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_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}')])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@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))))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@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'}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@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)))
 | 
			
		||||
							
								
								
									
										72
									
								
								tests/rules/test_dirty_unzip.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								tests/rules/test_dirty_unzip.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,72 @@
 | 
			
		||||
# -*- 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)
 | 
			
		||||
 | 
			
		||||
        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.extractall()
 | 
			
		||||
 | 
			
		||||
        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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@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)
 | 
			
		||||
    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)
 | 
			
		||||
    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'}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@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)
 | 
			
		||||
    assert get_new_command(Command(script=script)) == fixed
 | 
			
		||||
@@ -41,13 +41,13 @@ south.exceptions.GhostMigrations:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_match(stderr):
 | 
			
		||||
    assert match(Command('./manage.py migrate', stderr=stderr), None)
 | 
			
		||||
    assert match(Command('python manage.py migrate', stderr=stderr), None)
 | 
			
		||||
    assert not match(Command('./manage.py migrate'), None)
 | 
			
		||||
    assert not match(Command('app migrate', stderr=stderr), None)
 | 
			
		||||
    assert not match(Command('./manage.py test', stderr=stderr), None)
 | 
			
		||||
    assert match(Command('./manage.py migrate', stderr=stderr))
 | 
			
		||||
    assert match(Command('python manage.py migrate', stderr=stderr))
 | 
			
		||||
    assert not match(Command('./manage.py migrate'))
 | 
			
		||||
    assert not match(Command('app migrate', stderr=stderr))
 | 
			
		||||
    assert not match(Command('./manage.py test', stderr=stderr))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_get_new_command():
 | 
			
		||||
    assert get_new_command(Command('./manage.py migrate auth'), None)\
 | 
			
		||||
    assert get_new_command(Command('./manage.py migrate auth'))\
 | 
			
		||||
        == './manage.py migrate auth --delete-ghost-migrations'
 | 
			
		||||
 
 | 
			
		||||
@@ -31,13 +31,13 @@ The following options are available:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_match(stderr):
 | 
			
		||||
    assert match(Command('./manage.py migrate', stderr=stderr), None)
 | 
			
		||||
    assert match(Command('python manage.py migrate', stderr=stderr), None)
 | 
			
		||||
    assert not match(Command('./manage.py migrate'), None)
 | 
			
		||||
    assert not match(Command('app migrate', stderr=stderr), None)
 | 
			
		||||
    assert not match(Command('./manage.py test', stderr=stderr), None)
 | 
			
		||||
    assert match(Command('./manage.py migrate', stderr=stderr))
 | 
			
		||||
    assert match(Command('python manage.py migrate', stderr=stderr))
 | 
			
		||||
    assert not match(Command('./manage.py migrate'))
 | 
			
		||||
    assert not match(Command('app migrate', stderr=stderr))
 | 
			
		||||
    assert not match(Command('./manage.py test', stderr=stderr))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_get_new_command():
 | 
			
		||||
    assert get_new_command(Command('./manage.py migrate auth'), None) \
 | 
			
		||||
    assert get_new_command(Command('./manage.py migrate auth')) \
 | 
			
		||||
           == './manage.py migrate auth --merge'
 | 
			
		||||
 
 | 
			
		||||
@@ -110,20 +110,20 @@ def stderr(cmd):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_match():
 | 
			
		||||
    assert match(Command('docker pes', stderr=stderr('pes')), None)
 | 
			
		||||
    assert match(Command('docker pes', stderr=stderr('pes')))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('script, stderr', [
 | 
			
		||||
    ('docker ps', ''),
 | 
			
		||||
    ('cat pes', stderr('pes'))])
 | 
			
		||||
def test_not_match(script, stderr):
 | 
			
		||||
    assert not match(Command(script, stderr=stderr), None)
 | 
			
		||||
    assert not match(Command(script, stderr=stderr))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.usefixtures('docker_help')
 | 
			
		||||
@pytest.mark.parametrize('wrong, fixed', [
 | 
			
		||||
    ('pes', 'ps'),
 | 
			
		||||
    ('tags', 'tag')])
 | 
			
		||||
    ('pes', ['ps', 'push', 'pause']),
 | 
			
		||||
    ('tags', ['tag', 'stats', 'images'])])
 | 
			
		||||
def test_get_new_command(wrong, fixed):
 | 
			
		||||
    command = Command('docker {}'.format(wrong), stderr=stderr(wrong))
 | 
			
		||||
    assert get_new_command(command, None) == 'docker {}'.format(fixed)
 | 
			
		||||
    assert get_new_command(command) == ['docker {}'.format(x) for x in fixed]
 | 
			
		||||
 
 | 
			
		||||
@@ -7,11 +7,11 @@ from tests.utils import Command
 | 
			
		||||
    Command(script='cd cd foo'),
 | 
			
		||||
    Command(script='git git push origin/master')])
 | 
			
		||||
def test_match(command):
 | 
			
		||||
    assert match(command, None)
 | 
			
		||||
    assert match(command)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command, new_command', [
 | 
			
		||||
    (Command('cd cd foo'), 'cd foo'),
 | 
			
		||||
    (Command('git git push origin/master'), 'git push origin/master')])
 | 
			
		||||
def test_get_new_command(command, new_command):
 | 
			
		||||
    assert get_new_command(command, None) == new_command
 | 
			
		||||
    assert get_new_command(command) == new_command
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										49
									
								
								tests/rules/test_fab_command_not_found.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								tests/rules/test_fab_command_not_found.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
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
 | 
			
		||||
@@ -11,12 +11,12 @@ def test_match():
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
    assert match(Command(u'ps -ef | grep foo',
 | 
			
		||||
                         stderr=u'-bash:  grep: command not found'), None)
 | 
			
		||||
    assert not match(Command('ps -ef | grep foo'), None)
 | 
			
		||||
    assert not match(Command(), None)
 | 
			
		||||
                         stderr=u'-bash:  grep: command not found'))
 | 
			
		||||
    assert not match(Command('ps -ef | grep foo'))
 | 
			
		||||
    assert not match(Command())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_get_new_command():
 | 
			
		||||
    """ Replace the Alt+Space character by a simple space """
 | 
			
		||||
    assert get_new_command(Command(u'ps -ef | grep foo'), None)\
 | 
			
		||||
    assert get_new_command(Command(u'ps -ef | grep foo'))\
 | 
			
		||||
           == 'ps -ef | grep foo'
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										249
									
								
								tests/rules/test_fix_file.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										249
									
								
								tests/rules/test_fix_file.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,249 @@
 | 
			
		||||
# -*- coding: utf-8 -*-
 | 
			
		||||
 | 
			
		||||
import pytest
 | 
			
		||||
import os
 | 
			
		||||
from thefuck.rules.fix_file import match, get_new_command
 | 
			
		||||
from tests.utils import Command
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# (script, file, line, col (or None), stdout, stderr)
 | 
			
		||||
tests = (
 | 
			
		||||
('gcc a.c', 'a.c', 3, 1, '',
 | 
			
		||||
"""
 | 
			
		||||
a.c: In function 'main':
 | 
			
		||||
a.c:3:1: error: expected expression before '}' token
 | 
			
		||||
 }
 | 
			
		||||
  ^
 | 
			
		||||
"""),
 | 
			
		||||
 | 
			
		||||
('clang a.c', 'a.c', 3, 1, '',
 | 
			
		||||
"""
 | 
			
		||||
a.c:3:1: error: expected expression
 | 
			
		||||
}
 | 
			
		||||
^
 | 
			
		||||
"""),
 | 
			
		||||
 | 
			
		||||
('perl a.pl', 'a.pl', 3, None, '',
 | 
			
		||||
"""
 | 
			
		||||
syntax error at a.pl line 3, at EOF
 | 
			
		||||
Execution of a.pl aborted due to compilation errors.
 | 
			
		||||
"""),
 | 
			
		||||
 | 
			
		||||
('perl a.pl', 'a.pl', 2, None, '',
 | 
			
		||||
"""
 | 
			
		||||
Search pattern not terminated at a.pl line 2.
 | 
			
		||||
"""),
 | 
			
		||||
 | 
			
		||||
('sh a.sh', 'a.sh', 2, None, '',
 | 
			
		||||
"""
 | 
			
		||||
a.sh: line 2: foo: command not found
 | 
			
		||||
"""),
 | 
			
		||||
 | 
			
		||||
('zsh a.sh', 'a.sh', 2, None, '',
 | 
			
		||||
"""
 | 
			
		||||
a.sh:2: command not found: foo
 | 
			
		||||
"""),
 | 
			
		||||
 | 
			
		||||
('bash a.sh', 'a.sh', 2, None, '',
 | 
			
		||||
"""
 | 
			
		||||
a.sh: line 2: foo: command not found
 | 
			
		||||
"""),
 | 
			
		||||
 | 
			
		||||
('rustc a.rs', 'a.rs', 2, 5, '',
 | 
			
		||||
"""
 | 
			
		||||
a.rs:2:5: 2:6 error: unexpected token: `+`
 | 
			
		||||
a.rs:2     +
 | 
			
		||||
           ^
 | 
			
		||||
"""),
 | 
			
		||||
 | 
			
		||||
('cargo build', 'src/lib.rs', 3, 5, '',
 | 
			
		||||
"""
 | 
			
		||||
   Compiling test v0.1.0 (file:///tmp/fix-error/test)
 | 
			
		||||
   src/lib.rs:3:5: 3:6 error: unexpected token: `+`
 | 
			
		||||
   src/lib.rs:3     +
 | 
			
		||||
                    ^
 | 
			
		||||
Could not compile `test`.
 | 
			
		||||
 | 
			
		||||
To learn more, run the command again with --verbose.
 | 
			
		||||
"""),
 | 
			
		||||
 | 
			
		||||
('python a.py', 'a.py', 2, None, '',
 | 
			
		||||
"""
 | 
			
		||||
  File "a.py", line 2
 | 
			
		||||
      +
 | 
			
		||||
          ^
 | 
			
		||||
SyntaxError: invalid syntax
 | 
			
		||||
"""),
 | 
			
		||||
 | 
			
		||||
('python a.py', 'a.py', 8, None, '',
 | 
			
		||||
"""
 | 
			
		||||
Traceback (most recent call last):
 | 
			
		||||
  File "a.py", line 8, in <module>
 | 
			
		||||
    match("foo")
 | 
			
		||||
  File "a.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
 | 
			
		||||
"""),
 | 
			
		||||
 | 
			
		||||
(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
 | 
			
		||||
"""),
 | 
			
		||||
 | 
			
		||||
('lua a.lua', 'a.lua', 2, None, '',
 | 
			
		||||
"""
 | 
			
		||||
lua: a.lua:2: unexpected symbol near '+'
 | 
			
		||||
"""),
 | 
			
		||||
 | 
			
		||||
('fish a.sh', '/tmp/fix-error/a.sh', 2, None, '',
 | 
			
		||||
"""
 | 
			
		||||
fish: Unknown command 'foo'
 | 
			
		||||
/tmp/fix-error/a.sh (line 2): foo
 | 
			
		||||
                              ^
 | 
			
		||||
"""),
 | 
			
		||||
 | 
			
		||||
('./a', './a', 2, None, '',
 | 
			
		||||
"""
 | 
			
		||||
awk: ./a:2: BEGIN { print "Hello, world!" + }
 | 
			
		||||
awk: ./a:2:                                 ^ syntax error
 | 
			
		||||
"""),
 | 
			
		||||
 | 
			
		||||
('llc a.ll', 'a.ll', 1, 2, '',
 | 
			
		||||
"""
 | 
			
		||||
llc: a.ll:1:2: error: expected top-level entity
 | 
			
		||||
+
 | 
			
		||||
^
 | 
			
		||||
"""),
 | 
			
		||||
 | 
			
		||||
('go build a.go', 'a.go', 1, 2, '',
 | 
			
		||||
"""
 | 
			
		||||
can't load package:
 | 
			
		||||
a.go:1:2: expected 'package', found '+'
 | 
			
		||||
"""),
 | 
			
		||||
 | 
			
		||||
('make', 'Makefile', 2, None, '',
 | 
			
		||||
"""
 | 
			
		||||
bidule
 | 
			
		||||
make: bidule: Command not found
 | 
			
		||||
Makefile:2: recipe for target 'target' failed
 | 
			
		||||
make: *** [target] Error 127
 | 
			
		||||
"""),
 | 
			
		||||
 | 
			
		||||
('git st', '/home/martin/.config/git/config', 1, None, '',
 | 
			
		||||
"""
 | 
			
		||||
fatal: bad config file line 1 in /home/martin/.config/git/config
 | 
			
		||||
"""),
 | 
			
		||||
 | 
			
		||||
('node fuck.js asdf qwer', '/Users/pablo/Workspace/barebones/fuck.js', '2', 5, '',
 | 
			
		||||
"""
 | 
			
		||||
/Users/pablo/Workspace/barebones/fuck.js:2
 | 
			
		||||
conole.log(arg);  // this should read console.log(arg);
 | 
			
		||||
^
 | 
			
		||||
ReferenceError: conole is not defined
 | 
			
		||||
    at /Users/pablo/Workspace/barebones/fuck.js:2:5
 | 
			
		||||
    at Array.forEach (native)
 | 
			
		||||
    at Object.<anonymous> (/Users/pablo/Workspace/barebones/fuck.js:1:85)
 | 
			
		||||
    at Module._compile (module.js:460:26)
 | 
			
		||||
    at Object.Module._extensions..js (module.js:478:10)
 | 
			
		||||
    at Module.load (module.js:355:32)
 | 
			
		||||
    at Function.Module._load (module.js:310:12)
 | 
			
		||||
    at Function.Module.runMain (module.js:501:10)
 | 
			
		||||
    at startup (node.js:129:16)
 | 
			
		||||
    at node.js:814:3
 | 
			
		||||
"""),
 | 
			
		||||
 | 
			
		||||
('pep8', './tests/rules/test_systemctl.py', 17, 80,
 | 
			
		||||
"""
 | 
			
		||||
./tests/rules/test_systemctl.py:17:80: E501 line too long (93 > 79 characters)
 | 
			
		||||
./tests/rules/test_systemctl.py:18:80: E501 line too long (103 > 79 characters)
 | 
			
		||||
./tests/rules/test_whois.py:20:80: E501 line too long (89 > 79 characters)
 | 
			
		||||
./tests/rules/test_whois.py:22:80: E501 line too long (83 > 79 characters)
 | 
			
		||||
""", ''),
 | 
			
		||||
 | 
			
		||||
('py.test', '/home/thefuck/tests/rules/test_fix_file.py', 218, None,
 | 
			
		||||
"""
 | 
			
		||||
monkeypatch = <_pytest.monkeypatch.monkeypatch object at 0x7fdb76a25b38>
 | 
			
		||||
test = ('fish a.sh', '/tmp/fix-error/a.sh', 2, None, '', "\\nfish: Unknown command 'foo'\\n/tmp/fix-error/a.sh (line 2): foo\\n                              ^\\n")
 | 
			
		||||
 | 
			
		||||
    @pytest.mark.parametrize('test', tests)
 | 
			
		||||
    @pytest.mark.usefixtures('no_memoize')
 | 
			
		||||
    def test_get_new_command(monkeypatch, test):
 | 
			
		||||
>       mocker.patch('os.path.isfile', return_value=True)
 | 
			
		||||
E       NameError: name 'mocker' is not defined
 | 
			
		||||
 | 
			
		||||
/home/thefuck/tests/rules/test_fix_file.py:218: NameError
 | 
			
		||||
""", ''),
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('test', tests)
 | 
			
		||||
@pytest.mark.usefixtures('no_memoize')
 | 
			
		||||
def test_match(mocker, monkeypatch, test):
 | 
			
		||||
    mocker.patch('os.path.isfile', return_value=True)
 | 
			
		||||
    monkeypatch.setenv('EDITOR', 'dummy_editor')
 | 
			
		||||
    assert match(Command(stdout=test[4], stderr=test[5]))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('test', tests)
 | 
			
		||||
@pytest.mark.usefixtures('no_memoize')
 | 
			
		||||
def test_no_editor(mocker, monkeypatch, test):
 | 
			
		||||
    mocker.patch('os.path.isfile', return_value=True)
 | 
			
		||||
    if 'EDITOR' in os.environ:
 | 
			
		||||
        monkeypatch.delenv('EDITOR')
 | 
			
		||||
 | 
			
		||||
    assert not match(Command(stdout=test[4], stderr=test[5]))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('test', tests)
 | 
			
		||||
@pytest.mark.usefixtures('no_memoize')
 | 
			
		||||
def test_not_file(mocker, monkeypatch, test):
 | 
			
		||||
    mocker.patch('os.path.isfile', return_value=False)
 | 
			
		||||
    monkeypatch.setenv('EDITOR', 'dummy_editor')
 | 
			
		||||
 | 
			
		||||
    assert not match(Command(stdout=test[4], stderr=test[5]))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('test', tests)
 | 
			
		||||
@pytest.mark.usefixtures('no_memoize')
 | 
			
		||||
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')
 | 
			
		||||
def test_get_new_command_with_settings(mocker, monkeypatch, test, settings):
 | 
			
		||||
    mocker.patch('os.path.isfile', return_value=True)
 | 
			
		||||
    monkeypatch.setenv('EDITOR', 'dummy_editor')
 | 
			
		||||
 | 
			
		||||
    cmd = Command(script=test[0], stdout=test[4], stderr=test[5])
 | 
			
		||||
    settings.fixcolcmd = '{editor} {file} +{line}:{col}'
 | 
			
		||||
 | 
			
		||||
    if test[3]:
 | 
			
		||||
        assert (get_new_command(cmd) ==
 | 
			
		||||
            u'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]))
 | 
			
		||||
@@ -3,37 +3,38 @@ 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 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
 | 
			
		||||
def stderr(target):
 | 
			
		||||
    return ("error: pathspec '{}' did not match any "
 | 
			
		||||
            'file(s) known to git.'.format(target))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@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, None)
 | 
			
		||||
@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 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, None)
 | 
			
		||||
@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, new_command', [
 | 
			
		||||
    (Command('git submodule update unknown', stderr=did_not_match('unknown')),
 | 
			
		||||
@pytest.mark.parametrize('script, target, new_command', [
 | 
			
		||||
    ('git submodule update unknown', 'unknown',
 | 
			
		||||
     'git add -- unknown && git submodule update unknown'),
 | 
			
		||||
    (Command('git commit unknown', stderr=did_not_match('unknown')),  # Old Git
 | 
			
		||||
    ('git commit unknown', 'unknown',
 | 
			
		||||
     'git add -- unknown && git commit unknown')])
 | 
			
		||||
def test_get_new_command(command, new_command):
 | 
			
		||||
    assert get_new_command(command, None) == new_command
 | 
			
		||||
def test_get_new_command(stderr, script, target, new_command):
 | 
			
		||||
    assert get_new_command(Command(script=script, stderr=stderr)) == new_command
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										30
									
								
								tests/rules/test_git_bisect_usage.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								tests/rules/test_git_bisect_usage.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
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
 | 
			
		||||
@@ -12,11 +12,11 @@ If you are sure you want to delete it, run 'git branch -D branch'.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_match(stderr):
 | 
			
		||||
    assert match(Command('git branch -d branch', stderr=stderr), None)
 | 
			
		||||
    assert not match(Command('git branch -d branch'), None)
 | 
			
		||||
    assert not match(Command('ls', stderr=stderr), None)
 | 
			
		||||
    assert match(Command('git branch -d branch', stderr=stderr))
 | 
			
		||||
    assert not match(Command('git branch -d branch'))
 | 
			
		||||
    assert not match(Command('ls', stderr=stderr))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_get_new_command(stderr):
 | 
			
		||||
    assert get_new_command(Command('git branch -d branch', stderr=stderr), None)\
 | 
			
		||||
    assert get_new_command(Command('git branch -d branch', stderr=stderr))\
 | 
			
		||||
        == "git branch -D branch"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										34
									
								
								tests/rules/test_git_branch_exists.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								tests/rules/test_git_branch_exists.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
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
 | 
			
		||||
@@ -1,18 +1,19 @@
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_match():
 | 
			
		||||
    assert match(Command('git branch list'), None)
 | 
			
		||||
    assert match(Command('git branch list'))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_not_match():
 | 
			
		||||
    assert not match(Command(), None)
 | 
			
		||||
    assert not match(Command('git commit'), None)
 | 
			
		||||
    assert not match(Command('git branch'), None)
 | 
			
		||||
    assert not match(Command('git stash list'), None)
 | 
			
		||||
    assert not match(Command())
 | 
			
		||||
    assert not match(Command('git commit'))
 | 
			
		||||
    assert not match(Command('git branch'))
 | 
			
		||||
    assert not match(Command('git stash list'))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_get_new_command():
 | 
			
		||||
    assert (get_new_command(Command('git branch list'), None) ==
 | 
			
		||||
            shells.and_('git branch --delete list', 'git branch'))
 | 
			
		||||
    assert (get_new_command(Command('git branch list')) ==
 | 
			
		||||
            shell.and_('git branch --delete list', 'git branch'))
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
import pytest
 | 
			
		||||
from thefuck.rules.git_checkout import match, get_new_command
 | 
			
		||||
from io import BytesIO
 | 
			
		||||
from thefuck.rules.git_checkout import match, get_branches, get_new_command
 | 
			
		||||
from tests.utils import Command
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -13,15 +14,17 @@ def did_not_match(target, did_you_forget=False):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture
 | 
			
		||||
def get_branches(mocker):
 | 
			
		||||
    return mocker.patch('thefuck.rules.git_checkout.get_branches')
 | 
			
		||||
def git_branch(mocker, branches):
 | 
			
		||||
    mock = mocker.patch('subprocess.Popen')
 | 
			
		||||
    mock.return_value.stdout = BytesIO(branches)
 | 
			
		||||
    return mock
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command', [
 | 
			
		||||
    Command(script='git checkout unknown', stderr=did_not_match('unknown')),
 | 
			
		||||
    Command(script='git commit unknown', stderr=did_not_match('unknown'))])
 | 
			
		||||
def test_match(command):
 | 
			
		||||
    assert match(command, None)
 | 
			
		||||
    assert match(command)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command', [
 | 
			
		||||
@@ -30,24 +33,37 @@ def test_match(command):
 | 
			
		||||
    Command(script='git checkout known', stderr=('')),
 | 
			
		||||
    Command(script='git commit known', stderr=(''))])
 | 
			
		||||
def test_not_match(command):
 | 
			
		||||
    assert not match(command, None)
 | 
			
		||||
    assert not match(command)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('branches, 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'),
 | 
			
		||||
    (['test-random-branch-123'],
 | 
			
		||||
    (b'  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'),
 | 
			
		||||
    (['test-random-branch-123'],
 | 
			
		||||
    (b'  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, get_branches):
 | 
			
		||||
    get_branches.return_value = branches
 | 
			
		||||
    assert get_new_command(command, None) == new_command
 | 
			
		||||
def test_get_new_command(branches, command, new_command, git_branch):
 | 
			
		||||
    git_branch(branches)
 | 
			
		||||
    assert get_new_command(command) == new_command
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										23
									
								
								tests/rules/test_git_diff_no_index.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								tests/rules/test_git_diff_no_index.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
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
 | 
			
		||||
@@ -7,7 +7,7 @@ from tests.utils import Command
 | 
			
		||||
    Command(script='git diff foo'),
 | 
			
		||||
    Command(script='git diff')])
 | 
			
		||||
def test_match(command):
 | 
			
		||||
    assert match(command, None)
 | 
			
		||||
    assert match(command)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command', [
 | 
			
		||||
@@ -16,11 +16,11 @@ def test_match(command):
 | 
			
		||||
    Command(script='git branch'),
 | 
			
		||||
    Command(script='git log')])
 | 
			
		||||
def test_not_match(command):
 | 
			
		||||
    assert not match(command, None)
 | 
			
		||||
    assert not match(command)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command, new_command', [
 | 
			
		||||
    (Command('git diff'), 'git diff --staged'),
 | 
			
		||||
    (Command('git diff foo'), 'git diff --staged foo')])
 | 
			
		||||
def test_get_new_command(command, new_command):
 | 
			
		||||
    assert get_new_command(command, None) == new_command
 | 
			
		||||
    assert get_new_command(command) == new_command
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@ usage: git stash list [<options>]
 | 
			
		||||
   or: git stash ( pop | apply ) [--index] [-q|--quiet] [<stash>]
 | 
			
		||||
   or: git stash branch <branchname> [<stash>]
 | 
			
		||||
   or: git stash [save [--patch] [-k|--[no-]keep-index] [-q|--quiet]
 | 
			
		||||
		       [-u|--include-untracked] [-a|--all] [<message>]]
 | 
			
		||||
\t\t       [-u|--include-untracked] [-a|--all] [<message>]]
 | 
			
		||||
   or: git stash clear
 | 
			
		||||
'''
 | 
			
		||||
 | 
			
		||||
@@ -20,7 +20,11 @@ usage: git stash list [<options>]
 | 
			
		||||
    'git stash Some message',
 | 
			
		||||
    'git stash saev Some message'])
 | 
			
		||||
def test_match(wrong):
 | 
			
		||||
    assert match(Command(wrong, stderr=git_stash_err), None)
 | 
			
		||||
    assert match(Command(wrong, stderr=git_stash_err))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_not_match():
 | 
			
		||||
    assert not match(Command("git", stderr=git_stash_err))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('wrong,fixed', [
 | 
			
		||||
@@ -28,4 +32,4 @@ def test_match(wrong):
 | 
			
		||||
    ('git stash Some message', 'git stash save Some message'),
 | 
			
		||||
    ('git stash saev Some message', 'git stash save Some message')])
 | 
			
		||||
def test_get_new_command(wrong, fixed):
 | 
			
		||||
    assert get_new_command(Command(wrong, stderr=git_stash_err), None) == fixed
 | 
			
		||||
    assert get_new_command(Command(wrong, stderr=git_stash_err)) == fixed
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										31
									
								
								tests/rules/test_git_flag_after_filename.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								tests/rules/test_git_flag_after_filename.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
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
 | 
			
		||||
							
								
								
									
										24
									
								
								tests/rules/test_git_help_aliased.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								tests/rules/test_git_help_aliased.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
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
 | 
			
		||||
@@ -30,8 +30,8 @@ def git_not_command_closest():
 | 
			
		||||
    return '''git: 'tags' is not a git command. See 'git --help'.
 | 
			
		||||
 | 
			
		||||
Did you mean one of these?
 | 
			
		||||
	stage
 | 
			
		||||
	tag
 | 
			
		||||
\tstage
 | 
			
		||||
\ttag
 | 
			
		||||
'''
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -41,17 +41,17 @@ def git_command():
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_match(git_not_command, git_command, git_not_command_one_of_this):
 | 
			
		||||
    assert match(Command('git brnch', stderr=git_not_command), None)
 | 
			
		||||
    assert match(Command('git st', stderr=git_not_command_one_of_this), None)
 | 
			
		||||
    assert not match(Command('ls brnch', stderr=git_not_command), None)
 | 
			
		||||
    assert not match(Command('git branch', stderr=git_command), None)
 | 
			
		||||
    assert match(Command('git brnch', stderr=git_not_command))
 | 
			
		||||
    assert match(Command('git st', stderr=git_not_command_one_of_this))
 | 
			
		||||
    assert not match(Command('ls brnch', stderr=git_not_command))
 | 
			
		||||
    assert not match(Command('git branch', stderr=git_command))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_get_new_command(git_not_command, git_not_command_one_of_this,
 | 
			
		||||
                         git_not_command_closest):
 | 
			
		||||
    assert get_new_command(Command('git brnch', stderr=git_not_command), None) \
 | 
			
		||||
           == 'git branch'
 | 
			
		||||
    assert get_new_command(Command('git st', stderr=git_not_command_one_of_this),
 | 
			
		||||
                           None) == 'git status'
 | 
			
		||||
    assert get_new_command(Command('git tags', stderr=git_not_command_closest),
 | 
			
		||||
                           None) == 'git tag'
 | 
			
		||||
    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']
 | 
			
		||||
 
 | 
			
		||||
@@ -19,11 +19,11 @@ If you wish to set tracking information for this branch you can do so with:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_match(stderr):
 | 
			
		||||
    assert match(Command('git pull', stderr=stderr), None)
 | 
			
		||||
    assert not match(Command('git pull'), None)
 | 
			
		||||
    assert not match(Command('ls', stderr=stderr), None)
 | 
			
		||||
    assert match(Command('git pull', stderr=stderr))
 | 
			
		||||
    assert not match(Command('git pull'))
 | 
			
		||||
    assert not match(Command('ls', stderr=stderr))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_get_new_command(stderr):
 | 
			
		||||
    assert get_new_command(Command('git pull', stderr=stderr), None) \
 | 
			
		||||
    assert get_new_command(Command('git pull', stderr=stderr)) \
 | 
			
		||||
           == "git branch --set-upstream-to=origin/master master && git pull"
 | 
			
		||||
 
 | 
			
		||||
@@ -12,10 +12,10 @@ Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
 | 
			
		||||
@pytest.mark.parametrize('command', [
 | 
			
		||||
    Command(script='git pull git@github.com:mcarton/thefuck.git', stderr=git_err)])
 | 
			
		||||
def test_match(command):
 | 
			
		||||
    assert match(command, None)
 | 
			
		||||
    assert match(command)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command, output', [
 | 
			
		||||
    (Command(script='git pull git@github.com:mcarton/thefuck.git', stderr=git_err), 'git clone git@github.com:mcarton/thefuck.git')])
 | 
			
		||||
def test_get_new_command(command, output):
 | 
			
		||||
    assert get_new_command(command, None) == output
 | 
			
		||||
    assert get_new_command(command) == output
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										19
									
								
								tests/rules/test_git_pull_uncommitted_changes.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								tests/rules/test_git_pull_uncommitted_changes.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
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"
 | 
			
		||||
							
								
								
									
										19
									
								
								tests/rules/test_git_pull_unstaged_changes.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								tests/rules/test_git_pull_unstaged_changes.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
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"
 | 
			
		||||
@@ -14,11 +14,20 @@ To push the current branch and set the remote as upstream, use
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_match(stderr):
 | 
			
		||||
    assert match(Command('git push master', stderr=stderr), None)
 | 
			
		||||
    assert not match(Command('git push master'), None)
 | 
			
		||||
    assert not match(Command('ls', stderr=stderr), None)
 | 
			
		||||
    assert match(Command('git push', stderr=stderr))
 | 
			
		||||
    assert match(Command('git push master', stderr=stderr))
 | 
			
		||||
    assert not match(Command('git push master'))
 | 
			
		||||
    assert not match(Command('ls', stderr=stderr))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_get_new_command(stderr):
 | 
			
		||||
    assert get_new_command(Command('git push', stderr=stderr), None)\
 | 
			
		||||
    assert get_new_command(Command('git push', stderr=stderr))\
 | 
			
		||||
        == "git push --set-upstream origin master"
 | 
			
		||||
    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"
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@ To /tmp/bar
 | 
			
		||||
    Command(script='git push nvbn', stderr=git_err),
 | 
			
		||||
    Command(script='git push nvbn master', stderr=git_err)])
 | 
			
		||||
def test_match(command):
 | 
			
		||||
    assert match(command, None)
 | 
			
		||||
    assert match(command)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command', [
 | 
			
		||||
@@ -41,12 +41,12 @@ def test_match(command):
 | 
			
		||||
    Command(script='git push nvbn', stderr=git_ok),
 | 
			
		||||
    Command(script='git push nvbn master', stderr=git_uptodate)])
 | 
			
		||||
def test_not_match(command):
 | 
			
		||||
    assert not match(command, None)
 | 
			
		||||
    assert not match(command)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command, output', [
 | 
			
		||||
    (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')])
 | 
			
		||||
    (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')])
 | 
			
		||||
def test_get_new_command(command, output):
 | 
			
		||||
    assert get_new_command(command, None) == output
 | 
			
		||||
    assert get_new_command(command) == output
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,17 @@ 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.
 | 
			
		||||
@@ -30,7 +41,15 @@ To /tmp/bar
 | 
			
		||||
    Command(script='git push nvbn', stderr=git_err),
 | 
			
		||||
    Command(script='git push nvbn master', stderr=git_err)])
 | 
			
		||||
def test_match(command):
 | 
			
		||||
    assert match(command, None)
 | 
			
		||||
    assert match(command)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command', [
 | 
			
		||||
    Command(script='git push', stderr=git_err2),
 | 
			
		||||
    Command(script='git push nvbn', stderr=git_err2),
 | 
			
		||||
    Command(script='git push nvbn master', stderr=git_err2)])
 | 
			
		||||
def test_match(command):
 | 
			
		||||
    assert match(command)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command', [
 | 
			
		||||
@@ -41,7 +60,7 @@ def test_match(command):
 | 
			
		||||
    Command(script='git push nvbn', stderr=git_ok),
 | 
			
		||||
    Command(script='git push nvbn master', stderr=git_uptodate)])
 | 
			
		||||
def test_not_match(command):
 | 
			
		||||
    assert not match(command, None)
 | 
			
		||||
    assert not match(command)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command, output', [
 | 
			
		||||
@@ -51,4 +70,14 @@ def test_not_match(command):
 | 
			
		||||
    (Command(script='git push nvbn master', stderr=git_err),
 | 
			
		||||
     'git pull nvbn master && git push nvbn master')])
 | 
			
		||||
def test_get_new_command(command, output):
 | 
			
		||||
    assert get_new_command(command, None) == output
 | 
			
		||||
    assert get_new_command(command) == output
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command, output', [
 | 
			
		||||
    (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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										40
									
								
								tests/rules/test_git_rebase_merge_dir.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								tests/rules/test_git_rebase_merge_dir.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
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
 | 
			
		||||
							
								
								
									
										28
									
								
								tests/rules/test_git_rebase_no_changes.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								tests/rules/test_git_rebase_no_changes.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
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')
 | 
			
		||||
							
								
								
									
										26
									
								
								tests/rules/test_git_remote_seturl_add.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								tests/rules/test_git_remote_seturl_add.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
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
 | 
			
		||||
							
								
								
									
										28
									
								
								tests/rules/test_git_rm_local_modifications.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								tests/rules/test_git_rm_local_modifications.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
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
 | 
			
		||||
							
								
								
									
										27
									
								
								tests/rules/test_git_rm_recursive.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								tests/rules/test_git_rm_recursive.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
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
 | 
			
		||||
@@ -18,14 +18,14 @@ rebase_error = (
 | 
			
		||||
    Command(script='git cherry-pick a1b2c3d', stderr=cherry_pick_error),
 | 
			
		||||
    Command(script='git rebase -i HEAD~7', stderr=rebase_error)])
 | 
			
		||||
def test_match(command):
 | 
			
		||||
    assert match(command, None)
 | 
			
		||||
    assert match(command)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command', [
 | 
			
		||||
    Command(script='git cherry-pick a1b2c3d', stderr=('')),
 | 
			
		||||
    Command(script='git rebase -i HEAD~7', stderr=(''))])
 | 
			
		||||
def test_not_match(command):
 | 
			
		||||
    assert not match(command, None)
 | 
			
		||||
    assert not match(command)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command, new_command', [
 | 
			
		||||
@@ -34,4 +34,4 @@ def test_not_match(command):
 | 
			
		||||
    (Command('git rebase -i HEAD~7', stderr=rebase_error),
 | 
			
		||||
     'git stash && git rebase -i HEAD~7')])
 | 
			
		||||
def test_get_new_command(command, new_command):
 | 
			
		||||
    assert get_new_command(command, None) == new_command
 | 
			
		||||
    assert get_new_command(command) == new_command
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										18
									
								
								tests/rules/test_git_stash_pop.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								tests/rules/test_git_stash_pop.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
			
		||||
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 ."
 | 
			
		||||
							
								
								
									
										47
									
								
								tests/rules/test_git_two_dashes.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								tests/rules/test_git_two_dashes.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
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
 | 
			
		||||
@@ -7,11 +7,11 @@ from tests.utils import Command
 | 
			
		||||
    Command(script='go run foo'),
 | 
			
		||||
    Command(script='go run bar')])
 | 
			
		||||
def test_match(command):
 | 
			
		||||
    assert match(command, None)
 | 
			
		||||
    assert match(command)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command, new_command', [
 | 
			
		||||
    (Command('go run foo'), 'go run foo.go'),
 | 
			
		||||
    (Command('go run bar'), 'go run bar.go')])
 | 
			
		||||
def test_get_new_command(command, new_command):
 | 
			
		||||
    assert get_new_command(command, None) == new_command
 | 
			
		||||
    assert get_new_command(command) == new_command
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										158
									
								
								tests/rules/test_gradle_not_task.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								tests/rules/test_gradle_not_task.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,158 @@
 | 
			
		||||
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
 | 
			
		||||
							
								
								
									
										38
									
								
								tests/rules/test_gradle_wrapper.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								tests/rules/test_gradle_wrapper.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
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
 | 
			
		||||
							
								
								
									
										40
									
								
								tests/rules/test_grep_arguments_order.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								tests/rules/test_grep_arguments_order.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
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
 | 
			
		||||
@@ -1,12 +1,15 @@
 | 
			
		||||
# -*- 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'), None)
 | 
			
		||||
    assert not match(Command(), None)
 | 
			
		||||
    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 .'), None) == 'grep -r blah .'
 | 
			
		||||
    assert get_new_command(Command('grep blah .')) == 'grep -r blah .'
 | 
			
		||||
    assert get_new_command(Command(u'grep café .')) == u'grep -r café .'
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										129
									
								
								tests/rules/test_grunt_task_not_found.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								tests/rules/test_grunt_task_not_found.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,129 @@
 | 
			
		||||
# -*- 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
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
import pytest
 | 
			
		||||
from io import BytesIO
 | 
			
		||||
from tests.utils import Command
 | 
			
		||||
from thefuck.rules.gulp_not_task import match, get_new_command
 | 
			
		||||
 | 
			
		||||
@@ -11,18 +12,18 @@ def stdout(task):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_match():
 | 
			
		||||
    assert match(Command('gulp srve', stdout('srve')), None)
 | 
			
		||||
    assert match(Command('gulp srve', stdout('srve')))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('script, stdout', [
 | 
			
		||||
    ('gulp serve', ''),
 | 
			
		||||
    ('cat srve', stdout('srve'))])
 | 
			
		||||
def test_not_march(script, stdout):
 | 
			
		||||
    assert not match(Command(script, stdout), None)
 | 
			
		||||
    assert not match(Command(script, stdout))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_get_new_command(mocker):
 | 
			
		||||
    mocker.patch('thefuck.rules.gulp_not_task.get_gulp_tasks', return_value=[
 | 
			
		||||
        'serve', 'build', 'default'])
 | 
			
		||||
    mock = mocker.patch('subprocess.Popen')
 | 
			
		||||
    mock.return_value.stdout = BytesIO(b'serve \nbuild \ndefault \n')
 | 
			
		||||
    command = Command('gulp srve', stdout('srve'))
 | 
			
		||||
    assert get_new_command(command, None) == 'gulp serve'
 | 
			
		||||
    assert get_new_command(command) == ['gulp serve', 'gulp default']
 | 
			
		||||
 
 | 
			
		||||
@@ -1,20 +1,18 @@
 | 
			
		||||
from mock import Mock, patch
 | 
			
		||||
from mock import 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(Mock(script='main', stderr='main: command not found'),
 | 
			
		||||
                     None)
 | 
			
		||||
        assert match(Mock(script='main --help',
 | 
			
		||||
                          stderr='main: command not found'),
 | 
			
		||||
                     None)
 | 
			
		||||
        assert not match(Mock(script='main', stderr=''), None)
 | 
			
		||||
        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=''))
 | 
			
		||||
 | 
			
		||||
    with patch('os.path.exists', return_value=False):
 | 
			
		||||
        assert not match(Mock(script='main', stderr='main: command not found'),
 | 
			
		||||
                         None)
 | 
			
		||||
        assert not match(Command(script='main', stderr='main: command not found'))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_get_new_command():
 | 
			
		||||
    assert get_new_command(Mock(script='main --help'), None) == './main --help'
 | 
			
		||||
    assert get_new_command(Command(script='main --help')) == './main --help'
 | 
			
		||||
 
 | 
			
		||||
@@ -16,19 +16,19 @@ no_suggest_stderr = ''' !    `aaaaa` is not a heroku command.
 | 
			
		||||
@pytest.mark.parametrize('cmd', ['log', 'pge'])
 | 
			
		||||
def test_match(cmd):
 | 
			
		||||
    assert match(
 | 
			
		||||
        Command('heroku {}'.format(cmd), stderr=suggest_stderr(cmd)), None)
 | 
			
		||||
        Command('heroku {}'.format(cmd), stderr=suggest_stderr(cmd)))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('script, stderr', [
 | 
			
		||||
    ('cat log', suggest_stderr('log')),
 | 
			
		||||
    ('heroku aaa', no_suggest_stderr)])
 | 
			
		||||
def test_not_match(script, stderr):
 | 
			
		||||
    assert not match(Command(script, stderr=stderr), None)
 | 
			
		||||
    assert not match(Command(script, stderr=stderr))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('cmd, result', [
 | 
			
		||||
    ('log', 'heroku logs'),
 | 
			
		||||
    ('pge', 'heroku pg')])
 | 
			
		||||
    ('log', ['heroku logs', 'heroku pg']),
 | 
			
		||||
    ('pge', ['heroku pg', 'heroku logs'])])
 | 
			
		||||
def test_get_new_command(cmd, result):
 | 
			
		||||
    command = Command('heroku {}'.format(cmd), stderr=suggest_stderr(cmd))
 | 
			
		||||
    assert get_new_command(command, None) == result
 | 
			
		||||
    assert get_new_command(command) == result
 | 
			
		||||
 
 | 
			
		||||
@@ -3,40 +3,25 @@ from thefuck.rules.history import match, get_new_command
 | 
			
		||||
from tests.utils import Command
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@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(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 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), None)
 | 
			
		||||
    assert match(Command(script=script))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.usefixtures('history', 'callables', 'no_memoize', 'alias')
 | 
			
		||||
@pytest.mark.parametrize('script', ['apt-get', 'nocommand y'])
 | 
			
		||||
def test_not_match(script):
 | 
			
		||||
    assert not match(Command(script=script), None)
 | 
			
		||||
    assert not match(Command(script=script))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.usefixtures('history', 'callables', 'no_memoize', 'alias')
 | 
			
		||||
@pytest.mark.parametrize('script, result', [
 | 
			
		||||
    ('ls cet', 'ls cat'),
 | 
			
		||||
    ('daff x', 'diff x')])
 | 
			
		||||
def test_get_new_command(script, result):
 | 
			
		||||
    assert get_new_command(Command(script), None) == result
 | 
			
		||||
    assert get_new_command(Command(script)) == result
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										53
									
								
								tests/rules/test_ifconfig_device_not_found.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								tests/rules/test_ifconfig_device_not_found.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
			
		||||
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
 | 
			
		||||
@@ -7,11 +7,11 @@ from tests.utils import Command
 | 
			
		||||
    Command(script='java foo.java'),
 | 
			
		||||
    Command(script='java bar.java')])
 | 
			
		||||
def test_match(command):
 | 
			
		||||
    assert match(command, None)
 | 
			
		||||
    assert match(command)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command, new_command', [
 | 
			
		||||
    (Command('java foo.java'), 'java foo'),
 | 
			
		||||
    (Command('java bar.java'), 'java bar')])
 | 
			
		||||
def test_get_new_command(command, new_command):
 | 
			
		||||
    assert get_new_command(command, None) == new_command
 | 
			
		||||
    assert get_new_command(command) == new_command
 | 
			
		||||
 
 | 
			
		||||
@@ -7,11 +7,11 @@ from tests.utils import Command
 | 
			
		||||
    Command(script='javac foo'),
 | 
			
		||||
    Command(script='javac bar')])
 | 
			
		||||
def test_match(command):
 | 
			
		||||
    assert match(command, None)
 | 
			
		||||
    assert match(command)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command, new_command', [
 | 
			
		||||
    (Command('javac foo'), 'javac foo.java'),
 | 
			
		||||
    (Command('javac bar'), 'javac bar.java')])
 | 
			
		||||
def test_get_new_command(command, new_command):
 | 
			
		||||
    assert get_new_command(command, None) == new_command
 | 
			
		||||
    assert get_new_command(command) == new_command
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
import pytest
 | 
			
		||||
from mock import Mock
 | 
			
		||||
from thefuck.rules.lein_not_task import match, get_new_command
 | 
			
		||||
from tests.utils import Command
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture
 | 
			
		||||
@@ -9,14 +9,15 @@ def is_not_task():
 | 
			
		||||
 | 
			
		||||
Did you mean this?
 | 
			
		||||
         repl
 | 
			
		||||
         jar
 | 
			
		||||
'''
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_match(is_not_task):
 | 
			
		||||
    assert match(Mock(script='lein rpl', stderr=is_not_task), None)
 | 
			
		||||
    assert not match(Mock(script='ls', stderr=is_not_task), None)
 | 
			
		||||
    assert match(Command(script='lein rpl', stderr=is_not_task))
 | 
			
		||||
    assert not match(Command(script='ls', stderr=is_not_task))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_get_new_command(is_not_task):
 | 
			
		||||
    assert get_new_command(Mock(script='lein rpl --help', stderr=is_not_task),
 | 
			
		||||
                           None) == 'lein repl --help'
 | 
			
		||||
    assert get_new_command(Command(script='lein rpl --help', stderr=is_not_task)) \
 | 
			
		||||
           == ['lein repl --help', 'lein jar --help']
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										37
									
								
								tests/rules/test_ln_no_hard_link.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								tests/rules/test_ln_no_hard_link.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
# -*- 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
 | 
			
		||||
							
								
								
									
										41
									
								
								tests/rules/test_ln_s_order.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								tests/rules/test_ln_s_order.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
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.usefixtures('file_exists')
 | 
			
		||||
@pytest.mark.parametrize('script', [
 | 
			
		||||
    'ln -s dest source',
 | 
			
		||||
    'ln dest -s source',
 | 
			
		||||
    'ln dest source -s'])
 | 
			
		||||
def test_match(script):
 | 
			
		||||
    stderr = get_stderr('source')
 | 
			
		||||
    assert match(Command(script, stderr=stderr))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('script, stderr, exists', [
 | 
			
		||||
    ('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 get_new_command(Command(script, stderr=stderr)) == result
 | 
			
		||||
							
								
								
									
										12
									
								
								tests/rules/test_ls_all.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								tests/rules/test_ls_all.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
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'
 | 
			
		||||
@@ -1,16 +1,16 @@
 | 
			
		||||
from mock import patch, Mock
 | 
			
		||||
from thefuck.rules.ls_lah import match, get_new_command
 | 
			
		||||
from tests.utils import Command
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_match():
 | 
			
		||||
    assert match(Mock(script='ls'), None)
 | 
			
		||||
    assert match(Mock(script='ls file.py'), None)
 | 
			
		||||
    assert match(Mock(script='ls /opt'), None)
 | 
			
		||||
    assert not match(Mock(script='ls -lah /opt'), None)
 | 
			
		||||
    assert not match(Mock(script='pacman -S binutils'), None)
 | 
			
		||||
    assert not match(Mock(script='lsof'), None)
 | 
			
		||||
    assert match(Command(script='ls'))
 | 
			
		||||
    assert match(Command(script='ls file.py'))
 | 
			
		||||
    assert match(Command(script='ls /opt'))
 | 
			
		||||
    assert not match(Command(script='ls -lah /opt'))
 | 
			
		||||
    assert not match(Command(script='pacman -S binutils'))
 | 
			
		||||
    assert not match(Command(script='lsof'))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_get_new_command():
 | 
			
		||||
    assert get_new_command(Mock(script='ls file.py'), None) == 'ls -lah file.py'
 | 
			
		||||
    assert get_new_command(Mock(script='ls'), None) == 'ls -lah'
 | 
			
		||||
    assert get_new_command(Command(script='ls file.py')) == 'ls -lah file.py'
 | 
			
		||||
    assert get_new_command(Command(script='ls')) == 'ls -lah'
 | 
			
		||||
 
 | 
			
		||||
@@ -12,18 +12,19 @@ from tests.utils import Command
 | 
			
		||||
    Command('man -s 2 read'),
 | 
			
		||||
    Command('man -s 3 read')])
 | 
			
		||||
def test_match(command):
 | 
			
		||||
    assert match(command, None)
 | 
			
		||||
    assert match(command)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command', [
 | 
			
		||||
    Command('man'),
 | 
			
		||||
    Command('man ')])
 | 
			
		||||
def test_not_match(command):
 | 
			
		||||
    assert not match(command, None)
 | 
			
		||||
    assert not match(command)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command, new_command', [
 | 
			
		||||
    (Command('man read'), 'man 3 read'),
 | 
			
		||||
    (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 2 read'), 'man 3 read'),
 | 
			
		||||
    (Command('man 3 read'), 'man 2 read'),
 | 
			
		||||
    (Command('man -s2 read'), 'man -s3 read'),
 | 
			
		||||
@@ -31,4 +32,4 @@ def test_not_match(command):
 | 
			
		||||
    (Command('man -s 2 read'), 'man -s 3 read'),
 | 
			
		||||
    (Command('man -s 3 read'), 'man -s 2 read')])
 | 
			
		||||
def test_get_new_command(command, new_command):
 | 
			
		||||
    assert get_new_command(command, None) == new_command
 | 
			
		||||
    assert get_new_command(command) == new_command
 | 
			
		||||
 
 | 
			
		||||
@@ -3,10 +3,10 @@ from tests.utils import Command
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_match():
 | 
			
		||||
    assert match(Command('mandiff', stderr='mandiff: command not found'), None)
 | 
			
		||||
    assert not match(Command(), None)
 | 
			
		||||
    assert match(Command('mandiff', stderr='mandiff: command not found'))
 | 
			
		||||
    assert not match(Command())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_get_new_command():
 | 
			
		||||
    assert get_new_command(
 | 
			
		||||
        Command('mandiff'), None) == 'man diff'
 | 
			
		||||
        Command('mandiff')) == 'man diff'
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@ import pytest
 | 
			
		||||
 | 
			
		||||
from tests.utils import Command
 | 
			
		||||
from thefuck.rules.mercurial import (
 | 
			
		||||
    extract_possisiblities, match, get_new_command
 | 
			
		||||
    extract_possibilities, match, get_new_command
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -37,7 +37,7 @@ from thefuck.rules.mercurial import (
 | 
			
		||||
    )),
 | 
			
		||||
])
 | 
			
		||||
def test_match(command):
 | 
			
		||||
    assert match(command, None)
 | 
			
		||||
    assert match(command)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command', [
 | 
			
		||||
@@ -63,7 +63,7 @@ def test_match(command):
 | 
			
		||||
    )),
 | 
			
		||||
])
 | 
			
		||||
def test_not_match(command):
 | 
			
		||||
    assert not match(command, None)
 | 
			
		||||
    assert not match(command)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command, possibilities', [
 | 
			
		||||
@@ -96,8 +96,8 @@ def test_not_match(command):
 | 
			
		||||
        '\n    rebase recover remove rename resolve revert'
 | 
			
		||||
    )), ['rebase', 'recover', 'remove', 'rename', 'resolve', 'revert']),
 | 
			
		||||
])
 | 
			
		||||
def test_extract_possisiblities(command, possibilities):
 | 
			
		||||
    assert extract_possisiblities(command) == possibilities
 | 
			
		||||
def test_extract_possibilities(command, possibilities):
 | 
			
		||||
    assert extract_possibilities(command) == possibilities
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command, new_command', [
 | 
			
		||||
@@ -131,4 +131,4 @@ def test_extract_possisiblities(command, possibilities):
 | 
			
		||||
    )), 'hg rebase re'),
 | 
			
		||||
])
 | 
			
		||||
def test_get_new_command(command, new_command):
 | 
			
		||||
    assert get_new_command(command, None) == new_command
 | 
			
		||||
    assert get_new_command(command) == new_command
 | 
			
		||||
 
 | 
			
		||||
@@ -3,20 +3,30 @@ from thefuck.rules.mkdir_p import match, get_new_command
 | 
			
		||||
from tests.utils import Command
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_match():
 | 
			
		||||
    assert match(Command('mkdir foo/bar/baz',
 | 
			
		||||
                         stderr='mkdir: foo/bar: No such file or directory'),
 | 
			
		||||
                 None)
 | 
			
		||||
@pytest.mark.parametrize('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)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command', [
 | 
			
		||||
    Command('mkdir foo/bar/baz'),
 | 
			
		||||
    Command('mkdir foo/bar/baz', stderr='foo bar baz'),
 | 
			
		||||
    Command()])
 | 
			
		||||
    Command('hdfs dfs -mkdir foo/bar/baz'),
 | 
			
		||||
    Command('./bin/hdfs dfs -mkdir foo/bar/baz'),
 | 
			
		||||
    Command(),
 | 
			
		||||
])
 | 
			
		||||
def test_not_match(command):
 | 
			
		||||
    assert not match(command, None)
 | 
			
		||||
    assert not match(command)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_get_new_command():
 | 
			
		||||
    assert get_new_command(Command('mkdir foo/bar/baz'), None)\
 | 
			
		||||
           == 'mkdir -p foo/bar/baz'
 | 
			
		||||
@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'),
 | 
			
		||||
])
 | 
			
		||||
def test_get_new_command(command, new_command):
 | 
			
		||||
    assert get_new_command(command) == new_command
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										40
									
								
								tests/rules/test_mvn_no_command.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								tests/rules/test_mvn_no_command.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
import pytest
 | 
			
		||||
from thefuck.rules.mvn_no_command import match, get_new_command
 | 
			
		||||
from tests.utils import Command
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command', [
 | 
			
		||||
    Command(script='mvn', stdout='[ERROR] No goals have been specified for this build. You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle phases are: validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy, pre-clean, clean, post-clean, pre-site, site, post-site, site-deploy. -> [Help 1]')])
 | 
			
		||||
def test_match(command):
 | 
			
		||||
    assert match(command)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command', [
 | 
			
		||||
    Command(script='mvn clean', stdout="""
 | 
			
		||||
[INFO] Scanning for projects...[INFO]                                                                         
 | 
			
		||||
[INFO] ------------------------------------------------------------------------
 | 
			
		||||
[INFO] Building test 0.2
 | 
			
		||||
[INFO] ------------------------------------------------------------------------
 | 
			
		||||
[INFO] 
 | 
			
		||||
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ test ---
 | 
			
		||||
[INFO] Deleting /home/mlk/code/test/target
 | 
			
		||||
[INFO] ------------------------------------------------------------------------
 | 
			
		||||
[INFO] BUILD SUCCESS
 | 
			
		||||
[INFO] ------------------------------------------------------------------------
 | 
			
		||||
[INFO] Total time: 0.477s
 | 
			
		||||
[INFO] Finished at: Wed Aug 26 13:05:47 BST 2015
 | 
			
		||||
[INFO] Final Memory: 6M/240M
 | 
			
		||||
[INFO] ------------------------------------------------------------------------
 | 
			
		||||
"""),
 | 
			
		||||
    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
 | 
			
		||||
							
								
								
									
										40
									
								
								tests/rules/test_mvn_unknown_lifecycle_phase.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								tests/rules/test_mvn_unknown_lifecycle_phase.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
import pytest
 | 
			
		||||
from thefuck.rules.mvn_unknown_lifecycle_phase import match, get_new_command
 | 
			
		||||
from tests.utils import Command
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command', [
 | 
			
		||||
    Command(script='mvn cle', stdout='[ERROR] Unknown lifecycle phase "cle". You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle phases are: validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy, pre-clean, clean, post-clean, pre-site, site, post-site, site-deploy. -> [Help 1]')])
 | 
			
		||||
def test_match(command):
 | 
			
		||||
    assert match(command)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize('command', [
 | 
			
		||||
    Command(script='mvn clean', stdout="""
 | 
			
		||||
[INFO] Scanning for projects...[INFO]                                                                         
 | 
			
		||||
[INFO] ------------------------------------------------------------------------
 | 
			
		||||
[INFO] Building test 0.2
 | 
			
		||||
[INFO] ------------------------------------------------------------------------
 | 
			
		||||
[INFO] 
 | 
			
		||||
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ test ---
 | 
			
		||||
[INFO] Deleting /home/mlk/code/test/target
 | 
			
		||||
[INFO] ------------------------------------------------------------------------
 | 
			
		||||
[INFO] BUILD SUCCESS
 | 
			
		||||
[INFO] ------------------------------------------------------------------------
 | 
			
		||||
[INFO] Total time: 0.477s
 | 
			
		||||
[INFO] Finished at: Wed Aug 26 13:05:47 BST 2015
 | 
			
		||||
[INFO] Final Memory: 6M/240M
 | 
			
		||||
[INFO] ------------------------------------------------------------------------
 | 
			
		||||
"""),
 | 
			
		||||
    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
 | 
			
		||||
@@ -6,24 +6,42 @@ 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', 'apt-get', 'fsck'])
 | 
			
		||||
                 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'])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.usefixtures('no_memoize')
 | 
			
		||||
def test_match():
 | 
			
		||||
    assert match(Command(stderr='vom: not found', script='vom file.py'), None)
 | 
			
		||||
    assert match(Command(stderr='fucck: not found', script='fucck'), None)
 | 
			
		||||
    assert not match(Command(stderr='qweqwe: not found', script='qweqwe'), None)
 | 
			
		||||
    assert not match(Command(stderr='some text', script='vom file.py'), None)
 | 
			
		||||
@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))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.usefixtures('no_memoize')
 | 
			
		||||
def test_get_new_command():
 | 
			
		||||
    assert get_new_command(
 | 
			
		||||
        Command(stderr='vom: not found',
 | 
			
		||||
                script='vom file.py'),
 | 
			
		||||
        None) == 'vim file.py'
 | 
			
		||||
    assert get_new_command(
 | 
			
		||||
        Command(stderr='fucck: not found',
 | 
			
		||||
                script='fucck'),
 | 
			
		||||
        Command) == 'fsck'
 | 
			
		||||
@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
 | 
			
		||||
 
 | 
			
		||||
@@ -6,14 +6,22 @@ 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, None)
 | 
			
		||||
    assert 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)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@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, None) == new_command
 | 
			
		||||
    assert get_new_command(command) == new_command
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										69
									
								
								tests/rules/test_npm_missing_script.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								tests/rules/test_npm_missing_script.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,69 @@
 | 
			
		||||
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
 | 
			
		||||
							
								
								
									
										84
									
								
								tests/rules/test_npm_run_script.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								tests/rules/test_npm_run_script.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,84 @@
 | 
			
		||||
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
 | 
			
		||||
							
								
								
									
										58
									
								
								tests/rules/test_npm_wrong_command.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								tests/rules/test_npm_wrong_command.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
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
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user