diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index 4c36cfc1..a49e0185 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -21,7 +21,7 @@ jobs: ruby: ["3.1"] postgres: ["12"] gemfile: [ - "gemfiles/rails7.gemfile" + "gemfiles/rails72.gemfile" ] fx: ["false"] after_trigger: ["false"] @@ -33,17 +33,27 @@ jobs: after_trigger: "false" - ruby: "3.2" postgres: "15" - gemfile: "gemfiles/rails7.gemfile" + gemfile: "gemfiles/rails72.gemfile" + fx: "false" + after_trigger: "false" + - ruby: "3.2" + postgres: "15" + gemfile: "gemfiles/rails71.gemfile" + fx: "false" + after_trigger: "false" + - ruby: "3.2" + postgres: "15" + gemfile: "gemfiles/rails70.gemfile" fx: "false" after_trigger: "false" - ruby: "3.1" postgres: "12" - gemfile: "gemfiles/rails7.gemfile" + gemfile: "gemfiles/rails72.gemfile" fx: "false" after_trigger: "true" - ruby: "3.0" postgres: "13" - gemfile: "gemfiles/rails7.gemfile" + gemfile: "gemfiles/rails72.gemfile" fx: "false" after_trigger: "false" - ruby: "2.7" diff --git a/CHANGELOG.md b/CHANGELOG.md index e1be7680..7ad7237d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master (unreleased) +- Support Rails 7.2 ([@atomaka][]) + ## 1.3.1 (2024-10-23) - Fix `rails destroy logidze:model SomeModel` not deleting the `fx` trigger file file. ([@tylerhunt][]) diff --git a/gemfiles/rails7.gemfile b/gemfiles/rails70.gemfile similarity index 100% rename from gemfiles/rails7.gemfile rename to gemfiles/rails70.gemfile diff --git a/gemfiles/rails71.gemfile b/gemfiles/rails71.gemfile new file mode 100644 index 00000000..3c4a8909 --- /dev/null +++ b/gemfiles/rails71.gemfile @@ -0,0 +1,9 @@ +source 'https://rubygems.org' + +rails_version = '~> 7.1.0' +gem 'railties', rails_version +gem 'activerecord', rails_version + +eval_gemfile './shared.gemfile' + +gemspec path: '..' diff --git a/gemfiles/rails72.gemfile b/gemfiles/rails72.gemfile new file mode 100644 index 00000000..8970685a --- /dev/null +++ b/gemfiles/rails72.gemfile @@ -0,0 +1,9 @@ +source 'https://rubygems.org' + +rails_version = '~> 7.2.0' +gem 'railties', rails_version +gem 'activerecord', rails_version + +eval_gemfile './shared.gemfile' + +gemspec path: '..' diff --git a/spec/generators/install_generator_spec.rb b/spec/generators/install_generator_spec.rb index aad2ed61..8eade51d 100644 --- a/spec/generators/install_generator_spec.rb +++ b/spec/generators/install_generator_spec.rb @@ -24,7 +24,7 @@ it "creates migration", :aggregate_failures do run_generator(args) - is_expected.to exist + is_expected.to be_a_file is_expected.to contain "ActiveRecord::Migration[#{ar_version}]" is_expected.to contain(/create or replace function logidze_logger()/i) is_expected.to contain(/create or replace function logidze_logger_after()/i) @@ -40,7 +40,7 @@ it "creates migration", :aggregate_failures do run_generator(args) - is_expected.to exist + is_expected.to be_a_file is_expected.to contain "ActiveRecord::Migration[#{ar_version}]" is_expected.to contain("create_function :logidze_logger, version: 4") is_expected.to contain("create_function :logidze_logger_after, version: 4") @@ -62,7 +62,7 @@ it "creates function files" do run_generator(args) - is_expected.to exist + is_expected.to be_a_file %w[ logidze_logger_v04.sql logidze_logger_after_v04.sql @@ -72,7 +72,7 @@ logidze_compact_history_v01.sql logidze_capture_exception_v01.sql ].each do |path| - expect(file("db/functions/#{path}")).to exist + expect(file("db/functions/#{path}")).to be_a_file end end end @@ -84,7 +84,7 @@ it "creates migration", :aggregate_failures do run_generator(args) - is_expected.to exist + is_expected.to be_a_file is_expected.to contain "ActiveRecord::Migration[#{ar_version}]" is_expected.to contain(/enable_extension :hstore/i) end @@ -99,10 +99,10 @@ it "creates only functions", :aggregate_failures do run_generator(args) - expect(migration_file("db/migrate/enable_hstore.rb")).not_to exist - expect(migration_file("db/migrate/logidze_install.rb")).not_to exist + expect(migration_file("db/migrate/enable_hstore.rb")).not_to be_a_file + expect(migration_file("db/migrate/logidze_install.rb")).not_to be_a_file - is_expected.to exist + is_expected.to be_a_file is_expected.to contain(/create or replace function logidze_logger()/i) is_expected.to contain(/create or replace function logidze_logger_after()/i) is_expected.to contain(/create or replace function logidze_snapshot/i) @@ -144,7 +144,7 @@ it "creates migration", :aggregate_failures do run_generator(args) - is_expected.to exist + is_expected.to be_a_file is_expected.to contain("update_function :logidze_version, version: 2, revert_to_version: 3") is_expected.to contain("update_function :logidze_snapshot, version: 3, revert_to_version: 4") is_expected.not_to contain("update_function :logidze_filter_keys") @@ -157,7 +157,7 @@ it "creates function files" do run_generator(args) - is_expected.to exist + is_expected.to be_a_file %w[ logidze_logger_v04.sql logidze_logger_after_v04.sql @@ -166,7 +166,7 @@ logidze_compact_history_v01.sql logidze_capture_exception_v01.sql ].each do |path| - expect(file("db/functions/#{path}")).to exist + expect(file("db/functions/#{path}")).to be_a_file end end end diff --git a/spec/generators/model_generator_spec.rb b/spec/generators/model_generator_spec.rb index 6a28a442..cdeb5eab 100644 --- a/spec/generators/model_generator_spec.rb +++ b/spec/generators/model_generator_spec.rb @@ -49,7 +49,7 @@ class User < ActiveRecord::Base end it "creates migration", :aggregate_failures do - is_expected.to exist + is_expected.to be_a_file is_expected.to contain "ActiveRecord::Migration[#{ar_version}]" is_expected.to contain "add_column :users, :log_data, :jsonb" is_expected.to contain(/create trigger "logidze_on_#{full_table_name("users")}"/i) @@ -65,13 +65,13 @@ class User < ActiveRecord::Base let(:fx_args) { use_fx_args } it "creates migration", :aggregate_failures do - is_expected.to exist + is_expected.to be_a_file is_expected.to contain("create_trigger :logidze_on_users, on: :users") end it "creates a trigger file" do - is_expected.to exist - expect(file("db/triggers/logidze_on_users_v01.sql")).to exist + is_expected.to be_a_file + expect(file("db/triggers/logidze_on_users_v01.sql")).to be_a_file end end @@ -79,7 +79,7 @@ class User < ActiveRecord::Base let(:base_args) { ["user", "--limit=5", "--no-after-trigger"] } it "creates trigger with limit" do - is_expected.to exist + is_expected.to be_a_file is_expected.to contain(/execute procedure logidze_logger\(5, 'updated_at'\);/i) end end @@ -88,7 +88,7 @@ class User < ActiveRecord::Base let(:base_args) { ["user", "--debounce_time=5000", "--no-after-trigger"] } it "creates trigger with debounce_time" do - is_expected.to exist + is_expected.to be_a_file is_expected.to contain(/execute procedure logidze_logger\(null, 'updated_at', null, null, 5000\);/i) end end @@ -97,7 +97,7 @@ class User < ActiveRecord::Base let(:base_args) { ["user", "--except", "age", "active", "--no-after-trigger"] } it "creates trigger with columns exclusion" do - is_expected.to exist + is_expected.to be_a_file is_expected.to contain( /execute procedure logidze_logger\(null, 'updated_at', '\{age, active\}'\);/i ) @@ -108,7 +108,7 @@ class User < ActiveRecord::Base let(:base_args) { ["user", "--only", "age", "active", "--no-after-trigger"] } it "creates trigger with columns inclusion" do - is_expected.to exist + is_expected.to be_a_file is_expected.to contain( /execute procedure logidze_logger\(null, 'updated_at', '\{age, active\}', true\);/i ) @@ -119,7 +119,7 @@ class User < ActiveRecord::Base let(:base_args) { ["user", "--backfill", "--no-after-trigger"] } it "creates backfill query" do - is_expected.to exist + is_expected.to be_a_file is_expected.to contain(/update "#{full_table_name("users")}" as t/i) is_expected.to contain(/set log_data = logidze_snapshot\(to_jsonb\(t\), 'updated_at'\);/i) end @@ -129,7 +129,7 @@ class User < ActiveRecord::Base let(:base_args) { ["user", "--only-trigger", "--no-after-trigger"] } it "creates migration with trigger" do - is_expected.to exist + is_expected.to be_a_file is_expected.not_to contain "add_column :users, :log_data, :jsonb" is_expected.to contain(/create trigger "logidze_on_#{full_table_name("users")}"/i) is_expected.to contain(/before update or insert on "#{full_table_name("users")}" for each row/i) @@ -148,7 +148,7 @@ class User < ActiveRecord::Base let(:base_args) { ["user", "--update", "--no-after-trigger"] } it "creates migration with drop and create trigger" do - is_expected.to exist + is_expected.to be_a_file is_expected.not_to contain "add_column :users, :log_data, :jsonb" is_expected.to contain(/drop trigger if exists "logidze_on_#{full_table_name("users")}" on "#{full_table_name("users")}"/i) is_expected.to contain(/before update or insert on "#{full_table_name("users")}" for each row/i) @@ -169,13 +169,13 @@ class User < ActiveRecord::Base end it "creates migration", :aggregate_failures do - is_expected.to exist + is_expected.to be_a_file is_expected.to contain("update_trigger :logidze_on_users, on: :users, version: 2, revert_to_version: 1") end it "creates a trigger file" do - is_expected.to exist - expect(file("db/triggers/logidze_on_users_v02.sql")).to exist + is_expected.to be_a_file + expect(file("db/triggers/logidze_on_users_v02.sql")).to be_a_file end end @@ -189,7 +189,7 @@ class User < ActiveRecord::Base end it "creates migration", :aggregate_failures do - is_expected.to exist + is_expected.to be_a_file is_expected.to contain "add_column :users, :log_data, :jsonb" end end @@ -200,7 +200,7 @@ class User < ActiveRecord::Base let(:base_args) { ["user", "--timestamp_column", "time", "--no-after-trigger"] } it "creates trigger with 'time' timestamp column" do - is_expected.to exist + is_expected.to be_a_file is_expected.to contain( /execute procedure logidze_logger\(null, 'time'\);/i ) @@ -211,7 +211,7 @@ class User < ActiveRecord::Base let(:base_args) { ["user", "--timestamp_column", "nil", "--no-after-trigger"] } it "creates trigger without timestamp column" do - is_expected.to exist + is_expected.to be_a_file is_expected.to contain( /execute procedure logidze_logger\(\);/i ) @@ -223,7 +223,7 @@ class User < ActiveRecord::Base let(:base_args) { ["user", "--after-trigger"] } it "use after trigger" do - is_expected.to exist + is_expected.to be_a_file is_expected.to contain(/after update or insert on "#{full_table_name("users")}" for each row/i) is_expected.to contain(/execute procedure logidze_logger_after\(null, 'updated_at'\);/i) end @@ -232,8 +232,8 @@ class User < ActiveRecord::Base let(:fx_args) { use_fx_args } it "generates after trigger" do - is_expected.to exist - expect(file("db/triggers/logidze_on_users_v01.sql")).to exist + is_expected.to be_a_file + expect(file("db/triggers/logidze_on_users_v01.sql")).to be_a_file expect(file("db/triggers/logidze_on_users_v01.sql")).to contain(/after update or insert on/i) end end @@ -261,7 +261,7 @@ class Guest < ActiveRecord::Base end it "creates migration", :aggregate_failures do - is_expected.to exist + is_expected.to be_a_file is_expected.to contain "add_column :user_guests, :log_data, :jsonb" expect(file("app/models/user/guest.rb")).to contain "has_logidze" @@ -289,7 +289,7 @@ class Set < ActiveRecord::Base end it "creates migration", :aggregate_failures do - is_expected.to exist + is_expected.to be_a_file is_expected.to contain "add_column :data_sets, :log_data, :jsonb" expect(file("app/models/custom/data/set.rb")).to contain "has_logidze" @@ -319,13 +319,13 @@ class User < ActiveRecord::Base it "deletes migration file it created" do migration_file = migration_file("db/migrate/add_logidze_to_users.rb") - expect(migration_file).to exist + expect(migration_file).to be_a_file Rails::Generators.invoke "logidze:model", args, behavior: :revoke, destination_root: destination_root - expect(migration_file).not_to exist + expect(migration_file).not_to be_a_file end context "with fx" do @@ -334,13 +334,13 @@ class User < ActiveRecord::Base it "deletes trigger file it created" do trigger_file = file("db/triggers/logidze_on_users_v01.sql") - expect(trigger_file).to exist + expect(trigger_file).to be_a_file Rails::Generators.invoke "logidze:model", args, behavior: :revoke, destination_root: destination_root - expect(trigger_file).not_to exist + expect(trigger_file).not_to be_a_file end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 1c7aaabb..6a993948 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -39,6 +39,12 @@ config.append_after(:each, db: true) do |ex| ActiveRecord::Base.connection.rollback_transaction - raise "Migrations are pending: #{ex.metadata[:location]}" if ActiveRecord::Base.connection.migration_context.needs_migration? + migration_context = if Rails::VERSION::MAJOR >= 7 + ActiveRecord::MigrationContext.new("db/migrate") + else + ActiveRecord::Base.connection.migration_context + end + + raise "Migrations are pending: #{ex.metadata[:location]}" if migration_context.needs_migration? end end diff --git a/spec/sql/snapshot_spec.rb b/spec/sql/snapshot_spec.rb index 96541d2d..837ed42d 100644 --- a/spec/sql/snapshot_spec.rb +++ b/spec/sql/snapshot_spec.rb @@ -4,8 +4,11 @@ describe "logidze_snapshot" do let(:now) { Time.zone.local(1989, 7, 10, 18, 23, 33) } + let(:now_to_s) do + now.respond_to?(:to_fs) ? now.to_fs(:db) : now.to_s(:db) + end - let(:data) { %('{"title": "Feel me", "rating": 42, "name": "Jack", "extra": {"gender": "X"}, "updated_at": "#{now.to_s(:db)}"}'::jsonb) } + let(:data) { %('{"title": "Feel me", "rating": 42, "name": "Jack", "extra": {"gender": "X"}, "updated_at": "#{now_to_s}"}'::jsonb) } specify "without optional args" do res = sql "select logidze_snapshot(#{data})" diff --git a/spec/support/matchers/be_a_file.rb b/spec/support/matchers/be_a_file.rb new file mode 100644 index 00000000..24651882 --- /dev/null +++ b/spec/support/matchers/be_a_file.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +RSpec::Matchers.define :be_a_file do |expected| + match do |file_path| + File.exist?(file_path) + end +end