diff --git a/features/fixtures/empty-app/.gitignore b/features/fixtures/empty-app/.gitignore new file mode 100644 index 000000000..0cb6eeb06 --- /dev/null +++ b/features/fixtures/empty-app/.gitignore @@ -0,0 +1,9 @@ +/.bundle/ +/.yardoc +/Gemfile.lock +/_yardoc/ +/coverage/ +/doc/ +/pkg/ +/spec/reports/ +/tmp/ diff --git a/features/fixtures/empty-app/.rspec b/features/fixtures/empty-app/.rspec new file mode 100644 index 000000000..8c18f1abd --- /dev/null +++ b/features/fixtures/empty-app/.rspec @@ -0,0 +1,2 @@ +--format documentation +--color diff --git a/features/fixtures/empty-app/README.md b/features/fixtures/empty-app/README.md new file mode 100644 index 000000000..343aa79ae --- /dev/null +++ b/features/fixtures/empty-app/README.md @@ -0,0 +1,34 @@ +# Simple Cli App + +This is a simple test cli app + +## Installation + +Add this line to your application's Gemfile: + +```ruby +gem 'cli-app' +``` + +And then execute: + + $ bundle + +Or install it yourself as: + + $ gem install cli-app + +## Usage + +Place files in `lib/cli/app/`. They are loaded automatically. If you need a +specific load order, use `require` in your files. + +### CLI + +``` +cli +``` + +### Library + +You can use `script/console` to load your library. diff --git a/features/fixtures/empty-app/Rakefile b/features/fixtures/empty-app/Rakefile new file mode 100644 index 000000000..29955274e --- /dev/null +++ b/features/fixtures/empty-app/Rakefile @@ -0,0 +1 @@ +require "bundler/gem_tasks" diff --git a/features/fixtures/empty-app/bin/cli b/features/fixtures/empty-app/bin/cli new file mode 100755 index 000000000..4a49462ab --- /dev/null +++ b/features/fixtures/empty-app/bin/cli @@ -0,0 +1,6 @@ +#!/usr/bin/env ruby + +$LOAD_PATH << File.expand_path('../../lib', __FILE__) +require 'cli/app' + +exit 0 diff --git a/features/fixtures/empty-app/cli-app.gemspec b/features/fixtures/empty-app/cli-app.gemspec new file mode 100644 index 000000000..6481ca4af --- /dev/null +++ b/features/fixtures/empty-app/cli-app.gemspec @@ -0,0 +1,26 @@ +# coding: utf-8 +lib = File.expand_path('../lib', __FILE__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require 'cli/app/version' + +Gem::Specification.new do |spec| + spec.name = 'cli-app' + spec.version = Cli::App::VERSION + spec.authors = ['Aruba Developers'] + spec.email = 'cukes@googlegroups.com' + + spec.summary = 'Summary' + spec.description = 'Description' + spec.homepage = 'http://example.com' + + # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or + # delete this section to allow pushing this gem to any host. + + spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } + spec.bindir = 'exe' + spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } + spec.require_paths = ['lib'] + + spec.add_development_dependency 'bundler', '~> 1.9' + spec.add_development_dependency 'rake', '~> 10.0' +end diff --git a/features/fixtures/empty-app/lib/cli/app.rb b/features/fixtures/empty-app/lib/cli/app.rb new file mode 100644 index 000000000..8f8b44076 --- /dev/null +++ b/features/fixtures/empty-app/lib/cli/app.rb @@ -0,0 +1,13 @@ +require 'cli/app/version' + +if RUBY_VERSION < '1.9' + ::Dir.glob(::File.expand_path('../**/*.rb', __FILE__)).each { |f| require File.join(File.dirname(f), File.basename(f, '.rb')) } +else + ::Dir.glob(File.expand_path('../**/*.rb', __FILE__)).each { |f| require_relative f } +end + +module Cli + module App + # Your code goes here... + end +end diff --git a/features/fixtures/empty-app/lib/cli/app/version.rb b/features/fixtures/empty-app/lib/cli/app/version.rb new file mode 100644 index 000000000..07b8ed6a8 --- /dev/null +++ b/features/fixtures/empty-app/lib/cli/app/version.rb @@ -0,0 +1,5 @@ +module Cli + module App + VERSION = "0.1.0" + end +end diff --git a/features/fixtures/empty-app/script/console b/features/fixtures/empty-app/script/console new file mode 100755 index 000000000..1a4888ae7 --- /dev/null +++ b/features/fixtures/empty-app/script/console @@ -0,0 +1,14 @@ +#!/usr/bin/env ruby + +require "bundler/setup" +require "cli/app" + +# You can add fixtures and/or initialization code here to make experimenting +# with your gem easier. You can also use a different console, if you like. + +# (If you use this, don't forget to add pry to your Gemfile!) +# require "pry" +# Pry.start + +require "irb" +IRB.start diff --git a/features/fixtures/empty-app/spec/spec_helper.rb b/features/fixtures/empty-app/spec/spec_helper.rb new file mode 100644 index 000000000..56c0fe444 --- /dev/null +++ b/features/fixtures/empty-app/spec/spec_helper.rb @@ -0,0 +1,9 @@ +$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__) + +require 'cli/app' + +if RUBY_VERSION < '1.9.' + ::Dir.glob(::File.expand_path('../support/**/*.rb', __FILE__)).each { |f| require File.join(File.dirname(f), File.basename(f, '.rb')) } +else + ::Dir.glob(::File.expand_path('../support/**/*.rb', __FILE__)).each { |f| require_relative f } +end diff --git a/features/integration/rspec/getting_started.feature b/features/integration/rspec/getting_started.feature new file mode 100644 index 000000000..82f19d436 --- /dev/null +++ b/features/integration/rspec/getting_started.feature @@ -0,0 +1,148 @@ +Feature: Getting started with RSpec and aruba + + Background: + Given I use the fixture "empty-app" + + Scenario: Simple Integration + + To use the simple integration just require `aruba/rspec` in your + `spec_helper.rb`. After that you only need to flag your tests with `type: + :aruba` and some things are set up for. + + The simple integration adds some `before(:each)`-hooks for you: + + \* Setup Aruba Test directory + \* Clear environment (ENV) + \* Make HOME-variable configarable via `arub.config.home_directory` + \* Configure `aruba` via `RSpec`-metadata + \* Activate announcers based on `RSpec`-metadata + + Be careful, if you are going to use a `before(:all)`-hook to set up + files/directories. Those will be deleted by the `setup_aruba`-call within + the `before(:each)`-hook. Look for some custom integration further down the + documentation for a solution. + + Given a file named "spec/spec_helper.rb" with: + """ + require 'aruba/rspec' + """ + And a file named "spec/getting_started_spec.rb" with: + """ + require 'spec_helper' + + RSpec.describe 'Integrate Aruba into RSpec', :type => :aruba do + context 'when to be or not be...' do + it { expect(aruba).to be } + end + + context 'when write file' do + let(:file) { 'file.txt' } + + before(:each) { write_file file, 'Hello World' } + + it { expect(file).to be_an_existing_file } + it { expect([file]).to include an_existing_file } + end + end + """ + When I run `rspec` + Then the specs should all pass + + Scenario: Simple Custom Integration + + There might be some use cases where you want to build an aruba integration + of your own. You need to include the API and make sure, that you run + + \* `restore_env` (only for aruba < 1.0.0) + \* `setup_aruba` + + before any method of aruba is used. + + Given a file named "spec/spec_helper.rb" with: + """ + require 'aruba/api' + + RSpec.configure do |config| + config.include Aruba::Api + end + """ + And a file named "spec/getting_started_spec.rb" with: + """ + require 'spec_helper' + + RSpec.describe 'Custom Integration of aruba' do + let(:file) { 'file.txt' } + + before(:each) { setup_aruba } + before(:each) { write_file file, 'Hello World' } + + it { expect(file).to be_an_existing_file } + end + """ + When I run `rspec` + Then the specs should all pass + + Scenario: Custom Integration using before(:all)-hook + + You can even use `aruba` within a `before(:all)`-hook. But again, make sure + that `setup_aruba` is run before you use any method of `aruba`. Using + `setup_aruba` both in `before(:all)`- and `before(:each)`-hook is not + possible and therefor not supported: + + Running `setup_aruba` removes `tmp/aruba`, creates a new one `tmp/aruba` + and make it the working directory. Running it within a `before(:all)`-hook, + run some `aruba`-method and then run `setup_arub` again within a + `before(:each)`-hook, will remove the files/directories created within the + `before(:all)`-hook. + + Given a file named "spec/spec_helper.rb" with: + """ + require 'aruba/api' + + RSpec.configure do |config| + config.include Aruba::Api + end + """ + And a file named "spec/getting_started_spec.rb" with: + """ + require 'spec_helper' + + RSpec.describe 'Custom Integration of aruba' do + before(:all) { setup_aruba } + before(:all) { write_file 'file.txt', 'Hello World' } + + it { expect('file.txt').to be_an_existing_file } + end + """ + When I run `rspec` + Then the specs should all pass + + Scenario: Fail-safe use if "setup_aruba" is not used + + If you forgot to run `setup_aruba` before the first method of aruba is + used, you might see an error. Although we did our best to prevent this. + + Make sure that you run `setup_aruba` before any method of aruba is used. At + best before each and every test. + + Given a file named "spec/spec_helper.rb" with: + """ + require 'aruba/api' + + RSpec.configure do |config| + config.include Aruba::Api + end + """ + And a file named "spec/getting_started_spec.rb" with: + """ + require 'spec_helper' + + RSpec.describe 'Custom Integration of aruba' do + let(:file) { 'file.txt' } + + it { expect { write_file file, 'Hello World' }.not_to raise_error } + it { expect(aruba.current_directory.directory?).to be true } + end + """ + When I run `rspec` + Then the specs should all pass diff --git a/features/step_definitions/aruba_dev_steps.rb b/features/step_definitions/aruba_dev_steps.rb index 07e356b51..984aece63 100644 --- a/features/step_definitions/aruba_dev_steps.rb +++ b/features/step_definitions/aruba_dev_steps.rb @@ -51,9 +51,14 @@ step 'the output should contain:', string if string end -Then /^the spec(?:s)? should( not)?(?: all)? pass$/ do |negated| +Then /^the spec(?:s)? should( not)?(?: all)? pass(?: with (\d+) failures?)?$/ do |negated, count_failures| if negated - step 'the output should not contain "0 failures"' + if count_failures.nil? + step 'the output should not contain "0 failures"' + else + step %(the output should contain "#{count_failures} failures") + end + step 'the exit status should be 1' else step 'the output should contain "0 failures"' diff --git a/features/steps/environment/home_variable.feature b/features/steps/environment/home_variable.feature index 755fbcae9..42d4f7c9a 100644 --- a/features/steps/environment/home_variable.feature +++ b/features/steps/environment/home_variable.feature @@ -25,10 +25,7 @@ Feature: Mock the HOME variable Scenario: Run command Given a mocked home directory When I run `cli` - Then the output should contain: - \"\"\" - tmp/aruba - \"\"\" + Then the output should match %r """ When I run `cucumber` Then the features should all pass @@ -40,10 +37,26 @@ Feature: Mock the HOME variable @mocked-home-directory Scenario: Run command When I run `cli` - Then the output should contain: - \"\"\" - tmp/aruba - \"\"\" + Then the output should match %r + """ + When I run `cucumber` + Then the features should all pass + + Scenario: Redefine home directory by using the aruba configuration + Given a file named "features/support/home_variable.rb" with: + """ + require 'aruba/cucumber' + + Aruba.configure do |config| + config.home_directory = File.join(config.root_directory, config.working_directory) + end + """ + Given a file named "features/home_variable.feature" with: + """ + Feature: Home Variable + Scenario: Run command + When I run `cli` + Then the output should match %r """ When I run `cucumber` Then the features should all pass diff --git a/lib/aruba/api/command.rb b/lib/aruba/api/command.rb index 830ce6062..4a4d2f9cf 100644 --- a/lib/aruba/api/command.rb +++ b/lib/aruba/api/command.rb @@ -279,7 +279,6 @@ def run(cmd, timeout = nil) else aruba.config.main_class end - command = Command.new( cmd, :mode => mode, diff --git a/lib/aruba/api/core.rb b/lib/aruba/api/core.rb index 9139da449..9c8ee995f 100644 --- a/lib/aruba/api/core.rb +++ b/lib/aruba/api/core.rb @@ -132,18 +132,17 @@ def expand_path(file_name, dir_string = nil) if aruba.config.fixtures_path_prefix == prefix File.join aruba.fixtures_directory, rest elsif '~' == prefix - with_environment do - path = aruba.config.home_directory + path = with_environment do + ArubaPath.new(File.expand_path(file_name)) + end - fail 'Expanding "~/" to "/" is not allowed' if path == '/' + fail 'Expanding "~/" to "/" is not allowed' if path.to_s == '/' + fail %(Expanding "~/" to a relative path "#{path}" is not allowed) unless path.absolute? - Aruba::Platform.chdir(path) { Aruba::Platform.expand_path(file_name, dir_string) } - end + path.to_s else directory = File.join(aruba.root_directory, aruba.current_directory) - - Aruba::Platform.mkdir directory unless File.exist? directory - Aruba::Platform.chdir(directory) { Aruba::Platform.expand_path(file_name, dir_string) } + ArubaPath.new(File.join(*[directory, dir_string, file_name].compact)).expand_path.to_s end end # rubocop:enable Metrics/MethodLength diff --git a/lib/aruba/cucumber/hooks.rb b/lib/aruba/cucumber/hooks.rb index 886dd9acc..8aa8e8f71 100644 --- a/lib/aruba/cucumber/hooks.rb +++ b/lib/aruba/cucumber/hooks.rb @@ -2,37 +2,30 @@ require 'aruba/api' World(Aruba::Api) -# Activate on 1.0.0 -# -# Around do |_, block| -# begin -# if RUBY_VERSION < '1.9' -# old_env = ENV.to_hash -# else -# old_env = ENV.to_h -# end -# -# block.call -# ensure -# ENV.clear -# ENV.update old_env -# end -# end - -Around do |_, block| - begin - old_home = ENV['HOME'] - ENV['HOME'] = aruba.config.home_directory - - block.call - ensure - ENV['HOME'] = old_home +if Aruba::VERSION >= '1.0.0' + Around do |_, block| + begin + if RUBY_VERSION < '1.9' + old_env = ENV.to_hash + else + old_env = ENV.to_h + end + + block.call + ensure + ENV.clear + ENV.update old_env + end end end Before do + # this is ENV by default ... aruba.environment.update aruba.config.command_runtime_environment + + # ... so every change needs to be done later prepend_environment_variable 'PATH', aruba.config.command_search_paths.join(':') + ':' + set_environment_variable 'HOME', aruba.config.home_directory end After do diff --git a/lib/aruba/rspec.rb b/lib/aruba/rspec.rb index cb0b3d8d8..d8fd05545 100644 --- a/lib/aruba/rspec.rb +++ b/lib/aruba/rspec.rb @@ -33,20 +33,6 @@ end end - # Use configured home directory as HOME - config.around :each do |example| - next example.run unless self.class.include? Aruba::Api - - begin - old_home = ENV['HOME'] - ENV['HOME'] = aruba.config.home_directory - - example.run - ensure - ENV['HOME'] = old_home - end - end - # Use rspec metadata as option for aruba config.before :each do |example| next unless self.class.include? Aruba::Api @@ -94,4 +80,11 @@ aruba.environment.update aruba.config.command_runtime_environment aruba.environment.prepend 'PATH', aruba.config.command_search_paths.join(':') + ':' end + + # Use configured home directory as HOME + config.before :each do |example| + next unless self.class.include? Aruba::Api + + aruba.environment['HOME'] = aruba.config.home_directory + end end diff --git a/lib/aruba/version.rb b/lib/aruba/version.rb index c23ed8500..10603fd83 100644 --- a/lib/aruba/version.rb +++ b/lib/aruba/version.rb @@ -1,3 +1,3 @@ module Aruba - VERSION = '0.8.0' + VERSION = '0.8.1' end