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/Rakefile CHANGED
@@ -8,7 +8,7 @@ require 'cucumber/rake/task'
8
8
 
9
9
  Cucumber::Rake::Task.new do |t|
10
10
  t.cucumber_opts = ""
11
- t.cucumber_opts = "--format Cucumber::Pro --out cucumber-pro.log" if ENV['CUCUMBER_PRO_TOKEN']
11
+ # t.cucumber_opts = "--format Cucumber::Pro --out cucumber-pro.log" if ENV['CUCUMBER_PRO_TOKEN']
12
12
  t.cucumber_opts << "--format pretty"
13
13
  end
14
14
 
data/aruba.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'aruba'
5
- s.version = '0.6.2'
5
+ s.version = '0.7.0'
6
6
  s.authors = ["Aslak Hellesøy", "David Chelimsky", "Mike Sassak", "Matt Wynne"]
7
7
  s.description = 'CLI Steps for Cucumber, hand-crafted for you in Aruba'
8
8
  s.summary = "aruba-#{s.version}"
@@ -13,15 +13,13 @@ Gem::Specification.new do |s|
13
13
  s.add_runtime_dependency 'cucumber', '>= 1.1.1'
14
14
  s.add_runtime_dependency 'childprocess', '>= 0.3.6'
15
15
  s.add_runtime_dependency 'rspec-expectations', '>= 2.7.0'
16
- s.add_development_dependency 'bcat', '>= 0.6.1'
17
- s.add_development_dependency 'kramdown', '>= 0.14'
18
- s.add_development_dependency 'rake', '>= 0.9.2'
19
- s.add_development_dependency 'rspec', '>= 3.0.0'
20
- s.add_development_dependency 'fuubar', '>= 1.1.1'
21
- s.add_development_dependency 'cucumber-pro', '~> 0.0'
22
- s.add_development_dependency 'rubocop', '~> 0.26.0'
16
+
17
+ s.add_development_dependency 'bundler', '~> 1.10.2'
23
18
 
24
19
  s.rubygems_version = ">= 1.6.1"
20
+ # s.required_ruby_version = '>= 2.0'
21
+ s.post_install_message = 'From aruba > 2.0 ruby 1.9.3-support is discontinued'
22
+
25
23
  s.files = `git ls-files`.split("\n")
26
24
  s.test_files = `git ls-files -- {spec,features}/*`.split("\n")
27
25
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
data/cucumber.yml CHANGED
@@ -1,10 +1,9 @@
1
1
  <%
2
2
  java_version = (RUBY_DESCRIPTION.match(/.*?on.*?(1\.[\d]\..*? )/))[1] if defined?(JRUBY_VERSION)
3
- std_opts = "--color --tags ~@wip"
4
- std_opts << " --tags ~@wip-jruby-java-1.6" if defined?(JRUBY_VERSION) && (java_version < '1.7.0')
5
3
 
6
- wip_opts = "--color --tags @wip:3"
7
- wip_opts = "--color --tags @wip:3,@wip-jruby-java-1.6:3" if defined?(JRUBY_VERSION) && (java_version < '1.7.0')
4
+ std_opts = "--color --exclude features/fixtures"
5
+ java_default_opts = "--tags ~@wip-jruby-java-1.6" if defined?(JRUBY_VERSION) && (java_version < '1.7.0')
6
+ java_wip_opts = "--tags @wip-jruby-java-1.6:3" if defined?(JRUBY_VERSION) && (java_version < '1.7.0')
8
7
  %>
9
- default: <%= std_opts %>
10
- wip: --wip <%= wip_opts %>
8
+ default: <%= std_opts %> --tags ~@wip <%= java_default_opts %>
9
+ wip: <%= std_opts %> --wip --tags @wip:3 <%= java_wip_opts %>
@@ -0,0 +1,15 @@
1
+ Feature: Debug command execution
2
+
3
+ As a developer
4
+ I want to use some debugger in my code and therefor need system() to execute my program
5
+ In order to find a bug
6
+
7
+ @debug
8
+ Scenario: Run program with debug code
9
+ When I run `true`
10
+ Then the exit status should be 0
11
+
12
+ @debug
13
+ Scenario: Run failing program with debug code
14
+ When I run `false`
15
+ Then the exit status should be 1
@@ -17,6 +17,14 @@ Feature: file system commands
17
17
  When I run `cat foo/bar/example.txt`
18
18
  Then the output should contain exactly "hello world"
19
19
 
20
+ Scenario: a file does not exist
21
+ Given a file named "example.txt" does not exist
22
+ Then the file "example.txt" should not exist
23
+
24
+ Scenario: a directory does not exist
25
+ Given a directory named "example.d" does not exist
26
+ Then the directory "foo" should not exist
27
+
20
28
  Scenario: create a fixed sized file
21
29
  Given a 1048576 byte file named "test.txt"
22
30
  Then a 1048576 byte file named "test.txt" should exist
@@ -125,7 +133,7 @@ Feature: file system commands
125
133
  Given a directory named "foo/bar"
126
134
  Then the following step should fail with Spec::Expectations::ExpectationNotMetError:
127
135
  """
128
- Then a directory named "foo/bar" should not exist
136
+ Then the directory "foo/bar" should not exist
129
137
  """
130
138
 
131
139
  Scenario: Check file contents with text
@@ -185,7 +193,7 @@ Feature: file system commands
185
193
  Scenario: Remove directory
186
194
  Given a directory named "foo"
187
195
  When I remove the directory "foo"
188
- Then a directory named "foo" should not exist
196
+ Then the directory "foo" should not exist
189
197
 
190
198
  Scenario: Just a dummy for reporting
191
199
  Given an empty file named "a/b.txt"
@@ -206,3 +214,7 @@ Feature: file system commands
206
214
  asdf
