aruba 0.6.2 → 0.7.0

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