rspec-bash 0.1.1 → 0.2.0

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.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +8 -0
  3. data/Gemfile +1 -0
  4. data/README.md +23 -0
  5. data/Rakefile +15 -4
  6. data/bin/bash_stub.sh +92 -0
  7. data/bin/bash_wrapper.sh.erb +12 -0
  8. data/bin/ruby_stub.rb +33 -0
  9. data/lib/rspec/bash.rb +5 -4
  10. data/lib/rspec/bash/command.rb +5 -0
  11. data/lib/rspec/bash/command/call_configuration.rb +76 -0
  12. data/lib/rspec/bash/command/call_configuration_manager.rb +24 -0
  13. data/lib/rspec/bash/command/call_log.rb +48 -0
  14. data/lib/rspec/bash/command/call_log_manager.rb +38 -0
  15. data/lib/rspec/bash/command/stubbed_command.rb +64 -0
  16. data/lib/rspec/bash/server.rb +3 -0
  17. data/lib/rspec/bash/server/bash_stub_marshaller.rb +19 -0
  18. data/lib/rspec/bash/server/ruby_stub_marshaller.rb +13 -0
  19. data/lib/rspec/bash/server/stub_server.rb +47 -0
  20. data/lib/rspec/bash/stubbed_env.rb +75 -54
  21. data/lib/rspec/bash/util/call_conf_argument_list_matcher.rb +5 -5
  22. data/lib/rspec/bash/util/call_log_argument_list_matcher.rb +1 -1
  23. data/lib/rspec/bash/wrapper.rb +4 -0
  24. data/lib/rspec/bash/wrapper/bash_stub_script.rb +15 -0
  25. data/lib/rspec/bash/wrapper/bash_wrapper.rb +54 -0
  26. data/lib/rspec/bash/wrapper/ruby_stub_script.rb +15 -0
  27. data/lib/rspec/bash/wrapper/stub_function.rb +36 -0
  28. data/rspec-bash.gemspec +2 -1
  29. data/spec/classes/command/call_configuration_manager_spec.rb +68 -0
  30. data/spec/classes/{call_configuration_spec.rb → command/call_configuration_spec.rb} +51 -114
  31. data/spec/classes/command/call_log_manager_spec.rb +83 -0
  32. data/spec/classes/{call_log_spec.rb → command/call_log_spec.rb} +23 -82
  33. data/spec/classes/command/stubbed_command_spec.rb +118 -0
  34. data/spec/classes/server/bash_stub_marshaller_spec.rb +38 -0
  35. data/spec/classes/server/ruby_stub_marshaller_spec.rb +31 -0
  36. data/spec/classes/server/stub_server_spec.rb +121 -0
  37. data/spec/classes/stubbed_env_spec.rb +141 -280
  38. data/spec/classes/util/call_conf_argument_list_matcher_spec.rb +17 -17
  39. data/spec/classes/util/call_log_argument_list_matcher_spec.rb +24 -18
  40. data/spec/classes/wrapper/bash_wrapper_spec.rb +37 -0
  41. data/spec/classes/wrapper/ruby_stub_script_spec.rb +204 -0
  42. data/spec/helper/string_file_io.rb +1 -1
  43. data/spec/integration/call_log/called_with_args_spec.rb +8 -4
  44. data/spec/integration/call_log/called_with_no_args_spec.rb +1 -1
  45. data/spec/integration/call_log/stdin_spec.rb +10 -4
  46. data/spec/integration/edge_cases_spec.rb +34 -0
  47. data/spec/integration/matchers/be_called_with_arguments_spec.rb +12 -13
  48. data/spec/integration/matchers/be_called_with_no_arguments_spec.rb +6 -7
  49. data/spec/integration/stubbed_command/outputs_spec.rb +111 -91
  50. data/spec/integration/stubbed_command/returns_exitstatus_spec.rb +46 -37
  51. data/spec/integration/stubbed_env/execute_with_env_vars_spec.rb +3 -4
  52. data/spec/integration/stubbed_env/execute_with_path_spec.rb +6 -7
  53. data/spec/integration/stubbed_env/execute_with_stub_wrapper_spec.rb +4 -12
  54. data/spec/integration/stubbed_env/override_spec.rb +354 -0
  55. data/spec/integration/wrapper/bash_stub_script_spec.rb +383 -0
  56. data/spec/integration/wrapper/bash_wrapper_spec.rb +48 -0
  57. data/spec/scripts/function_library.sh +9 -1
  58. data/spec/spec_helper.rb +2 -0
  59. metadata +65 -21
  60. data/bin/function_override.sh.erb +0 -7
  61. data/bin/function_override_wrapper.sh.erb +0 -19
  62. data/bin/stub.rb.erb +0 -56
  63. data/lib/rspec/bash/call_configuration.rb +0 -62
  64. data/lib/rspec/bash/call_log.rb +0 -71
  65. data/lib/rspec/bash/stubbed_command.rb +0 -88
  66. data/spec/classes/stub_spec.rb +0 -510
  67. data/spec/classes/stubbed_command_spec.rb +0 -134
  68. data/spec/integration/assert_called_spec.rb +0 -0
