├── .travis.yml ├── LICENSE ├── README.md ├── functions ├── mock.fish └── unmock.fish └── tests ├── mock.fish └── unmock.fish /.travis.yml: -------------------------------------------------------------------------------- 1 | langauge: minimal 2 | 3 | env: 4 | global: 5 | - HOMEBREW_NO_AUTO_UPDATE=1 6 | - BREW_FISH2="https://raw.githubusercontent.com/Homebrew/homebrew-core/2827b020c3366ea93566a344167ba62388c16c7d/Formula/fish.rb" 7 | 8 | script: 9 | - curl -Lo ~/.config/fish/functions/fisher.fish --create-dirs git.io/fisherman 10 | - fish -c "fisher fishtape .; fishtape tests/*.fish" 11 | 12 | jobs: 13 | include: 14 | - stage: test 15 | name: "Fish 2.X Linux" 16 | os: linux 17 | sudo: required 18 | install: 19 | - sudo apt-add-repository -y ppa:fish-shell/release-2 20 | - sudo apt-get update 21 | - sudo apt-get install -y fish 22 | 23 | - stage: test 24 | name: "Fish 2.X macOS" 25 | os: osx 26 | install: brew install $BREW_FISH2 27 | 28 | - stage: test 29 | name: "Fish 3.X Linux" 30 | os: linux 31 | sudo: required 32 | install: 33 | - sudo apt-add-repository -y ppa:fish-shell/release-3 34 | - sudo apt-get update 35 | - sudo apt-get install -y fish 36 | 37 | - stage: test 38 | name: "Fish 3.X macOS" 39 | os: osx 40 | install: brew install fish 41 | 42 | - stage: deploy 43 | language: node_js 44 | node_js: stable 45 | provider: script 46 | skip_cleanup: true 47 | script: npx semantic-release -p @semantic-release/commit-analyzer,@semantic-release/release-notes-generator,@semantic-release/github 48 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (c) 2019 Matan Kushner 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | Fish 3 | Performance arts masks 4 |

fish-mock

5 |

Quick and powerful fish shell mocks

6 |

7 | Build Status 8 | Fish Version 9 | License 10 |

11 |

