From 6373da1ebdd14f33675cb5b6e89ad6a4ef05627d Mon Sep 17 00:00:00 2001 From: Matheus Sales Date: Fri, 6 Oct 2023 11:54:32 -0300 Subject: [PATCH 1/9] Add Rails 7.1 to appraisals --- Appraisals | 28 +++ gemfiles/rails_7_1.gemfile | 38 ++++ gemfiles/rails_7_1.gemfile.lock | 362 ++++++++++++++++++++++++++++++++ 3 files changed, 428 insertions(+) create mode 100644 gemfiles/rails_7_1.gemfile create mode 100644 gemfiles/rails_7_1.gemfile.lock diff --git a/Appraisals b/Appraisals index bab3a9ed9..f24fbf8e5 100644 --- a/Appraisals +++ b/Appraisals @@ -68,3 +68,31 @@ appraise 'rails_7_0' do gem 'sqlite3', '~> 1.4' gem 'pg', '~> 1.1' end + +appraise 'rails_7_1' do + instance_eval(&shared_spring_dependencies) + instance_eval(&controller_test_dependency) + + gem 'rails', '7.1.0' + gem 'sprockets-rails' + gem 'puma', '~> 6.0' + gem 'importmap-rails' + gem 'turbo-rails' + gem 'stimulus-rails' + gem 'jbuilder' + gem 'bootsnap', require: false + gem 'capybara' + gem 'selenium-webdriver' + gem 'webdrivers' + + # test dependencies + gem 'rspec-rails', '~> 6.0' + gem 'shoulda-context', '~> 2.0.0' + + # other dependencies + gem 'bcrypt', '~> 3.1.7' + + # Database adapters + gem 'sqlite3', '~> 1.4' + gem 'pg', '~> 1.1' +end diff --git a/gemfiles/rails_7_1.gemfile b/gemfiles/rails_7_1.gemfile new file mode 100644 index 000000000..0a21a31f9 --- /dev/null +++ b/gemfiles/rails_7_1.gemfile @@ -0,0 +1,38 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "appraisal", "2.4.0" +gem "bundler", "~> 2.0" +gem "pry" +gem "pry-byebug" +gem "rake", "13.0.1" +gem "rspec", "~> 3.9" +gem "rubocop", require: false +gem "rubocop-packaging", require: false +gem "rubocop-rails", require: false +gem "warnings_logger" +gem "zeus", require: false +gem "fssm" +gem "redcarpet" +gem "rouge" +gem "yard" +gem "spring" +gem "spring-watcher-listen", "~> 2.0.0" +gem "rails-controller-testing", ">= 1.0.1" +gem "rails", "7.1.0" +gem "sprockets-rails" +gem "puma", "~> 6.0" +gem "importmap-rails" +gem "turbo-rails" +gem "stimulus-rails" +gem "jbuilder" +gem "bootsnap", require: false +gem "capybara" +gem "selenium-webdriver" +gem "webdrivers" +gem "rspec-rails", "~> 6.0" +gem "shoulda-context", "~> 2.0.0" +gem "bcrypt", "~> 3.1.7" +gem "sqlite3", "~> 1.4" +gem "pg", "~> 1.1" diff --git a/gemfiles/rails_7_1.gemfile.lock b/gemfiles/rails_7_1.gemfile.lock new file mode 100644 index 000000000..7cbc7e9f7 --- /dev/null +++ b/gemfiles/rails_7_1.gemfile.lock @@ -0,0 +1,362 @@ +GEM + remote: https://rubygems.org/ + specs: + actioncable (7.1.0) + actionpack (= 7.1.0) + activesupport (= 7.1.0) + nio4r (~> 2.0) + websocket-driver (>= 0.6.1) + zeitwerk (~> 2.6) + actionmailbox (7.1.0) + actionpack (= 7.1.0) + activejob (= 7.1.0) + activerecord (= 7.1.0) + activestorage (= 7.1.0) + activesupport (= 7.1.0) + mail (>= 2.7.1) + net-imap + net-pop + net-smtp + actionmailer (7.1.0) + actionpack (= 7.1.0) + actionview (= 7.1.0) + activejob (= 7.1.0) + activesupport (= 7.1.0) + mail (~> 2.5, >= 2.5.4) + net-imap + net-pop + net-smtp + rails-dom-testing (~> 2.2) + actionpack (7.1.0) + actionview (= 7.1.0) + activesupport (= 7.1.0) + nokogiri (>= 1.8.5) + rack (>= 2.2.4) + rack-session (>= 1.0.1) + rack-test (>= 0.6.3) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + actiontext (7.1.0) + actionpack (= 7.1.0) + activerecord (= 7.1.0) + activestorage (= 7.1.0) + activesupport (= 7.1.0) + globalid (>= 0.6.0) + nokogiri (>= 1.8.5) + actionview (7.1.0) + activesupport (= 7.1.0) + builder (~> 3.1) + erubi (~> 1.11) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + activejob (7.1.0) + activesupport (= 7.1.0) + globalid (>= 0.3.6) + activemodel (7.1.0) + activesupport (= 7.1.0) + activerecord (7.1.0) + activemodel (= 7.1.0) + activesupport (= 7.1.0) + timeout (>= 0.4.0) + activestorage (7.1.0) + actionpack (= 7.1.0) + activejob (= 7.1.0) + activerecord (= 7.1.0) + activesupport (= 7.1.0) + marcel (~> 1.0) + activesupport (7.1.0) + base64 + bigdecimal + concurrent-ruby (~> 1.0, >= 1.0.2) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + minitest (>= 5.1) + mutex_m + tzinfo (~> 2.0) + addressable (2.8.5) + public_suffix (>= 2.0.2, < 6.0) + appraisal (2.4.0) + bundler + rake + thor (>= 0.14.0) + ast (2.4.2) + base64 (0.1.1) + bcrypt (3.1.19) + bigdecimal (3.1.4) + bootsnap (1.16.0) + msgpack (~> 1.2) + builder (3.2.4) + byebug (11.1.3) + capybara (3.39.2) + addressable + matrix + mini_mime (>= 0.1.3) + nokogiri (~> 1.8) + rack (>= 1.6.0) + rack-test (>= 0.6.3) + regexp_parser (>= 1.5, < 3.0) + xpath (~> 3.2) + coderay (1.1.3) + concurrent-ruby (1.2.2) + connection_pool (2.4.1) + crass (1.0.6) + date (3.3.3) + diff-lcs (1.5.0) + drb (2.1.1) + ruby2_keywords + erubi (1.12.0) + ffi (1.16.3) + fssm (0.2.10) + globalid (1.2.1) + activesupport (>= 6.1) + i18n (1.14.1) + concurrent-ruby (~> 1.0) + importmap-rails (1.2.1) + actionpack (>= 6.0.0) + railties (>= 6.0.0) + io-console (0.6.0) + irb (1.8.1) + rdoc + reline (>= 0.3.8) + jbuilder (2.11.5) + actionview (>= 5.0.0) + activesupport (>= 5.0.0) + json (2.6.3) + language_server-protocol (3.17.0.3) + listen (3.8.0) + rb-fsevent (~> 0.10, >= 0.10.3) + rb-inotify (~> 0.9, >= 0.9.10) + loofah (2.21.3) + crass (~> 1.0.2) + nokogiri (>= 1.12.0) + mail (2.8.1) + mini_mime (>= 0.1.1) + net-imap + net-pop + net-smtp + marcel (1.0.2) + matrix (0.4.2) + method_source (1.0.0) + mini_mime (1.1.5) + minitest (5.20.0) + msgpack (1.7.2) + mutex_m (0.1.2) + net-imap (0.4.0) + date + net-protocol + net-pop (0.1.2) + net-protocol + net-protocol (0.2.1) + timeout + net-smtp (0.4.0) + net-protocol + nio4r (2.5.9) + nokogiri (1.15.4-arm64-darwin) + racc (~> 1.4) + nokogiri (1.15.4-x86_64-linux) + racc (~> 1.4) + parallel (1.23.0) + parser (3.2.2.4) + ast (~> 2.4.1) + racc + pg (1.5.4) + pry (0.14.2) + coderay (~> 1.1) + method_source (~> 1.0) + pry-byebug (3.10.1) + byebug (~> 11.0) + pry (>= 0.13, < 0.15) + psych (5.1.0) + stringio + public_suffix (5.0.3) + puma (6.4.0) + nio4r (~> 2.0) + racc (1.7.1) + rack (3.0.8) + rack-session (2.0.0) + rack (>= 3.0.0) + rack-test (2.1.0) + rack (>= 1.3) + rackup (2.1.0) + rack (>= 3) + webrick (~> 1.8) + rails (7.1.0) + actioncable (= 7.1.0) + actionmailbox (= 7.1.0) + actionmailer (= 7.1.0) + actionpack (= 7.1.0) + actiontext (= 7.1.0) + actionview (= 7.1.0) + activejob (= 7.1.0) + activemodel (= 7.1.0) + activerecord (= 7.1.0) + activestorage (= 7.1.0) + activesupport (= 7.1.0) + bundler (>= 1.15.0) + railties (= 7.1.0) + rails-controller-testing (1.0.5) + actionpack (>= 5.0.1.rc1) + actionview (>= 5.0.1.rc1) + activesupport (>= 5.0.1.rc1) + rails-dom-testing (2.2.0) + activesupport (>= 5.0.0) + minitest + nokogiri (>= 1.6) + rails-html-sanitizer (1.6.0) + loofah (~> 2.21) + nokogiri (~> 1.14) + railties (7.1.0) + actionpack (= 7.1.0) + activesupport (= 7.1.0) + irb + rackup (>= 1.0.0) + rake (>= 12.2) + thor (~> 1.0, >= 1.2.2) + zeitwerk (~> 2.6) + rainbow (3.1.1) + rake (13.0.1) + rb-fsevent (0.11.2) + rb-inotify (0.10.1) + ffi (~> 1.0) + rdoc (6.5.0) + psych (>= 4.0.0) + redcarpet (3.6.0) + regexp_parser (2.8.1) + reline (0.3.9) + io-console (~> 0.5) + rexml (3.2.6) + rouge (4.1.3) + rspec (3.12.0) + rspec-core (~> 3.12.0) + rspec-expectations (~> 3.12.0) + rspec-mocks (~> 3.12.0) + rspec-core (3.12.2) + rspec-support (~> 3.12.0) + rspec-expectations (3.12.3) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.12.0) + rspec-mocks (3.12.6) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.12.0) + rspec-rails (6.0.3) + actionpack (>= 6.1) + activesupport (>= 6.1) + railties (>= 6.1) + rspec-core (~> 3.12) + rspec-expectations (~> 3.12) + rspec-mocks (~> 3.12) + rspec-support (~> 3.12) + rspec-support (3.12.1) + rubocop (1.56.4) + base64 (~> 0.1.1) + json (~> 2.3) + language_server-protocol (>= 3.17.0) + parallel (~> 1.10) + parser (>= 3.2.2.3) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) + rexml (>= 3.2.5, < 4.0) + rubocop-ast (>= 1.28.1, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 3.0) + rubocop-ast (1.29.0) + parser (>= 3.2.1.0) + rubocop-packaging (0.5.2) + rubocop (>= 1.33, < 2.0) + rubocop-rails (2.21.2) + activesupport (>= 4.2.0) + rack (>= 1.1) + rubocop (>= 1.33.0, < 2.0) + ruby-progressbar (1.13.0) + ruby2_keywords (0.0.5) + rubyzip (2.3.2) + selenium-webdriver (4.10.0) + rexml (~> 3.2, >= 3.2.5) + rubyzip (>= 1.2.2, < 3.0) + websocket (~> 1.0) + shoulda-context (2.0.0) + spring (2.1.1) + spring-watcher-listen (2.0.1) + listen (>= 2.7, < 4.0) + spring (>= 1.2, < 3.0) + sprockets (4.2.1) + concurrent-ruby (~> 1.0) + rack (>= 2.2.4, < 4) + sprockets-rails (3.4.2) + actionpack (>= 5.2) + activesupport (>= 5.2) + sprockets (>= 3.0.0) + sqlite3 (1.6.6-arm64-darwin) + sqlite3 (1.6.6-x86_64-linux) + stimulus-rails (1.2.2) + railties (>= 6.0.0) + stringio (3.0.8) + thor (1.2.2) + timeout (0.4.0) + turbo-rails (1.4.0) + actionpack (>= 6.0.0) + activejob (>= 6.0.0) + railties (>= 6.0.0) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + unicode-display_width (2.5.0) + warnings_logger (0.1.1) + webdrivers (5.3.1) + nokogiri (~> 1.6) + rubyzip (>= 1.3.0) + selenium-webdriver (~> 4.0, < 4.11) + webrick (1.8.1) + websocket (1.2.10) + websocket-driver (0.7.6) + websocket-extensions (>= 0.1.0) + websocket-extensions (0.1.5) + xpath (3.2.0) + nokogiri (~> 1.8) + yard (0.9.34) + zeitwerk (2.6.12) + zeus (0.15.14) + method_source (>= 0.6.7) + +PLATFORMS + arm64-darwin-22 + x86_64-linux + +DEPENDENCIES + appraisal (= 2.4.0) + bcrypt (~> 3.1.7) + bootsnap + bundler (~> 2.0) + capybara + fssm + importmap-rails + jbuilder + pg (~> 1.1) + pry + pry-byebug + puma (~> 6.0) + rails (= 7.1.0) + rails-controller-testing (>= 1.0.1) + rake (= 13.0.1) + redcarpet + rouge + rspec (~> 3.9) + rspec-rails (~> 6.0) + rubocop + rubocop-packaging + rubocop-rails + selenium-webdriver + shoulda-context (~> 2.0.0) + spring + spring-watcher-listen (~> 2.0.0) + sprockets-rails + sqlite3 (~> 1.4) + stimulus-rails + turbo-rails + warnings_logger + webdrivers + yard + zeus + +BUNDLED WITH + 2.4.13 From 2be4162eb0622ac88d5e882444e199e1844efcd3 Mon Sep 17 00:00:00 2001 From: Matheus Sales Date: Fri, 6 Oct 2023 12:18:58 -0300 Subject: [PATCH 2/9] fix: Adjust validate options when managing columns and tables in migration This commit adjusts the way we manage columns and tables in migrations to account for the changes in Rails 7.1.0, it was introduced in this Rails version a validation around the options passed to tables and columns in migrations, so we need to adjust our code to skip this validation. This PR introduced this new validation on the migrations: https://github.com/rails/rails/pull/46178 --- lib/shoulda/matchers/rails_shim.rb | 4 ++++ spec/support/unit/active_record/create_table.rb | 1 + spec/support/unit/attribute.rb | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/shoulda/matchers/rails_shim.rb b/lib/shoulda/matchers/rails_shim.rb index 5c903d4e5..a69867cb2 100644 --- a/lib/shoulda/matchers/rails_shim.rb +++ b/lib/shoulda/matchers/rails_shim.rb @@ -146,6 +146,10 @@ def supports_full_attributes_api?(model) model.respond_to?(:attribute_types) end + def validates_column_options? + active_record_version >= '7.1.0' + end + private def simply_generate_validation_message( diff --git a/spec/support/unit/active_record/create_table.rb b/spec/support/unit/active_record/create_table.rb index 208207675..ed93268f0 100644 --- a/spec/support/unit/active_record/create_table.rb +++ b/spec/support/unit/active_record/create_table.rb @@ -92,6 +92,7 @@ def add_column_to_table(table, column_name, column_specification) column_specification = column_specification.dup column_type = column_specification.delete(:type) column_options = column_specification.delete(:options) { {} } + column_options.merge!({ _skip_validate_options: true }) if Shoulda::Matchers::RailsShim.validates_column_options? if column_options[:array] && !database_supports_array_columns? raise ArgumentError.new( diff --git a/spec/support/unit/attribute.rb b/spec/support/unit/attribute.rb index f3e8ad49f..68e9e3810 100644 --- a/spec/support/unit/attribute.rb +++ b/spec/support/unit/attribute.rb @@ -3,7 +3,7 @@ class Attribute DEFAULT_COLUMN_TYPE = :string DEFAULT_COLUMN_OPTIONS = { null: false, - array: false, + array: false }.freeze def initialize(args) From e836d246c4e77a0c5ef54b022006209cd106fdfa Mon Sep 17 00:00:00 2001 From: Matheus Sales Date: Fri, 6 Oct 2023 15:16:06 -0300 Subject: [PATCH 3/9] Refine `ActiveRecord::SerializeMatcher` for Rails 7.1 compatibility This commit refines the `ActiveRecord::SerializeMatcher` to accommodate changes in the public API introduced in Rails 7.1. The `serialize` method's API has been updated, necessitating adjustments to our matcher specs to align with the new API. While this PR addresses the immediate need for compatibility, there is potential for further enhancements and refinements in the matcher's implementation to bring it in line with the revised public API. However, such improvements will be explored in a future PR. For reference, the changes in the public API can be found in the following PR: https://github.com/rails/rails/pull/47463 This commit adjusts the `ActiveRecord::SerializeMatcher` the public API for the `serialize` method has changed on Rails 7.1, so we had to --- lib/shoulda/matchers/rails_shim.rb | 2 +- spec/support/unit/attribute.rb | 2 +- .../validate_presence_of_matcher_spec.rb | 97 ++++++++++++++----- .../active_record/serialize_matcher_spec.rb | 18 ++-- 4 files changed, 86 insertions(+), 33 deletions(-) diff --git a/lib/shoulda/matchers/rails_shim.rb b/lib/shoulda/matchers/rails_shim.rb index a69867cb2..079b8d2de 100644 --- a/lib/shoulda/matchers/rails_shim.rb +++ b/lib/shoulda/matchers/rails_shim.rb @@ -147,7 +147,7 @@ def supports_full_attributes_api?(model) end def validates_column_options? - active_record_version >= '7.1.0' + Gem::Requirement.new('>= 7.1.0').satisfied_by?(active_record_version) end private diff --git a/spec/support/unit/attribute.rb b/spec/support/unit/attribute.rb index 68e9e3810..f3e8ad49f 100644 --- a/spec/support/unit/attribute.rb +++ b/spec/support/unit/attribute.rb @@ -3,7 +3,7 @@ class Attribute DEFAULT_COLUMN_TYPE = :string DEFAULT_COLUMN_OPTIONS = { null: false, - array: false + array: false, }.freeze def initialize(args) diff --git a/spec/unit/shoulda/matchers/active_model/validate_presence_of_matcher_spec.rb b/spec/unit/shoulda/matchers/active_model/validate_presence_of_matcher_spec.rb index afa52e816..a54c029b2 100644 --- a/spec/unit/shoulda/matchers/active_model/validate_presence_of_matcher_spec.rb +++ b/spec/unit/shoulda/matchers/active_model/validate_presence_of_matcher_spec.rb @@ -56,51 +56,102 @@ expect(&assertion).to fail_with_message(message) end - context 'when the attribute is decorated with serialize' do - context 'and the serializer is a built-in Ruby type' do - context 'and the type is a string' do + if rails_version >= 7.1 + context 'when the attribute is decorated with serialize' do + context 'and the serializer is a built-in Ruby type' do + context 'and the type is a string' do + it 'still works' do + record = record_validating_presence_of(:traits) do + serialize :traits, type: String, coder: YAML + end + + expect(record).to validate_presence_of(:traits) + end + end + + context 'and the type is not a string' do + it 'still works' do + record = record_validating_presence_of(:traits) do + serialize :traits, type: Array, coder: YAML + end + + expect(record).to validate_presence_of(:traits) + end + end + end + + context 'and the serializer is JSON' do it 'still works' do record = record_validating_presence_of(:traits) do - serialize :traits, String + serialize :traits, coder: JSON end expect(record).to validate_presence_of(:traits) end end - context 'and the type is not a string' do + context 'and the serializer is something custom' do it 'still works' do - record = record_validating_presence_of(:traits) do - serialize :traits, Array + serializer = Class.new do + define_singleton_method(:dump) { |value| value } + define_singleton_method(:load) { |value| value } end - expect(record).to validate_presence_of(:traits) + record = record_validating_presence_of(:data) do + serialize :data, coder: serializer + end + + expect(record).to validate_presence_of(:data) end end end + else + context 'when the attribute is decorated with serialize' do + context 'and the serializer is a built-in Ruby type' do + context 'and the type is a string' do + it 'still works' do + record = record_validating_presence_of(:traits) do + serialize :traits, String + end - context 'and the serializer is JSON' do - it 'still works' do - record = record_validating_presence_of(:traits) do - serialize :traits, JSON + expect(record).to validate_presence_of(:traits) + end end - expect(record).to validate_presence_of(:traits) - end - end + context 'and the type is not a string' do + it 'still works' do + record = record_validating_presence_of(:traits) do + serialize :traits, Array + end - context 'and the serializer is something custom' do - it 'still works' do - serializer = Class.new do - define_singleton_method(:dump) { |value| value } - define_singleton_method(:load) { |value| value } + expect(record).to validate_presence_of(:traits) + end end + end + + context 'and the serializer is JSON' do + it 'still works' do + record = record_validating_presence_of(:traits) do + serialize :traits, JSON + end - record = record_validating_presence_of(:data) do - serialize :data, serializer + expect(record).to validate_presence_of(:traits) end + end + + context 'and the serializer is something custom' do + it 'still works' do + serializer = Class.new do + define_singleton_method(:dump) { |value| value } + define_singleton_method(:load) { |value| value } + end + + record = record_validating_presence_of(:data) do + serialize :data, serializer + end - expect(record).to validate_presence_of(:data) + expect(record).to validate_presence_of(:data) + end end end end diff --git a/spec/unit/shoulda/matchers/active_record/serialize_matcher_spec.rb b/spec/unit/shoulda/matchers/active_record/serialize_matcher_spec.rb index 6f90583c3..7e63b6d1b 100644 --- a/spec/unit/shoulda/matchers/active_record/serialize_matcher_spec.rb +++ b/spec/unit/shoulda/matchers/active_record/serialize_matcher_spec.rb @@ -41,38 +41,40 @@ def unserialized_model context 'an attribute that will end up being serialized as YAML' do it 'accepts when the types match' do - expect(with_serialized_attr(Hash)).to serialize(:attr).as(Hash) + expect(with_serialized_attr(type: Hash, coder: JSON)).to serialize(:attr).as(Hash) end it 'rejects when the types do not match' do - expect(with_serialized_attr(Hash)).not_to serialize(:attr).as(String) + expect(with_serialized_attr(type: Hash)).not_to serialize(:attr).as(String) end it 'rejects when using as_instance_of' do - expect(with_serialized_attr(Hash)).not_to serialize(:attr).as_instance_of(Hash) + expect(with_serialized_attr(type: Hash)).not_to serialize(:attr).as_instance_of(Hash) end end context 'a serializer that is an instance of a class' do it 'accepts when using #as_instance_of' do define_serializer(:ExampleSerializer) - expect(with_serialized_attr(ExampleSerializer.new)). + expect(with_serialized_attr(coder: ExampleSerializer.new)). to serialize(:attr).as_instance_of(ExampleSerializer) end it 'rejects when using #as' do define_serializer(:ExampleSerializer) - expect(with_serialized_attr(ExampleSerializer.new)). + expect(with_serialized_attr(coder: ExampleSerializer.new)). not_to serialize(:attr).as(ExampleSerializer) end end - def with_serialized_attr(type = nil) + def with_serialized_attr(type: nil, coder: YAML) + type_or_coder = rails_version >= 7.1 ? nil : type || coder + define_model(:example, attr: :string) do if type - serialize :attr, type + serialize :attr, type_or_coder, type: type, coder: coder else - serialize :attr + serialize :attr, type_or_coder, coder: coder end end.new end From d6d03927c4ed86901c1e9823d8a003af915b2b9e Mon Sep 17 00:00:00 2001 From: Matheus Sales Date: Fri, 27 Oct 2023 16:11:58 -0300 Subject: [PATCH 4/9] feat: Upadte workflow matrix --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 52fa6cafb..ba6cfc8ba 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,6 +31,7 @@ jobs: - 3.1.4 - 3.0.6 appraisal: + - rails_7_1 - rails_7_0 - rails_6_1 adapter: @@ -38,9 +39,8 @@ jobs: - postgresql exclude: - { ruby: 3.2.2, appraisal: rails_6_1 } - - { ruby: 3.1.4, appraisal: rails_5_2 } - - { ruby: 3.0.6, appraisal: rails_5_2 } - { ruby: 3.0.6, appraisal: rails_7_0 } + - { ruby: 3.0.6, appraisal: rails_7_1 } env: DATABASE_ADAPTER: ${{ matrix.adapter }} BUNDLE_GEMFILE: gemfiles/${{ matrix.appraisal }}.gemfile From 4cb1dab2437a2d19d9216523f3a3eaa23f268405 Mon Sep 17 00:00:00 2001 From: Matheus Sales Date: Fri, 27 Oct 2023 18:07:30 -0300 Subject: [PATCH 5/9] fix: Adjust comparison between hash and `ActionController::Parameters` The behavior of the comparison between hash and a `ActionController::Parameters` was changed and now will be deprecated. Check this Rails PR for more context https://github.com/rails/rails/pull/44826. --- .../shoulda/matchers/action_controller/permit_matcher_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/unit/shoulda/matchers/action_controller/permit_matcher_spec.rb b/spec/unit/shoulda/matchers/action_controller/permit_matcher_spec.rb index 14bcc5006..d711f1b0b 100644 --- a/spec/unit/shoulda/matchers/action_controller/permit_matcher_spec.rb +++ b/spec/unit/shoulda/matchers/action_controller/permit_matcher_spec.rb @@ -230,7 +230,7 @@ def params_with_conditional_require(params, *filters) matcher.matches?(controller) - expect(actual_user_params).to eq('some' => 'params') + expect(actual_user_params).to eq ActionController::Parameters.new('some' => 'params') expect(actual_foo_param).to eq 'bar' end @@ -252,7 +252,7 @@ def params_with_conditional_require(params, *filters) matcher.matches?(controller) - expect(actual_user_params).to eq expected_user_params + expect(actual_user_params).to eq ActionController::Parameters.new(expected_user_params) end it 'does not permanently stub the params hash' do From d2b2d55bca7ee9471d32f3a778fcab98b909d8c2 Mon Sep 17 00:00:00 2001 From: Matheus Sales Date: Fri, 27 Oct 2023 18:14:29 -0300 Subject: [PATCH 6/9] fix: Adjust usage of `has_secure_token` without a token attr The behaviour of this method was changed in Rails 7.1, and now it'll search for a `token` attr in the initialization of the record instead of the creation. To stay with the same behaviour as before it's necessary to pass a new argument `on: : create` to the method. --- .../have_secure_token_matcher_spec.rb | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/spec/unit/shoulda/matchers/active_record/have_secure_token_matcher_spec.rb b/spec/unit/shoulda/matchers/active_record/have_secure_token_matcher_spec.rb index 574ee7bea..399a02a45 100644 --- a/spec/unit/shoulda/matchers/active_record/have_secure_token_matcher_spec.rb +++ b/spec/unit/shoulda/matchers/active_record/have_secure_token_matcher_spec.rb @@ -67,7 +67,11 @@ it 'does not match when missing a token column' do create_table(:users) - invalid_model = define_model_class(:User) { has_secure_token } + invalid_model = if rails_version >= 7.1 + define_model_class(:User) { has_secure_token(on: :create) } + else + define_model_class(:User) { has_secure_token } + end expected_message = 'Expected User to have :token as a secure token but the following ' \ @@ -125,9 +129,11 @@ it 'does not match when missing a column for a custom attribute' do create_table(:users) - invalid_model = define_model_class(:User) do - has_secure_token(:auth_token) - end + invalid_model = if rails_version >= 7.1 + define_model_class(:User) { has_secure_token(:auth_token, on: :create) } + else + define_model_class(:User) { has_secure_token(:auth_token) } + end expected_message = 'Expected User to have :auth_token as a secure token but the ' \ From d1a011bc784f4f3761c91968c83517e6769dcccb Mon Sep 17 00:00:00 2001 From: Matheus Sales Date: Fri, 27 Oct 2023 18:44:02 -0300 Subject: [PATCH 7/9] fix: Adjust specs for primary_key check --- .../active_record/have_db_column_matcher_spec.rb | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/spec/unit/shoulda/matchers/active_record/have_db_column_matcher_spec.rb b/spec/unit/shoulda/matchers/active_record/have_db_column_matcher_spec.rb index 13e564d00..04db4d3c6 100644 --- a/spec/unit/shoulda/matchers/active_record/have_db_column_matcher_spec.rb +++ b/spec/unit/shoulda/matchers/active_record/have_db_column_matcher_spec.rb @@ -124,12 +124,12 @@ context 'with primary option' do it 'accepts a column that is primary' do - expect(with_table(:custom_id, :integer, primary: true)). - to have_db_column(:id).with_options(primary: true) + expect(with_table_custom_primary_key(:custom_id)). + to have_db_column(:custom_id).with_options(primary: true) end it 'rejects a column that is not primary' do - expect(with_table(:whatever, :integer, primary: false)). + expect(with_table(:whatever, :integer, {})). not_to have_db_column(:whatever).with_options(primary: true) end end @@ -161,9 +161,16 @@ def model(options = {}) end def with_table(column_name, column_type, options) - create_table 'employees' do |table| + create_table 'employees', id: false do |table| table.__send__(column_type, column_name, **options) end define_model_class('Employee').new end + + def with_table_custom_primary_key(column_name, options = {}) + create_table 'employees', id: false do |table| + table.__send__(:primary_key, column_name, **options) + end + define_model_class('Employee').new + end end From 75612f6eee76214df72eee531e6ce03eadb1014b Mon Sep 17 00:00:00 2001 From: Matheus Sales Date: Fri, 27 Oct 2023 21:50:54 -0300 Subject: [PATCH 8/9] fix: Test updating error_highlight gem --- gemfiles/rails_7_1.gemfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gemfiles/rails_7_1.gemfile b/gemfiles/rails_7_1.gemfile index 0a21a31f9..22a183d93 100644 --- a/gemfiles/rails_7_1.gemfile +++ b/gemfiles/rails_7_1.gemfile @@ -36,3 +36,7 @@ gem "shoulda-context", "~> 2.0.0" gem "bcrypt", "~> 3.1.7" gem "sqlite3", "~> 1.4" gem "pg", "~> 1.1" + +if RUBY_VERSION >= "3.1" && RUBY_VERSION < "3.2" + gem "error_highlight", ">= 0.4.0", platforms: [:ruby] +end From aae4ed2d09693f59d034623148ed922bfc79f5ff Mon Sep 17 00:00:00 2001 From: Matheus Sales Date: Fri, 10 Nov 2023 11:44:33 -0300 Subject: [PATCH 9/9] fix: Add default Rails tables to acceptance spec This commit fixes the problem of not finding the tables when running the specs in eager load mode, this was introduced by Rails 7.1. Load the model schema when running test in eager load context https://github.com/rails/rails/pull/49470 --- spec/acceptance/rails_integration_spec.rb | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/spec/acceptance/rails_integration_spec.rb b/spec/acceptance/rails_integration_spec.rb index ec761f5ac..9f16600da 100644 --- a/spec/acceptance/rails_integration_spec.rb +++ b/spec/acceptance/rails_integration_spec.rb @@ -4,7 +4,21 @@ before do create_rails_application - write_file 'db/migrate/1_create_users.rb', <<-FILE + write_file 'db/migrate/1_create_defaults.rb', <<-FILE + class CreateDefaults < #{migration_class_name} + def self.up + create_table :action_text_rich_texts + create_table :active_storage_variant_records + create_table :active_storage_blobs + create_table :active_storage_attachments + create_table :action_mailbox_inbound_emails do |t| + t.integer :status + end + end + end + FILE + + write_file 'db/migrate/2_create_users.rb', <<-FILE class CreateUsers < #{migration_class_name} def self.up create_table :users do |t|