diff --git a/features/docs/getting_started.feature b/features/docs/getting_started.feature index fc1fd5bd7c..29b63fb4c4 100644 --- a/features/docs/getting_started.feature +++ b/features/docs/getting_started.feature @@ -19,7 +19,7 @@ Feature: Getting started puts 'this will not be shown' """ When I run `cucumber` - Then the exit status should be 1 + Then the exit status should be 2 And the output should not contain: """ this will not be shown diff --git a/features/docs/raketask.feature b/features/docs/raketask.feature index 541f5a955e..3eb138d588 100644 --- a/features/docs/raketask.feature +++ b/features/docs/raketask.feature @@ -40,5 +40,5 @@ Feature: Raketask Scenario: Failing feature When I run `bundle exec rake fail` - Then the exit status should not be 0 + Then the exit status should be 1 But the output should not contain "rake aborted!" diff --git a/lib/cucumber/cli/main.rb b/lib/cucumber/cli/main.rb index a338108723..924d5fcfca 100644 --- a/lib/cucumber/cli/main.rb +++ b/lib/cucumber/cli/main.rb @@ -36,27 +36,34 @@ def execute!(existing_runtime = nil) end runtime.run! - failure = runtime.failure? || Cucumber.wants_to_quit - @kernel.exit(failure ? 1 : 0) + if Cucumber.wants_to_quit + exit_unable_to_finish + else + if runtime.failure? + exit_tests_failed + else + exit_ok + end + end + rescue SystemExit => e + @kernel.exit(e.status) rescue FileNotFoundException => e @err.puts(e.message) @err.puts("Couldn't open #{e.path}") - @kernel.exit(1) + exit_unable_to_finish rescue FeatureFolderNotFoundException => e @err.puts(e.message + ". You can use `cucumber --init` to get started.") - @kernel.exit(1) + exit_unable_to_finish rescue ProfilesNotDefinedError, YmlLoadError, ProfileNotFound => e @err.puts(e.message) - @kernel.exit(1) - rescue SystemExit => e - @kernel.exit(e.status) + exit_unable_to_finish rescue Errno::EACCES, Errno::ENOENT => e @err.puts("#{e.message} (#{e.class})") - @kernel.exit(1) + exit_unable_to_finish rescue Exception => e @err.puts("#{e.message} (#{e.class})") @err.puts(e.backtrace.join("\n")) - @kernel.exit(1) + exit_unable_to_finish end def configuration @@ -68,9 +75,27 @@ def configuration private + + def exit_ok + @kernel.exit 0 + end + + def exit_tests_failed + @kernel.exit 1 + end + + def exit_unable_to_finish + @kernel.exit 2 + end + + # stops the program immediately, without running at_exit blocks + def exit_unable_to_finish! + @kernel.exit! 2 + end + def trap_interrupt trap('INT') do - exit!(1) if Cucumber.wants_to_quit + exit_unable_to_finish! if Cucumber.wants_to_quit Cucumber.wants_to_quit = true STDERR.puts "\nExiting... Interrupt again to exit immediately." end diff --git a/spec/cucumber/cli/main_spec.rb b/spec/cucumber/cli/main_spec.rb index b93781e7db..c643d31224 100644 --- a/spec/cucumber/cli/main_spec.rb +++ b/spec/cucumber/cli/main_spec.rb @@ -51,7 +51,7 @@ def do_execute Cucumber.wants_to_quit = false end - it "registers as a failure" do + it "exits with error code" do results = double('results', :failure? => false) allow_any_instance_of(Runtime).to receive(:run!) @@ -59,7 +59,7 @@ def do_execute Cucumber.wants_to_quit = true - expect(kernel).to receive(:exit).with(1) + expect(kernel).to receive(:exit).with(2) subject.execute! end @@ -93,7 +93,7 @@ def do_execute allow(Configuration).to receive(:new) { configuration } allow(configuration).to receive(:parse!).and_raise(exception_klass.new("error message")) - allow(kernel).to receive(:exit).with(1) + allow(kernel).to receive(:exit).with(2) subject.execute!