command_exec 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/Gemfile +6 -2
  2. data/Gemfile.lock +42 -18
  3. data/README.md +707 -72
  4. data/RELEASE_NOTES.md +62 -0
  5. data/Rakefile +40 -9
  6. data/TODO.md +8 -2
  7. data/command_exec.gemspec +3 -2
  8. data/gemfiles/Gemfile.default +28 -0
  9. data/gemfiles/Gemfile.travis +16 -0
  10. data/gemfiles/Gemfile.travis.lock +48 -0
  11. data/lib/command_exec.rb +22 -2
  12. data/lib/command_exec/command.rb +307 -157
  13. data/lib/command_exec/exceptions.rb +16 -6
  14. data/lib/command_exec/field_helper.rb +263 -0
  15. data/lib/command_exec/formatter/array.rb +158 -0
  16. data/lib/command_exec/formatter/hash.rb +78 -0
  17. data/lib/command_exec/formatter/json.rb +22 -0
  18. data/lib/command_exec/formatter/string.rb +22 -0
  19. data/lib/command_exec/formatter/xml.rb +22 -0
  20. data/lib/command_exec/formatter/yaml.rb +22 -0
  21. data/lib/command_exec/logger.rb +9 -0
  22. data/lib/command_exec/process.rb +294 -0
  23. data/lib/command_exec/spec_helper_module.rb +52 -0
  24. data/lib/command_exec/version.rb +1 -1
  25. data/script/console +8 -0
  26. data/spec/command/command_spec.rb +413 -117
  27. data/spec/command/test_data/echo_test +3 -0
  28. data/spec/command/test_data/exit_status_test +2 -0
  29. data/spec/command/test_data/log_file_test +3 -0
  30. data/spec/command/test_data/logger_test +2 -0
  31. data/spec/command/test_data/not_raise_error_test +4 -0
  32. data/spec/command/test_data/not_throw_error_test +4 -0
  33. data/spec/command/test_data/output_test +6 -0
  34. data/spec/command/test_data/raise_error_test +6 -0
  35. data/spec/command/test_data/runner_open3_test +4 -0
  36. data/spec/command/test_data/runner_system_test +4 -0
  37. data/spec/command/test_data/stderr_test +4 -0
  38. data/spec/command/test_data/stdout_multiple_lines_test +4 -0
  39. data/spec/command/test_data/stdout_test +4 -0
  40. data/spec/command/test_data/throw_error_test +6 -0
  41. data/spec/command/test_data/true_test +2 -0
  42. data/spec/formatter/array_spec.rb +215 -0
  43. data/spec/formatter/hash_spec.rb +117 -0
  44. data/spec/formatter/json_spec.rb +21 -0
  45. data/spec/formatter/xml_spec.rb +33 -0
  46. data/spec/formatter/yaml_spec.rb +21 -0
  47. data/spec/process/process_spec.rb +329 -0
  48. data/spec/spec_helper.rb +15 -4
  49. metadata +79 -5
@@ -1,5 +1,12 @@
1
+ #encoding: utf-8
2
+
3
+ # Main
1
4
  module CommandExec
5
+ # Helpers for specs
2
6
  module SpecHelper
7
+ # Capture stderr
8
+ #
9
+ # @param [Block] block
3
10
  def capture_stderr(&block)
4
11
  previous_stderr, $stderr = $stderr, StringIO.new
5
12
  block.call
@@ -8,6 +15,9 @@ module CommandExec
8
15
  $stderr = previous_stderr
9
16
  end
10
17
 
18
+ # Capture stdout
19
+ #
20
+ # @param [Block] block
11
21
  def capture_stdout(&block)
12
22
  previous_stdout, $stdout = $stdout, StringIO.new
13
23
  block.call
@@ -15,5 +25,47 @@ module CommandExec
15
25
  ensure
16
26
  $stdout = previous_stdout
17
27
  end
