aruba 0.6.2 → 0.7.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 (72) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.rubocop.yml +167 -3
  4. data/.simplecov +32 -0
  5. data/.travis.yml +5 -2
  6. data/.yardopts +8 -0
  7. data/CONTRIBUTING.md +18 -8
  8. data/Gemfile +25 -0
  9. data/History.md +8 -0
  10. data/README.md +80 -18
  11. data/Rakefile +1 -1
  12. data/aruba.gemspec +6 -8
  13. data/cucumber.yml +5 -6
  14. data/features/debug.feature +15 -0
  15. data/features/file_system_commands.feature +14 -2
  16. data/features/fixtures/copy/file.txt +1 -0
  17. data/features/fixtures/fixtures-app/test.txt +1 -0
  18. data/features/fixtures/spawn_process/stderr.sh +3 -0
  19. data/features/interactive.feature +2 -2
  20. data/features/step_definitions/aruba_dev_steps.rb +1 -1
  21. data/features/support/custom_main.rb +10 -6
  22. data/features/support/env.rb +27 -2
  23. data/features/support/simplecov_setup.rb +8 -0
  24. data/lib/aruba.rb +2 -2
  25. data/lib/aruba/announcer.rb +161 -0
  26. data/lib/aruba/api.rb +490 -251
  27. data/lib/aruba/config.rb +0 -1
  28. data/lib/aruba/cucumber.rb +71 -59
  29. data/lib/aruba/cucumber/hooks.rb +18 -13
  30. data/lib/aruba/errors.rb +6 -0
  31. data/lib/aruba/in_process.rb +5 -45
  32. data/lib/aruba/matchers/command.rb +79 -0
  33. data/lib/aruba/matchers/directory.rb +59 -0
  34. data/lib/aruba/matchers/file.rb +177 -0
  35. data/lib/aruba/matchers/mode.rb +52 -0
  36. data/lib/aruba/matchers/path.rb +99 -0
  37. data/lib/aruba/matchers/rspec_matcher_include_regexp.rb +21 -1
  38. data/lib/aruba/process_monitor.rb +113 -0
  39. data/lib/aruba/processes/basic_process.rb +25 -0
  40. data/lib/aruba/processes/debug_process.rb +59 -0
  41. data/lib/aruba/processes/in_process.rb +86 -0
  42. data/lib/aruba/processes/spawn_process.rb +159 -0
  43. data/lib/aruba/reporting.rb +2 -2
  44. data/lib/aruba/rspec.rb +26 -0
  45. data/lib/aruba/spawn_process.rb +5 -104
  46. data/lib/aruba/utils.rb +21 -0
  47. data/script/bootstrap +22 -0
  48. data/script/console +17 -0
  49. data/script/test +3 -0
  50. data/spec/aruba/api_spec.rb +813 -147
  51. data/spec/aruba/hooks_spec.rb +0 -1
  52. data/spec/aruba/matchers/command_spec.rb +43 -0
  53. data/spec/aruba/matchers/directory_spec.rb +58 -0
  54. data/spec/aruba/matchers/file_spec.rb +131 -0
  55. data/spec/aruba/matchers/path_spec.rb +85 -0
  56. data/spec/aruba/spawn_process_spec.rb +46 -28
  57. data/spec/spec_helper.rb +18 -13
  58. data/{config/rubocop/include.yml → spec/support/configs/.keep} +0 -0
  59. data/spec/support/configs/rspec.rb +15 -0
  60. data/spec/support/helpers/.keep +0 -0
  61. data/spec/support/helpers/reporting.rb +44 -0
  62. data/spec/support/matchers/.keep +0 -0
  63. data/spec/support/shared_contexts/.keep +0 -0
  64. data/spec/support/shared_contexts/aruba.rb +45 -0
  65. data/spec/support/shared_examples/.keep +0 -0
  66. data/spec/support/shared_examples/directory.rb +7 -0
  67. data/spec/support/shared_examples/file.rb +7 -0
  68. data/templates/js/jquery-1.11.3.min.js +5 -0
  69. data/templates/main.erb +1 -1
  70. metadata +87 -96
  71. data/config/rubocop/exclude.yml +0 -160
  72. data/templates/js/jquery-1.6.1.min.js +0 -18