@@ -0,0 +1,36 @@
1
+ module Rspec
2
+ module Bash
3
+ class StubFunction
4
+ def initialize(port, stub_script_class)
5
+ @port = port
6
+ @stub_script_class = stub_script_class
7
+ end
8
+
9
+ def header(name)
10
+ "function #{name} {"
11
+ end
12
+
13
+ def footer(name)
14
+ "}\nreadonly -f #{name} &> /dev/null"
15
+ end
16
+
17
+ def body(name)
18
+ "#{stub_path} #{name} #{@port} \"${@}\""
19
+ end
20
+
21
+ def script(name)
22
+ <<-multiline_string
23
+ #{header(name)}
24
+ #{body(name)}
25
+ #{footer(name)}
26
+ multiline_string
27
+ end
28
+
29
+ private
30
+
31
+ def stub_path
32
+ @stub_script_class.path
33
+ end
34
+ end
35
+ end
36
+ end
data/rspec-bash.gemspec CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = 'rspec-bash'
7
- spec.version = '0.1.1'
7
+ spec.version = '0.2.0'
8
8
  spec.authors = ['Ben Brewer', 'Mike Urban', 'Matthijs Groen']
9
9
  spec.email = ['ben@benbrewer.me', 'mike.david.urban@gmail.com']
10
10
  spec.summary = 'Test Bash with RSpec'
@@ -19,6 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
20
  spec.require_paths = ['lib']
21
21
 
22
+ spec.add_runtime_dependency 'sparsify', '~> 1.1'
22
23
  spec.add_development_dependency 'bundler', '~> 1.6'
23
24
  spec.add_development_dependency 'rake', '~> 10.0'
24
25
  end