28
+
29
+ # Manipulate environment for the given block
30
+ #
31
+ # @param [Hash] env
32
+ # The environment for the block which should
33
+ # be merged with ENV
34
+ #
35
+ # @param [Hash] options
36
+ # Options for environment manipulation
37
+ #
38
+ # @option options [True,False] :clear
39
+ # Should the environment clear before merge?
40
+ #
41
+ # @yield Block which should be executed
42
+ def environment(env={},options={},&block)
43
+ previous_environment, environment = ENV.to_hash, env
44
+ ENV.clear if options[:clear] == true
45
+ ENV.update(environment)
46
+ block.call
47
+ ensure
48
+ ENV.clear
49
+ ENV.update previous_environment
50
+ end
51
+
52
+ # Create temporary files for testing
53
+ # (which will be deleted when the
54
+ # ruby process terminates)
55
+ #
56
+ # @param [String] base_name
57
+ # the path to the temporary file
58
+ #
59
+ # @param [String] content
60
+ # the content which should be written to the file
61
+ #
62
+ # @return [String]
63
+ # the path to the temporary file
64
+ def create_temp_file_with(base_name, content)
65
+ file = Tempfile.new(base_name)
66
+ file.write(content)
67
+ file.close
68
+ file.path
69
+ end
18
70
  end
19
71
  end
@@ -1,4 +1,4 @@
1
1
  #main CommandExec
2
2
  module CommandExec
3
- VERSION = '0.1.3'
3
+ VERSION = '0.2.0'
4
4
  end
data/script/console ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH << File.expand_path('../lib', File.dirname(__FILE__))
4
+
5
+ require 'command_exec'
6
+ require 'pry'
7
+
8
+ Pry.start
@@ -1,125 +1,421 @@
1
+ #encoding: utf-8
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Command do
4
- let(:logger) {Logger.new(StringIO.new)}
6
+ let(:lib_logger) {Logger.new(StringIO.new)}
5
7
  #let(:logger) {Logger.new($stdout)}
