diff --git a/CHANGELOG.md b/CHANGELOG.md index e8c4cb5212..449b9636bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,16 @@ Please visit [cucumber/CONTRIBUTING.md](https://github.com/cucumber/cucumber/blo ## [In Git](https://github.com/cucumber/cucumber-ruby/compare/v4.0.0.rc.1...master) (Not released) ### Added +* There is a new methodology in Cucumber for how the auto-loader works + * The old `load` behaviour is now replaced with a newer `require` behaviour + * Cucumber will (From version 4), now auto-load files using the `require` method + * If you wish to alter this, then you can set a top level config option: `Cucumber.use_legacy_autoloader` + * Like most config options, setting this inside a `spec_helper.rb` or `env.rb` file is advised + * For more information on this change, including why it was made. Please read this + [Blog Post](www.google.com) + ([#1349](https://github.com/cucumber/cucumber-ruby/pull/1349), + [#1043](https://github.com/cucumber/cucumber-ruby/issues/1043) + [luke-hill](https://github.com/luke-hill)) ### Changed * Going forward the minimum ruby version for all cucumber based gems is 2.3 diff --git a/features/lib/support/env.rb b/features/lib/support/env.rb index 7743638a12..7b3ea23ada 100644 --- a/features/lib/support/env.rb +++ b/features/lib/support/env.rb @@ -19,3 +19,7 @@ # Set a longer timeout for aruba, and a really long one if running on JRuby @aruba_timeout_seconds = Cucumber::JRUBY ? 60 : 15 end + +# TODO: This probably shouldn't be used. To fix this we need to triage all of the +# file names created in tests, and ensure they are unique +Cucumber.use_legacy_autoloader = true diff --git a/lib/cucumber.rb b/lib/cucumber.rb index 0297746bdf..67d36a1d73 100644 --- a/lib/cucumber.rb +++ b/lib/cucumber.rb @@ -10,7 +10,7 @@ module Cucumber class << self - attr_accessor :wants_to_quit + attr_accessor :wants_to_quit, :use_legacy_autoloader def logger return @log if @log diff --git a/lib/cucumber/glue/registry_and_more.rb b/lib/cucumber/glue/registry_and_more.rb index b2a18d844f..80e96df164 100644 --- a/lib/cucumber/glue/registry_and_more.rb +++ b/lib/cucumber/glue/registry_and_more.rb @@ -102,7 +102,14 @@ def build_rb_world_factory(world_modules, namespaced_world_modules, proc) def load_code_file(code_file) return unless File.extname(code_file) == '.rb' - load File.expand_path(code_file) # This will cause self.add_step_definition, self.add_hook, and self.define_parameter_type to be called from Glue::Dsl + + # This will cause self.add_step_definition, self.add_hook, and self.define_parameter_type to be called from Glue::Dsl + + if Cucumber.use_legacy_autoloader + load File.expand_path(code_file) + else + require File.expand_path(code_file) + end end def begin_scenario(test_case) diff --git a/spec/cucumber/glue/registry_and_more_spec.rb b/spec/cucumber/glue/registry_and_more_spec.rb index 32a615fffe..fe516c2603 100644 --- a/spec/cucumber/glue/registry_and_more_spec.rb +++ b/spec/cucumber/glue/registry_and_more_spec.rb @@ -18,7 +18,9 @@ module Glue # rubocop:disable Style/GlobalVars describe '#load_code_file' do - after do + before(:each) { $foo = nil } + + after(:each) do FileUtils.rm_rf('tmp.rb') FileUtils.rm_rf('docs.md') end @@ -29,30 +31,107 @@ def a_file_called(name) end end - it 're-loads the file when called multiple times' do - a_file_called('tmp.rb') do - '$foo = 1' + context 'by default' do + after(:each) do + FileUtils.rm_rf('tmp1.rb') end - registry.load_code_file('tmp.rb') - expect($foo).to eq 1 + it 'does not re-load the file when called multiple times' do + a_file_called('tmp1.rb') do + '$foo = 1' + end + + registry.load_code_file('tmp1.rb') + expect($foo).to eq 1 - a_file_called('tmp.rb') do - '$foo = 2' + a_file_called('tmp1.rb') do + '$foo = 2' + end + + registry.load_code_file('tmp1.rb') + expect($foo).to eq 1 end - registry.load_code_file('tmp.rb') + it 'only loads ruby files' do + a_file_called('docs.md') do + '$foo = 1' + end - expect($foo).to eq 2 + registry.load_code_file('docs.md') + expect($foo).to be nil + end end - # rubocop:enable Style/GlobalVars - it 'only loads ruby files' do - a_file_called('docs.md') do - 'yo' + context 'With `use_legacy_autoloader` set to true' do + before(:each) do + allow(Cucumber).to receive(:use_legacy_autoloader).and_return(true) + end + + after(:each) do + FileUtils.rm_rf('tmp2.rb') + end + + it 're-loads the file when called multiple times' do + a_file_called('tmp2.rb') do + '$foo = 1' + end + + registry.load_code_file('tmp2.rb') + expect($foo).to eq 1 + + a_file_called('tmp2.rb') do + '$foo = 2' + end + + registry.load_code_file('tmp2.rb') + expect($foo).to eq 2 + end + + it 'only loads ruby files' do + a_file_called('docs.md') do + '$foo = 1' + end + + registry.load_code_file('docs.md') + expect($foo).to be nil end - registry.load_code_file('docs.md') end + + context 'With `use_legacy_autoloader` set to false' do + before(:each) do + allow(Cucumber).to receive(:use_legacy_autoloader).and_return(false) + end + + after(:each) do + FileUtils.rm_rf('tmp3.rb') + end + + it 'does not re-load the file when called multiple times' do + a_file_called('tmp3.rb') do + '$foo = 1' + end + + registry.load_code_file('tmp3.rb') + expect($foo).to eq 1 + + a_file_called('tmp3.rb') do + '$foo = 2' + end + + registry.load_code_file('tmp3.rb') + expect($foo).to eq 1 + end + + it 'only loads ruby files' do + a_file_called('docs.md') do + '$foo = 1' + end + + registry.load_code_file('docs.md') + expect($foo).to be nil + end + end + # rubocop:enable Style/GlobalVars end describe 'Handling the World' do