@@ -0,0 +1,68 @@
1
+ require 'spec_helper'
2
+ include Rspec::Bash
3
+
4
+ describe 'CallConfigurationManager' do
5
+ subject { CallConfigurationManager.new }
6
+
7
+ context 'with a command call configuration' do
8
+ let(:first_command_call_conf) do
9
+ call_conf = double(CallConfiguration)
10
+ allow(CallConfiguration).to receive(:new)
11
+ .and_return(call_conf).once
12
+ call_conf
13
+ end
14
+ context '#set_exitcode' do
15
+ it 'passes the exit code along to the correct CallConfiguration' do
16
+ expect(first_command_call_conf).to receive(:set_exitcode)
17
+ .with(0, %w(first_argument second_argument)).once
18
+ expect(first_command_call_conf).to receive(:set_exitcode)
19
+ .with(1, %w(first_argument second_argument)).once
20
+
21
+ subject.set_exitcode('first_command', 0, %w(first_argument second_argument))
22
+ subject.set_exitcode('first_command', 1, %w(first_argument second_argument))
23
+ end
24
+ end
25
+ context '#add_output' do
26
+ it 'passes the output addition along to the correct CallConfiguration' do
27
+ expect(first_command_call_conf).to receive(:add_output)
28
+ .with('hello', :stdout, %w(first_argument second_argument)).once
29
+ expect(first_command_call_conf).to receive(:add_output)
30
+ .with('world', :stderr, %w(first_argument second_argument)).once
31
+
32
+ subject.add_output('first_command', 'hello', :stdout, %w(first_argument second_argument))
33
+ subject.add_output('first_command', 'world', :stderr, %w(first_argument second_argument))
34
+ end
35
+ end
36
+ context '#get_best_call_conf' do
37
+ it 'passes the query along to the correct CallConfiguration' do
38
+ allow(first_command_call_conf).to receive(:get_best_call_conf)
39
+ .with(%w(first_argument second_argument))
40
+ .and_return(
41
+ args: %w(first_argument second_argument),
42
+ exitcode: 0,
43
+ outputs: []
44
+ ).once
45
+ allow(first_command_call_conf).to receive(:get_best_call_conf)
46
+ .with(%w(first_argument other_argument))
47
+ .and_return(
48
+ args: %w(first_argument other_argument),
49
+ exitcode: 1,
50
+ outputs: []
51
+ ).once
52
+
53
+ expect(subject.get_best_call_conf('first_command', %w(first_argument second_argument)))
54
+ .to eql(
55
+ args: %w(first_argument second_argument),
56
+ exitcode: 0,
57
+ outputs: []
58
+ )
59
+ expect(subject.get_best_call_conf('first_command', %w(first_argument other_argument)))
60
+ .to eql(
61
+ args: %w(first_argument other_argument),
62
+ exitcode: 1,
63
+ outputs: []
64
+ )
65
+ end
66
+ end
67
+ end
68
+ end
@@ -1,20 +1,11 @@
1
1
  require 'spec_helper'
2
+ include Rspec::Bash
2
3
 
3
4
  describe 'CallConfiguration' do
4
- let(:stubbed_env) { create_stubbed_env }
5
- include Rspec::Bash
6
-
7
- let(:mock_conf_file) { StringFileIO.new }
8
- let(:mock_conf_pathname) { instance_double(Pathname) }
9
- before(:each) do
10
- allow(mock_conf_pathname).to receive(:open).with('r').and_yield(mock_conf_file)
11
- allow(mock_conf_pathname).to receive(:open).with('w').and_yield(mock_conf_file)
12
- end
5
+ subject { Rspec::Bash::CallConfiguration.new }
13
6
 
14
7
  context '#set_exitcode' do
15
8
  context 'with any setup' do
16
- subject { Rspec::Bash::CallConfiguration.new(mock_conf_pathname, 'command_name') }
17
-
18
9
  context 'with no existing configuration' do
19
10
  let(:expected_conf) do
20
11
  [
@@ -30,11 +21,6 @@ describe 'CallConfiguration' do
30
21
  subject.set_exitcode(1, %w(first_argument second_argument))
31
22
  expect(subject.call_configuration).to eql expected_conf
32
23
  end
33
-
34
- it 'writes that configuration to its conf file' do
35
- expect(mock_conf_file).to receive(:write).with(expected_conf.to_yaml)
36
- subject.set_exitcode(1, %w(first_argument second_argument))
37
- end
38
24
  end
39
25
  context 'with an existing, non-matching configuration' do
40
26
  let(:expected_conf) do
@@ -52,7 +38,7 @@ describe 'CallConfiguration' do
52
38
  }
53
39
  ]
54
40
  end