6
- let(:log_level) {:info}
7
- let(:command) { Command.new(:echo , :log_level => :silent, :logger => logger, :parameter => "hello world" , :error_keywords => %q[abc def], :working_directory => '/tmp' ) }
8
-
9
-
10
- it "has a path" do
11
- command.path.should == '/bin/echo'
12
- end
13
-
14
- it "has parameter" do
15
- command.parameter.should == 'hello world'
16
- end
17
-
18
- it "has options" do
19
- command.options.should == ''
20
- end
21
-
22
- it "offers the possibility to change the working directory of the process" do
23
- command.working_directory.should == '/tmp'
24
- Dir.pwd.should == '/tmp'
25
- end
26
-
27
- it "has special keywords indicating errors in stdout" do
28
- command.error_keywords.should == %q[abc def]
29
- end
30
-
31
- it "can be used to construct a command string, which can be executed" do
32
- command = Command.new(:pdflatex, :log_level => :silent, :logger => logger, :parameter => "index.tex blub.tex", :options => "-a -b")
33
- command.send(:build_cmd_string).should == "/usr/bin/pdflatex -a -b index.tex blub.tex"
34
- end
35
-
36
- it "runs programms" do
37
- command.run
38
- command.result.should == true
39
- end
40
-
41
- it "returns the textual rep of a command" do
42
- command.to_txt.should == '/bin/echo hello world'
43
- end
44
-
45
- it "execute existing programs" do
46
- command = Command.execute(:echo, :log_level => :silent, :logger => logger ,:parameter => "index.tex blub.tex", :options => "-- -a -b")
47
- command.result.should == true
48
- end
49
-
50
- it "does not execute non-existing programs" do
51
- command = Command.execute(:grep, :log_level => :silent, :logger => logger, :parameter => "index.tex blub.tex", :options => "-- -a -b")
52
- command.result.should == false
53
- end
54
-
55
- it "checks if errors have happend during execution" do
56
- lambda { Command.new(:echo1, :log_level => :silent, :logger => logger, :parameter => "index.tex blub.tex", :options => "-- -a -b") }.should raise_error CommandNotFound
57
- end
58
-
59
- it "decides which output should be returned to the user" do
60
- logfile = StringIO.new
61
- logfile << 'Error in ... found'
62
-
63
- stderr = StringIO.new
64
- stderr << 'Error found'
65
-
66
- stdout = StringIO.new
67
- stdout << 'Error found'
68
-
69
- #result = command.send(:help_logger)({ :error_in_exec => true , :error_in_stdout => false} , { :logfile => logfile, :stderr => stderr , :stdout => stdout })
70
- result = command.send(:help_output, { :error_in_exec => true , :error_in_stdout => false} , { :logfile => logfile, :stderr => stderr , :stdout => stdout })
71
- result.should == ["================== LOGFILE ================== ", "Error in ... found", "================== STDOUT ================== ", "Error found", "================== STDERR ================== ", "Error found"]
72
-
73
- result = command.send(:help_output, { :error_in_exec => false , :error_in_stdout => true} , { :logfile => logfile, :stderr => stderr , :stdout => stdout })
74
- result.should == ["================== STDOUT ================== ", "Error found"]
75
-
76
- result = command.send(:help_output, { :error_in_exec => true , :error_in_stdout => true} , { :logfile => logfile, :stderr => stderr , :stdout => stdout })
77
- result.should == ["================== LOGFILE ================== ", "Error in ... found", "================== STDOUT ================== ", "Error found", "================== STDERR ================== ", "Error found"]
78
-
79
-
80
- result = command.send(:help_output, { :error_in_exec => false , :error_in_stdout => false} , { :logfile => logfile, :stderr => stderr , :stdout => stdout })
81
- result.should == []
82
-
8
+ let(:lib_log_level) {:info}
9
+ let(:command) { Command.new(:echo , :lib_logger => lib_logger, :parameter => "hello world" , :error_keywords => %q[abc def], :working_directory => '/tmp' ) }
10
+
11
+ context :public_api do
12
+ test_dir = File.expand_path('test_data', File.dirname(__FILE__))
13
+
14
+ it "supports relative paths" do
15
+ Dir.chdir('spec/command') do
16
+ command = Command.new('test_data/true_test')
17
+ expect(command.path).to eq(File.join(test_dir, 'true_test'))
18
+ end
19
+
20
+ Dir.chdir test_dir do
21
+ command = Command.new('./true_test')
22
+ expect(command.path).to eq(File.join(test_dir, 'true_test'))
23
+ end
24
+
25
+ Dir.chdir '/tmp/' do
26
+ command = Command.new('../bin/true')
27
+ expect(command.path).to eq('/bin/true')
28
+ end
29
+ end
30
+
31
+ it 'searches $PATH to find the command' do
32
+ environment({ 'PATH' => '/bin' }) do
33
+ command = Command.new(:true)
34
+ expect(command.path).to eq("/bin/true")
35
+ end
36
+ end
37
+
38
+ it 'offers an option to change $PATH for the command execution' do
39
+ command = Command.new(:echo_test, search_paths: [test_dir])
40
+ expect(command.path).to eq(File.join(test_dir, 'echo_test'))
41
+ end
42
+
43
+ it "checks if exec is executable" do
44
+ command = Command.new('/bin/true')
45
+ expect(command.executable?).to eq(true)
46
+
47
+ command = Command.new('/etc/passwd')
48
+ expect(command.executable?).to eq(false)
49
+ end
50
+
51
+ it "checks if exec exists" do
52
+ command = Command.new('/bin/true')
53
+ expect(command.exists?).to eq(true)
54
+
55
+ command = Command.new('/usr/bin/does_not_exist')
56
+ expect(command.exists?).to eq(false)
57
+ end
58
+
59
+ it "checks if exec is valid (exists, executable, type = file)" do
60
+ #does not exist
61
+ command = Command.new('/usr/bin/does_not_exist')
62
+ expect(command.valid?).to eq(false)
63
+
64
+ #is a directory not a file
65
+ command = Command.new('/tmp')
66
+ expect(command.valid?).to eq(false)
67
+
68
+ #exists and is executable and is a file
69
+ command = Command.new('/bin/true')
70
+ expect(command.valid?).to eq(true)
71
+ end
72
+
73
+ it "has parameter" do
74
+ command = Command.new(:true, :parameter=>'parameter')
75
+ expect(command.parameter).to eq('parameter')
76
+ end
77
+
78
+ it "has options" do
79
+ expect(command.options).to eq('')
80
+ end
81
+
82
+ it "offers the possibility to change the working directory of the process without any side effects" do
83
+ expect(command.working_directory).to eq('/tmp')
84
+
85
+ #no side effects
86
+ lambda { command.run }
87
+
88
+ expect(Dir.pwd).to eq(File.expand_path('../..', File.dirname(__FILE__)))
89
+ end
90
+
91
+ it "can be used to construct a command string, which can be executed" do
92
+ environment('PATH' => '/bin') {
93
+ command = Command.new(:true, :parameter => "index.tex blub.tex", :options => "-a -b")
94
+ expect(command.to_s).to eq("/bin/true -a -b index.tex blub.tex")
95
+ }
96
+ end
97
+
98
+ it "runs programms" do
99
+ command = Command.new(:echo, :parameter => "output", :lib_log_level => :silent )
100
+ command.run
101
+ expect(command.result.status).to eq(:success)
102
+ end
103
+
104
+ it "execute existing programs" do
105
+ command = Command.execute(:echo, :parameter => "output", :options => "-- -a -b", :lib_log_level => :silent )
106
+ expect(command.result.status).to eq(:success)
107
+ end
108
+
109
+ it "is very verbose and returns a lot of output" do
110
+ bucket = StringIO.new
111
+ lib_logger = Logger.new(bucket)
112
+ Command.execute(:echo, :lib_logger => lib_logger ,:parameter => "output", :lib_log_level => :debug)
113
+
114
+ expect(bucket.string['DEBUG']).to_not eq(nil)
115
+ end
116
+
117
+ it "is silent and returns no output" do
118
+ # if you choose the system runner output of commands will be not suppressed"
119
+ bucket = StringIO.new
120
+ lib_logger = Logger.new(bucket)
121
+ Command.execute(:echo, :lib_logger => lib_logger ,:parameter => "output", :lib_log_level => :silent)
122
+
123
+ expect(bucket.string).to eq("")
124
+ end
125
+
126
+ it "supports other log levels as well" do
127
+ bucket = StringIO.new
128
+ lib_logger = Logger.new(bucket)
129
+
130
+ Command.execute(:echo, :lib_logger => lib_logger ,:parameter => "output", :lib_log_level => :info)
131
+ Command.execute(:echo, :lib_logger => lib_logger ,:parameter => "output", :lib_log_level => :warn)
132
+ Command.execute(:echo, :lib_logger => lib_logger ,:parameter => "output", :lib_log_level => :error)
133
+ Command.execute(:echo, :lib_logger => lib_logger ,:parameter => "output", :lib_log_level => :fatal)
134
+ Command.execute(:echo, :lib_logger => lib_logger ,:parameter => "output", :lib_log_level => :unknown)
135
+ Command.execute(:echo, :lib_logger => lib_logger ,:parameter => "output", :lib_log_level => :garbage_sasdfasf)
136
+ end
137
+
138
+ it "use a log file if given" do
139
+ application_log_file = create_temp_file_with('command_exec_test', 'TEXT IN LOG')
140
+
141
+ bucket = StringIO.new
142
+ lib_logger = Logger.new(bucket)
143
+
144
+ command = Command.new(:logger_test ,
145
+ :lib_logger => lib_logger ,
146
+ :log_file => application_log_file ,
147
+ :search_paths => File.expand_path('test_data', File.dirname(__FILE__))).run
148
+ end
149
+
150
+ it "outputs only warnings when told to output those" do
151
+ bucket = StringIO.new
152
+ lib_logger = Logger.new(bucket)
153
+
154
+ command = Command.new(:logger_test ,
155
+ :lib_logger => lib_logger ,
156
+ :lib_log_level => :warn,
157
+ :log_file => '/tmp/i_do_not_exist.log',
158
+ :search_paths => File.expand_path('test_data', File.dirname(__FILE__))).run
159
+
160
+ expect(bucket.string['WARN']).to_not eq(nil)
161
+ end
162
+
163
+ it "considers status for error handling (default 0)" do
164
+ command = Command.new(:exit_status_test,
165
+ :search_paths => File.expand_path('test_data', File.dirname(__FILE__)),
166
+ :parameter => '1',
167
+ :lib_log_level => :silent,
168
+ :error_detection_on => [:return_code],
169
+ )
170
+ command.run
171
+ expect(command.result.status).to eq(:failed)
172
+ end
173
+
174
+ it "considers status for error handling (single value as array)" do
175
+ command = Command.new(:exit_status_test,
176
+ :search_paths => File.expand_path('test_data', File.dirname(__FILE__)),
177
+ :parameter => '1',
178
+ :lib_log_level => :silent,
179
+ :error_detection_on => [:return_code],
180
+ :error_indicators => { :allowed_return_code => [0] })
181
+ command.run
182
+ expect(command.result.status).to eq(:failed)
183
+ end
184
+
185
+ it "considers status for error handling (single value as symbol)" do
186
+ command = Command.new(:exit_status_test,
187
+ :search_paths => File.expand_path('test_data', File.dirname(__FILE__)),
188
+ :parameter => '1',
189
+ :lib_log_level => :silent,
190
+ :error_detection_on => :return_code,
191
+ :error_indicators => { :allowed_return_code => [0] })
192
+ command.run
193
+ expect(command.result.status).to eq(:failed)
194
+ end
195
+
196
+ it "considers status for error handling (single value)" do
197
+ command = Command.new(:exit_status_test,
198
+ :search_paths => File.expand_path('test_data', File.dirname(__FILE__)),
199
+ :parameter => '0',
200
+ :lib_log_level => :silent,
201
+ :error_detection_on => [:return_code],
202
+ :error_indicators => { :allowed_return_code => [0,2] })
203
+ command.run
204
+ expect(command.result.status).to eq(:success)
205
+
206
+ command = Command.new(:exit_status_test,
207
+ :search_paths => File.expand_path('test_data', File.dirname(__FILE__)),
208
+ :parameter => '2',
209
+ :lib_log_level => :silent,
210
+ :error_detection_on => [:return_code],
211
+ :error_indicators => { :allowed_return_code => [0,2] })
212
+ command.run
213
+ expect(command.result.status).to eq(:success)
214
+ end
215
+
216
+ it "considers stderr for error handling" do
217
+ command = Command.new(:stderr_test,
218
+ :search_paths => File.expand_path('test_data', File.dirname(__FILE__)),
219
+ :lib_log_level => :silent,
220
+ :error_detection_on => :stderr,
221
+ :error_indicators => { :forbidden_words_in_stderr => %w{error} })
222
+ command.run
223
+ expect(command.result.status).to eq(:failed)
224
+ end
225
+
226
+ it "considers stderr for error handling but can make exceptions" do
227
+ command = Command.new(:stderr_test,
228
+ :search_paths => File.expand_path('test_data', File.dirname(__FILE__)),
229
+ :lib_log_level => :silent,
230
+ :error_detection_on => :stderr,
231
+ :error_indicators => { :forbidden_words_in_stderr => %w{error}, :allowed_words_in_stderr => ["error. execution failed"]})
232
+ command.run
233
+ expect(command.result.status).to eq(:success)
234
+ end
235
+
236
+ it "considers stdout for error handling" do
237
+ command = Command.new(:stdout_test,
238
+ :search_paths => File.expand_path('test_data', File.dirname(__FILE__)),
239
+ :lib_log_level => :silent,
240
+ :error_detection_on => :stdout,
241
+ :error_indicators => { :forbidden_words_in_stdout => %w{error} })
242
+ command.run
243
+ expect(command.result.status).to eq(:failed)
244
+ end
245
+
246
+
247
+ it "removes newlines from stdout" do
248
+ #same for stderr
249
+ command = Command.new(:stdout_multiple_lines_test,
250
+ :search_paths => File.expand_path('test_data', File.dirname(__FILE__)),
251
+ :lib_log_level => :silent,
252
+ :error_detection_on => :stdout,
253
+ :error_indicators => { :forbidden_words_in_stdout => %w{error} })
254
+ command.run
255
+ expect(command.result.stdout).to eq(["error. execution failed", "error. execution failed"])
256
+ end
257
+
258
+ it "considers log file for error handling" do
259
+ temp_file = create_temp_file_with('log_file_test', 'error, huh, what goes on' )
260
+
261
+ command = Command.new(:log_file_test,
262
+ :search_paths => File.expand_path('test_data', File.dirname(__FILE__)),
263
+ :lib_log_level => :silent,
264
+ :log_file => temp_file,
265
+ :error_detection_on => :log_file,
266
+ :error_indicators => { :forbidden_words_in_log_file => %w{error} })
267
+ command.run
268
+ expect(command.result.status).to eq(:failed)
269
+ end
270
+
271
+ it "returns the result of command execution as process object (defaults to :return_process_information)" do
272
+ command = Command.new(:output_test,
273
+ :search_paths => File.expand_path('test_data', File.dirname(__FILE__)),
274
+ :lib_log_level => :silent,
275
+ :error_detection_on => :return_code,
276
+ :error_indicators => { :allowed_return_code => [ 0 ]})
277
+ command.run
278
+ expect(command.result.class).to eq(CommandExec::Process)
279
+ end
280
+
281
+ it "returns the result of command execution as process object" do
282
+ command = Command.new(:output_test,
283
+ :search_paths => File.expand_path('test_data', File.dirname(__FILE__)),
284
+ :lib_log_level => :silent,
285
+ :on_error_do => :return_process_information,
286
+ :error_detection_on => :return_code,
287
+ :error_indicators => { :allowed_return_code => [ 0 ]})
288
+ command.run
289
+ expect(command.result.class).to eq(CommandExec::Process)
290
+ end
291
+
292
+ it "does nothing on error if told so" do
293
+ command = Command.new(:raise_error_test,
294
+ :search_paths => File.expand_path('test_data', File.dirname(__FILE__)),
295
+ :lib_log_level => :silent,
296
+ :on_error_do => :nothing,
297
+ :error_detection_on => :return_code,
298
+ :error_indicators => { :allowed_return_code => [ 0 ]})
299
+ expect{command.run}.to_not raise_error
300
+ expect{command.run}.to_not throw_symbol
301
+ end
302
+
303
+ it "raises an exception" do
304
+ command = Command.new(:raise_error_test,
305
+ :search_paths => File.expand_path('test_data', File.dirname(__FILE__)),
306
+ :lib_log_level => :silent,
307
+ :on_error_do => :raise_error,
308
+ :error_detection_on => :return_code,
309
+ :error_indicators => { :allowed_return_code => [ 0 ]})
310
+ expect{command.run}.to raise_error(CommandExec::Exceptions::CommandExecutionFailed)
311
+
312
+ command = Command.new(:not_raise_error_test,
313
+ :search_paths => File.expand_path('test_data', File.dirname(__FILE__)),
314
+ :lib_log_level => :silent,
315
+ :on_error_do => :raise_error,
316
+ :error_detection_on => :return_code,
317
+ :error_indicators => { :allowed_return_code => [ 0 ]})
318
+ expect{command.run}.to_not raise_error
319
+ end
320
+
321
+ it "throws an error" do
322
+ command = Command.new(:throw_error_test,
323
+ :search_paths => File.expand_path('test_data', File.dirname(__FILE__)),
324
+ :lib_log_level => :silent,
325
+ :on_error_do => :throw_error,
326
+ :error_detection_on => :return_code,
327
+ :error_indicators => { :allowed_return_code => [ 0 ]})
328
+ expect{command.run}.to throw_symbol(:command_execution_failed)
329
+
330
+ command = Command.new(:not_throw_error_test,
331
+ :search_paths => File.expand_path('test_data', File.dirname(__FILE__)),
332
+ :lib_log_level => :silent,
333
+ :on_error_do => :throw_error,
334
+ :error_detection_on => :return_code,
335
+ :error_indicators => { :allowed_return_code => [ 0 ]})
336
+ expect{command.run}.to_not throw_symbol
337
+ end
338
+
339
+ it "support open3 as runner" do
340
+ #implicit via default value (open3)
341
+ command = Command.new(:runner_open3_test,
342
+ :search_paths => File.expand_path('test_data', File.dirname(__FILE__)),
343
+ :lib_log_level => :silent,
344
+ :error_detection_on => :return_code,
345
+ :error_indicators => { :allowed_return_code => [ 0 ]})
346
+ command.run
347
+ expect(command.result.status).to eq(:success)
348
+
349
+ #or explicit
350
+ command = Command.new(:runner_open3_test,
351
+ :search_paths => File.expand_path('test_data', File.dirname(__FILE__)),
352
+ :run_via => :open3,
353
+ :lib_log_level => :silent,
354
+ :error_detection_on => :return_code,
355
+ :error_indicators => { :allowed_return_code => [ 0 ]})
356
+ command.run
357
+ expect(command.result.status).to eq(:success)
358
+ end
359
+
360
+ it "support system as runner" do
361
+ command = Command.new(:runner_system_test,
362
+ :search_paths => File.expand_path('test_data', File.dirname(__FILE__)),
363
+ :run_via => :system,
364
+ :lib_log_level => :silent,
365
+ :error_detection_on => :return_code,
366
+ :error_indicators => { :allowed_return_code => [ 0 ]})
367
+ command.run
368
+ expect(command.result.status).to eq(:success)
369
+ end
370
+
371
+ it "has a default runner: open3" do
372
+ command = Command.new(:runner_system_test,
373
+ :search_paths => File.expand_path('test_data', File.dirname(__FILE__)),
374
+ :run_via => :unknown_runner,
375
+ :lib_log_level => :silent,
376
+ :error_detection_on => :return_code,
377
+ :error_indicators => { :allowed_return_code => [ 0 ]})
378
+ command.run
379
+ expect(command.result.status).to eq(:success)
380
+ end
381
+
382
+ it "find errors beyond newlines in the string" do
383
+ command = CommandExec::Command.new( :echo ,
384
+ :options => '-e',
385
+ :parameter => "\"wow, a test. That's great.\nBut an error occured in this line\"",
386
+ :error_detection_on => [:stdout],
387
+ :error_indicators => {
388
+ :forbidden_words_in_stdout => %w{ error }
389
+ },
390
+ )
391
+ command.run
392
+ expect(command.result.status).to eq(:failed)
393
+ end
83
394
  end
