From 1de1b0f2f98137b351a7580e07aee2f0266a959e Mon Sep 17 00:00:00 2001 From: Nick Gauthier Date: Wed, 31 Mar 2010 11:05:42 -0400 Subject: [PATCH] fixed cucumber feature loading to support more than one feature file per runner --- hydra.gemspec | 3 +- lib/hydra/cucumber/formatter.rb | 3 +- lib/hydra/runner.rb | 73 ++++++++++--------- test/fixtures/features/step_definitions.rb | 4 + .../features/write_alternate_file.feature | 7 ++ test/runner_test.rb | 26 +++++-- test/test_helper.rb | 8 ++ 7 files changed, 79 insertions(+), 45 deletions(-) create mode 100644 test/fixtures/features/write_alternate_file.feature diff --git a/hydra.gemspec b/hydra.gemspec index 6c2f177..8827fb0 100644 --- a/hydra.gemspec +++ b/hydra.gemspec @@ -9,7 +9,7 @@ Gem::Specification.new do |s| s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Nick Gauthier"] - s.date = %q{2010-03-30} + s.date = %q{2010-03-31} s.description = %q{Spread your tests over multiple machines to test your code faster.} s.email = %q{nick@smartlogicsolutions.com} s.extra_rdoc_files = [ @@ -54,6 +54,7 @@ Gem::Specification.new do |s| "test/fixtures/assert_true.rb", "test/fixtures/config.yml", "test/fixtures/features/step_definitions.rb", + "test/fixtures/features/write_alternate_file.feature", "test/fixtures/features/write_file.feature", "test/fixtures/hello_world.rb", "test/fixtures/slow.rb", diff --git a/lib/hydra/cucumber/formatter.rb b/lib/hydra/cucumber/formatter.rb index 274be93..6812f0f 100644 --- a/lib/hydra/cucumber/formatter.rb +++ b/lib/hydra/cucumber/formatter.rb @@ -1,5 +1,4 @@ -require 'cucumber/formatter/console' -require 'cucumber/formatter/io' +require 'cucumber/formatter/progress' module Cucumber #:nodoc: module Formatter #:nodoc: diff --git a/lib/hydra/runner.rb b/lib/hydra/runner.rb index 200bdc1..f7d69b2 100644 --- a/lib/hydra/runner.rb +++ b/lib/hydra/runner.rb @@ -44,6 +44,7 @@ module Hydra #:nodoc: output = "." if output == "" @io.write Results.new(:output => output, :file => file) + return output end # Stop running @@ -114,48 +115,38 @@ module Hydra #:nodoc: # run all the scenarios in a cucumber feature file def run_cucumber_file(file) - require 'cucumber' - require 'cucumber/formatter/progress' - require 'hydra/cucumber/formatter' - def tag_excess(features, limits) - limits.map do |tag_name, tag_limit| - tag_locations = features.tag_locations(tag_name) - if tag_limit && (tag_locations.length > tag_limit) - [tag_name, tag_limit, tag_locations] - else - nil - end - end.compact - end files = [file] dev_null = StringIO.new - - options = Cucumber::Cli::Options.new - configuration = Cucumber::Cli::Configuration.new(dev_null, dev_null) - configuration.parse!([]+files) - step_mother = Cucumber::StepMother.new - - step_mother.options = configuration.options - step_mother.log = configuration.log - step_mother.load_code_files(configuration.support_to_load) - step_mother.after_configuration(configuration) - features = step_mother.load_plain_text_features(files) - step_mother.load_code_files(configuration.step_defs_to_load) - - tag_excess = tag_excess(features, configuration.options[:tag_expression].limits) - configuration.options[:tag_excess] = tag_excess - hydra_response = StringIO.new - formatter = Cucumber::Formatter::Hydra.new( - step_mother, hydra_response, configuration.options + + unless @step_mother + require 'cucumber' + require 'hydra/cucumber/formatter' + @step_mother = Cucumber::StepMother.new + @cuke_configuration = Cucumber::Cli::Configuration.new(dev_null, dev_null) + @cuke_configuration.parse!(['features']+files) + + @step_mother.options = @cuke_configuration.options + @step_mother.log = @cuke_configuration.log + @step_mother.load_code_files(@cuke_configuration.support_to_load) + @step_mother.after_configuration(@cuke_configuration) + @step_mother.load_code_files(@cuke_configuration.step_defs_to_load) + end + cuke_formatter = Cucumber::Formatter::Hydra.new( + @step_mother, hydra_response, @cuke_configuration.options ) - runner = Cucumber::Ast::TreeWalker.new( - step_mother, [formatter], configuration.options, dev_null + cuke_runner ||= Cucumber::Ast::TreeWalker.new( + @step_mother, [cuke_formatter], @cuke_configuration.options, dev_null ) - step_mother.visitor = runner - runner.visit_features(features) + @step_mother.visitor = cuke_runner + + features = @step_mother.load_plain_text_features(files) + tag_excess = tag_excess(features, @cuke_configuration.options[:tag_expression].limits) + @cuke_configuration.options[:tag_excess] = tag_excess + + cuke_runner.visit_features(features) hydra_response.rewind return hydra_response.read @@ -184,5 +175,17 @@ module Hydra #:nodoc: end return klasses.select{|k| k.respond_to? 'suite'} end + + # Yanked a method from Cucumber + def tag_excess(features, limits) + limits.map do |tag_name, tag_limit| + tag_locations = features.tag_locations(tag_name) + if tag_limit && (tag_locations.length > tag_limit) + [tag_name, tag_limit, tag_locations] + else + nil + end + end.compact + end end end diff --git a/test/fixtures/features/step_definitions.rb b/test/fixtures/features/step_definitions.rb index d6cbfc3..08f6487 100644 --- a/test/fixtures/features/step_definitions.rb +++ b/test/fixtures/features/step_definitions.rb @@ -2,6 +2,10 @@ Given /^a target file$/ do @target_file = File.expand_path(File.join(Dir.tmpdir, 'hydra_test.txt')) end +Given /^an alternate target file$/ do + @target_file = File.expand_path(File.join(Dir.tmpdir, 'alternate_hydra_test.txt')) +end + When /^I write "([^\"]*)" to the file$/ do |text| f = File.new(@target_file, 'w') f.write text diff --git a/test/fixtures/features/write_alternate_file.feature b/test/fixtures/features/write_alternate_file.feature new file mode 100644 index 0000000..623f742 --- /dev/null +++ b/test/fixtures/features/write_alternate_file.feature @@ -0,0 +1,7 @@ +Feature: Write a file + + Scenario: Write to hydra_test.txt + Given an alternate target file + When I write "HYDRA" to the file + Then "HYDRA" should be written in the file + diff --git a/test/runner_test.rb b/test/runner_test.rb index df378ea..77333d8 100644 --- a/test/runner_test.rb +++ b/test/runner_test.rb @@ -5,10 +5,12 @@ class RunnerTest < Test::Unit::TestCase setup do sleep(0.2) FileUtils.rm_f(target_file) + FileUtils.rm_f(alternate_target_file) end teardown do FileUtils.rm_f(target_file) + FileUtils.rm_f(alternate_target_file) end @@ -35,13 +37,22 @@ class RunnerTest < Test::Unit::TestCase Process.wait(child) end - should "run a cucumber test" do - pipe = Hydra::Pipe.new - parent = Process.fork do - request_a_file_and_verify_completion(pipe, cucumber_feature_file) - end - run_the_runner(pipe) - Process.wait(parent) + should "run two cucumber tests" do + puts "THE FOLLOWING WARNINGS CAN BE IGNORED" + puts "It is caused by Cucumber loading all rb files near its features" + + runner = Hydra::Runner.new(:io => File.new('/dev/null', 'w')) + runner.run_file(cucumber_feature_file) + assert File.exists?(target_file) + assert_equal "HYDRA", File.read(target_file) + + FileUtils.rm_f(target_file) + + runner.run_file(alternate_cucumber_feature_file) + assert File.exists?(alternate_target_file) + assert_equal "HYDRA", File.read(alternate_target_file) + + puts "END IGNORABLE OUTPUT" end should "be able to run a runner over ssh" do @@ -80,6 +91,7 @@ class RunnerTest < Test::Unit::TestCase # grab its response. This makes us wait for it to finish response = pipe.gets + puts response.output # tell it to shut down pipe.write(Hydra::Messages::Worker::Shutdown.new) diff --git a/test/test_helper.rb b/test/test_helper.rb index 6d4e585..bbae8cb 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -14,6 +14,10 @@ class Test::Unit::TestCase def target_file File.expand_path(File.join(Dir.tmpdir, 'hydra_test.txt')) end + + def alternate_target_file + File.expand_path(File.join(Dir.tmpdir, 'alternate_hydra_test.txt')) + end def test_file File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', 'write_file.rb')) @@ -22,6 +26,10 @@ class Test::Unit::TestCase def cucumber_feature_file File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', 'features', 'write_file.feature')) end + + def alternate_cucumber_feature_file + File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', 'features', 'write_alternate_file.feature')) + end end module Hydra #:nodoc: