rspec-bash 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|