84
395
 
85
- it "finds errors in stdout" do
86
- command.send(:error_in_string_found?, ['error'] , 'long string witherror inside' ).should == true
87
- command.send(:error_in_string_found?, ['long', 'inside'] , 'long string witherror inside' ).should == true
88
- command.send(:error_in_string_found?, ['error'] , 'long string with erro inside' ).should == false
396
+ context :private_api do
397
+ it "raises an error if command is not executable" do
398
+ command = Command.new('/etc/passwd', lib_log_level: :silent)
399
+ expect{command.send(:check_path)}.to raise_error CommandNotExecutable
400
+ end
401
+
402
+ it "raises an error if command does not exist" do
403
+ command = Command.new('/usr/bin/does_not_exist', lib_log_level: :silent)
404
+ expect{command.send(:check_path)}.to raise_error CommandNotFound
405
+ end
406
+
407
+ it "raises an error if command is not a file" do
408
+ command = Command.new('/tmp', lib_log_level: :silent)
409
+ expect{command.send(:check_path)}.to raise_error CommandIsNotAFile
410
+ end
411
+
412
+ it "finds errors in string" do
413
+ expect(command.send(:error_occured?, ['error'] , [], ['long string witherrorinside'] )).to eq(true)
414
+ expect(command.send(:error_occured?, ['error', 'inside'] , [], ['long string with error inside'] )).to eq(true)
415
+ expect(command.send(:error_occured?, ['error'] , [], ['long string with no erro"r" inside'] )).to eq(false)
416
+
417
+ expect(command.send(:error_occured?, ['error'] , ['long string with error inside but an exception defined'], ['long string with error inside but an exception defined'] )).to eq(false)
418
+ expect(command.send(:error_occured?, ['error'] , ['substring exception defined'], ['long string with error inside but a substring exception defined'] )).to eq(false)
419
+ end
89
420
  end
