├── .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 |
3 |
4 |
fish-mock
5 | Quick and powerful fish shell mocks
6 |
7 |
8 |
9 |
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 |
--------------------------------------------------------------------------------