data/lib/aruba/config.rb CHANGED
@@ -37,7 +37,6 @@ module Aruba
37
37
  def configure
38
38
  yield config
39
39
  end
40
-
41
40
  end
42
41
 
43
42
  self.config = Config.new
@@ -8,6 +8,11 @@ Given /the default aruba timeout is (\d+) seconds/ do |seconds|
8
8
  @aruba_timeout_seconds = seconds.to_i
9
9
  end
10
10
 
11
+ Given /I use (?:a|the) fixture(?: named)? "([^"]*)"/ do |name|
12
+ copy File.join(Aruba::Api::FIXTURES_PATH_PREFIX, name), name
13
+ cd name
14
+ end
15
+
11
16
  Given /The default aruba timeout is (\d+) seconds/ do |seconds|
12
17
  warn(%{\e[35m The /^The default aruba timeout is (\d+) seconds/ step definition is deprecated. Please use the one with `the` and not `The` at the beginning.\e[0m})
13
18
  @aruba_timeout_seconds = seconds.to_i
@@ -17,37 +22,45 @@ Given /^I'm using a clean gemset "([^"]*)"$/ do |gemset|
17
22
  use_clean_gemset(gemset)
18
23
  end
19
24
 
20
- Given /^a directory named "([^"]*)"$/ do |dir_name|
25
+ Given /^(?:a|the) directory(?: named)? "([^"]*)"$/ do |dir_name|
21
26
  create_dir(dir_name)
22
27
  end
23
28
 
24
- Given /^a directory named "([^"]*)" with mode "([^"]*)"$/ do |dir_name, dir_mode|
29
+ Given /^(?:a|the) directory(?: named)? "([^"]*)" with mode "([^"]*)"$/ do |dir_name, dir_mode|
25
30
  create_dir(dir_name)
26
31
  filesystem_permissions(dir_mode, dir_name)
27
32
  end
28
33
 
29
- Given /^a file named "([^"]*)" with:$/ do |file_name, file_content|
34
+ Given /^(?:a|the) file(?: named)? "([^"]*)" with:$/ do |file_name, file_content|
30
35
  write_file(file_name, file_content)
31
36
  end
32
37
 
33
- Given /^a file named "([^"]*)" with mode "([^"]*)" and with:$/ do |file_name, file_mode, file_content|
38
+ Given /^(?:a|the) file(?: named)? "([^"]*)" with mode "([^"]*)" and with:$/ do |file_name, file_mode, file_content|
34
39
  write_file(file_name, file_content)
35
40
  filesystem_permissions(file_mode, file_name)
36
41
  end
37
42
 
38
- Given /^a (\d+) byte file named "([^"]*)"$/ do |file_size, file_name|
43
+ Given /^(?:a|the) (\d+) byte file(?: named)? "([^"]*)"$/ do |file_size, file_name|
39
44
  write_fixed_size_file(file_name, file_size.to_i)
40
45
  end
41
46
 
42
- Given /^an empty file named "([^"]*)"$/ do |file_name|
47
+ Given /^(?:an|the) empty file(?: named)? "([^"]*)"$/ do |file_name|
43
48
  write_file(file_name, "")
44
49
  end
45
50
 
46
- Given /^an empty file named "([^"]*)" with mode "([^"]*)"$/ do |file_name, file_mode|
51
+ Given /^(?:an|the) empty file(?: named)? "([^"]*)" with mode "([^"]*)"$/ do |file_name, file_mode|
47
52
  write_file(file_name, "")
48
53
  filesystem_permissions(file_mode, file_name)
49
54
  end
50
55
 
56
+ Given /^a mocked home directory$/ do
57
+ set_env 'HOME', File.expand_path(current_dir)
58
+ end
59
+
60
+ Given /^(?:a|the) directory(?: named)? "([^"]*)" does not exist$/ do |directory_name|
61
+ remove_directory(directory_name, force: true)
62
+ end
63
+
51
64
  When /^I write to "([^"]*)" with:$/ do |file_name, file_content|
