From 3afdba5e8ecb17d0a1ff4c5cb89539b6bd3e182c Mon Sep 17 00:00:00 2001 From: Luke Hill <20105237+luke-hill@users.noreply.github.com> Date: Wed, 27 Mar 2024 13:41:03 +0000 Subject: [PATCH] Bugfix/fix factorybot ci issue (#583) * Add new constraints for several gemfiles * Update readme * Ensure generated app has lower factory bot * Split helpers into 2 files * Update helper doc * Add changelog --- Appraisals | 21 ++-- CHANGELOG.md | 2 + README.md | 6 +- ...helper.rb => cucumber_rails_gem_helper.rb} | 109 ++++++------------ .../support/cucumber_rails_setup_helper.rb | 52 +++++++++ gemfiles/rails_5_2.gemfile | 3 +- gemfiles/rails_6_0.gemfile | 5 +- gemfiles/rails_6_1.gemfile | 3 +- gemfiles/rails_7_0.gemfile | 4 +- gemfiles/rails_7_1.gemfile | 4 +- 10 files changed, 118 insertions(+), 91 deletions(-) rename features/support/{cucumber_rails_helper.rb => cucumber_rails_gem_helper.rb} (63%) create mode 100644 features/support/cucumber_rails_setup_helper.rb diff --git a/Appraisals b/Appraisals index 1c0773df..c3f7ba57 100644 --- a/Appraisals +++ b/Appraisals @@ -4,9 +4,10 @@ appraise 'rails_5_2' do gem 'activerecord' gem 'capybara', '< 3.33' gem 'cucumber', '< 6' + gem 'factory_bot', '< 6.4' gem 'psych', '< 4' gem 'rails-html-sanitizer', '< 1.4.3' - gem 'railties', '~> 5.2.4' + gem 'railties', '~> 5.2.8' gem 'sqlite3', '~> 1.3.13' end @@ -14,30 +15,32 @@ appraise 'rails_6_0' do gem 'activerecord' gem 'capybara', '< 3.35' gem 'cucumber', '< 6' - gem 'matrix' # Until capybara 3.36+ + gem 'factory_bot', '< 6.4' + gem 'matrix' gem 'psych', '< 4' gem 'rails-html-sanitizer', '< 1.4.3' - gem 'railties', '~> 6.0.3' - gem 'sqlite3', '~> 1.4' + gem 'railties', '~> 6.0.6' + gem 'sqlite3', '< 1.6' end appraise 'rails_6_1' do gem 'activerecord' gem 'capybara', '< 3.38' + gem 'factory_bot', '< 6.4' gem 'psych', '< 4' - gem 'railties', '~> 6.1.3' + gem 'railties', '~> 6.1.7' gem 'sqlite3', '~> 1.4' end appraise 'rails_7_0' do gem 'activerecord' gem 'cucumber', '< 10' - gem 'railties', '~> 7.0.0' - gem 'sqlite3', '~> 1.4' + gem 'railties', '~> 7.0.8' + gem 'sqlite3', '~> 1.7' end appraise 'rails_7_1' do gem 'activerecord' - gem 'railties', '~> 7.1.0' - gem 'sqlite3', '~> 1.4' + gem 'railties', '~> 7.1.3' + gem 'sqlite3', '~> 1.7' end diff --git a/CHANGELOG.md b/CHANGELOG.md index 602f9718..2cfac4c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 This file is intended to be modified using the [`changelog`](github.com/cucumber/changelog) command-line tool. ## [Unreleased] +### Changed +- Internal testing code has been refactored to handle older ruby/rails installs ## [3.0.0] - 2023-11-01 ### Changed diff --git a/README.md b/README.md index 29ad4612..c22576cc 100644 --- a/README.md +++ b/README.md @@ -95,8 +95,8 @@ With all dependencies installed, all specs and features should pass: In order to test against multiple versions of key dependencies, the [Appraisal](https://github.com/thoughtbot/appraisal) gem is used to generate multiple gemfiles, stored in the `gemfiles/` directory. -Normally these will only run on Travis; however, if you want to run the full test suite against -all gemfiles, run the following commands: +Normally these will only run on GitHub via GitHub Actions; however if you want to run the full test +suite against all gemfiles, run the following commands: [bundle exec] appraisal install [bundle exec] appraisal rake test @@ -115,4 +115,4 @@ To support the multiple-gemfile testing, when adding a new dependency the follow For example, rspec is a primary development dependency, so it lives in the gemspec. -[the helper method]: https://github.com/cucumber/cucumber-rails/blob/main/features/support/cucumber_rails_helper.rb#L19 +[the helper method]: ./features/support/cucumber_rails_gem_helper.rb diff --git a/features/support/cucumber_rails_helper.rb b/features/support/cucumber_rails_gem_helper.rb similarity index 63% rename from features/support/cucumber_rails_helper.rb rename to features/support/cucumber_rails_gem_helper.rb index dcb64f7d..f5d9e469 100644 --- a/features/support/cucumber_rails_helper.rb +++ b/features/support/cucumber_rails_gem_helper.rb @@ -4,19 +4,9 @@ require 'cucumber' require 'capybara' -module CucumberRailsHelper - def rails_new(options = {}) - # This expectation allows us to wait until the command line monitor has output a README file (i.e. the command has completed) - expect(run_rails_new_command(options)).to have_output(/README/) - - cd 'test_app' - configure_rails_gems - configure_rails_requires - configure_rails_layout - clear_bundle_env_vars - end - +module CucumberRailsGemHelper def install_cucumber_rails(*options) + configure_rails_gems add_cucumber_rails(options) add_rails_conditional_gems add_remaining_gems(options) @@ -26,68 +16,11 @@ def install_cucumber_rails(*options) private - def run_rails_new_command(options) - flags = %w[--skip-action-cable --skip-action-mailer --skip-active-job --skip-bootsnap --skip-bundle --skip-javascript - --skip-jbuilder --skip-listen --skip-spring --skip-sprockets --skip-test-unit --skip-turbolinks --skip-active-storage] - flags += %w[--skip-action-mailbox --skip-action-text] if rails_equal_or_higher_than?('6.0') - run_command "bundle exec rails new test_app #{flags.join(' ')} #{options[:args]}" - end - def configure_rails_gems %w[bootsnap byebug jbuilder listen rails sass-rails turbolinks webpacker].each { |gem| remove_gem(gem) } %w[railties activerecord actionpack].each { |rails_gem| add_gem(rails_gem, Rails.version) } end - def configure_rails_requires - content = File.read(expand_path('config/application.rb')) - %w[active_job/railtie active_storage/engine action_mailer/railtie action_mailbox/engine - action_text/engine action_cable/engine rails/test_unit/railtie sprockets/railtie].each do |require| - content = content.gsub(/^.*require ["']#{require}["']\s*$/, '') - end - overwrite_file('config/application.rb', content) - end - - def configure_rails_layout - file = 'app/views/layouts/application.html.erb' - content = File.read(expand_path(file)).gsub(/^\s*<%= stylesheet_link_tag .*%>\s*$/, '') - overwrite_file(file, content) - end - - def clear_bundle_env_vars - unset_bundler_env_vars - delete_environment_variable 'BUNDLE_GEMFILE' - end - - def rails_equal_or_higher_than?(version) - Rails.gem_version >= Gem::Version.new(version) - end - - def remove_gem(name) - content = File.read(expand_path('Gemfile')).gsub(/^\s*gem ["']#{name}["'].*$/, '') - overwrite_file('Gemfile', content) - end - - def add_gem(name, *args) - line = convert_gem_opts_to_string(name, *args) - gem_regexp = /gem ["']#{name}["'].*$/ - gemfile_content = File.read(expand_path('Gemfile')) - - if gemfile_content.match?(gem_regexp) - updated_gemfile_content = gemfile_content.gsub(gem_regexp, line) - overwrite_file('Gemfile', updated_gemfile_content) - else - append_to_file('Gemfile', line) - end - end - - def convert_gem_opts_to_string(name, *args) - options = args.last.is_a?(Hash) ? args.pop : {} - parts = ["'#{name}'"] - parts << args.map(&:inspect) if args.any? - parts << options.inspect[1..-2] if options.any? - "gem #{parts.flatten.join(', ')}\n" - end - def add_cucumber_rails(options) if options.include?(:not_in_test_group) add_gem 'cucumber-rails', path: File.expand_path('.').to_s @@ -114,7 +47,11 @@ def add_remaining_gems(options) add_gem 'capybara', Capybara::VERSION, group: :test add_gem 'database_cleaner', '>= 2.0.0', group: :test unless options.include?(:no_database_cleaner) add_gem 'database_cleaner-active_record', '>= 2.0.0', group: :test if options.include?(:database_cleaner_active_record) - add_gem 'factory_bot', '>= 5.0', group: :test unless options.include?(:no_factory_bot) + if rails_equal_or_higher_than?('6.0') + add_gem 'factory_bot', '>= 6.4', group: :test unless options.include?(:no_factory_bot) + else + add_gem 'factory_bot', '< 6.4', group: :test unless options.include?(:no_factory_bot) + end add_gem 'rspec-expectations', '~> 3.12', group: :test end @@ -123,6 +60,36 @@ def bundle_install run_command_and_stop "bundle config set --local path '#{ENV.fetch('GITHUB_WORKSPACE')}/vendor/bundle'" if ENV.key?('GITHUB_WORKSPACE') run_command_and_stop 'bundle install --jobs 4' end + + def convert_gem_opts_to_string(name, *args) + options = args.last.is_a?(Hash) ? args.pop : {} + parts = ["'#{name}'"] + parts << args.map(&:inspect) if args.any? + parts << options.inspect[1..-2] if options.any? + "gem #{parts.flatten.join(', ')}\n" + end + + def remove_gem(name) + content = File.read(expand_path('Gemfile')).gsub(/^\s*gem ["']#{name}["'].*$/, '') + overwrite_file('Gemfile', content) + end + + def add_gem(name, *args) + line = convert_gem_opts_to_string(name, *args) + gem_regexp = /gem ["']#{name}["'].*$/ + gemfile_content = File.read(expand_path('Gemfile')) + + if gemfile_content.match?(gem_regexp) + updated_gemfile_content = gemfile_content.gsub(gem_regexp, line) + overwrite_file('Gemfile', updated_gemfile_content) + else + append_to_file('Gemfile', line) + end + end + + def rails_equal_or_higher_than?(version) + Rails.gem_version >= Gem::Version.new(version) + end end -World(CucumberRailsHelper) +World(CucumberRailsGemHelper) diff --git a/features/support/cucumber_rails_setup_helper.rb b/features/support/cucumber_rails_setup_helper.rb new file mode 100644 index 00000000..89357708 --- /dev/null +++ b/features/support/cucumber_rails_setup_helper.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +require 'rails' +require 'cucumber' +require 'capybara' + +module CucumberRailsSetupHelper + def rails_new(options = {}) + # This expectation allows us to wait until the command line monitor has output a README file (i.e. the command has completed) + expect(run_rails_new_command(options)).to have_output(/README/) + + cd 'test_app' + configure_rails_requires + configure_rails_layout + clear_bundle_env_vars + end + + private + + def run_rails_new_command(options) + flags = %w[--skip-action-cable --skip-action-mailer --skip-active-job --skip-bootsnap --skip-bundle --skip-javascript + --skip-jbuilder --skip-listen --skip-spring --skip-sprockets --skip-test-unit --skip-turbolinks --skip-active-storage] + flags += %w[--skip-action-mailbox --skip-action-text] if rails_equal_or_higher_than?('6.0') + run_command "bundle exec rails new test_app #{flags.join(' ')} #{options[:args]}" + end + + def configure_rails_requires + content = File.read(expand_path('config/application.rb')) + %w[active_job/railtie active_storage/engine action_mailer/railtie action_mailbox/engine + action_text/engine action_cable/engine rails/test_unit/railtie sprockets/railtie].each do |require| + content = content.gsub(/^.*require ["']#{require}["']\s*$/, '') + end + overwrite_file('config/application.rb', content) + end + + def configure_rails_layout + file = 'app/views/layouts/application.html.erb' + content = File.read(expand_path(file)).gsub(/^\s*<%= stylesheet_link_tag .*%>\s*$/, '') + overwrite_file(file, content) + end + + def clear_bundle_env_vars + unset_bundler_env_vars + delete_environment_variable 'BUNDLE_GEMFILE' + end + + def rails_equal_or_higher_than?(version) + Rails.gem_version >= Gem::Version.new(version) + end +end + +World(CucumberRailsSetupHelper) diff --git a/gemfiles/rails_5_2.gemfile b/gemfiles/rails_5_2.gemfile index 3efc3945..2c2df730 100644 --- a/gemfiles/rails_5_2.gemfile +++ b/gemfiles/rails_5_2.gemfile @@ -5,9 +5,10 @@ source "https://rubygems.org" gem "activerecord" gem "capybara", "< 3.33" gem "cucumber", "< 6" +gem "factory_bot", "< 6.4" gem "psych", "< 4" gem "rails-html-sanitizer", "< 1.4.3" -gem "railties", "~> 5.2.4" +gem "railties", "~> 5.2.8" gem "sqlite3", "~> 1.3.13" gemspec path: "../" diff --git a/gemfiles/rails_6_0.gemfile b/gemfiles/rails_6_0.gemfile index 25ee6c3f..e2018574 100644 --- a/gemfiles/rails_6_0.gemfile +++ b/gemfiles/rails_6_0.gemfile @@ -5,10 +5,11 @@ source "https://rubygems.org" gem "activerecord" gem "capybara", "< 3.35" gem "cucumber", "< 6" +gem "factory_bot", "< 6.4" gem "matrix" gem "psych", "< 4" gem "rails-html-sanitizer", "< 1.4.3" -gem "railties", "~> 6.0.3" -gem "sqlite3", "~> 1.4" +gem "railties", "~> 6.0.6" +gem "sqlite3", "< 1.6" gemspec path: "../" diff --git a/gemfiles/rails_6_1.gemfile b/gemfiles/rails_6_1.gemfile index 2f5a0b11..a8a89c52 100644 --- a/gemfiles/rails_6_1.gemfile +++ b/gemfiles/rails_6_1.gemfile @@ -4,8 +4,9 @@ source "https://rubygems.org" gem "activerecord" gem "capybara", "< 3.38" +gem "factory_bot", "< 6.4" gem "psych", "< 4" -gem "railties", "~> 6.1.3" +gem "railties", "~> 6.1.7" gem "sqlite3", "~> 1.4" gemspec path: "../" diff --git a/gemfiles/rails_7_0.gemfile b/gemfiles/rails_7_0.gemfile index a2328f80..b92b07dc 100644 --- a/gemfiles/rails_7_0.gemfile +++ b/gemfiles/rails_7_0.gemfile @@ -4,7 +4,7 @@ source "https://rubygems.org" gem "activerecord" gem "cucumber", "< 10" -gem "railties", "~> 7.0.0" -gem "sqlite3", "~> 1.4" +gem "railties", "~> 7.0.8" +gem "sqlite3", "~> 1.7" gemspec path: "../" diff --git a/gemfiles/rails_7_1.gemfile b/gemfiles/rails_7_1.gemfile index a484a611..f0dd90ce 100644 --- a/gemfiles/rails_7_1.gemfile +++ b/gemfiles/rails_7_1.gemfile @@ -3,7 +3,7 @@ source "https://rubygems.org" gem "activerecord" -gem "railties", "~> 7.1.0" -gem "sqlite3", "~> 1.4" +gem "railties", "~> 7.1.3" +gem "sqlite3", "~> 1.7" gemspec path: "../"