55
- before(:each) do
41
+ before do
56
42
  subject.call_configuration = [
57
43
  {
58
44
  args: %w(first_argument),
@@ -65,11 +51,6 @@ describe 'CallConfiguration' do
65
51
  subject.set_exitcode(1, %w(first_argument second_argument))
66
52
  expect(subject.call_configuration).to eql expected_conf
67
53
  end
68
-
69
- it 'writes that configuration to its conf file' do
70
- expect(mock_conf_file).to receive(:write).with(expected_conf.to_yaml)
71
- subject.set_exitcode(1, %w(first_argument second_argument))
72
- end
73
54
  end
74
55
  context 'with an existing, matching configuration' do
75
56
  let(:expected_conf) do
@@ -81,7 +62,7 @@ describe 'CallConfiguration' do
81
62
  }
82
63
  ]
83
64
  end
84
- before(:each) do
65
+ before do
85
66
  subject.call_configuration = [
86
67
  {
87
68
  args: %w(first_argument second_argument),
@@ -95,26 +76,11 @@ describe 'CallConfiguration' do
95
76
  subject.set_exitcode(1, %w(first_argument second_argument))
96
77
  expect(subject.call_configuration).to eql expected_conf
97
78
  end
98
-
99
- it 'writes that configuration to its conf file' do
100
- expect(mock_conf_file).to receive(:write).with(expected_conf.to_yaml)
101
- subject.set_exitcode(1, %w(first_argument second_argument))
102
- end
103
- end
104
- end
105
- context 'with no config_path' do
106
- subject { Rspec::Bash::CallConfiguration.new(nil, anything) }
107
- it 'raises an error' do
108
- expect do
109
- subject.set_exitcode(1, %w(first_argument second_argument))
110
- end.to raise_exception(NoMethodError)
111
79
  end
112
80
  end
113
81
  end
114
82
  context '#add_output' do
115
83
  context 'with any setup' do
116
- subject { Rspec::Bash::CallConfiguration.new(mock_conf_pathname, 'command_name') }
117
-
118
84
  context 'with no existing configuration' do
119
85
  let(:expected_conf) do
120
86
  [
@@ -134,11 +100,6 @@ describe 'CallConfiguration' do
134
100
  subject.add_output('new_content', :stderr, %w(first_argument second_argument))
135
101
  expect(subject.call_configuration).to eql expected_conf
136
102
  end
137
-
138
- it 'writes that configuration to its conf file' do
139
- expect(mock_conf_file).to receive(:write).with(expected_conf.to_yaml)
140
- subject.add_output('new_content', :stderr, %w(first_argument second_argument))
141
- end
142
103
  end
143
104
  context 'with an existing, non-matching configuration' do
144
105
  let(:expected_conf) do
@@ -165,7 +126,7 @@ describe 'CallConfiguration' do
165
126
  }
166
127
  ]
167
128
  end
168
- before(:each) do
129
+ before do
169
130
  subject.call_configuration = [
170
131
  {
171
132
  args: %w(first_argument),
@@ -183,11 +144,6 @@ describe 'CallConfiguration' do
183
144
  subject.add_output('new_content', :stderr, %w(first_argument second_argument))
184
145
  expect(subject.call_configuration).to eql expected_conf
185
146
  end
186
-
187
- it 'writes that configuration to its conf file' do
188
- expect(mock_conf_file).to receive(:write).with(expected_conf.to_yaml)
189
- subject.add_output('new_content', :stderr, %w(first_argument second_argument))
190
- end
191
147
  end
192
148
  context 'with an existing, matching configuration' do
193
149
  let(:expected_conf) do
@@ -208,7 +164,7 @@ describe 'CallConfiguration' do
208
164
  }
209
165
  ]
210
166
  end
211
- before(:each) do
167
+ before do
212
168
  subject.call_configuration = [
213
169
  {
214
170
  args: %w(first_argument second_argument),
@@ -226,82 +182,63 @@ describe 'CallConfiguration' do
226
182
  subject.add_output('new_content', :stderr, %w(first_argument second_argument))
227
183
  expect(subject.call_configuration).to eql expected_conf
228
184
  end
229
-
230
- it 'writes that configuration to its conf file' do
231
- expect(mock_conf_file).to receive(:write).with(expected_conf.to_yaml)
232
- subject.add_output('new_content', :stderr, %w(first_argument second_argument))
233
- end
234
- end
235
- end
236
- context 'with no config_path' do
237
- subject { Rspec::Bash::CallConfiguration.new(nil, anything) }
238
- it 'raises an error' do
239
- expect do
240
- subject.add_output('new_content', :stderr, %w(first_argument second_argument))
241
- end.to raise_exception(NoMethodError)
242
185
  end
243
186
  end
244
187
  end
245
- context '#call_configuration' do
246
- context 'when there is no config_path' do
247
- subject { Rspec::Bash::CallConfiguration.new(nil, anything) }
248
- it 'returns an empty array' do
249
- expect(subject.call_configuration).to eql []
250
- end
251
- end
252
- context 'when the conf file exists but is empty' do
253
- subject { Rspec::Bash::CallConfiguration.new(mock_conf_pathname, anything) }
254
- before(:each) do
255
- allow(mock_conf_file).to receive(:read).and_return('')
256
- end
257
- it 'returns an empty array' do
258
- expect(subject.call_configuration).to eql []
259
- end
260
- end
261
- context 'when the call log file open throws a file not found exception' do
262
- subject { Rspec::Bash::CallConfiguration.new(mock_conf_pathname, anything) }
263
- before(:each) do
264
- allow(mock_conf_pathname).to receive(:open).with('r').and_raise(Errno::ENOENT)
265
- end
266
- it 'returns an empty array' do
267
- expect(subject.call_configuration).to eql []
188
+ context '#get_best_call_conf' do
189
+ context 'with any setup' do
190
+ context 'with no existing configuration' do
191
+ it 'updates the status code conf for the arguments passed in' do
192
+ call_conf = subject.get_best_call_conf(%w(first_argument second_argument))
193
+ expect(call_conf).to eql({})
194
+ end
268
195
  end
269
- end
270
- context 'when setup is valid' do
271
- subject { Rspec::Bash::CallConfiguration.new(mock_conf_pathname, 'command_name') }
272
- let(:conf) do
273
- [{
274
- args: %w(first_argument second_argument),
275
- exitcode: 1,
276
- outputs: [
277
- {
278
- target: :stdout,
279
- content: 'old_content'
280
- },
196
+ context 'with an existing, non-matching configuration' do
197
+ before do
198
+ subject.call_configuration = [
281
199
  {
282
- target: :stderr,
283
- content: 'new_content'
200
+ args: %w(first_argument),
201
+ exitcode: 1,
202
+ outputs: []
284
203
  }
285
204
  ]
286
- }]
287
- end
288
- context 'and no configuration exists' do
289
- before(:each) do
290
- allow(mock_conf_file).to receive(:read).and_return(conf.to_yaml)
291
- allow(mock_conf_pathname).to receive(:open).with('r').and_yield(mock_conf_file)
292
205
  end
293
-
294
- it 'reads out what was in its configuration file' do
295
- expect(subject.call_configuration).to eql conf
206
+ it 'returns an empty hash indicating no match was found' do
207
+ call_conf = subject.get_best_call_conf(%w(first_argument second_argument))
208
+ expect(call_conf).to eql({})
296
209
  end
297
210
  end
298
- context 'and a configuration already exists' do
299
- before(:each) do
300
- subject.call_configuration = conf
211
+ context 'with an existing, matching configuration' do
212
+ let(:expected_conf) do
213
+ {
214
+ exitcode: 2,
215
+ outputs: [
216
+ target: 'first_argument-something-second_argument-another.txt',
217
+ content: 'dynamically generated file name contents'
218
+ ]
219
+ }
220
+ end
221
+ before do
222
+ subject.call_configuration = [
223
+ {
224
+ args: %w(first_argument second_argument),
225
+ exitcode: 2,
226
+ outputs: [
227
+ target: [
228
+ :arg1,
229
+ '-something-',
230
+ :arg2,
231
+ '-another.txt'
232
+ ],
233
+ content: 'dynamically generated file name contents'
234
+ ]
235
+ }
236
+ ]
301
237
  end
302
238
 
303
- it 'reads out what was in its configuration file' do
304
- expect(subject.call_configuration).to eql conf
239
+ it 'returns the matching hash with args removed and paths adjusted' do
240
+ call_conf = subject.get_best_call_conf(%w(first_argument second_argument))
241
+ expect(call_conf).to eql expected_conf
305
242
  end
306
243
  end
307
244
  end
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+ include Rspec::Bash
3
+
4
+ describe 'CallLogManager' do
5
+ subject { CallLogManager.new }
6
+
7
+ context 'with a command call configuration' do
8
+ let(:first_command_call_log) do
9
+ call_log = double(CallLog)
10
+ allow(CallLog).to receive(:new)
11
+ .and_return(call_log).once
12
+ call_log
13
+ end
14
+
15
+ context '#add_log' do
16
+ it 'passes the logs to their respective calllogs' do
17
+ expect(first_command_call_log).to receive(:add_log)
18
+ .with('stdin', %w(first_argument second_argument)).twice
19
+
20
+ subject.add_log('first_command', 'stdin', %w(first_argument second_argument))
21
+ subject.add_log('first_command', 'stdin', %w(first_argument second_argument))
22
+ end
23
+ end
24
+
25
+ context '#stdin_for_args' do
26
+ it 'gets the respective stdin for an array of arguments' do
27
+ allow(first_command_call_log).to receive(:stdin_for_args)
28
+ .with(%w(first_argument second_argument))
29
+ .and_return('first_command stdin for [first_argument, second_argument]')
30
+ allow(first_command_call_log).to receive(:stdin_for_args)
31
+ .with(%w(third_argument fourth_argument))
32
+ .and_return('first_command stdin for [third_argument, fourth_argument]')
33
+
34
+ expect(subject.stdin_for_args('first_command', %w(first_argument second_argument)))
35
+ .to eql('first_command stdin for [first_argument, second_argument]')
36
+ expect(subject.stdin_for_args('first_command', %w(third_argument fourth_argument)))
37
+ .to eql('first_command stdin for [third_argument, fourth_argument]')
38
+ end
39
+ end
40
+
41
+ context '#call_count' do
42
+ it 'gets the respective call count for an array of arguments' do
43
+ allow(first_command_call_log).to receive(:call_count)
44
+ .with(%w(first_argument second_argument))
45
+ .and_return(2)
46
+ allow(first_command_call_log).to receive(:call_count)
47
+ .with(%w(third_argument fourth_argument))
48
+ .and_return(3)
49
+
50
+ expect(subject.call_count('first_command', %w(first_argument second_argument)))
51
+ .to eql(2)
52
+ expect(subject.call_count('first_command', %w(third_argument fourth_argument)))
53
+ .to eql(3)
54
+ end
55
+ end
56
+
57
+ context '#called_with_args?' do
58
+ it 'gets the respective call status for the arguments' do
59
+ allow(first_command_call_log).to receive(:called_with_args?)
60
+ .with(%w(first_argument second_argument))
61
+ .and_return(true)
62
+ allow(first_command_call_log).to receive(:called_with_args?)
63
+ .with(%w(third_argument fourth_argument))
64
+ .and_return(false)
65
+
66
+ expect(subject.called_with_args?('first_command', %w(first_argument second_argument)))
67
+ .to eql(true)
68
+ expect(subject.called_with_args?('first_command', %w(third_argument fourth_argument)))
69
+ .to eql(false)
70
+ end
71
+ end
72
+
73
+ context '#called_with_no_args?' do
74
+ it 'gets the respective call status for the arguments' do
75
+ allow(first_command_call_log).to receive(:called_with_no_args?)
76
+ .and_return(true)
77
+
78
+ expect(subject.called_with_no_args?('first_command'))
79
+ .to eql(true)
80
+ end
81
+ end
82
+ end
83
+ end