52
65
  write_file(file_name, file_content)
53
66
  end
@@ -64,12 +77,16 @@ When /^I append to "([^"]*)" with "([^"]*)"$/ do |file_name, file_content|
64
77
  append_to_file(file_name, file_content)
65
78
  end
66
79
 
67
- When /^I remove the file "([^"]*)"$/ do |file_name|
80
+ When /^I remove (?:a|the) file(?: named)? "([^"]*)"$/ do |file_name|
68
81
  remove_file(file_name)
69
82
  end
70
83
 
71
- When(/^I remove the directory "(.*?)"$/) do |directory_name|
72
- remove_dir(directory_name)
84
+ Given /^(?:a|the) file(?: named)? "([^"]*)" does not exist$/ do |file_name|
85
+ remove_file(file_name, force: true)
86
+ end
87
+
88
+ When(/^I remove (?:a|the) directory(?: named)? "(.*?)"$/) do |directory_name|
89
+ remove_directory(directory_name)
73
90
  end
74
91
 
75
92
  When /^I cd to "([^"]*)"$/ do |dir|
@@ -85,6 +102,15 @@ Given /^I set the environment variables to:/ do |table|
85
102
  end
86
103
  end
87
104
 
105
+ Given /^I append the value to the environment variable:/ do |table|
106
+ table.hashes.each do |row|
107
+ variable = row['variable'].to_s.upcase
108
+ value = row['value'].to_s + row['value'].to_s
109
+
110
+ set_env(variable, value)
111
+ end
112
+ end
113
+
88
114
  When /^I run "(.*)"$/ do |cmd|
89
115
  warn(%{\e[35m The /^I run "(.*)"$/ step definition is deprecated. Please use the `backticks` version\e[0m})
90
116
  run_simple(unescape(cmd), false)
@@ -107,11 +133,11 @@ end
107
133
 
108
134
  When /^I run "([^"]*)" interactively$/ do |cmd|
