diff --git a/lib/detest/publishers/cucumber.rb b/lib/detest/publishers/cucumber.rb index dc3c20f..beff7c1 100644 --- a/lib/detest/publishers/cucumber.rb +++ b/lib/detest/publishers/cucumber.rb @@ -1,8 +1,13 @@ cucumber_version = Gem::Version.new(Cucumber::VERSION) cucumber_4_x_version = Gem::Version.new("4.0.0") +cucumber_10_version = Gem::Version.new("10.0.0") +cucumber_11_version = Gem::Version.new("11.0.0") if cucumber_version < cucumber_4_x_version require_relative "cucumber_3_x/cli" require_relative "cucumber_3_x/runtime" +elsif cucumber_version >= cucumber_10_version && cucumber_version < cucumber_11_version + require_relative "cucumber_10_x/cli" + require_relative "cucumber_10_x/runtime" else require_relative "cucumber_unsupported/cli" end diff --git a/lib/detest/publishers/cucumber_10_x/cli.rb b/lib/detest/publishers/cucumber_10_x/cli.rb new file mode 100644 index 0000000..0ade933 --- /dev/null +++ b/lib/detest/publishers/cucumber_10_x/cli.rb @@ -0,0 +1,51 @@ +require "cucumber/cli/main" + +module Detest + module Publishers + module Cucumber + class Cli < ::Cucumber::Cli::Main + + def execute!(adapter, existing_runtime = nil) + trap_interrupt + + runtime = if existing_runtime + existing_runtime.configure(configuration) + existing_runtime + else + ::Detest::Publishers::Cucumber::Runtime.new(configuration) + end + + runtime.run!(adapter) + 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 ::Cucumber::FileNotFoundException => e + @err.puts(e.message) + @err.puts("Couldn't open #{e.path}") + exit_unable_to_finish + rescue ::Cucumber::FeatureFolderNotFoundException => e + @err.puts(e.message + '. You can use `cucumber --init` to get started.') + exit_unable_to_finish + rescue ::Cucumber::Cli::ProfilesNotDefinedError, ::Cucumber::Cli::YmlLoadError, ::Cucumber::Cli::ProfileNotFound => e + @err.puts(e.message) + exit_unable_to_finish + rescue Errno::EACCES, Errno::ENOENT => e + @err.puts("#{e.message} (#{e.class})") + exit_unable_to_finish + rescue Exception => e + @err.puts("#{e.message} (#{e.class})") + @err.puts(e.backtrace.join("\n")) + exit_unable_to_finish + end + end + end + end +end \ No newline at end of file diff --git a/lib/detest/publishers/cucumber_10_x/runtime.rb b/lib/detest/publishers/cucumber_10_x/runtime.rb new file mode 100644 index 0000000..12fa2bb --- /dev/null +++ b/lib/detest/publishers/cucumber_10_x/runtime.rb @@ -0,0 +1,34 @@ +require "cucumber/runtime" +require "cucumber/messages" + +module Detest + module Publishers + module Cucumber + class Runtime < ::Cucumber::Runtime + def run!(adapter) + @configuration.notify :envelope, ::Cucumber::Messages::Envelope.new( + meta: MetaMessageBuilder.build_meta_message + ) + + load_step_definitions + fire_install_plugin_hook + + adapter.enqueue(feature_file_paths) + end + + def feature_file_paths + our_cwd = Dir.pwd + feature_files.map do |s_file| + s_path = Pathname(s_file) + if s_path.absolute? + s_path.relative_path_from(our_cwd).to_s + else + s_full_path = Pathname(our_cwd) + s_path + s_full_path.relative_path_from(our_cwd).to_s + end + end + end + end + end + end +end diff --git a/lib/detest/workers/cucumber.rb b/lib/detest/workers/cucumber.rb index 5df6e8b..ef5e5e4 100644 --- a/lib/detest/workers/cucumber.rb +++ b/lib/detest/workers/cucumber.rb @@ -1,9 +1,15 @@ cucumber_version = Gem::Version.new(Cucumber::VERSION) cucumber_4_x_version = Gem::Version.new("4.0.0") +cucumber_10_version = Gem::Version.new("10.0.0") +cucumber_11_version = Gem::Version.new("11.0.0") if cucumber_version < cucumber_4_x_version require_relative "cucumber_3_x/cli" require_relative "cucumber_3_x/runtime" require_relative "cucumber_3_x/event_bus" +elsif cucumber_version >= cucumber_10_version && cucumber_version < cucumber_11_version + require_relative "cucumber_10_x/cli" + require_relative "cucumber_10_x/runtime" + require_relative "cucumber_10_x/event_bus" else require_relative "cucumber_unsupported/cli" end diff --git a/lib/detest/workers/cucumber_10_x/cli.rb b/lib/detest/workers/cucumber_10_x/cli.rb new file mode 100644 index 0000000..2decce9 --- /dev/null +++ b/lib/detest/workers/cucumber_10_x/cli.rb @@ -0,0 +1,51 @@ +require "cucumber/cli/main" + +module Detest + module Workers + module Cucumber + class Cli < ::Cucumber::Cli::Main + + def execute!(adapter, existing_runtime = nil) + trap_interrupt + + runtime = if existing_runtime + existing_runtime.configure(configuration) + existing_runtime + else + ::Detest::Workers::Cucumber::Runtime.new(configuration.to_hash.merge(:event_bus => Detest::Workers::Cucumber::EventBus.make_event_bus)) + end + + runtime.run!(adapter) + 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 ::Cucumber::FileNotFoundException => e + @err.puts(e.message) + @err.puts("Couldn't open #{e.path}") + exit_unable_to_finish + rescue ::Cucumber::FeatureFolderNotFoundException => e + @err.puts(e.message + '. You can use `cucumber --init` to get started.') + exit_unable_to_finish + rescue ::Cucumber::Cli::ProfilesNotDefinedError, ::Cucumber::Cli::YmlLoadError, ::Cucumber::Cli::ProfileNotFound => e + @err.puts(e.message) + exit_unable_to_finish + rescue Errno::EACCES, Errno::ENOENT => e + @err.puts("#{e.message} (#{e.class})") + exit_unable_to_finish + rescue Exception => e + @err.puts("#{e.message} (#{e.class})") + @err.puts(e.backtrace.join("\n")) + exit_unable_to_finish + end + end + end + end +end \ No newline at end of file diff --git a/lib/detest/workers/cucumber_10_x/event_bus.rb b/lib/detest/workers/cucumber_10_x/event_bus.rb new file mode 100644 index 0000000..3c522fd --- /dev/null +++ b/lib/detest/workers/cucumber_10_x/event_bus.rb @@ -0,0 +1,44 @@ +require "cucumber/events" + +module Detest + module Workers + module Cucumber + module EventBus + class TestFileStarted < ::Cucumber::Core::Event.new(:path) + attr_reader :path + end + + class TestFileFinished < ::Cucumber::Core::Event.new(:path) + attr_reader :path + end + + def self.make_event_bus + ::Cucumber::Core::EventBus.new(registry) + end + + def self.registry + ::Cucumber::Core::Events.build_registry( + ::Cucumber::Events::GherkinSourceParsed, + ::Cucumber::Events::GherkinSourceRead, + ::Cucumber::Events::HookTestStepCreated, + ::Cucumber::Events::StepActivated, + ::Cucumber::Events::StepDefinitionRegistered, + ::Cucumber::Events::TestCaseCreated, + ::Cucumber::Events::TestCaseFinished, + ::Cucumber::Events::TestCaseStarted, + ::Cucumber::Events::TestCaseReady, + ::Cucumber::Events::TestRunFinished, + ::Cucumber::Events::TestRunStarted, + ::Cucumber::Events::TestStepCreated, + ::Cucumber::Events::TestStepFinished, + ::Cucumber::Events::TestStepStarted, + ::Cucumber::Events::Envelope, + ::Cucumber::Events::UndefinedParameterType, + TestFileStarted, + TestFileFinished + ) + end + end + end + end +end \ No newline at end of file diff --git a/lib/detest/workers/cucumber_10_x/runtime.rb b/lib/detest/workers/cucumber_10_x/runtime.rb new file mode 100644 index 0000000..bba22fd --- /dev/null +++ b/lib/detest/workers/cucumber_10_x/runtime.rb @@ -0,0 +1,89 @@ +require "cucumber/runtime" + +module Detest + module Workers + module Cucumber + class Runtime < ::Cucumber::Runtime + def test_file_started(event) + @test_start_time = Time.now + @current_test_file = event.path + @passing = true + end + + def test_case_finished(event) + @passing = false if event.result.failed? + end + + def test_file_finished(event) + test_end_time = Time.now + unless @passing + @adapter.log_failure(@current_test_file) + end + time_elapsed = test_end_time - @test_start_time + @adapter.log_result( + @current_test_file, + @passing, + { + duration: time_elapsed + } + ) + @test_start_time = nil + @current_test_file = nil + end + + def run!(adapter) + @adapter = adapter + + load_step_definitions + fire_install_plugin_hook + fire_before_all_hook unless dry_run? + # TODO: can we remove this state? + self.visitor = report + + receiver = ::Cucumber::Core::Test::Runner.new(@configuration.event_bus) + + @configuration.event_bus.on(:test_file_started) do |event| + self.test_file_started(event) + end + + @configuration.event_bus.on(:test_file_finished) do |event| + self.test_file_finished(event) + end + + @configuration.event_bus.on(:test_case_finished) do |event| + self.test_case_finished(event) + end + + adapter.record_worker + if ENV["DETEST_RERUN"] == "true" + while f_file = adapter.fpop + @configuration.notify :test_file_started, f_file + fs = process_feature_file(f_file) + compile fs, receiver, filters, @configuration.event_bus + @configuration.notify :test_file_finished, f_file + end + else + while f_file = adapter.pop + @configuration.notify :test_file_started, f_file + fs = process_feature_file(f_file) + compile fs, receiver, filters, @configuration.event_bus + @configuration.notify :test_file_finished, f_file + end + end + @configuration.notify :test_run_finished + adapter.end_worker + end + + def process_feature_file(file) + f_filespecs = ::Cucumber::FileSpecs.new([file]) + f_files = f_filespecs.files + f_files.map do |path| + source = NormalisedEncodingFile.read(path) + @configuration.notify :gherkin_source_read, path, source + ::Cucumber::Core::Gherkin::Document.new(path, source) + end + end + end + end + end +end \ No newline at end of file