rspec-bash 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.rspec +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +6 -0
- data/CHANGELOG.md +24 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +23 -0
- data/README.md +227 -0
- data/Rakefile +13 -0
- data/bin/function_override.sh.erb +7 -0
- data/bin/function_override_wrapper.sh.erb +16 -0
- data/bin/stub +62 -0
- data/lib/rspec/bash.rb +5 -0
- data/lib/rspec/bash/call_configuration.rb +37 -0
- data/lib/rspec/bash/call_log.rb +77 -0
- data/lib/rspec/bash/matchers.rb +2 -0
- data/lib/rspec/bash/matchers/called_with_arguments.rb +14 -0
- data/lib/rspec/bash/matchers/called_with_no_arguments.rb +5 -0
- data/lib/rspec/bash/stubbed_command.rb +76 -0
- data/lib/rspec/bash/stubbed_env.rb +99 -0
- data/rspec-bash.gemspec +25 -0
- data/spec/classes/call_configuration_spec.rb +21 -0
- data/spec/classes/call_log_spec.rb +309 -0
- data/spec/classes/stubbed_command_spec.rb +134 -0
- data/spec/classes/stubbed_env_spec.rb +306 -0
- data/spec/integration/assert_called_spec.rb +48 -0
- data/spec/integration/assert_stdin_spec.rb +39 -0
- data/spec/integration/chain_args_spec.rb +65 -0
- data/spec/integration/change_exitstatus_spec.rb +53 -0
- data/spec/integration/provide_env_vars_spec.rb +31 -0
- data/spec/integration/replace_shell_commands_spec.rb +48 -0
- data/spec/integration/stub_output_spec.rb +110 -0
- data/spec/matchers/be_called_with_arguments_spec.rb +55 -0
- data/spec/matchers/be_called_with_no_arguments_spec.rb +32 -0
- data/spec/scripts/function_library.sh +9 -0
- metadata +129 -0
@@ -0,0 +1,77 @@
|
|
1
|
+
module Rspec
|
2
|
+
module Bash
|
3
|
+
# Log of calls to a command
|
4
|
+
class CallLog
|
5
|
+
def initialize(call_log_path)
|
6
|
+
@call_log_path = call_log_path
|
7
|
+
end
|
8
|
+
|
9
|
+
def exist?
|
10
|
+
@call_log_path.exist?
|
11
|
+
end
|
12
|
+
|
13
|
+
def called_with_args?(*args)
|
14
|
+
call_count(*args) > 0
|
15
|
+
end
|
16
|
+
|
17
|
+
def stdin_for_args(*args)
|
18
|
+
call = find_call(*args)
|
19
|
+
call['stdin'] unless call.nil?
|
20
|
+
end
|
21
|
+
|
22
|
+
def call_count(*expected_argument_series)
|
23
|
+
get_call_log_args.count do |actual_argument_series|
|
24
|
+
argument_series_contains?(actual_argument_series, expected_argument_series || [])
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def called_with_no_args?
|
29
|
+
call_log_list = load_call_log_list
|
30
|
+
!call_log_list.empty? && call_log_list.first['args'].nil?
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def find_call(*args)
|
36
|
+
load_call_log_list.find do |call|
|
37
|
+
call_args = call['args'] || []
|
38
|
+
(args - call_args).empty?
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def get_position_range_from_argument_list(argument_list, range_start_position, range_length)
|
43
|
+
argument_list.map do |argument_series|
|
44
|
+
range_start_position ? argument_series[range_start_position, range_length] : argument_series
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def get_call_log_args
|
49
|
+
load_call_log_list.map { |call_log| call_log["args"] || [] }.compact
|
50
|
+
end
|
51
|
+
|
52
|
+
def argument_series_contains?(actual_argument_series, expected_argument_series)
|
53
|
+
ensure_wildcards_match(actual_argument_series, expected_argument_series)
|
54
|
+
expected_argument_series.empty? || (actual_argument_series == expected_argument_series)
|
55
|
+
end
|
56
|
+
|
57
|
+
def ensure_wildcards_match(actual_argument_series, expected_argument_series)
|
58
|
+
# yes, i know. i am disappointed in myself
|
59
|
+
num_of_args = actual_argument_series.size
|
60
|
+
expected_argument_series.zip((0..num_of_args), actual_argument_series) do |expected_arg, index, _actual_arg|
|
61
|
+
if expected_arg.is_a? RSpec::Mocks::ArgumentMatchers::AnyArgMatcher
|
62
|
+
actual_argument_series[index] = expected_arg
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def load_call_log_list
|
68
|
+
begin
|
69
|
+
YAML.load_file @call_log_path
|
70
|
+
rescue Errno::ENOENT
|
71
|
+
return []
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rspec/expectations'
|
2
|
+
|
3
|
+
RSpec::Matchers.define :be_called_with_arguments do |*expected_argument_list|
|
4
|
+
chain :times do |expected_invocations|
|
5
|
+
@expected_invocations = expected_invocations
|
6
|
+
end
|
7
|
+
|
8
|
+
match do |actual_command|
|
9
|
+
called_with_correct_args = actual_command.called_with_args?(*expected_argument_list)
|
10
|
+
called_correct_number_of_times = @expected_invocations ? actual_command.call_count(*expected_argument_list) == @expected_invocations : true
|
11
|
+
|
12
|
+
called_with_correct_args && called_correct_number_of_times
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Rspec
|
2
|
+
module Bash
|
3
|
+
class StubbedCommand
|
4
|
+
attr_reader :call_log, :arguments
|
5
|
+
|
6
|
+
def initialize(command, dir)
|
7
|
+
command_path = File.join(dir, command)
|
8
|
+
FileUtils.cp(stub_filepath, command_path)
|
9
|
+
@arguments = []
|
10
|
+
@call_configuration = CallConfiguration.new(
|
11
|
+
Pathname.new(dir).join("#{command}_stub.yml"),
|
12
|
+
command
|
13
|
+
)
|
14
|
+
@call_log = CallLog.new(
|
15
|
+
Pathname.new(dir).join("#{command}_calls.yml")
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
def with_args(*args)
|
20
|
+
@arguments = args
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
def called?
|
25
|
+
@call_log.exist? && @call_log.called_with_args?(*@args)
|
26
|
+
end
|
27
|
+
|
28
|
+
def called_with_no_args?
|
29
|
+
@call_log.called_with_no_args?
|
30
|
+
end
|
31
|
+
|
32
|
+
def called_with_args?(*args)
|
33
|
+
@call_log.called_with_args?(*args)
|
34
|
+
end
|
35
|
+
|
36
|
+
def call_count(*arg)
|
37
|
+
@call_log.call_count(*arg)
|
38
|
+
end
|
39
|
+
|
40
|
+
def returns_exitstatus(statuscode)
|
41
|
+
@call_configuration.set_exitcode(statuscode, @arguments)
|
42
|
+
@call_configuration.write
|
43
|
+
self
|
44
|
+
end
|
45
|
+
|
46
|
+
def stdin
|
47
|
+
@call_log.stdin_for_args(*@arguments) if @call_log.exist?
|
48
|
+
end
|
49
|
+
|
50
|
+
def outputs(contents, to: :stdout)
|
51
|
+
@call_configuration.set_output(contents, to, @arguments)
|
52
|
+
@call_configuration.write
|
53
|
+
self
|
54
|
+
end
|
55
|
+
|
56
|
+
def inspect
|
57
|
+
if @arguments.any?
|
58
|
+
"<Stubbed #{@call_configuration.command.inspect} " \
|
59
|
+
"args: #{@arguments.join(' ').inspect}>"
|
60
|
+
else
|
61
|
+
"<Stubbed #{@call_configuration.command.inspect}>"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def stub_filepath
|
68
|
+
project_root.join('bin', 'stub')
|
69
|
+
end
|
70
|
+
|
71
|
+
def project_root
|
72
|
+
Pathname.new(File.dirname(File.expand_path(__FILE__))).join('..', '..', '..')
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'tmpdir'
|
2
|
+
require 'English'
|
3
|
+
require 'open3'
|
4
|
+
|
5
|
+
module Rspec
|
6
|
+
# Define stubbed environment to set and assert expectations
|
7
|
+
module Bash
|
8
|
+
def create_stubbed_env
|
9
|
+
StubbedEnv.new
|
10
|
+
end
|
11
|
+
|
12
|
+
# A shell environment that can manipulate behaviour
|
13
|
+
# of executables
|
14
|
+
class StubbedEnv
|
15
|
+
attr_reader :dir
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@dir = Dir.mktmpdir
|
19
|
+
ENV['PATH'] = "#{@dir}:#{ENV['PATH']}"
|
20
|
+
at_exit { cleanup }
|
21
|
+
end
|
22
|
+
|
23
|
+
def cleanup
|
24
|
+
paths = (ENV['PATH'].split ':') - [@dir]
|
25
|
+
ENV['PATH'] = paths.join ':'
|
26
|
+
FileUtils.remove_entry_secure @dir if Pathname.new(@dir).exist?
|
27
|
+
end
|
28
|
+
|
29
|
+
def stub_command(command)
|
30
|
+
write_function_override_file_for_command command
|
31
|
+
StubbedCommand.new command, @dir
|
32
|
+
end
|
33
|
+
|
34
|
+
def execute(command, env_vars = {})
|
35
|
+
full_command = get_wrapped_execution_with_function_overrides(<<-multiline_script
|
36
|
+
#{env} source #{command}
|
37
|
+
multiline_script
|
38
|
+
)
|
39
|
+
|
40
|
+
Open3.capture3(env_vars, full_command)
|
41
|
+
end
|
42
|
+
|
43
|
+
def execute_function(script, command, env_vars = {})
|
44
|
+
full_command = get_wrapped_execution_with_function_overrides(<<-multiline_script
|
45
|
+
source #{script}
|
46
|
+
#{env} #{command}
|
47
|
+
multiline_script
|
48
|
+
)
|
49
|
+
|
50
|
+
Open3.capture3(env_vars, full_command)
|
51
|
+
end
|
52
|
+
|
53
|
+
def execute_inline(command_string, env_vars = {})
|
54
|
+
temp_command_path = Dir::Tmpname.make_tmpname("#{@dir}/inline-", nil)
|
55
|
+
File.write(temp_command_path, command_string)
|
56
|
+
execute(temp_command_path, env_vars)
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def write_function_override_file_for_command(command)
|
62
|
+
function_command_binding_for_template = command
|
63
|
+
function_command_path_binding_for_template = File.join(@dir, command)
|
64
|
+
|
65
|
+
function_override_file_path = File.join(@dir, "#{command}_overrides.sh")
|
66
|
+
function_override_file_template = ERB.new File.new(function_override_template_path).read, nil, '%'
|
67
|
+
function_override_file_content = function_override_file_template.result(binding)
|
68
|
+
|
69
|
+
File.write(function_override_file_path, function_override_file_content)
|
70
|
+
end
|
71
|
+
|
72
|
+
def get_wrapped_execution_with_function_overrides(execution_snippet)
|
73
|
+
execution_binding_for_template = execution_snippet
|
74
|
+
function_override_path_binding_for_template = "#{@dir}/*_overrides.sh"
|
75
|
+
wrapped_error_path_binding_for_template = "#{@dir}/errors"
|
76
|
+
|
77
|
+
function_override_wrapper_template = ERB.new File.new(function_override_wrapper_template_path).read, nil, '%'
|
78
|
+
|
79
|
+
function_override_wrapper_template.result(binding)
|
80
|
+
end
|
81
|
+
|
82
|
+
def env
|
83
|
+
"PATH=#{@dir}:$PATH"
|
84
|
+
end
|
85
|
+
|
86
|
+
def function_override_template_path
|
87
|
+
project_root.join('bin', 'function_override.sh.erb')
|
88
|
+
end
|
89
|
+
|
90
|
+
def function_override_wrapper_template_path
|
91
|
+
project_root.join('bin', 'function_override_wrapper.sh.erb')
|
92
|
+
end
|
93
|
+
|
94
|
+
def project_root
|
95
|
+
Pathname.new(File.dirname(File.expand_path(__FILE__))).join('..', '..', '..')
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/rspec-bash.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'rspec-bash'
|
7
|
+
spec.version = '0.0.3'
|
8
|
+
spec.authors = ['Ben Brewer', 'Mike Urban', 'Matthijs Groen']
|
9
|
+
spec.email = ['ben@benbrewer.me', 'mike.david.urban@gmail.com']
|
10
|
+
spec.summary = 'Test Bash with RSpec'
|
11
|
+
spec.description = <<-DESCRIPTION
|
12
|
+
Stub and mock Bash commands
|
13
|
+
Verify Bash calls and outputs
|
14
|
+
DESCRIPTION
|
15
|
+
spec.homepage = 'https://github.com/mdurban/rspec-bash'
|
16
|
+
spec.license = 'MIT'
|
17
|
+
|
18
|
+
spec.files = `git ls-files -z`.split("\x0")
|
19
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
21
|
+
spec.require_paths = ['lib']
|
22
|
+
|
23
|
+
spec.add_development_dependency 'bundler', '~> 1.6'
|
24
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
25
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rspec/bash'
|
2
|
+
|
3
|
+
describe 'CallConfiguration' do
|
4
|
+
let(:stubbed_env) { create_stubbed_env }
|
5
|
+
include Rspec::Bash
|
6
|
+
|
7
|
+
context '#set_exitcode' do
|
8
|
+
it 'returns the status code that is provided' do
|
9
|
+
@subject = Rspec::Bash::CallConfiguration.new(anything, anything)
|
10
|
+
|
11
|
+
expect(@subject.set_exitcode('status')).to eql 'status'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
context '#write' do
|
15
|
+
it 'raises error when there is no config_path' do
|
16
|
+
@subject = Rspec::Bash::CallConfiguration.new(nil, anything)
|
17
|
+
|
18
|
+
expect { @subject.write }.to raise_exception(NoMethodError)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,309 @@
|
|
1
|
+
require 'English'
|
2
|
+
require 'rspec/bash'
|
3
|
+
|
4
|
+
describe 'CallLog' do
|
5
|
+
let(:stubbed_env) { create_stubbed_env }
|
6
|
+
include Rspec::Bash
|
7
|
+
|
8
|
+
context '#stdin_for_args' do
|
9
|
+
it 'returns nil when no YAML file is used for call log' do
|
10
|
+
@subject = Rspec::Bash::CallLog.new(anything)
|
11
|
+
allow(YAML).to receive(:load_file).and_return([])
|
12
|
+
|
13
|
+
expect(@subject.stdin_for_args(anything)).to be nil
|
14
|
+
end
|
15
|
+
it 'returns the stdin from call log when there is a single value for stdin' do
|
16
|
+
actual_call_log_list =
|
17
|
+
[{
|
18
|
+
'args' => ['arbitrary argument'],
|
19
|
+
'stdin' => ['correct value'],
|
20
|
+
}]
|
21
|
+
@subject = Rspec::Bash::CallLog.new(anything)
|
22
|
+
allow(YAML).to receive(:load_file).and_return(actual_call_log_list)
|
23
|
+
|
24
|
+
expect(@subject.stdin_for_args('arbitrary argument').first).to eql 'correct value'
|
25
|
+
end
|
26
|
+
it 'returns the stdin from call log when there are multiple values for stdin' do
|
27
|
+
actual_call_log_list =
|
28
|
+
[{
|
29
|
+
'args' => ['arbitrary argument'],
|
30
|
+
'stdin' => ['first value', 'second value'],
|
31
|
+
}]
|
32
|
+
@subject = Rspec::Bash::CallLog.new(anything)
|
33
|
+
allow(YAML).to receive(:load_file).and_return(actual_call_log_list)
|
34
|
+
|
35
|
+
expect(@subject.stdin_for_args('arbitrary argument').sort).to eql ['first value', 'second value'].sort
|
36
|
+
end
|
37
|
+
it 'returns the stdin from call log when no arguments are provided' do
|
38
|
+
actual_call_log_list =
|
39
|
+
[{
|
40
|
+
'args' => nil,
|
41
|
+
'stdin' => ['correct value'],
|
42
|
+
}]
|
43
|
+
@subject = Rspec::Bash::CallLog.new(anything)
|
44
|
+
allow(YAML).to receive(:load_file).and_return(actual_call_log_list)
|
45
|
+
|
46
|
+
expect(@subject.stdin_for_args).to eql ['correct value']
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context '#call_count?' do
|
51
|
+
context 'with no calls made at all (missing call log file)' do
|
52
|
+
before(:each) do
|
53
|
+
@subject = Rspec::Bash::CallLog.new('command_with_no_call_log_file')
|
54
|
+
allow(YAML).to receive(:load_file).and_raise(Errno::ENOENT)
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'does not find an un-passed argument anywhere in the series' do
|
58
|
+
expect(@subject.call_count('not_an_argument')).to eql 0
|
59
|
+
end
|
60
|
+
end
|
61
|
+
context 'with only an series of arguments provided' do
|
62
|
+
context 'and a command log with only one argument' do
|
63
|
+
before(:each) do
|
64
|
+
actual_call_log_list =
|
65
|
+
[{
|
66
|
+
'args' => ['first_argument'],
|
67
|
+
'stdin' => [],
|
68
|
+
}]
|
69
|
+
@subject = Rspec::Bash::CallLog.new('command_with_one_argument_log')
|
70
|
+
allow(@subject).to receive(:load_call_log_list).and_return(actual_call_log_list)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'finds the single argument anywhere in the series exactly once' do
|
74
|
+
expect(@subject.call_count('first_argument')).to eql 1
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'does not find an un-passed argument anywhere in the series' do
|
78
|
+
expect(@subject.call_count('not_an_argument')).to eql 0
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'finds the single wildcard argument exactly once' do
|
82
|
+
expect(@subject.call_count(anything)).to eql 1
|
83
|
+
end
|
84
|
+
end
|
85
|
+
context 'and a command called with two arguments' do
|
86
|
+
before(:each) do
|
87
|
+
actual_call_log_list =
|
88
|
+
[{
|
89
|
+
'args' => ['first_argument', 'second_argument'],
|
90
|
+
'stdin' => [],
|
91
|
+
}]
|
92
|
+
@subject = Rspec::Bash::CallLog.new('command_with_two_arguments_log')
|
93
|
+
allow(@subject).to receive(:load_call_log_list).and_return(actual_call_log_list)
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'does not find the first argument when other argument is not provided' do
|
97
|
+
expect(@subject.call_count('first_argument')).to eql 0
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'finds the first argument anywhere in the series exactly once' do
|
101
|
+
expect(@subject.call_count('first_argument', anything)).to eql 1
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'does not find the second argument when first argument is not provided' do
|
105
|
+
expect(@subject.call_count('second_argument')).to eql 0
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'finds the second argument anywhere in the series exactly once' do
|
109
|
+
expect(@subject.call_count(anything, 'second_argument')).to eql 1
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'finds two contiguous arguments in the series exactly once' do
|
113
|
+
expect(@subject.call_count('first_argument', 'second_argument')).to eql 1
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'does not find an un-passed argument anywhere in the series' do
|
117
|
+
expect(@subject.call_count('not_an_argument')).to eql 0
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'does not find a wildcard argument when other argument is not provided' do
|
121
|
+
expect(@subject.call_count(anything)).to eql 0
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'finds when both arguments are wildcards exactly once' do
|
125
|
+
expect(@subject.call_count(anything, anything)).to eql 1
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'finds when only the first argument is a wildcard exactly once' do
|
129
|
+
expect(@subject.call_count(anything, 'second_argument')).to eql 1
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'finds when only the second argument is a wildcard exactly once' do
|
133
|
+
expect(@subject.call_count('first_argument', anything)).to eql 1
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'does not find when wildcard is in wrong position' do
|
137
|
+
expect(@subject.call_count('first_argument', anything, 'second_argument')).to eql 0
|
138
|
+
end
|
139
|
+
end
|
140
|
+
context 'and a command called with three arguments' do
|
141
|
+
before(:each) do
|
142
|
+
actual_call_log_list =
|
143
|
+
[{
|
144
|
+
'args' => ['first_argument', 'second_argument', 'third_argument'],
|
145
|
+
'stdin' => [],
|
146
|
+
}]
|
147
|
+
@subject = Rspec::Bash::CallLog.new('command_with_three_arguments_log')
|
148
|
+
allow(@subject).to receive(:load_call_log_list).and_return(actual_call_log_list)
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'does not find first argument when other arguments are not provided' do
|
152
|
+
expect(@subject.call_count('first_argument')).to eql 0
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'finds the first argument anywhere in the series exactly once' do
|
156
|
+
expect(@subject.call_count('first_argument', anything, anything)).to eql 1
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'does not find second argument when other arguments are not provided' do
|
160
|
+
expect(@subject.call_count('second_argument')).to eql 0
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'finds the second argument anywhere in the series exactly once' do
|
164
|
+
expect(@subject.call_count(anything, 'second_argument', anything)).to eql 1
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'does not find third argument when other arguments are not provided' do
|
168
|
+
expect(@subject.call_count('third_argument')).to eql 0
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'finds the third argument anywhere in the series exactly once' do
|
172
|
+
expect(@subject.call_count(anything, anything, 'third_argument')).to eql 1
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'finds three contiguous arguments in the series exactly once' do
|
176
|
+
expect(@subject.call_count('first_argument', 'second_argument', 'third_argument')).to eql 1
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'does not find two non-contiguous arguments in the series exactly once' do
|
180
|
+
expect(@subject.call_count('first_argument', 'third_argument')).to eql 0
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'does not find an un-passed argument anywhere in the series' do
|
184
|
+
expect(@subject.call_count('not_an_argument')).to eql 0
|
185
|
+
end
|
186
|
+
|
187
|
+
it 'finds when only the first argument is a wildcard' do
|
188
|
+
expect(@subject.call_count(anything, 'second_argument', 'third_argument')).to eql 1
|
189
|
+
end
|
190
|
+
|
191
|
+
it 'finds when only the second argument is a wildcard' do
|
192
|
+
expect(@subject.call_count('first_argument', anything, 'third_argument')).to eql 1
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'finds when only the third argument is a wildcard' do
|
196
|
+
expect(@subject.call_count('first_argument', 'second_argument', anything)).to eql 1
|
197
|
+
end
|
198
|
+
|
199
|
+
it 'finds when both the first and second arguments are wildcards' do
|
200
|
+
expect(@subject.call_count(anything, anything, 'third_argument')).to eql 1
|
201
|
+
end
|
202
|
+
|
203
|
+
it 'finds when both the first and third arguments are wildcards' do
|
204
|
+
expect(@subject.call_count(anything, 'second_argument', anything)).to eql 1
|
205
|
+
end
|
206
|
+
|
207
|
+
it 'finds when both the second and third arguments are wildcards' do
|
208
|
+
expect(@subject.call_count('first_argument', anything, anything)).to eql 1
|
209
|
+
end
|
210
|
+
|
211
|
+
it 'does not find when wildcard is in wrong position' do
|
212
|
+
expect(@subject.call_count('first_argument', anything, 'second_argument', 'third_argument')).to eql 0
|
213
|
+
end
|
214
|
+
end
|
215
|
+
context 'with an argument called multiple times' do
|
216
|
+
before(:each) do
|
217
|
+
actual_call_log_list =
|
218
|
+
[{
|
219
|
+
'args' => ['twice_called_arg'],
|
220
|
+
'stdin' => []
|
221
|
+
},
|
222
|
+
{
|
223
|
+
'args' => ['twice_called_arg'],
|
224
|
+
'stdin' => []
|
225
|
+
}]
|
226
|
+
@subject = Rspec::Bash::CallLog.new(anything)
|
227
|
+
allow(@subject).to receive(:load_call_log_list).and_return(actual_call_log_list)
|
228
|
+
end
|
229
|
+
it 'returns 2 when argument is called 2 times' do
|
230
|
+
expect(@subject.call_count('twice_called_arg')).to eql 2
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
context '#called_with_args' do
|
237
|
+
before(:each) do
|
238
|
+
actual_call_log_list =
|
239
|
+
[{
|
240
|
+
'args' => ['once_called_arg'],
|
241
|
+
'stdin' => []
|
242
|
+
},
|
243
|
+
{
|
244
|
+
'args' => ['twice_called_arg'],
|
245
|
+
'stdin' => []
|
246
|
+
},
|
247
|
+
{
|
248
|
+
'args' => ['twice_called_arg'],
|
249
|
+
'stdin' => []
|
250
|
+
}]
|
251
|
+
@subject = Rspec::Bash::CallLog.new(anything)
|
252
|
+
allow(@subject).to receive(:load_call_log_list).and_return(actual_call_log_list)
|
253
|
+
end
|
254
|
+
|
255
|
+
it 'returns false when there are no matching args' do
|
256
|
+
expect(@subject.called_with_args?('no-match')).to be_falsey
|
257
|
+
end
|
258
|
+
|
259
|
+
it 'returns true when there is a single matching arg' do
|
260
|
+
expect(@subject.called_with_args?('once_called_arg', anything)).to be_truthy
|
261
|
+
end
|
262
|
+
|
263
|
+
it 'returns true when there are multiple matching args' do
|
264
|
+
expect(@subject.called_with_args?('twice_called_arg')).to be_truthy
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
context '#called_with_no_args?' do
|
269
|
+
it 'returns false if no call log is found' do
|
270
|
+
@subject = Rspec::Bash::CallLog.new(anything)
|
271
|
+
allow(YAML).to receive(:load_file).and_raise(Errno::ENOENT)
|
272
|
+
|
273
|
+
expect(@subject.called_with_no_args?).to be_falsey
|
274
|
+
end
|
275
|
+
it 'returns true if no arguments are in call log' do
|
276
|
+
actual_call_log_list =
|
277
|
+
[{
|
278
|
+
'args' => nil,
|
279
|
+
'stdin' => [],
|
280
|
+
}]
|
281
|
+
@subject = Rspec::Bash::CallLog.new(anything)
|
282
|
+
allow(YAML).to receive(:load_file).and_return(actual_call_log_list)
|
283
|
+
|
284
|
+
expect(@subject.called_with_no_args?).to be_truthy
|
285
|
+
end
|
286
|
+
it 'returns fails if a single argument is in call log' do
|
287
|
+
actual_call_log_list =
|
288
|
+
[{
|
289
|
+
'args' => ['I am an argument'],
|
290
|
+
'stdin' => [],
|
291
|
+
}]
|
292
|
+
@subject = Rspec::Bash::CallLog.new(anything)
|
293
|
+
allow(YAML).to receive(:load_file).and_return(actual_call_log_list)
|
294
|
+
|
295
|
+
expect(@subject.called_with_no_args?).to be_falsey
|
296
|
+
end
|
297
|
+
it 'returns fails if multiple arguments is in call log' do
|
298
|
+
actual_call_log_list =
|
299
|
+
[{
|
300
|
+
'args' => ['I am an argument', 'as am I'],
|
301
|
+
'stdin' => [],
|
302
|
+
}]
|
303
|
+
@subject = Rspec::Bash::CallLog.new(anything)
|
304
|
+
allow(YAML).to receive(:load_file).and_return(actual_call_log_list)
|
305
|
+
|
306
|
+
expect(@subject.called_with_no_args?).to be_falsey
|
307
|
+
end
|
308
|
+
end
|
309
|
+
end
|