12 | 13 | --- 14 | 15 | **fish-mock** provides a quick and easy way to override the behavior of commands for use when testing. Mocking commands causes them to behave predictably, allowing you isolate and focus on the code being tested. 16 | 17 | ## Installation 18 | 19 | ### [Fisher](https://github.com/jorgebucaran/fisher) 20 | 21 | ```fish 22 | fisher add matchai/fish-mock 23 | ``` 24 | 25 | ## Usage 26 | 27 | ``` 28 | $ mock 29 | 30 | Usage 31 | $ mock [exit code] [executed code] 32 | $ unmock 33 | 34 | Arguments 35 | command The command you would like to have mocked 36 | argument The argument the mock should apply to ('*' defines a fallback for all arguments) 37 | exit code The exit code returned when the command executes 38 | executed code Code to be executed when the command is called with the given argument 39 | 40 | Examples 41 | $ mock git pull 0 "echo This command successfully echoes" 42 | $ mock git push 1 "echo This command fails with status 1" 43 | $ mock git \* 0 "echo This command acts as a fallback to all git commands" 44 | $ unmock git # Original git functionality is now restored 45 | 46 | Tips 47 | To view this manual, use the mock command without providing arguments. 48 | The array of arguments ($argv) is accessible within mocked functions as $args. 49 | Many mocks can be applied to the same command at the same time with different arguments. 50 | Be sure to escape the asterisk symbol when using it as a fallback (\*). 51 | ``` 52 | 53 | ## License 54 | 55 | ISC © [Matan Kushner](https://matchai.me/) 56 | -------------------------------------------------------------------------------- /functions/mock.fish: -------------------------------------------------------------------------------- 1 | function mock -a cmd -a argument -a exit_code -a executed_code -d "Mock a command" 2 | set -l cmd_blacklist "[" and argparse begin break builtin case command continue else end eval exec for function functions if not or read return set status switch test while 3 | 4 | if test (count $argv) -lt 1 5 | echo " 6 | Usage 7 | \$ mock [exit code] [executed code] 8 | \$ unmock 9 | 10 | Arguments 11 | command The command you would like to have mocked 12 | argument The argument the mock should apply to ('*' defines a fallback for all arguments) 13 | exit code The exit code returned when the command executes 14 | executed code Code to be executed when the command is called with the given argument 15 | 16 | Examples 17 | \$ mock git pull 0 \"echo This command successfully echoes\" 18 | \$ mock git push 1 \"echo This command fails with status 1\" 19 | \$ mock git \* 0 \"echo This command acts as a fallback to all git commands\" 20 | \$ unmock git # Original git functionality is now restored 21 | 22 | Tips 23 | To view this manual, use the mock command without providing arguments. 24 | The array of arguments (\$argv) is accessible within mocked functions as \$args. 25 | Many mocks can be applied to the same command at the same time with different arguments. 26 | Be sure to escape the asterisk symbol when using it as a fallback (\*) 27 | " 28 | return 0 29 | end 30 | 31 | if contains $cmd $cmd_blacklist 32 | echo The function '"'$cmd'"' is reserved and therefore cannot be mocked. 33 | return 1 34 | end 35 | 36 | if not contains $cmd $_mocked 37 | # Generate variable with all mocked functions 38 | set -g _mocked $cmd $_mocked 39 | end 40 | 41 | set -l mocked_args "_mocked_"$cmd"_args" 42 | if not contains -- $argument $$mocked_args 43 | # Generate variable with all mocked arguments 44 | set -g $mocked_args $argument $$mocked_args 45 | end 46 | 47 | # Create a function for that command and argument combination 48 | set -l mocked_fn 49 | if test $argument = '*' 50 | set mocked_fn "mocked_"$cmd"_fn" 51 | else 52 | set mocked_fn "mocked_"$cmd"_fn_"$argument 53 | end 54 | function $mocked_fn -V exit_code -V executed_code 55 | set -l args $argv 56 | eval $executed_code 57 | return $exit_code 58 | end 59 | 60 | function $cmd -V cmd -V mocked_args 61 | # Call the mocked function created above 62 | if contains -- $argv[1] $$mocked_args 63 | set -l fn_name "mocked_"$cmd"_fn_"$argv[1] 64 | eval $fn_name $argv[2..(count $argv)] 65 | return $status 66 | end 67 | 68 | # Fallback on runnning the original command 69 | set -l mocked_fn "mocked_"$cmd"_fn" 70 | if type -q $mocked_fn 71 | eval $mocked_fn $argv 72 | else 73 | eval command $cmd $argv 74 | end 75 | end 76 | end 77 | -------------------------------------------------------------------------------- /functions/unmock.fish: -------------------------------------------------------------------------------- 1 | function unmock -a cmd -d "Destroy an existing mock" 2 | if test (count $argv) -lt 1 3 | echo " 4 | Usage 5 | \$ unmock 6 | 7 | Arguments 8 | command The command you would like to unmock 9 | 10 | Examples 11 | \$ unmock git # The original git command can now be used 12 | " 13 | return 0 14 | end 15 | 16 | functions -e $cmd 17 | set -l mocked_args "_mocked_"$cmd"_args" 18 | functions -e "mocked_"$cmd"_fn_"{$$mocked_args} 19 | set -e $mocked_args 20 | set _mocked (string match -v $cmd $_mocked) 21 | return 0 22 | end 23 | -------------------------------------------------------------------------------- /tests/mock.fish: -------------------------------------------------------------------------------- 1 | function setup 2 | set root (dirname (status -f)) 3 | source $root/functions/mock.fish 4 | end 5 | 6 | @test "It should be able to mock with exit success" ( 7 | mock ls \*; and ls 8 | ) $status -eq 0 9 | 10 | @test "It should be able to non-wildcard mock with exit success" ( 11 | mock ls a; and ls a 12 | ) $status -eq 0 13 | 14 | @test "It should be able to mock with fail status" ( 15 | mock ls \* 1; and ls 16 | ) $status -eq 1 17 | 18 | @test "It should be able to non-wildcard mock with fail status" ( 19 | mock ls a 1; and ls a 20 | ) $status -eq 1 21 | 22 | @test "It should be able to mock with function body" ( 23 | mock ls \* 0 "echo hello"; and ls 24 | ) = "hello" 25 | 26 | @test "It should be able to non-wildcard mock with function body" ( 27 | mock ls a 0 "echo hello"; and ls a 28 | ) = "hello" 29 | 30 | @test "It should be able to use argument" ( 31 | mock ls \* 0 "echo hello \$args"; and ls joe 32 | ) = "hello joe" 33 | 34 | @test "It should be able to use argument in non-wildcard mock" ( 35 | mock ls a 0 "echo hello \$args"; and ls a joe 36 | ) = "hello joe" 37 | 38 | @test "It should be able to use some arguments" ( 39 | mock ls \* 0 "echo hello \$args[1]"; and ls joe mike 40 | ) = "hello joe" 41 | 42 | @test "It should be able to use some arguments in non-wildcard mock" ( 43 | mock ls a 0 "echo hello \$args[1]"; and ls a joe mike 44 | ) = "hello joe" 45 | 46 | @test "It should be able to use multiple arguments" ( 47 | mock ls \* 0 "echo hello \$args[1] and \$args[2]"; and ls joe mike 48 | ) = "hello joe and mike" 49 | 50 | @test "It should be able to use multiple arguments in non-wildcard mock" ( 51 | mock ls a 0 "echo hello \$args[1] and \$args[2]"; and ls a joe mike 52 | ) = "hello joe and mike" 53 | 54 | @test "It should be able to use nested functions" ( 55 | mock ls \* 0 "echo (seq 5)"; and ls 56 | ) = "1 2 3 4 5" 57 | 58 | @test "It should be able to use nested functions in non-wildcard mock" ( 59 | mock ls a 0 "echo (seq 5)"; and ls a 60 | ) = "1 2 3 4 5" 61 | 62 | @test "It should be able to use nested functions with arguments" ( 63 | mock ls \* 0 "echo (seq \$args)"; and ls 5 64 | ) = "1 2 3 4 5" 65 | 66 | @test "It should be able to use nested functions in non-wildcard mock with arguments" ( 67 | mock ls a 0 "echo (seq \$args)"; and ls a 5 68 | ) = "1 2 3 4 5" 69 | 70 | @test "It should not mock blacklisted elements 1" ( 71 | echo ( 72 | mock builtin \* 73 | echo $status 74 | ) 75 | ) = "The function \"builtin\" is reserved and therefore cannot be mocked. 1" 76 | 77 | @test "It should not mock blacklisted elements 2" ( 78 | echo ( 79 | mock functions \* 80 | echo $status 81 | ) 82 | ) = "The function \"functions\" is reserved and therefore cannot be mocked. 1" 83 | 84 | @test "It should not mock blacklisted elements 3" ( 85 | echo ( 86 | mock eval \* 87 | echo $status 88 | ) 89 | ) = "The function \"eval\" is reserved and therefore cannot be mocked. 1" 90 | 91 | @test "It should not mock blacklisted elements 4" ( 92 | echo ( 93 | mock "[" \* 94 | echo $status 95 | ) 96 | ) = "The function \"[\" is reserved and therefore cannot be mocked. 1" 97 | -------------------------------------------------------------------------------- /tests/unmock.fish: -------------------------------------------------------------------------------- 1 | function setup 2 | set root (dirname (status -f)) 3 | source $root/functions/mock.fish 4 | source $root/functions/unmock.fish 5 | end 6 | 7 | test "$TESTNAME - It should unmock a previously created mock" 8 | "hello joe" = (mock echo \* 0 "echo fail"; and unmock echo; and echo "hello joe") 9 | end 10 | 11 | test "$TESTNAME - It should unmock a previously created mock with non-wildcard" 12 | "hi" = (mock echo hi 0 "echo fail"; and unmock echo; and echo hi) 13 | end 14 | --------------------------------------------------------------------------------