109
135
  warn(%{\e[35m The /^I run "([^"]*)" interactively$/ step definition is deprecated. Please use the `backticks` version\e[0m})
110
- run_interactive(unescape(cmd))
136
+ step %(I run `#{cmd}` interactively)
111
137
  end
112
138
 
113
139
  When /^I run `([^`]*)` interactively$/ do |cmd|
114
- run_interactive(unescape(cmd))
140
+ run(unescape(cmd))
115
141
  end
116
142
 
117
143
  When /^I type "([^"]*)"$/ do |input|
@@ -122,7 +148,7 @@ When /^I close the stdin stream$/ do
122
148
  close_input
123
149
  end
124
150
 
125
- When /^I pipe in the file "([^"]*)"$/ do |file|
151
+ When /^I pipe in (?:a|the) file(?: named)? "([^"]*)"$/ do |file|
126
152
  pipe_in_file(file)
127
153
 
128
154
  close_input
@@ -292,82 +318,68 @@ Then /^the stderr from "([^"]*)" should not contain "([^"]*)"$/ do |cmd, unexpec
292
318
  assert_no_partial_output(unexpected, stderr_from(cmd))
293
319
  end
294
320
 
295
- Then /^the file "([^"]*)" should not exist$/ do |file_name|
296
- check_file_presence([file_name], false)
297
- end
298
-
299
- Then /^the following files should exist:$/ do |files|
300
- check_file_presence(files.raw.map{|file_row| file_row[0]}, true)
301
- end
302
-
303
- Then /^the following files should not exist:$/ do |files|
304
- check_file_presence(files.raw.map{|file_row| file_row[0]}, false)
305
- end
306
-
307
- Then /^a file named "([^"]*)" should exist$/ do |file|
308
- check_file_presence([file], true)
309
- end
310
-
311
- Then /^a file named "([^"]*)" should not exist$/ do |file|
312
- check_file_presence([file], false)
321
+ Then /^the following files should (not )?exist:$/ do |expect_match, files|
322
+ files.raw.each do |row|
323
+ if expect_match
324
+ expect(row[0]).not_to be_existing_file
325
+ else
326
+ expect(row[0]).to be_existing_file
327
+ end
328
+ end
313
329
  end
314
330
 
315
- Then /^a file matching %r<(.*?)> should exist$/ do |regex|
316
- check_file_presence([ Regexp.new( regex ) ], true )
331
+ Then /^(?:a|the) file(?: named)? "([^"]*)" should (not )?exist$/ do |file, expect_match|
332
+ if expect_match
333
+ expect(file).not_to be_existing_file
334
+ else
335
+ expect(file).to be_existing_file
336
+ end
317
337
  end
318
338
 
319
- Then /^a file matching %r<(.*?)> should not exist$/ do |regex|
320
- check_file_presence([ Regexp.new( regex ) ], false )
339
+ Then /^(?:a|the) file matching %r<(.*?)> should (not )?exist$/ do |pattern, expect_match|
340
+ if expect_match
341
+ expect(all_paths).not_to match_path_pattern(Regexp.new(pattern))
342
+ else
343
+ expect(all_paths).to match_path_pattern(Regexp.new(pattern))
344
+ end
321
345
  end
322
346
 
323
- Then /^a (\d+) byte file named "([^"]*)" should exist$/ do |file_size, file_name|
347
+ Then /^(?:a|the) (\d+) byte file(?: named)? "([^"]*)" should exist$/ do |file_size, file_name|
324
348
  check_file_size([[file_name, file_size.to_i]])
325
349
  end
326
350
 
327
- Then /^the following directories should exist:$/ do |directories|
328
- check_directory_presence(directories.raw.map{|directory_row| directory_row[0]}, true)
329
- end
330
-
331
- Then /^the following directories should not exist:$/ do |directories|
332
- check_directory_presence(directories.raw.map{|directory_row| directory_row[0]}, false)
351
+ Then /^the following directories should (not )?exist:$/ do |expect_match, directories|
352
+ check_directory_presence(directories.raw.map{|directory_row| directory_row[0]}, !expect_match)
333
353
  end
334
354
 
335
- Then /^a directory named "([^"]*)" should (not )?exist$/ do |directory, expect_match|
355
+ Then /^(?:a|the) directory(?: named)? "([^"]*)" should (not )?exist$/ do |directory, expect_match|
336
356
  check_directory_presence([directory], !expect_match)
337
357
  end
338
358
 
339
- Then /^the file "([^"]*)" should (not )?contain "([^"]*)"$/ do |file, expect_match, partial_content|
359
+ Then /^(?:a|the) file "([^"]*)" should (not )?contain "([^"]*)"$/ do |file, expect_match, partial_content|
340
360
  check_file_content(file, Regexp.compile(Regexp.escape(partial_content)), !expect_match)
341
361
  end
342
362
 
343
- Then /^the file "([^"]*)" should (not )?contain:$/ do |file, expect_match, partial_content|
363
+ Then /^(?:a|the) file "([^"]*)" should (not )?contain:$/ do |file, expect_match, partial_content|
344
364
  check_file_content(file, Regexp.compile(Regexp.escape(partial_content)), !expect_match)
345
365
  end
346
366
 
347
- Then /^the file "([^"]*)" should (not )?contain exactly:$/ do |file, expect_match, exact_content|
367
+ Then /^(?:a|the) file "([^"]*)" should (not )?contain exactly:$/ do |file, expect_match, exact_content|
348
368
  check_file_content(file, exact_content, !expect_match)
349
369
  end
350
370
 
351
- Then /^the file "([^"]*)" should (not )?match \/([^\/]*)\/$/ do |file, expect_match, partial_content|
371
+ Then /^(?:a|the) file "([^"]*)" should (not )?match \/([^\/]*)\/$/ do |file, expect_match, partial_content|
352
372
  check_file_content(file, /#{partial_content}/, !expect_match)
353
373
  end
354
374
 
355
- Then /^the file "([^"]*)" should (not )?be equal to file "([^"]*)"/ do |file, expect_match, reference_file|
375
+ Then /^(?:a|the) file "([^"]*)" should (not )?be equal to file "([^"]*)"/ do |file, expect_match, reference_file|
356
376
  check_binary_file_content(file, reference_file, !expect_match)
357
377
  end
358
378
 
359
- Then /^the mode of filesystem object "([^"]*)" should match "([^"]*)"$/ do |file, mode|
360
- check_filesystem_permissions(mode, file, true)
361
- end
362
-
363
- Given /^a mocked home directory$/ do
364
- set_env 'HOME', File.expand_path(current_dir)
379
+ Then /^the mode of filesystem object "([^"]*)" should (not )?match "([^"]*)"$/ do |file, expect_match, mode|
380
+ check_filesystem_permissions(mode, file, !expect_match)
365
381
  end
366
382
 
367
383
  Before '@mocked_home_directory' do
368
- set_env 'HOME', File.expand_path(current_dir)
369
- end
370
-
371
- After do
372
- restore_env
384
+ set_env 'HOME', expand_path('.')
373
385
  end
@@ -12,39 +12,44 @@ After do
12
12
  end
13
13
 
14
14
  Before('~@no-clobber') do
15
- clean_current_dir
15
+ clean_current_directory
16
16
  end
17
17
 
18
18
  Before('@puts') do
19
- @puts = true
19
+ announcer.mode = :puts
20
20
  end
21
21
 
22
22
  Before('@announce-cmd') do
23
- @announce_cmd = true
23
+ announcer.activate :command
24
24
  end
25
25
 
26
26
  Before('@announce-stdout') do
27
- @announce_stdout = true
27
+ announcer.activate :stdout
28
28
  end
29
29
 
30
30
  Before('@announce-stderr') do
31
- @announce_stderr = true
31
+ announcer.activate :stderr
32
32
  end
33
33
 
34
34
  Before('@announce-dir') do
35
- @announce_dir = true
35
+ announcer.activate :directory
36
36
  end
37
37
 
38
38
  Before('@announce-env') do
39
- @announce_env = true
39
+ announcer.activate :environment
40
40
  end
41
41
 
42
42
  Before('@announce') do
43
- @announce_stdout = true
44
- @announce_stderr = true
45
- @announce_cmd = true
46
- @announce_dir = true
47
- @announce_env = true
43
+ announcer.activate :command
44
+ announcer.activate :stdout
45
+ announcer.activate :stderr
46
+ announcer.activate :directory
47
+ announcer.activate :environment
48
+ end
49
+
50
+ Before('@debug') do
51
+ require 'aruba/processes/debug_process'
52
+ Aruba.process = Aruba::Processes::DebugProcess
48
53
  end
49
54
 
50
55
  Before('@ansi') do
@@ -53,5 +58,5 @@ end
53
58
 
54
59
  After do
55
60
  restore_env
56
- processes.clear
61
+ process_monitor.clear
57
62
  end
data/lib/aruba/errors.rb CHANGED
@@ -1,4 +1,10 @@
1
1
  module Aruba
2
+ # Standard error
2
3
  class Error < StandardError; end
4
+
5
+ # An error because a user of the API did something wrong
6
+ class UserError < StandardError; end
7
+
8
+ # Raised on launch error
3
9
  class LaunchError < Error; end
4
10
  end
@@ -1,51 +1,11 @@
1
- require 'shellwords'
2
- require 'stringio'
1
+ require 'aruba/processes/in_process'
3
2
 
4
3
  module Aruba
5
- class InProcess
6
- include Shellwords
4
+ class InProcess < Aruba::Processes::InProcess
5
+ def initialize(*args)
6
+ warn('The use of "Aruba::InProcess" is deprecated. Use "Aruba::Processes::InProcess" instead.')
7
7
 
8
- class FakeKernel
9
- attr_reader :exitstatus
10
-
11
- def initialize
12
- @exitstatus = 0
13
- end
14
-
15
- def exit(exitstatus)
16
- @exitstatus = exitstatus
17
- end
18
- end
19
-
20
- def self.main_class=(main_class)
21
- @@main_class = main_class
22
- end
23
-
24
- def initialize(cmd, exit_timeout, io_wait)
25
- args = shellwords(cmd)
26
- @argv = args[1..-1]
27
- @stdin = StringIO.new
28
- @stdout = StringIO.new
29
- @stderr = StringIO.new
30
- @kernel = FakeKernel.new
31
- end
32
-
33
- def run!
34
- raise "You need to call Aruba::InProcess.main_class = YourMainClass" unless @@main_class
35
- @@main_class.new(@argv, @stdin, @stdout, @stderr, @kernel).execute!
36
- yield self if block_given?
37
- end
38
-
39
- def stop(reader)
40
- @kernel.exitstatus
41
- end
42
-
43
- def stdout
44
- @stdout.string
45
- end
46
-
47
- def stderr
48
- @stderr.string
8
+ super
49
9
  end
50
10
  end
51
11
  end
@@ -0,0 +1,79 @@
1
+ # @!method have_exit_status(status)
2
+ # This matchers checks if <command> has exit status <status>
3
+ #
4
+ # @param [Integer] status
5
+ # The value of the exit status
6
+ #
7
+ # @return [TrueClass, FalseClass] The result
8
+ #
9
+ # false:
10
+ # * if command does not have exit status
11
+ # true:
12
+ # * if command has exit status
13
+ #
14
+ # @example Use matcher
15
+ #
16
+ # RSpec.describe do
17
+ # it { expect(last_command).to have_exit_status(0) }
18
+ # end
19
+ RSpec::Matchers.define :have_exit_status do |expected|
20
+ match do |actual|
21
+ @old_actual = actual
22
+
23
+ @announcer ||= Aruba::Announcer.new(
24
+ self,
25
+ :stdout => @announce_stdout,
26
+ :stderr => @announce_stderr,
27
+ :dir => @announce_dir,
28
+ :cmd => @announce_cmd,
29
+ :env => @announce_env
30
+ )
31
+
32
+ @old_actual.stop(@announcer) unless @old_actual.stopped?
33
+ @actual = actual.exit_status
34
+
35
+ next false unless @old_actual.respond_to? :exit_status
36
+
37
+ values_match? expected, @actual
38
+ end
39
+
40
+ failure_message do |actual|
41
+ format(%(expected that command "%s" has exit status of "%s", but has "%s".), @old_actual.commandline, expected.to_s, actual.to_s)
42
+ end
43
+
44
+ failure_message_when_negated do |actual|
45
+ format(%(expected that command "%s" does not have exit status of "%s", but has "%s".), @old_actual.commandline, expected.to_s, actual.to_s)
46
+ end
47
+ end
48
+
49
+ # @!method be_successfuly_executed
50
+ # This matchers checks if execution of <command> was successful
51
+ #
52
+ # @return [TrueClass, FalseClass] The result
53
+ #
54
+ # false:
55
+ # * if command was not successful
56
+ # true:
57
+ # * if command was successful
58
+ #
59
+ # @example Use matcher
60
+ #
61
+ # RSpec.describe do
62
+ # it { expect(last_command).to be_successfully_executed }
63
+ # end
64
+ RSpec::Matchers.define :be_successfully_executed do
65
+ match do |actual|
66
+ @old_actual = actual
67
+ @actual = actual.exit_status
68
+
69
+ expect(@old_actual).to have_exit_status 0
70
+ end
71
+
72
+ failure_message do |actual|
73
+ format(%(expected that command "%s" has exit status of "%s", but has "%s".), @old_actual.commandline, '0', actual.to_s)
74
+ end
75
+
76
+ failure_message_when_negated do |actual|
77
+ format(%(expected that command "%s" does not have exit status of "%s", but has "%s".), @old_actual.commandline, '0', actual.to_s)
78
+ end
79
+ end