207
215
  """
208
216
  Then the mode of filesystem object "test.txt" should match "0666"
217
+
218
+ Scenario: Use a fixture
219
+ Given I use a fixture named "fixtures-app"
220
+ Then a file named "test.txt" should exist
@@ -0,0 +1 @@
1
+ asdf
@@ -0,0 +1 @@
1
+ asdf
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env bash
2
+
3
+ echo $* >&2
@@ -62,5 +62,5 @@ Feature: Interactive process control
62
62
 
63
63
  Given a directory named "rename_me"
64
64
  When I run `mv rename_me renamed` interactively
65
- Then a directory named "renamed" should exist
66
- And a directory named "rename_me" should not exist
65
+ Then the directory "renamed" should exist
66
+ And the directory "rename_me" should not exist
@@ -20,7 +20,7 @@ Then /^aruba should fail with "([^"]*)"$/ do |error_message|
20
20
  end
21
21
 
22
22
  Then /^the following step should fail with Spec::Expectations::ExpectationNotMetError:$/ do |multiline_step|
23
- expect{steps multiline_step}.to raise_error(RSpec::Expectations::ExpectationNotMetError)
23
+ expect{steps multiline_step.to_s}.to raise_error(RSpec::Expectations::ExpectationNotMetError)
24
24
  end
25
25
 
26
26
  Then /^the output should be (\d+) bytes long$/ do |length|
@@ -1,12 +1,16 @@
1
1
  require 'aruba'
2
- require 'aruba/spawn_process'
3
- require 'aruba/in_process'
2
+ require 'aruba/processes/spawn_process'
3
+ require 'aruba/processes/in_process'
4
4
  require 'shellwords'
5
5
  require 'stringio'
6
6
 
7
7
  class CustomMain
8
8
  def initialize(argv, stdin, stdout, stderr, kernel)
9
- @argv, @stdin, @stdout, @stderr, @kernel = argv, stdin, stdout, stderr, kernel
9
+ @argv = argv
10
+ @stdin = stdin
11
+ @stdout = stdout
12
+ @stderr = stderr
13
+ @kernel = kernel
10
14
  end
11
15
 
12
16
  def execute!
@@ -15,10 +19,10 @@ class CustomMain
15
19
  end
16
20
 
17
21
  Before('@in-process') do
18
- Aruba::InProcess.main_class = CustomMain
19
- Aruba.process = Aruba::InProcess
22
+ Aruba.process = Aruba::Processes::InProcess
23
+ Aruba.process.main_class = CustomMain
20
24
  end
21
25
 
22
26
  After('~@in-process') do
23
- Aruba.process = Aruba::SpawnProcess
27
+ Aruba.process = Aruba::Processes::SpawnProcess
24
28
  end
@@ -1,4 +1,29 @@
1
- $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib')
2
- require 'aruba/cucumber'
1
+ $LOAD_PATH.unshift File.expand_path('../../../lib', __FILE__)
2
+
3
+ # Has to be the first file required so that all other files show coverage information
4
+ require 'simplecov'
5
+
6
+ # Standard Library
3
7
  require 'fileutils'
8
+ require 'pathname'
9
+
10
+ # Gems
11
+ require 'aruba/cucumber'
4
12
  require 'rspec/expectations'
13
+
14
+ Before do |scenario|
15
+ command_name = case scenario
16
+ when Cucumber::RunningTestCase::Scenario
17
+ "#{scenario.feature.title} #{scenario.name}"
18
+ else
19
+ raise TypeError.new("Don't know how to extract command name from #{scenario.class}")
20
+ end
21
+
22
+ # Used in simplecov_setup so that each scenario has a different name and their coverage results are merged instead
23
+ # of overwriting each other as 'Cucumber Features'
24
+ set_env('SIMPLECOV_COMMAND_NAME', command_name)
25
+
26
+ simplecov_setup_pathname = Pathname.new(__FILE__).expand_path.parent.join('simplecov_setup')
27
+ # set environment variable so child processes will merge their coverage data with parent process's coverage data.
28
+ set_env('RUBYOPT', "-r#{simplecov_setup_pathname} #{ENV['RUBYOPT']}")
29
+ end
@@ -0,0 +1,8 @@
1
+ # @note this file is loaded in env.rb to setup simplecov using RUBYOPTs for child processes and @in-process
2
+ require 'simplecov'
3
+
4
+ root = File.expand_path('../../../', __FILE__)
5
+
6
+ SimpleCov.command_name(ENV['SIMPLECOV_COMMAND_NAME'])
7
+ SimpleCov.root(root)
8
+ load File.join(root, '.simplecov')
data/lib/aruba.rb CHANGED
@@ -1,8 +1,8 @@
1
- require 'aruba/spawn_process'
1
+ require 'aruba/processes/spawn_process'
2
2
 
3
3
  module Aruba
4
4
  class << self
5
5
  attr_accessor :process
6
6
  end
7
- self.process = Aruba::SpawnProcess
7
+ self.process = Aruba::Processes::SpawnProcess
8
8
  end
@@ -0,0 +1,161 @@
1
+ module Aruba
2
+ # Announcer
3
+ #
4
+ # @example Activate your you own channel in cucumber
5
+ #
6
+ # Before('@announce-my-channel') do
7
+ # announcer.activate :my_channel
8
+ # end
9
+ #
10
+ # @example Activate your you own channel in rspec > 3
11
+ #
12
+ # before do
13
+ # current_example = context.example
14
+ # announcer.activate :my_channel if current_example.metadata[:announce_my_channel]
15
+ # end
16
+ #
17
+ # Aruba.announcer.announce(:my_channel, 'my message')
18
+ #
19
+ class Announcer
20
+ # Dev null
21
+ class NullAnnouncer
22
+ def announce(*)
23
+ nil
24
+ end
25
+
26
+ def mode?(*)
27
+ true
28
+ end
29
+ end
30
+
31
+ # Announcer using Kernel.puts
32
+ class KernelPutsAnnouncer
33
+ def announce(message)
34
+ Kernel.puts message
35
+ end
36
+
37
+ def mode?(m)
38
+ :kernel_puts == m
39
+ end
40
+ end
41
+
42
+ # Announcer using Main#puts
43
+ class PutsAnnouncer
44
+ def announce(message)
45
+ Kernel.puts message
46
+ end
47
+
48
+ def mode?(m)
49
+ :puts == m
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ attr_reader :announcers, :default_announcer, :announcer, :channels, :format_strings
56
+
57
+ public
58
+
59
+ def initialize(_, options)
60
+ @announcers = []
61
+ @announcers << PutsAnnouncer.new
62
+ @announcers << KernelPutsAnnouncer.new
63
+ @announcers << NullAnnouncer.new
64
+
65
+ @default_announcer = @announcers.last
66
+ @announcer = @announcers.first
67
+ @channels = {}
68
+ @format_strings = {}
69
+
70
+ @options = options
71
+
72
+ after_init
73
+ end
74
+
75
+ # rubocop:disable Metrics/MethodLength
76
+ def after_init
77
+ format_string :directory, '$ cd %s'
78
+ format_string :command, '$ %s'
79
+ format_string :environment, '$ export %s=%s"'
80
+
81
+ # rubocop:disable Metrics/LineLength
82
+ if @options[:stdout]
83
+ warn('The use of "@announce_stdout-instance" variable and "options[:stdout] = true" for Announcer.new is deprecated. Please use "announcer.activate(:stdout)" instead.')
84
+ activate :stdout
85
+ end
86
+ if @options[:stderr]
87
+ warn('The use of "@announce_stderr-instance" variable and "options[:stderr] = true" for Announcer.new is deprecated. Please use "announcer.activate(:stderr)" instead.')
88
+ activate :stderr
89
+ end
90
+ if @options[:dir]
91
+ warn('The use of "@announce_dir-instance" variable and "options[:dir] = true" for Announcer.new is deprecated. Please use "announcer.activate(:directory)" instead.')
92
+ activate :directory
93
+ end
94
+ if @options[:cmd]
95
+ warn('The use of "@announce_cmd-instance" variable and "options[:cmd] = true" for Announcer.new is deprecated. Please use "announcer.activate(:command)" instead.')
96
+ activate :command
97
+ end
98
+ if @options[:env]
99
+ warn('The use of "@announce_env-instance" variable and "options[:env] = true" for Announcer.new is deprecated. Please use "announcer.activate(:environment)" instead.')
100
+ activate :enviroment
101
+ end
102
+ # rubocop:enable Metrics/LineLength
103
+ end
104
+ # rubocop:enable Metrics/MethodLength
105
+
106
+ def reset
107
+ @default_announcer = @announcers.last
108
+ @announcer = @announcers.first
109
+ end
110
+
111
+ def format_string(channel, string)
112
+ format_strings[channel] = string
113
+
114
+ self
115
+ end
116
+
117
+ def mode=(m)
118
+ @announcer = @announcers.find { |a| f.mode? m }
119
+
120
+ self
121
+ end
122
+
123
+ def activate(channel)
124
+ channels[channel] = true
125
+
126
+ self
127
+ end
128
+
129
+ def announce(channel, *args)
130
+ message = format(format_strings.fetch(channel, '%s'), *args)
131
+ announcer.announce(message) if @channels[channel]
132
+
133
+ default_announcer.announce message
134
+ end
135
+
136
+ def stdout(content)
137
+ warn('The announcer now has a new api to activate channels. Please use this one: announce(:stdout, message)')
138
+ announce :stdout, content
139
+ end
140
+
141
+ def stderr(content)
142
+ warn('The announcer now has a new api to activate channels. Please use this one: announce(:stderr, message)')
143
+ announce :stderr, content
144
+ end
145
+
146
+ def dir(dir)
147
+ warn('The announcer now has a new api to activate channels. Please use this one announce(:directory, message)')
148
+ announce :directory, dir
149
+ end
150
+
151
+ def cmd(cmd)
152
+ warn('The announcer now has a new api to activate channels. Please use this one announce(:command, message)')
153
+ announce :command, cmd
154
+ end
155
+
156
+ def env(key, value)
157
+ warn('The announcer now has a new api to activate channels. Please use this one: announce(:environment, key, value)')
158
+ announce :environment, key, value
159
+ end
160
+ end
161
+ end
data/lib/aruba/api.rb CHANGED
@@ -3,70 +3,222 @@ require 'rbconfig'
3
3
  require 'rspec/expectations'
4
4
  require 'aruba'
5
5
  require 'aruba/config'
6
+ require 'aruba/errors'
7
+ require 'aruba/process_monitor'
8
+ require 'aruba/utils'
9
+ require 'aruba/announcer'
10
+ require 'ostruct'
11
+ require 'pathname'
6
12
 
7
13
  Dir.glob( File.join( File.expand_path( '../matchers' , __FILE__ ) , '*.rb' ) ).each { |rb| require rb }
8
14
 
9
15
  module Aruba
10
16
  module Api
11
17
  include RSpec::Matchers
18
+ include Aruba::Utils
12
19
 
13
20
  # Expand file name
14
21
  #
15
22
  # @param [String] file_name
16
23
  # Name of file
17
24
  #
25
+ # @param [String] dir_string
26
+ # Name of directory to use as starting point, otherwise current directory is used.
27
+ #
18
28
  # @return [String]
19
29
  # The full path
20
30
  #
21
31
  # @example Single file name
22
32
  #
23
33
  # # => <path>/tmp/aruba/file
24
- # absolute_path('file')
34
+ # expand_path('file')
25
35
  #
26
36
  # @example Single Dot
27
37
  #
28
38
  # # => <path>/tmp/aruba
29
- # absolute_path('.')
39
+ # expand_path('.')
40
+ #
41
+ # @example using home directory
30
42
  #
31
- # @example Join and Expand path
43
+ # # => <path>/home/<name>/file
44
+ # expand_path('~/file')
32
45
  #
33
- # # => <path>/tmp/aruba/path/file
34
- # absolute_path('path', 'file')
46
+ # @example using fixtures directory
35
47
  #
48
+ # # => <path>/test/fixtures/file
49
+ # expand_path('%/file')
50
+ #
51
+ def expand_path(file_name, dir_string = nil)
52
+ message = "Filename cannot be nil or empty. Please use `expand_path('.')` if you want the current directory to be expanded."
53
+ # rubocop:disable Style/RaiseArgs
54
+ fail ArgumentError, message if file_name.nil? || file_name.empty?
55
+ # rubocop:enable Style/RaiseArgs
56
+
57
+ if FIXTURES_PATH_PREFIX == file_name[0]
58
+ File.join fixtures_directory, file_name[1..-1]
59
+ else
60
+ in_current_directory { File.expand_path file_name, dir_string }
61
+ end
62
+ end
63
+
64
+ # @private
65
+ # @deprecated
36
66
  def absolute_path(*args)
37
- in_current_dir { File.expand_path File.join(*args) }
67
+ warn('The use of "absolute_path" is deprecated. Use "expand_path" instead. But be aware that "expand_path" uses a different implementation.')
68
+
69
+ in_current_directory { File.expand_path File.join(*args) }
38
70
  end
39
71
 
40
72
  # Execute block in current directory
41
73
  #
42
74
  # @yield
43
75
  # The block which should be run in current directory
44
- def in_current_dir(&block)
45
- _mkdir(current_dir)
46
- Dir.chdir(current_dir, &block)
76
+ def in_current_directory(&block)
77
+ _mkdir(current_directory)
78
+ Dir.chdir(current_directory, &block)
79
+ end
80
+
81
+ # Check if file or directory exist
82
+ #
83
+ # @param [String] file_or_directory
84
+ # The file/directory which should exist
85
+ def exist?(file_or_directory)
86
+ File.exist? expand_path(file_or_directory)
87
+ end
88
+
89
+ # Check if file exist and is file
90
+ #
91
+ # @param [String] file
92
+ # The file/directory which should exist
93
+ def file?(file)
94
+ File.file? expand_path(file)
95
+ end
96
+
97
+ # Check if directory exist and is directory
98
+ #
99
+ # @param [String] file
100
+ # The file/directory which should exist
101
+ def directory?(file)
102
+ File.directory? expand_path(file)
103
+ end
104
+
105
+ # Check if path is absolute
106
+ #
107
+ # @return [TrueClass, FalseClass]
108
+ # Result of check
109
+ def absolute?(path)
110
+ Pathname.new(path).absolute?
111
+ end
112
+
113
+ # Check if path is relative
114
+ #
115
+ # @return [TrueClass, FalseClass]
116
+ # Result of check
117
+ def relative?(path)
118
+ Pathname.new(path).relative?
119
+ end
120
+
121
+ # Return all existing paths (directories, files) in current dir
122
+ #
123
+ # @return [Array]
124
+ # List of files and directories
125
+ def all_paths
126
+ list('.').map { |p| expand_path(p) }
127
+ end
128
+
129
+ # Return all existing files in current directory
130
+ #
131
+ # @return [Array]
132
+ # List of files
133
+ def all_files
134
+ list('.').select { |p| file? p }.map { |p| expand_path(p) }
135
+ end
136
+
137
+ # Return all existing directories in current directory
138
+ #
139
+ # @return [Array]
140
+ # List of files
141
+ def all_directories
142
+ list('.').select { |p| directory? p }.map { |p| expand_path(p) }
143
+ end
144
+
145
+ # Create directory object
146
+ #
147
+ # @return [Dir]
148
+ # The directory object
149
+ def directory(path)
150
+ fail ArgumentError, %(Path "#{name}" does not exist.) unless exist? name
151
+
152
+ Dir.new(expand_path(path))
153
+ end
154
+
155
+ # @deprecated
156
+ # @private
157
+ def in_current_dir(*args, &block)
158
+ warn('The use of "in_current_dir" is deprecated. Use "in_current_directory" instead')
159
+ in_current_directory(*args, &block)
47
160
  end
48
161
 
49
162
  # Clean the current directory
50
- def clean_current_dir
51
- _rm_rf(current_dir)
52
- _mkdir(current_dir)
163
+ def clean_current_directory
164
+ _rm_rf(current_directory)
165
+ _mkdir(current_directory)
166
+ end
167
+
168
+ # @deprecated
169
+ # @private
170
+ def clean_current_dir(*args, &block)
171
+ warn('The use of "clean_current_dir" is deprecated. Use "clean_current_directory" instead')
172
+ clean_current_directory(*args, &block)
173
+ end
174
+
175
+ # Return content of directory
176
+ #
177
+ # @return [Array]
178
+ # The content of directory
179
+ def list(name)
180
+ fail ArgumentError, %(Path "#{name}" does not exist.) unless exist? name
181
+ fail ArgumentError, %(Only directories are supported. Path "#{name}" is not a directory.) unless directory? name
182
+
183
+ existing_files = Dir.glob(expand_path(File.join(name, '**', '*')))
184
+ current_working_directory = Pathname.new(expand_path('.'))
185
+
186
+ existing_files.map { |d| Pathname.new(d).relative_path_from(current_working_directory).to_s }
187
+ end
188
+
189
+ # Return content of file
190
+ #
191
+ # @return [Array]
192
+ # The content of file
193
+ def read(name)
194
+ fail ArgumentError, %(Path "#{name}" does not exist.) unless exist? name
195
+ fail ArgumentError, %(Only files are supported. Path "#{name}" is not a file.) unless file? name
196
+
197
+ File.readlines(expand_path(name))
53
198
  end
54
199
 
55
200
  # Get access to current dir
56
201
  #
57
202
  # @return
58
203
  # Current directory
59
- def current_dir
204
+ def current_directory
60
205
  File.join(*dirs)
61
206
  end
62
207
 
208
+ # @deprecated
209
+ # @private
210
+ def current_dir(*args, &block)
211
+ warn('The use of "current_dir" is deprecated. Use "current_directory" instead')
212
+ current_directory(*args, &block)
213
+ end
214
+
63
215
  # Switch to directory
64
216
  #
65
217
  # @param [String] dir
66
218
  # The directory
67
219
  def cd(dir)
68
220
  dirs << dir
69
- raise "#{current_dir} is not a directory." unless File.directory?(current_dir)
221
+ raise "#{current_directory} is not a directory." unless File.directory?(current_directory)
70
222
  end
71
223
 
72
224
  # The path to the directory which should contain all your test data
@@ -92,20 +244,78 @@ module Aruba
92
244
  _create_file(file_name, file_content, false)
93
245
  end
94
246
 
247
+ # @private
248
+ # @deprecated
249
+ # Create an empty file
250
+ #
251
+ # @param [String] file_name
252
+ # The name of the file
253
+ def touch_file(*args)
254
+ warn('The use of "touch_file" is deprecated. Use "touch" instead')
255
+
256
+ touch(*args)
257
+ end
258
+
95
259
  # Create an empty file
96
260
  #
97
261
  # @param [String] file_name
98
262
  # The name of the file
99
- def touch_file(file_name)
100
- in_current_dir do
101
- file_name = File.expand_path(file_name)
102
- _mkdir(File.dirname(file_name))
263
+ def touch(*args)
264
+ args = args.flatten
103
265
 
104
- FileUtils.touch file_name
266
+ options = if args.last.kind_of? Hash
267
+ args.pop
268
+ else
269
+ {}
270
+ end
271
+
272
+ args = args.map { |p| expand_path(p) }
273
+ args.each { |p| _mkdir(File.dirname(p)) }
274
+
275
+ FileUtils.touch(args, options)
276
+
277
+ self
278
+ end
279
+
280
+ # Copy a file and/or directory
281
+ #
282
+ # @param [String, Array] source
283
+ # A single file or directory, multiple files or directories or multiple
284
+ # files and directories. If multiple sources are given the destination
285
+ # needs to be a directory
286
+ #
287
+ # @param [String] destination
288
+ # A file or directory name. If multiple sources are given the destination
289
+ # needs to be a directory
290
+ #
291
+ # rubocop:disable Metrics/CyclomaticComplexity
292
+ # rubocop:disable Metrics/PerceivedComplexity
293
+ def copy(*source, destination)
294
+ source = source.flatten
295
+
296
+ source.each do |s|
297
+ raise ArgumentError, %(The following source "#{s}" does not exist.) unless exist? s
105
298
  end
106
299
 
300
+ raise ArgumentError, "Using a fixture as destination (#{destination}) is not supported" if destination.start_with? FIXTURES_PATH_PREFIX
301
+ raise ArgumentError, "Multiples sources can only be copied to a directory" if source.count > 1 && exist?(destination) && !directory?(destination)
302
+
303
+ source_paths = source.map { |f| expand_path(f) }
304
+ destination_path = expand_path(destination)
305
+
306
+ if source_paths.count > 1
307
+ _mkdir(destination_path)
308
+ else
309
+ _mkdir(File.dirname(destination_path))
310
+ source_paths = source_paths.first
311
+ end
312
+
313
+ FileUtils.cp_r source_paths, destination_path
314
+
107
315
  self
108
316
  end
317
+ # rubocop:enable Metrics/PerceivedComplexity
318
+ # rubocop:enable Metrics/CyclomaticComplexity
109
319
 
110
320
  # Create a file with the given size
111
321
  #
@@ -132,14 +342,12 @@ module Aruba
132
342
 
133
343
  # @private
134
344
  def _create_file(file_name, file_content, check_presence)
135
- in_current_dir do
136
- file_name = File.expand_path(file_name)
345
+ file_name = expand_path(file_name)
137
346
 
138
- raise "expected #{file_name} to be present" if check_presence && !File.file?(file_name)
347
+ raise "expected #{file_name} to be present" if check_presence && !File.file?(file_name)
139
348
 
140
- _mkdir(File.dirname(file_name))
141
- File.open(file_name, 'w') { |f| f << file_content }
142
- end
349
+ _mkdir(File.dirname(file_name))
350
+ File.open(file_name, 'w') { |f| f << file_content }
143
351
 
144
352
  self
145
353
  end
@@ -151,17 +359,28 @@ module Aruba
151
359
  #
152
360
  # @param [String] file_name
153
361
  # Name of file to be modified. This file needs to be present to succeed
154
- def filesystem_permissions(mode, file_name)
155
- in_current_dir do
156
- file_name = File.expand_path(file_name)
362
+ def filesystem_permissions(*args)
363
+ args = args.flatten
157
364
 
158
- raise "expected #{file_name} to be present" unless FileTest.exists?(file_name)
159
- if mode.kind_of? String
160
- FileUtils.chmod(mode.to_i(8),file_name)
161
- else
162
- FileUtils.chmod(mode, file_name)
163
- end
164
- end
365
+ options = if args.last.kind_of? Hash
366
+ args.pop
367
+ else
368
+ {}
369
+ end
370
+
371
+ mode = args.shift
372
+ mode = if mode.kind_of? String
373
+ mode.to_i(8)
374
+ else
375
+ mode
376
+ end
377
+
378
+ args = args.map { |p| expand_path(p) }
379
+ args.each { |p| raise "Expected #{p} to be present" unless FileTest.exists?(p) }
380
+
381
+ FileUtils.chmod(mode, args, options)
382
+
383
+ self
165
384
  end
166
385
 
167
386
  # @private
@@ -174,29 +393,27 @@ module Aruba
174
393
 
175
394
  # Check file system permissions of file
176
395
  #
177
- # @param [Octal] mode
396
+ # @param [Octal] expected_permissions
178
397
  # Expected file system permissions, e.g. 0755
179
- # @param [String] file_name
180
- # Expected file system permissions, e.g. 0755
181
- # @param [Boolean] expect_permissions
398
+ # @param [String] file_names
399
+ # The file name(s)
400
+ # @param [Boolean] expected_result
182
401
  # Are the permissions expected to be mode or are they expected not to be mode?
183
- def check_filesystem_permissions(mode, file_name, expect_permissions)
184
- in_current_dir do
185
- file_name = File.expand_path(file_name)
402
+ def check_filesystem_permissions(*args)
403
+ args = args.flatten
186
404
 
187
- raise "expected #{file_name} to be present" unless FileTest.exists?(file_name)
188
- if mode.kind_of? Integer
189
- expected_mode = mode.to_s(8)
190
- else
191
- expected_mode = mode.gsub(/^0*/, '')
192
- end
405
+ expected_permissions = args.shift
406
+ expected_result = args.pop
193
407
 
194
- file_mode = sprintf( "%o", File::Stat.new(file_name).mode )[-4,4].gsub(/^0*/, '')
408
+ args = args.map { |p| expand_path(p) }
195
409
 
196
- if expect_permissions
197
- expect(file_mode).to eq expected_mode
410
+ args.each do |p|
411
+ raise "Expected #{p} to be present" unless FileTest.exists?(p)
412
+
413
+ if expected_result
414
+ expect(p).to have_permissions expected_permissions
198
415
  else
199
- expect(file_mode).not_to eq expected_mode
416
+ expect(p).not_to have_permissions expected_permissions
200
417
  end
201
418
  end
202
419
  end
@@ -211,25 +428,23 @@ module Aruba
211
428
 
212
429
  # @private
213
430
  def _create_fixed_size_file(file_name, file_size, check_presence)
214
- in_current_dir do
215
- file_name = File.expand_path(file_name)
431
+ file_name = expand_path(file_name)
216
432
 
217
- raise "expected #{file_name} to be present" if check_presence && !File.file?(file_name)
218
- _mkdir(File.dirname(file_name))
219
- File.open(file_name, "wb"){ |f| f.seek(file_size - 1); f.write("\0") }
220
- end
433
+ raise "expected #{file_name} to be present" if check_presence && !File.file?(file_name)
434
+ _mkdir(File.dirname(file_name))
435
+ File.open(file_name, "wb"){ |f| f.seek(file_size - 1); f.write("\0") }
221
436
  end
222
437
 
438
+ # @private
439
+ # @deprecated
223
440
  # Remove file
224
441
  #
225
442
  # @param [String] file_name
226
443
  # The file which should be deleted in current directory
227
- def remove_file(file_name)
228
- in_current_dir do
229
- file_name = File.expand_path(file_name)
444
+ def remove_file(*args)
445
+ warn('The use of "remove_file" is deprecated. Use "remove" instead')
230
446
 
231
- FileUtils.rm(file_name)
232
- end
447
+ remove(*args)
233
448
  end
234
449
 
235
450
  # Append data to file
@@ -240,38 +455,67 @@ module Aruba
240
455
  # @param [String] file_content
241
456
  # The content which should be appended to file
242
457
  def append_to_file(file_name, file_content)
243
- in_current_dir do
244
- file_name = File.expand_path(file_name)
458
+ file_name = expand_path(file_name)
245
459
 
246
- _mkdir(File.dirname(file_name))
247
- File.open(file_name, 'a') { |f| f << file_content }
248
- end
460
+ _mkdir(File.dirname(file_name))
461
+ File.open(file_name, 'a') { |f| f << file_content }
249
462
  end
250
463
 
251
464
  # Create a directory in current directory
252
465
  #
253
466
  # @param [String] directory_name
254
467
  # The name of the directory which should be created
255
- def create_dir(directory_name)
256
- in_current_dir do
257
- _mkdir(directory_name)
258
- end
468
+ def create_directory(directory_name)
469
+ FileUtils.mkdir_p expand_path(directory_name)
259
470
 
260
471
  self
261
472
  end
262
473
 
474
+ # @private
475
+ # @deprecated
476
+ def create_dir(*args)
477
+ warn('The use of "create_dir" is deprecated. Use "create_directory" instead')
478
+ create_directory(*args)
479
+ end
480
+
481
+ # Remove file or directory
482
+ #
483
+ # @param [Array, String] name
484
+ # The name of the file / directory which should be removed
485
+ def remove(*args)
486
+ args = args.flatten
487
+
488
+ options = if args.last.kind_of? Hash
489
+ args.pop
490
+ else
491
+ {}
492
+ end
493
+
494
+ args = args.map { |p| expand_path(p) }
495
+
496
+ FileUtils.rm_r(args, options)
497
+ end
498
+
499
+ # @private
500
+ # @deprecated
263
501
  # Remove directory
264
502
  #
265
503
  # @param [String] directory_name
266
504
  # The name of the directory which should be removed
267
- def remove_dir(directory_name)
268
- in_current_dir do
269
- directory_name = File.expand_path(directory_name)
505
+ def remove_directory(*args)
506
+ warn('The use of "remove_directory" is deprecated. Use "remove" instead')
507
+ remove(*args)
508
+ end
270
509
 
271
- FileUtils.rmdir(directory_name)
272
- end
510
+ # @private
511
+ # @deprecated
512
+ def remove_dir(*args)
513
+ warn('The use of "remove_dir" is deprecated. Use "remove" instead')
514
+ remove(*args)
273
515
  end
274
516
 
517
+ # @deprecated
518
+ #
275
519
  # Check if paths are present
276
520
  #
277
521
  # @param [#each] paths
@@ -280,22 +524,22 @@ module Aruba
280
524
  # @param [true,false] expect_presence
281
525
  # Should the given paths be present (true) or absent (false)
282
526
  def check_file_presence(paths, expect_presence = true)
283
- prep_for_fs_check do
284
- Array(paths).each do |path|
285
- if path.kind_of? Regexp
286
- if expect_presence
287
- expect(Dir.glob('**/*')).to include_regexp(path)
288
- else
289
- expect(Dir.glob('**/*')).not_to include_regexp(path)
290
- end
291
- else
292
- path = File.expand_path(path)
527
+ warn('The use of "check_file_presence" is deprecated. Use "expect().to be_existing_file or expect(all_paths).to match_path_pattern() instead" ')
528
+
529
+ stop_processes!
293
530
 
294
- if expect_presence
295
- expect(File).to be_file(path)
296
- else
297
- expect(File).not_to be_file(path)
298
- end
531
+ Array(paths).each do |path|
532
+ if path.kind_of? Regexp
533
+ if expect_presence
534
+ expect(all_paths).to match_path_pattern(path)
535
+ else
536
+ expect(all_paths).not_to match_path_pattern(path)
537
+ end
538
+ else
539
+ if expect_presence
540
+ expect(path).to be_existing_file
541
+ else
542
+ expect(path).not_to be_existing_file
299
543
  end
300
544
  end
301
545
  end
@@ -306,12 +550,10 @@ module Aruba
306
550
  # @param [String] file_name
307
551
  # The file which should be used to pipe in data
308
552
  def pipe_in_file(file_name)
309
- in_current_dir do
310
- file_name = File.expand_path(file_name)
553
+ file_name = expand_path(file_name)
311
554
 
312
- File.open(file_name, 'r').each_line do |line|
313
- _write_interactive(line)
314
- end
555
+ File.open(file_name, 'r').each_line do |line|
556
+ last_command.write(line)
315
557
  end
316
558
  end
317
559
 
@@ -329,12 +571,12 @@ module Aruba
329
571
  # check_file_size(paths_and_sizes)
330
572
  #
331
573
  def check_file_size(paths_and_sizes)
332
- prep_for_fs_check do
333
- paths_and_sizes.each do |path, size|
334
- path = File.expand_path(path)
574
+ stop_processes!
335
575
 
336
- expect(File.size(path)).to eq size
337
- end
576
+ paths_and_sizes.each do |path, size|
577
+ path = expand_path(path)
578
+
579
+ expect(File.size(path)).to eq size
338
580
  end
339
581
  end
340
582
 
@@ -346,12 +588,12 @@ module Aruba
346
588
  # @yield
347
589
  # Pass the content of the given file to this block
348
590
  def with_file_content(file, &block)
349
- prep_for_fs_check do
350
- file = File.expand_path(file)
591
+ stop_processes!
351
592
 
352
- content = IO.read(file)
353
- yield(content)
354
- end
593
+ file = expand_path(file)
594
+ content = IO.read(file)
595
+
596
+ yield(content)
355
597
  end
356
598
 
357
599
  # Check the content of file
@@ -370,19 +612,21 @@ module Aruba
370
612
  # @param [true, false] expect_match
371
613
  # Must the content be in the file or not
372
614
  def check_file_content(file, content, expect_match = true)
615
+ stop_processes!
616
+
373
617
  match_content =
374
618
  if(Regexp === content)
375
619
  match(content)
376
620
  else
377
621
  eq(content)
378
622
  end
379
- prep_for_fs_check do
380
- content = IO.read(File.expand_path(file))
381
- if expect_match
382
- expect(content).to match_content
383
- else
384
- expect(content).not_to match_content
385
- end
623
+
624
+ content = IO.read(expand_path(file))
625
+
626
+ if expect_match
627
+ expect(content).to match_content
628
+ else
629
+ expect(content).not_to match_content
386
630
  end
387
631
  end
388
632
 
@@ -405,13 +649,10 @@ module Aruba
405
649
  # @param [true, false] expect_match
406
650
  # Must the content be in the file or not
407
651
  def check_binary_file_content(file, reference_file, expect_match = true)
408
- prep_for_fs_check do
409
- identical = FileUtils.compare_file(file, reference_file)
410
- if expect_match
411
- expect(identical).to be(true), "The file \"#{file}\" differs from file \"#{reference_file}\""
412
- else
413
- expect(identical).not_to be(true), "The file \"#{file}\" is identical to file \"#{reference_file}\""
414
- end
652
+ if expect_match
653
+ expect(file).to have_same_file_content_like reference_file
654
+ else
655
+ expect(file).not_to have_same_file_content_like reference_file
415
656
  end
416
657
  end
417
658
 
@@ -423,23 +664,25 @@ module Aruba
423
664
  # @param [true, false] expect_presence
424
665
  # Should the directory be there or should the directory not be there
425
666
  def check_directory_presence(paths, expect_presence)
426
- prep_for_fs_check do
427
- paths.each do |path|
428
- path = File.expand_path(path)
667
+ stop_processes!
429
668
 
430
- if expect_presence
431
- expect(File).to be_directory(path)
432
- else
433
- expect(File).not_to be_directory(path)
434
- end
669
+ paths.each do |path|
670
+ path = expand_path(path)
671
+
672
+ if expect_presence
673
+ expect(File).to be_directory(path)
674
+ else
675
+ expect(File).not_to be_directory(path)
435
676
  end
436
677
  end
437
678
  end
438
679
 
439
680
  # @private
440
681
  def prep_for_fs_check(&block)
441
- stop_processes!
442
- in_current_dir{ block.call }
682
+ warn('The use of "prep_for_fs_check" is deprecated. It will be removed soon.')
683
+
684
+ process_monitor.stop_processes!
685
+ in_current_directory{ block.call }
443
686
  end
444
687
 
445
688
  # @private
@@ -472,28 +715,25 @@ module Aruba
472
715
  # Fetch output (stdout, stderr) from command
473
716
  #
474
717
  # @param [String] cmd
475
- # The comand
718
+ # The command
476
719
  def output_from(cmd)
477
- cmd = detect_ruby(cmd)
478
- get_process(cmd).output
720
+ process_monitor.output_from(cmd)
479
721
  end
480
722
 
481
723
  # Fetch stdout from command
482
724
  #
483
725
  # @param [String] cmd
484
- # The comand
726
+ # The command
485
727
  def stdout_from(cmd)
486
- cmd = detect_ruby(cmd)
487
- get_process(cmd).stdout
728
+ process_monitor.stdout_from(cmd)
488
729
  end
489
730
 
490
731
  # Fetch stderr from command
491
732
  #
492
733
  # @param [String] cmd
493
- # The comand
734
+ # The command
494
735
  def stderr_from(cmd)
495
- cmd = detect_ruby(cmd)
496
- get_process(cmd).stderr
736
+ process_monitor.stderr_from(cmd)
497
737
  end
498
738
 
499
739
  # Get stdout of all processes
@@ -501,8 +741,7 @@ module Aruba
501
741
  # @return [String]
502
742
  # The stdout of all process which have run before
503
743
  def all_stdout
504
- stop_processes!
505
- only_processes.inject("") { |out, ps| out << ps.stdout }
744
+ process_monitor.all_stdout
506
745
  end
507
746
 
508
747
  # Get stderr of all processes
@@ -510,8 +749,7 @@ module Aruba
510
749
  # @return [String]
511
750
  # The stderr of all process which have run before
512
751
  def all_stderr
513
- stop_processes!
514
- only_processes.inject("") { |out, ps| out << ps.stderr }
752
+ process_monitor.all_stderr
515
753
  end
516
754
 
517
755
  # Get stderr and stdout of all processes
@@ -519,7 +757,7 @@ module Aruba
519
757
  # @return [String]
520
758
  # The stderr and stdout of all process which have run before
521
759
  def all_output
522
- all_stdout << all_stderr
760
+ process_monitor.all_output
523
761
  end
524
762
 
525
763
  # Full compare arg1 and arg2
@@ -546,7 +784,7 @@ module Aruba
546
784
  # If arg2 matches arg1 return true, otherwise false
547
785
  def assert_matching_output(expected, actual)
548
786
  actual.force_encoding(expected.encoding) if RUBY_VERSION >= "1.9"
549
- expect(unescape(actual)).to match /#{unescape(expected)}/m
787
+ expect(unescape(actual)).to match(/#{unescape(expected)}/m)
550
788
  end
551
789
 
552
790
  # Negative regex compare arg1 and arg2
@@ -576,7 +814,7 @@ module Aruba
576
814
  # @return [TrueClass, FalseClass]
577
815
  # If output of interactive command includes arg1 return true, otherwise false
578
816
  def assert_partial_output_interactive(expected)
579
- unescape(_read_interactive).include?(unescape(expected)) ? true : false
817
+ unescape(last_command.stdout).include?(unescape(expected)) ? true : false
580
818
  end
581
819
 
582
820
  # Check if command succeeded and if arg1 is included in output
@@ -624,13 +862,16 @@ module Aruba
624
862
  # If arg1 is true, return true if command was successful
625
863
  # If arg1 is false, return true if command failed
626
864
  def assert_success(success)
627
- success ? assert_exit_status(0) : assert_not_exit_status(0)
865
+ if success
866
+ expect(last_command).to be_successfully_executed
867
+ else
868
+ expect(last_command).not_to be_successfully_executed
869
+ end
628
870
  end
629
871
 
630
872
  # @private
631
873
  def assert_exit_status(status)
632
- expect(last_exit_status).to eq(status),
633
- append_output_to("Exit status was #{last_exit_status} but expected it to be #{status}.")
874
+ expect(last_command).to have_exit_status(status)
634
875
  end
635
876
 
636
877
  # @private
@@ -644,41 +885,43 @@ module Aruba
644
885
  "#{message} Output:\n\n#{all_output}\n"
645
886
  end
646
887
 
888
+ def process_monitor
889
+ @process_monitor ||= ProcessMonitor.new(announcer)
890
+ end
891
+
647
892
  # @private
648
893
  def processes
649
- @processes ||= []
894
+ process_monitor.send(:processes)
650
895
  end
651
896
 
652
897
  # @private
653
898
  def stop_processes!
654
- processes.each do |_, process|
655
- stop_process(process)
656
- end
899
+ process_monitor.stop_processes!
657
900
  end
658
901
 
659
902
  # Terminate all running processes
660
903
  def terminate_processes!
661
- processes.each do |_, process|
662
- terminate_process(process)
663
- stop_process(process)
664
- end
904
+ process_monitor.terminate_processes!
905
+ end
906
+
907
+ # @private
908
+ def last_command
909
+ processes.last[1]
665
910
  end
666
911
 
667
912
  # @private
668
- def register_process(name, process)
669
- processes << [name, process]
913
+ def register_process(*args)
914
+ process_monitor.register_process(*args)
670
915
  end
671
916
 
672
917
  # @private
673
918
  def get_process(wanted)
674
- matching_processes = processes.reverse.find{ |name, _| name == wanted }
675
- raise ArgumentError.new("No process named '#{wanted}' has been started") unless matching_processes
676
- matching_processes.last
919
+ process_monitor.get_process(wanted)
677
920
  end
678
921
 
679
922
  # @private
680
923
  def only_processes
681
- processes.collect{ |_, process| process }
924
+ process_monitor.only_processes
682
925
  end
683
926
 
684
927
  # Run given command and stop it if timeout is reached
@@ -688,6 +931,9 @@ module Aruba
688
931
  #
689
932
  # @param [Integer] timeout
690
933
  # If the timeout is reached the command will be killed
934
+ #
935
+ # @yield [SpawnProcess]
936
+ # Run block with process
691
937
  def run(cmd, timeout = nil)
692
938
  timeout ||= exit_timeout
693
939
  @commands ||= []
@@ -695,18 +941,16 @@ module Aruba
695
941
 
696
942
  cmd = detect_ruby(cmd)
697
943
 
698
- in_current_dir do
699
- Aruba.config.hooks.execute(:before_cmd, self, cmd)
944
+ Aruba.config.hooks.execute(:before_cmd, self, cmd)
700
945
 
701
- announcer.dir(Dir.pwd)
702
- announcer.cmd(cmd)
946
+ announcer.announce(:directory, Dir.pwd)
947
+ announcer.announce(:command, cmd)
703
948
 
704
- process = Aruba.process.new(cmd, timeout, io_wait)
705
- register_process(cmd, process)
706
- process.run!
949
+ process = Aruba.process.new(cmd, timeout, io_wait, expand_path('.'))
950
+ process_monitor.register_process(cmd, process)
951
+ process.run!
707
952
 
708
- block_given? ? yield(process) : process
709
- end
953
+ block_given? ? yield(process) : process
710
954
  end
711
955
 
712
956
  DEFAULT_TIMEOUT_SECONDS = 3
@@ -729,6 +973,37 @@ module Aruba
729
973
  @aruba_io_wait_seconds || DEFAULT_IO_WAIT_SECONDS
730
974
  end
731
975
 
976
+ DEFAULT_ROOT_DIRECTORY = Dir.getwd
977
+
978
+ # The root directory of aruba
979
+ def root_directory
980
+ @aruba_root_directory || DEFAULT_ROOT_DIRECTORY
981
+ end
982
+
983
+ # Path prefix for fixtures
984
+ FIXTURES_PATH_PREFIX = ?%
985
+
986
+ DEFAULT_FIXTURES_DIRECTORIES = %w(
987
+ features/fixtures
988
+ spec/fixtures
989
+ test/fixtures
990
+ )
991
+
992
+ # The path to the directory which contains fixtures
993
+ # You might want to overwrite this method to place your data else where.
994
+ #
995
+ # @return [String]
996
+ # The directory to where your fixtures are stored
997
+ def fixtures_directory
998
+ unless @fixtures_directory
999
+ candidates = DEFAULT_FIXTURES_DIRECTORIES.map { |dir| File.join(root_directory, dir) }
1000
+ @fixtures_directory = candidates.find { |dir| File.directory? dir }
1001
+ raise "No fixtures directories are found" unless @fixtures_directory
1002
+ end
1003
+ raise "#{@fixtures_directory} is not a directory" unless File.directory?(@fixtures_directory)
1004
+ @fixtures_directory
1005
+ end
1006
+
732
1007
  # Run a command with aruba
733
1008
  #
734
1009
  # Checks for error during command execution and checks the output to detect
@@ -743,11 +1018,15 @@ module Aruba
743
1018
  # @param [Integer] timeout
744
1019
  # Timeout for execution
745
1020
  def run_simple(cmd, fail_on_error = true, timeout = nil)
746
- run(cmd, timeout) do |process|
747
- stop_process(process)
1021
+ command = run(cmd, timeout) do |process|
1022
+ process_monitor.stop_process(process)
1023
+
1024
+ process
748
1025
  end
749
- @timed_out = last_exit_status.nil?
750
- assert_exit_status(0) if fail_on_error
1026
+
1027
+ @timed_out = command.exit_status.nil?
1028
+
1029
+ expect(command).to be_successfully_executed if fail_on_error
751
1030
  end
752
1031
 
753
1032
  # Run a command interactively
@@ -756,8 +1035,12 @@ module Aruba
756
1035
  # The command to by run
757
1036
  #
758
1037
  # @see #cmd
1038
+ # @deprectated
1039
+ # @private
759
1040
  def run_interactive(cmd)
760
- @interactive = run(cmd)
1041
+ warn('The use of "run_interactive" is deprecated. You can simply use "run" instead.')
1042
+
1043
+ run(cmd)
761
1044
  end
762
1045
 
763
1046
  # Provide data to command via stdin
@@ -766,12 +1049,12 @@ module Aruba
766
1049
  # The input for the command
767
1050
  def type(input)
768
1051
  return close_input if "" == input
769
- _write_interactive(_ensure_newline(input))
1052
+ last_command.write(_ensure_newline(input))
770
1053
  end
771
1054
 
772
1055
  # Close stdin
773
1056
  def close_input
774
- @interactive.stdin.close
1057
+ last_command.close_io(:stdin)
775
1058
  end
776
1059
 
777
1060
  # @deprecated
@@ -783,18 +1066,21 @@ module Aruba
783
1066
 
784
1067
  # @private
785
1068
  def _write_interactive(input)
786
- @interactive.stdin.write(input)
787
- @interactive.stdin.flush
1069
+ warn('The use of "_write_interactive" is deprecated. It will be removed soon.')
1070
+
1071
+ last_command.write(input)
788
1072
  end
789
1073
 
790
1074
  # @private
791
1075
  def _read_interactive
792
- @interactive.read_stdout
1076
+ warn('The use of "_read_interactive" is deprecated. It will be removed soon.')
1077
+
1078
+ last_command.stdout
793
1079
  end
794
1080
 
795
1081
  # @private
796
1082
  def _ensure_newline(str)
797
- str.chomp << "\n"
1083
+ Utils.ensure_newline(str)
798
1084
  end
799
1085
 
800
1086
  # @private
@@ -806,20 +1092,6 @@ module Aruba
806
1092
  end
807
1093
  end
808
1094
 
809
- # @private
810
- def detect_ruby(cmd)
811
- if cmd =~ /^ruby\s/
812
- cmd.gsub(/^ruby\s/, "#{current_ruby} ")
813
- else
814
- cmd
815
- end
816
- end
817
-
818
- # @private
819
- def current_ruby
820
- File.join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['ruby_install_name'])
821
- end
822
-
823
1095
  # Use a clean rvm gemset
824
1096
  #
825
1097
  # Please make sure that you've got [rvm](http://rvm.io/) installed.
@@ -859,7 +1131,7 @@ module Aruba
859
1131
  # @param [String] value
860
1132
  # The value of the environment variable. Needs to be a string.
861
1133
  def set_env(key, value)
862
- announcer.env(key, value)
1134
+ announcer.announce(:environment, key, value)
863
1135
  original_env[key] = ENV.delete(key) unless original_env.key? key
864
1136
  ENV[key] = value
865
1137
  end
@@ -895,69 +1167,36 @@ module Aruba
895
1167
  restore_env
896
1168
  end
897
1169
 
1170
+ # Access to announcer
1171
+ def announcer
1172
+ @announcer ||= Announcer.new(
1173
+ self,
1174
+ :stdout => @announce_stdout,
1175
+ :stderr => @announce_stderr,
1176
+ :dir => @announce_dir,
1177
+ :cmd => @announce_cmd,
1178
+ :env => @announce_env
1179
+ )
1180
+
1181
+ @announcer
1182
+ end
1183
+
1184
+ module_function :announcer
1185
+
898
1186
  # TODO: move some more methods under here!
899
1187
 
900
1188
  private
901
1189
 
902
1190
  def last_exit_status
903
- return @last_exit_status if @last_exit_status
904
- stop_processes!
905
- @last_exit_status
1191
+ process_monitor.last_exit_status
906
1192
  end
907
1193
 
908
1194
  def stop_process(process)
909
- @last_exit_status = process.stop(announcer)
1195
+ process_monitor.stop_process(process)
910
1196
  end
911
1197
 
912
1198
  def terminate_process(process)
913
- process.terminate
914
- end
915
-
916
- def announcer
917
- Announcer.new(self,
918
- :stdout => @announce_stdout,
919
- :stderr => @announce_stderr,
920
- :dir => @announce_dir,
921
- :cmd => @announce_cmd,
922
- :env => @announce_env)
1199
+ process_monitor.terminate_process(process)
923
1200
  end
924
-
925
- class Announcer
926
- def initialize(session, options = {})
927
- @session, @options = session, options
928
- end
929
-
930
- def stdout(content)
931
- return unless @options[:stdout]
932
- print content
933
- end
934
-
935
- def stderr(content)
936
- return unless @options[:stderr]
937
- print content
938
- end
939
-
940
- def dir(dir)
941
- return unless @options[:dir]
942
- print "$ cd #{dir}"
943
- end
944
-
945
- def cmd(cmd)
946
- return unless @options[:cmd]
947
- print "$ #{cmd}"
948
- end
949
-
950
- def env(key, value)
951
- return unless @options[:env]
952
- print %{$ export #{key}="#{value}"}
953
- end
954
-
955
- private
956
-
957
- def print(message)
958
- @session.announce_or_puts(message)
959
- end
960
- end
961
-
962
1201
  end
963
1202
  end