rspec-bash 0.2.1 → 0.3.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.
- checksums.yaml +4 -4
- data/bin/bash_stub.sh +14 -6
- data/bin/bash_wrapper.sh.erb +2 -2
- data/bin/ruby_stub.rb +4 -4
- data/lib/rspec/bash/command/call_configuration.rb +24 -7
- data/lib/rspec/bash/stubbed_env.rb +3 -3
- data/lib/rspec/bash/wrapper/stub_function.rb +1 -1
- data/rspec-bash.gemspec +1 -1
- data/spec/classes/command/call_configuration_spec.rb +104 -35
- data/spec/classes/stubbed_env_spec.rb +4 -4
- data/spec/classes/util/call_conf_argument_list_matcher_spec.rb +154 -154
- data/spec/classes/wrapper/ruby_stub_script_spec.rb +5 -5
- data/spec/integration/edge_cases/stub_internals_spec.rb +101 -0
- data/spec/integration/stubbed_command/outputs_spec.rb +46 -13
- data/spec/integration/stubbed_command/returns_exitstatus_spec.rb +0 -12
- data/spec/integration/stubbed_env/override_spec.rb +0 -25
- data/spec/integration/wrapper/bash_stub_script_spec.rb +49 -23
- data/spec/spec_helper.rb +25 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: adb76c72f692325f6aa85d9a578b13190083fcae
|
4
|
+
data.tar.gz: 712b69713f4ad701961cfb0332945456b37a803f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: df61e714d3a72219babba6fa5b7b9cb62f72f5f8183f0b7b984aaf0efc8d7e939bdc1b025576b7b6380219fe35de0d812863ffd6e051da3a997865e799af3826
|
7
|
+
data.tar.gz: f8649135e3247edb923e8f25b5df390ed50e50379e75f4027871606099a3fbf9e605cd0be1f8715a5b98f551a8e4c95b2196d75fd6479d5520ca640cc0b3e32f
|
data/bin/bash_stub.sh
CHANGED
@@ -64,15 +64,21 @@ function extract-string-properties {
|
|
64
64
|
}
|
65
65
|
|
66
66
|
function print-output {
|
67
|
-
|
67
|
+
local type=${1}
|
68
|
+
local target=${2}
|
69
|
+
local content=${3}
|
70
|
+
|
71
|
+
case ${type} in
|
68
72
|
stdout)
|
69
|
-
echo -en "${
|
73
|
+
echo -en "${content}"
|
70
74
|
;;
|
71
75
|
stderr)
|
72
|
-
echo -en "${
|
76
|
+
echo -en "${content}" >&2
|
73
77
|
;;
|
74
|
-
|
75
|
-
|
78
|
+
file)
|
79
|
+
if [[ -n "${target}" ]]; then
|
80
|
+
echo -en "${content}" > "${target}"
|
81
|
+
fi
|
76
82
|
;;
|
77
83
|
esac
|
78
84
|
}
|
@@ -81,13 +87,15 @@ function main {
|
|
81
87
|
server_message=$(send-to-server "${2}" "${client_message}")
|
82
88
|
IFS=$'\n'
|
83
89
|
target_list=( $(extract-string-properties "${server_message}" "outputs\..*\.target") )
|
90
|
+
type_list=( $(extract-string-properties "${server_message}" "outputs\..*\.type") )
|
84
91
|
content_list=( $(extract-string-properties "${server_message}" "outputs\..*\.content") )
|
85
92
|
exit_code=$(extract-number-properties "${server_message}" "exitcode")
|
86
93
|
|
87
94
|
for index in "${!target_list[@]}"; do
|
88
95
|
target=${target_list[${index}]}
|
96
|
+
type=${type_list[${index}]}
|
89
97
|
content=$(json-decode "${content_list[${index}]}")
|
90
|
-
print-output "${target}" "${content}"
|
98
|
+
print-output "${type}" "${target}" "${content}"
|
91
99
|
done
|
92
100
|
|
93
101
|
exit ${exit_code}
|
data/bin/bash_wrapper.sh.erb
CHANGED
data/bin/ruby_stub.rb
CHANGED
@@ -17,16 +17,16 @@ sock.close_read
|
|
17
17
|
|
18
18
|
exit 0 if conf_from_server.empty?
|
19
19
|
|
20
|
-
(conf_from_server[:outputs] || []).each do |data|
|
21
|
-
if
|
20
|
+
(conf_from_server[:outputs] || []).each do |target, data|
|
21
|
+
if target == :stdout
|
22
22
|
$stdout.print data[:content]
|
23
23
|
next
|
24
24
|
end
|
25
|
-
if
|
25
|
+
if target == :stderr
|
26
26
|
$stderr.print data[:content]
|
27
27
|
next
|
28
28
|
end
|
29
|
-
Pathname.new(
|
29
|
+
Pathname.new(target).open('w') do |f|
|
30
30
|
f.print data[:content]
|
31
31
|
end
|
32
32
|
end
|
@@ -16,9 +16,11 @@ module Rspec
|
|
16
16
|
|
17
17
|
def add_output(content, target, args = [])
|
18
18
|
current_conf = create_or_get_conf(args)
|
19
|
-
|
19
|
+
type = determine_output_type(target)
|
20
|
+
current_conf[:outputs][target] = {
|
20
21
|
target: target,
|
21
|
-
|
22
|
+
type: type,
|
23
|
+
content: content.to_s
|
22
24
|
}
|
23
25
|
end
|
24
26
|
|
@@ -27,7 +29,7 @@ module Rspec
|
|
27
29
|
best_call_conf = call_conf_arg_matcher.get_best_call_conf(args)
|
28
30
|
remove_args_from_conf(
|
29
31
|
interpolate_output_targets(
|
30
|
-
best_call_conf,
|
32
|
+
copy_conf(best_call_conf),
|
31
33
|
args
|
32
34
|
)
|
33
35
|
)
|
@@ -37,8 +39,13 @@ module Rspec
|
|
37
39
|
|
38
40
|
def interpolate_output_targets(conf, args)
|
39
41
|
return conf if conf.empty?
|
40
|
-
conf[:outputs].each do |
|
41
|
-
|
42
|
+
conf[:outputs].keys.each do |target|
|
43
|
+
interpolated_target = interpolate_target(target, args)
|
44
|
+
next if interpolated_target == target
|
45
|
+
|
46
|
+
conf[:outputs][interpolated_target] = conf[:outputs][target]
|
47
|
+
conf[:outputs][interpolated_target][:target] = interpolated_target
|
48
|
+
conf[:outputs].delete(target)
|
42
49
|
end
|
43
50
|
conf
|
44
51
|
end
|
@@ -58,19 +65,29 @@ module Rspec
|
|
58
65
|
end
|
59
66
|
|
60
67
|
def remove_args_from_conf(conf)
|
61
|
-
conf.
|
68
|
+
conf.delete(:args)
|
69
|
+
conf
|
62
70
|
end
|
63
71
|
|
64
72
|
def create_or_get_conf(args)
|
65
73
|
new_conf = {
|
66
74
|
args: args,
|
67
75
|
exitcode: 0,
|
68
|
-
outputs:
|
76
|
+
outputs: {}
|
69
77
|
}
|
70
78
|
current_conf = @call_configuration.select { |conf| conf[:args] == args }
|
71
79
|
@call_configuration << new_conf if current_conf.empty?
|
72
80
|
current_conf.first || new_conf
|
73
81
|
end
|
82
|
+
|
83
|
+
def copy_conf(configuration)
|
84
|
+
Marshal.load(Marshal.dump(configuration))
|
85
|
+
end
|
86
|
+
|
87
|
+
def determine_output_type(target)
|
88
|
+
is_a_file_target = !([:stdout, :stderr].include? target)
|
89
|
+
is_a_file_target ? :file : target
|
90
|
+
end
|
74
91
|
end
|
75
92
|
end
|
76
93
|
end
|
@@ -32,13 +32,13 @@ module Rspec
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def execute(command, env_vars = {})
|
35
|
-
script_runner = "source #{command}"
|
35
|
+
script_runner = "command source #{command}"
|
36
36
|
script_wrapper = wrap_script(script_runner)
|
37
37
|
execute_script(env_vars, script_wrapper)
|
38
38
|
end
|
39
39
|
|
40
40
|
def execute_function(script, command, env_vars = {})
|
41
|
-
script_runner = "source #{script}\n#{command}"
|
41
|
+
script_runner = "command source #{script}\n#{command}"
|
42
42
|
script_wrapper = wrap_script(script_runner)
|
43
43
|
execute_script(env_vars, script_wrapper)
|
44
44
|
end
|
@@ -62,7 +62,7 @@ module Rspec
|
|
62
62
|
RUBY_STUB => RubyStubScript,
|
63
63
|
BASH_STUB => BashStubScript
|
64
64
|
}.freeze
|
65
|
-
DISALLOWED_COMMANDS = %w(
|
65
|
+
DISALLOWED_COMMANDS = %w(command function).freeze
|
66
66
|
|
67
67
|
def create_tcp_server
|
68
68
|
tcp_server = TCPServer.new('localhost', 0)
|
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.
|
7
|
+
spec.version = '0.3.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'
|
@@ -12,7 +12,7 @@ describe 'CallConfiguration' do
|
|
12
12
|
{
|
13
13
|
args: %w(first_argument second_argument),
|
14
14
|
exitcode: 1,
|
15
|
-
outputs:
|
15
|
+
outputs: {}
|
16
16
|
}
|
17
17
|
]
|
18
18
|
end
|
@@ -28,13 +28,13 @@ describe 'CallConfiguration' do
|
|
28
28
|
{
|
29
29
|
args: %w(first_argument),
|
30
30
|
exitcode: 1,
|
31
|
-
outputs:
|
31
|
+
outputs: {}
|
32
32
|
},
|
33
33
|
{
|
34
34
|
|
35
35
|
args: %w(first_argument second_argument),
|
36
36
|
exitcode: 1,
|
37
|
-
outputs:
|
37
|
+
outputs: {}
|
38
38
|
}
|
39
39
|
]
|
40
40
|
end
|
@@ -43,7 +43,7 @@ describe 'CallConfiguration' do
|
|
43
43
|
{
|
44
44
|
args: %w(first_argument),
|
45
45
|
exitcode: 1,
|
46
|
-
outputs:
|
46
|
+
outputs: {}
|
47
47
|
}
|
48
48
|
]
|
49
49
|
end
|
@@ -58,7 +58,7 @@ describe 'CallConfiguration' do
|
|
58
58
|
{
|
59
59
|
args: %w(first_argument second_argument),
|
60
60
|
exitcode: 1,
|
61
|
-
outputs:
|
61
|
+
outputs: {}
|
62
62
|
}
|
63
63
|
]
|
64
64
|
end
|
@@ -67,7 +67,7 @@ describe 'CallConfiguration' do
|
|
67
67
|
{
|
68
68
|
args: %w(first_argument second_argument),
|
69
69
|
exitcode: 2,
|
70
|
-
outputs:
|
70
|
+
outputs: {}
|
71
71
|
}
|
72
72
|
]
|
73
73
|
end
|
@@ -81,18 +81,40 @@ describe 'CallConfiguration' do
|
|
81
81
|
end
|
82
82
|
context '#add_output' do
|
83
83
|
context 'with any setup' do
|
84
|
+
context 'regardless of existing or non-existing configuration' do
|
85
|
+
let(:expected_conf) do
|
86
|
+
[
|
87
|
+
{
|
88
|
+
args: %w(first_argument second_argument),
|
89
|
+
exitcode: 0,
|
90
|
+
outputs: {
|
91
|
+
stderr: {
|
92
|
+
target: :stderr,
|
93
|
+
type: :stderr,
|
94
|
+
content: '2'
|
95
|
+
}
|
96
|
+
}
|
97
|
+
}
|
98
|
+
]
|
99
|
+
end
|
100
|
+
it 'updates the internal configuration but converts output to a string' do
|
101
|
+
subject.add_output(2, :stderr, %w(first_argument second_argument))
|
102
|
+
expect(subject.call_configuration).to eql expected_conf
|
103
|
+
end
|
104
|
+
end
|
84
105
|
context 'with no existing configuration' do
|
85
106
|
let(:expected_conf) do
|
86
107
|
[
|
87
108
|
{
|
88
109
|
args: %w(first_argument second_argument),
|
89
110
|
exitcode: 0,
|
90
|
-
outputs:
|
91
|
-
{
|
111
|
+
outputs: {
|
112
|
+
stderr: {
|
92
113
|
target: :stderr,
|
114
|
+
type: :stderr,
|
93
115
|
content: 'new_content'
|
94
116
|
}
|
95
|
-
|
117
|
+
}
|
96
118
|
}
|
97
119
|
]
|
98
120
|
end
|
@@ -107,22 +129,24 @@ describe 'CallConfiguration' do
|
|
107
129
|
{
|
108
130
|
args: %w(first_argument),
|
109
131
|
exitcode: 1,
|
110
|
-
outputs:
|
111
|
-
{
|
132
|
+
outputs: {
|
133
|
+
stdout: {
|
112
134
|
target: :stdout,
|
135
|
+
type: :stdout,
|
113
136
|
content: 'different_content'
|
114
137
|
}
|
115
|
-
|
138
|
+
}
|
116
139
|
},
|
117
140
|
{
|
118
141
|
args: %w(first_argument second_argument),
|
119
142
|
exitcode: 0,
|
120
|
-
outputs:
|
121
|
-
{
|
143
|
+
outputs: {
|
144
|
+
stderr: {
|
122
145
|
target: :stderr,
|
146
|
+
type: :stderr,
|
123
147
|
content: 'new_content'
|
124
148
|
}
|
125
|
-
|
149
|
+
}
|
126
150
|
}
|
127
151
|
]
|
128
152
|
end
|
@@ -131,12 +155,13 @@ describe 'CallConfiguration' do
|
|
131
155
|
{
|
132
156
|
args: %w(first_argument),
|
133
157
|
exitcode: 1,
|
134
|
-
outputs:
|
135
|
-
{
|
158
|
+
outputs: {
|
159
|
+
stdout: {
|
136
160
|
target: :stdout,
|
161
|
+
type: :stdout,
|
137
162
|
content: 'different_content'
|
138
163
|
}
|
139
|
-
|
164
|
+
}
|
140
165
|
}
|
141
166
|
]
|
142
167
|
end
|
@@ -151,16 +176,18 @@ describe 'CallConfiguration' do
|
|
151
176
|
{
|
152
177
|
args: %w(first_argument second_argument),
|
153
178
|
exitcode: 1,
|
154
|
-
outputs:
|
155
|
-
{
|
179
|
+
outputs: {
|
180
|
+
stdout: {
|
156
181
|
target: :stdout,
|
182
|
+
type: :stdout,
|
157
183
|
content: 'old_content'
|
158
184
|
},
|
159
|
-
{
|
185
|
+
stderr: {
|
160
186
|
target: :stderr,
|
187
|
+
type: :stderr,
|
161
188
|
content: 'new_content'
|
162
189
|
}
|
163
|
-
|
190
|
+
}
|
164
191
|
}
|
165
192
|
]
|
166
193
|
end
|
@@ -169,12 +196,13 @@ describe 'CallConfiguration' do
|
|
169
196
|
{
|
170
197
|
args: %w(first_argument second_argument),
|
171
198
|
exitcode: 1,
|
172
|
-
outputs:
|
173
|
-
{
|
199
|
+
outputs: {
|
200
|
+
stdout: {
|
174
201
|
target: :stdout,
|
202
|
+
type: :stdout,
|
175
203
|
content: 'old_content'
|
176
204
|
}
|
177
|
-
|
205
|
+
}
|
178
206
|
}
|
179
207
|
]
|
180
208
|
end
|
@@ -182,6 +210,22 @@ describe 'CallConfiguration' do
|
|
182
210
|
subject.add_output('new_content', :stderr, %w(first_argument second_argument))
|
183
211
|
expect(subject.call_configuration).to eql expected_conf
|
184
212
|
end
|
213
|
+
it 'replaces the outputs conf for the matching target' do
|
214
|
+
subject.add_output('new_content', :stdout, %w(first_argument second_argument))
|
215
|
+
expect(subject.call_configuration).to eql [
|
216
|
+
{
|
217
|
+
args: %w(first_argument second_argument),
|
218
|
+
exitcode: 1,
|
219
|
+
outputs: {
|
220
|
+
stdout: {
|
221
|
+
target: :stdout,
|
222
|
+
type: :stdout,
|
223
|
+
content: 'new_content'
|
224
|
+
}
|
225
|
+
}
|
226
|
+
}
|
227
|
+
]
|
228
|
+
end
|
185
229
|
end
|
186
230
|
end
|
187
231
|
end
|
@@ -199,7 +243,7 @@ describe 'CallConfiguration' do
|
|
199
243
|
{
|
200
244
|
args: %w(first_argument),
|
201
245
|
exitcode: 1,
|
202
|
-
outputs:
|
246
|
+
outputs: {}
|
203
247
|
}
|
204
248
|
]
|
205
249
|
end
|
@@ -212,10 +256,17 @@ describe 'CallConfiguration' do
|
|
212
256
|
let(:expected_conf) do
|
213
257
|
{
|
214
258
|
exitcode: 2,
|
215
|
-
outputs:
|
216
|
-
|
217
|
-
|
218
|
-
|
259
|
+
outputs: {
|
260
|
+
'first_argument-something-second_argument-another.txt' => {
|
261
|
+
target: 'first_argument-something-second_argument-another.txt',
|
262
|
+
type: :file,
|
263
|
+
content: 'dynamically generated file name contents'
|
264
|
+
},
|
265
|
+
stdout: {
|
266
|
+
target: :stdout,
|
267
|
+
content: 'stdout content'
|
268
|
+
}
|
269
|
+
}
|
219
270
|
}
|
220
271
|
end
|
221
272
|
before do
|
@@ -223,15 +274,27 @@ describe 'CallConfiguration' do
|
|
223
274
|
{
|
224
275
|
args: %w(first_argument second_argument),
|
225
276
|
exitcode: 2,
|
226
|
-
outputs:
|
227
|
-
|
277
|
+
outputs: {
|
278
|
+
[
|
228
279
|
:arg1,
|
229
280
|
'-something-',
|
230
281
|
:arg2,
|
231
282
|
'-another.txt'
|
232
|
-
]
|
233
|
-
|
234
|
-
|
283
|
+
] => {
|
284
|
+
target: [
|
285
|
+
:arg1,
|
286
|
+
'-something-',
|
287
|
+
:arg2,
|
288
|
+
'-another.txt'
|
289
|
+
],
|
290
|
+
type: :file,
|
291
|
+
content: 'dynamically generated file name contents'
|
292
|
+
},
|
293
|
+
stdout: {
|
294
|
+
target: :stdout,
|
295
|
+
content: 'stdout content'
|
296
|
+
}
|
297
|
+
}
|
235
298
|
}
|
236
299
|
]
|
237
300
|
end
|
@@ -240,6 +303,12 @@ describe 'CallConfiguration' do
|
|
240
303
|
call_conf = subject.get_best_call_conf(%w(first_argument second_argument))
|
241
304
|
expect(call_conf).to eql expected_conf
|
242
305
|
end
|
306
|
+
|
307
|
+
it 'returns a copy of the conf it found' do
|
308
|
+
call_conf = subject.get_best_call_conf(%w(first_argument second_argument))
|
309
|
+
expect(call_conf.object_id)
|
310
|
+
.to_not eql subject.call_configuration[0].object_id
|
311
|
+
end
|
243
312
|
end
|
244
313
|
end
|
245
314
|
end
|