90
-
91
- it "output a message" do
92
- command.send(:message, false, 'Hello_world').should == "\e[1m\e[31mFAILED\e[0m\e[0m\nHello_world"
93
- command.send(:message, true, 'Hello_world').should == "\e[1m\e[32mOK\e[0m\e[0m"
94
- command.send(:message, true ).should == "\e[1m\e[32mOK\e[0m\e[0m"
95
- end
96
-
97
- it "is very verbose and returns a lot of output" do
98
- bucket = StringIO.new
99
- logger = Logger.new(bucket)
100
- Command.execute(:echo, :logger => logger ,:parameter => "index.tex blub.tex", :options => "-- -a -b" , :log_level => :debug)
101
-
102
- bucket.string.should =~ /OK/
103
- end
104
-
105
- it "is silent and returns no output" do
106
- bucket = StringIO.new
107
- logger = Logger.new(bucket)
108
- Command.execute(:echo, :logger => logger ,:parameter => "index.tex blub.tex", :options => "-- -a -b" , :log_level => :silent)
109
-
110
- bucket.string.should == ""
111
- end
112
-
113
- # not completed
114
- #it "use a log file if given" do
115
- # application_log_file = Tempfile.new('command_exec_test')
116
- # application_log_file.write "ERROR"
117
-
118
- # binding.pry
119
- # Command.execute(:echo, :logger => logger ,:parameter => "index.tex blub.tex", :options => "-- -a -b" , :log_level => :silent, :logfile => application_log_file, :error_keywords => %W[ERROR])
120
-
121
- #end
122
-
123
-
124
-
125
421
  end