From 8471caa73be70a832c8b3702fc798d4a05ed7ac4 Mon Sep 17 00:00:00 2001 From: Jose David Bayona Date: Wed, 25 Oct 2023 13:34:27 -0500 Subject: [PATCH] Initial test to assert migration file (#7) * Fix rubocop offenses * More generator tests * Linter offenses and catch up migration template with refactors * Adds test for postgresql adapter * Remove unnecesary changes * Specifies correct version of generator spec * Updates gemfile.lock * Removes absolute path from test * Generates migration timestap programtically * Fixes failing test about migration content * Improves time traveling * reverts workflow changes * Fix assertion tests * Reverts changes to CI file * Initial test to assert migration file * Remove pry --- Gemfile | 1 + Gemfile.lock | 27 ++--- .../generators/active_outbox_generator.rb | 8 +- .../generators/templates/migration.rb | 6 +- .../active_outbox_generator_spec.rb | 110 ++++++++++++++++++ 5 files changed, 132 insertions(+), 20 deletions(-) create mode 100644 spec/generators/active_outbox_generator_spec.rb diff --git a/Gemfile b/Gemfile index e8eb7c0..fa7d1e7 100644 --- a/Gemfile +++ b/Gemfile @@ -6,6 +6,7 @@ gemspec gem 'byebug', '~> 11.1.3' gem 'database_cleaner-active_record', '~> 2.1.0' +gem 'generator_spec', '~> 0.9.4' gem 'pg', '~> 1.5.4' gem 'pry-rails', '~> 0.3.9' gem 'reek', '~> 6.1.4' diff --git a/Gemfile.lock b/Gemfile.lock index 3b230d3..5c3408b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -88,6 +88,9 @@ GEM concurrent-ruby (~> 1.0) zeitwerk (~> 2.6) erubi (1.12.0) + generator_spec (0.9.4) + activesupport (>= 3.0.0) + railties (>= 3.0.0) globalid (1.2.1) activesupport (>= 6.1) i18n (1.14.1) @@ -95,7 +98,7 @@ GEM json (2.6.3) kwalify (0.7.2) language_server-protocol (3.17.0.3) - loofah (2.21.3) + loofah (2.21.4) crass (~> 1.0.2) nokogiri (>= 1.12.0) mail (2.8.1) @@ -106,9 +109,9 @@ GEM marcel (1.0.2) method_source (1.0.0) mini_mime (1.1.5) - mini_portile2 (2.8.4) + mini_portile2 (2.8.5) minitest (5.20.0) - net-imap (0.3.7) + net-imap (0.4.2) date net-protocol net-pop (0.1.2) @@ -121,12 +124,8 @@ GEM nokogiri (1.15.4) mini_portile2 (~> 2.8.2) racc (~> 1.4) - nokogiri (1.15.4-x86_64-darwin) - racc (~> 1.4) - nokogiri (1.15.4-x86_64-linux) - racc (~> 1.4) parallel (1.23.0) - parser (3.2.2.3) + parser (3.2.2.4) ast (~> 2.4.1) racc pg (1.5.4) @@ -173,7 +172,7 @@ GEM kwalify (~> 0.7.0) parser (~> 3.2.0) rainbow (>= 2.0, < 4.0) - regexp_parser (2.8.1) + regexp_parser (2.8.2) rexml (3.2.6) rspec (3.12.0) rspec-core (~> 3.12.0) @@ -188,7 +187,7 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.12.0) rspec-support (3.12.1) - rubocop (1.56.3) + rubocop (1.56.4) base64 (~> 0.1.1) json (~> 2.3) language_server-protocol (>= 3.17.0) @@ -225,11 +224,11 @@ GEM activesupport (>= 5.2) sprockets (>= 3.0.0) sqlite3 (1.4.2) - thor (1.2.2) + thor (1.3.0) timeout (0.4.0) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - unicode-display_width (2.4.2) + unicode-display_width (2.5.0) websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) @@ -237,14 +236,12 @@ GEM PLATFORMS ruby - x86_64-darwin-21 - x86_64-darwin-22 - x86_64-linux DEPENDENCIES active_outbox! byebug (~> 11.1.3) database_cleaner-active_record (~> 2.1.0) + generator_spec (~> 0.9.4) pg (~> 1.5.4) pry-rails (~> 0.3.9) reek (~> 6.1.4) diff --git a/lib/active_outbox/generators/active_outbox_generator.rb b/lib/active_outbox/generators/active_outbox_generator.rb index ec3eb74..6ca8862 100644 --- a/lib/active_outbox/generators/active_outbox_generator.rb +++ b/lib/active_outbox/generators/active_outbox_generator.rb @@ -8,10 +8,10 @@ class ActiveOutboxGenerator < ActiveRecord::Generators::Base include ActiveOutbox::AdapterHelper source_root File.expand_path('templates', __dir__) - class_option :root_components_path, type: :string, default: Rails.root + class_option :root_components_path, type: :string def create_migration_files - migration_path = "#{options['root_components_path']}/db/migrate" + migration_path = "#{root_path}/db/migrate" migration_template( 'migration.rb', "#{migration_path}/outbox_create_#{table_name}.rb", @@ -19,6 +19,10 @@ def create_migration_files ) end + def root_path + options['root_components_path'] || Rails.root + end + def migration_version "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]" end diff --git a/lib/active_outbox/generators/templates/migration.rb b/lib/active_outbox/generators/templates/migration.rb index ff7b31a..13768a5 100644 --- a/lib/active_outbox/generators/templates/migration.rb +++ b/lib/active_outbox/generators/templates/migration.rb @@ -3,11 +3,11 @@ class OutboxCreate<%= table_name.camelize.singularize %> < ActiveRecord::Migration<%= migration_version %> def change create_table :<%= table_name %> do |t| - t.<%= uuid_type %> :identifier, null: false, index: { unique: true } + t.<%= ActiveOutbox::AdapterHelper.uuid_type %> :identifier, null: false, index: { unique: true } t.string :event, null: false - t.<%= json_type %> :payload + t.<%= ActiveOutbox::AdapterHelper.json_type %> :payload t.string :aggregate, null: false - t.<%= uuid_type %> :aggregate_identifier, null: false, index: true + t.<%= ActiveOutbox::AdapterHelper.uuid_type %> :aggregate_identifier, null: false, index: true t.timestamps end diff --git a/spec/generators/active_outbox_generator_spec.rb b/spec/generators/active_outbox_generator_spec.rb new file mode 100644 index 0000000..d8c1cac --- /dev/null +++ b/spec/generators/active_outbox_generator_spec.rb @@ -0,0 +1,110 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'generator_spec' +require 'tempfile' + +RSpec.describe ActiveOutboxGenerator, type: :generator do + destination File.expand_path('tmp', __dir__) + + before do + prepare_destination + Time.use_zone('UTC') do + travel_to Time.zone.local(2023, 10, 20, 14, 25, 30) + end + end + + after do + travel_back + FileUtils.rm_rf(destination_root) + end + + let(:table_name) { 'custom_table_name' } + let(:migration_file_path) do + "#{destination_root}/db/migrate/#{timestamp_of_migration}_outbox_create_#{table_name}_outboxes.rb" + end + let(:timestamp_of_migration) { DateTime.now.in_time_zone('UTC').strftime('%Y%m%d%H%M%S') } + + context 'without root_component_path' do + before do + allow(Rails).to receive(:root).and_return(destination_root) + end + + it 'creates the expected files' do + run_generator [table_name] + assert_file migration_file_path + end + end + + context 'with root_component_path' do + it 'creates the expected files' do + run_generator([table_name, "--root_components_path=#{destination_root}"]) + assert_file migration_file_path + end + end + + describe 'migration content' do + subject(:generate) { run_generator([table_name, "--root_components_path=#{destination_root}"]) } + + let(:actual_content) { File.read(migration_file_path) } + let(:active_record_dependency) { ActiveRecord::VERSION::STRING.to_f } + + context 'when is not a postgres migration' do + before do + allow(ActiveOutbox::AdapterHelper).to receive(:postgres?).and_return(false) + end + + let(:expected_content) do + <<~MIGRATION + class OutboxCreate#{table_name.camelcase}Outbox < ActiveRecord::Migration[#{active_record_dependency}] + def change + create_table :#{table_name}_outboxes do |t| + t.string :identifier, null: false, index: { unique: true } + t.string :event, null: false + t.string :payload + t.string :aggregate, null: false + t.string :aggregate_identifier, null: false, index: true + + t.timestamps + end + end + end + MIGRATION + end + + it 'creates the migration with the correct content' do + generate + expect(actual_content).to include(expected_content) + end + end + + context 'when it is a postgres migration' do + before do + allow(ActiveOutbox::AdapterHelper).to receive(:postgres?).and_return(true) + end + + let(:expected_content) do + <<~MIGRATION + class OutboxCreate#{table_name.camelcase}Outbox < ActiveRecord::Migration[#{active_record_dependency}] + def change + create_table :#{table_name}_outboxes do |t| + t.uuid :identifier, null: false, index: { unique: true } + t.string :event, null: false + t.jsonb :payload + t.string :aggregate, null: false + t.uuid :aggregate_identifier, null: false, index: true + + t.timestamps + end + end + end + MIGRATION + end + + it 'creates the migration with the correct content' do + generate + expect(actual_content).to include(expected_content) + end + end + end +end