diff --git a/.gitignore b/.gitignore index 3c2860b..3a7bf6a 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,6 @@ pkg/ .idea/* *.db tmp/fixture_builder.yml -test/fixtures/magical_creatures.yml +test/fixtures/*.yml Gemfile.lock *.gem diff --git a/Rakefile b/Rakefile index 568b3ba..ad9cb94 100644 --- a/Rakefile +++ b/Rakefile @@ -3,9 +3,29 @@ include Rake::DSL if defined?(Rake::DSL) Bundler::GemHelper.install_tasks require 'rake/testtask' -Rake::TestTask.new(:test) do |t| +Rake::TestTask.new(:run_test) do |t| t.test_files = FileList['test/*_test.rb'] t.verbose = false end +task :test do + begin + Rake::Task[:run_test].execute + ensure + Rake::Task[:dbdrop].invoke + end +end + +require 'pg' +task :dbcreate do + PG.connect(dbname: 'postgres').exec("CREATE DATABASE testdb") +end + +task :dbdrop do + PG.connect(dbname: 'postgres').exec("DROP DATABASE testdb") +end + +task :test => :dbcreate + + task :default => :test diff --git a/fixture_builder.gemspec b/fixture_builder.gemspec index 34c7013..14e89ed 100644 --- a/fixture_builder.gemspec +++ b/fixture_builder.gemspec @@ -29,5 +29,5 @@ Gem::Specification.new do |s| s.add_development_dependency %q{rake} s.add_development_dependency %q{rails}, '>= 2' s.add_development_dependency %q{test-unit} - s.add_development_dependency %q{sqlite3} + s.add_development_dependency %q{pg} end diff --git a/lib/fixture_builder/builder.rb b/lib/fixture_builder/builder.rb index 83e5d9a..28c37aa 100644 --- a/lib/fixture_builder/builder.rb +++ b/lib/fixture_builder/builder.rb @@ -91,13 +91,25 @@ def dump_empty_fixtures_for_all_tables end end + def klass_by_table_name + @klass_by_table_name ||= ActiveRecord::Base + .descendants + .reject(&:abstract_class) + .group_by(&:table_name) + .transform_values { |klasses| klasses.min { |klass| klass.ancestors.size } } + end + + def eligible_for_serialization(table_klass) + table_klass && table_klass < ActiveRecord::Base && table_klass.attribute_names.include?('id') + end + def dump_tables default_date_format = Date::DATE_FORMATS[:default] Date::DATE_FORMATS[:default] = Date::DATE_FORMATS[:db] begin fixtures = tables.inject([]) do |files, table_name| - table_klass = table_name.classify.constantize rescue nil - if table_klass && table_klass < ActiveRecord::Base + table_klass = klass_by_table_name[table_name] rescue nil + if eligible_for_serialization(table_klass) rows = table_klass.unscoped do table_klass.order(:id).all.collect do |obj| attrs = obj.attributes.select { |attr_name| table_klass.column_names.include?(attr_name) } diff --git a/test/fixture_builder_test.rb b/test/fixture_builder_test.rb index eac005d..481070c 100644 --- a/test/fixture_builder_test.rb +++ b/test/fixture_builder_test.rb @@ -53,6 +53,58 @@ def test_serialization assert_equal "---\n- shading\n- rooting\n- seeding\n", generated_fixture['enty']['powers'] end + def test_sti_serialization + create_and_blow_away_old_db + force_fixture_generation + + FixtureBuilder.configure do |fbuilder| + fbuilder.files_to_check += Dir[test_path("*.rb")] + fbuilder.factory do + @argus = MythicalCreature.create(name: 'Argus', + species: 'giant', + powers: %w[watching seeing]) + end + end + generated_fixture = YAML.load(File.open(test_path("fixtures/magical_creatures.yml"))) + assert_equal "---\n- watching\n- seeing\n", generated_fixture['argus']['powers'] + assert_equal 'MythicalCreature', generated_fixture['argus']['type'] + end + + def test_namespace_serialization + create_and_blow_away_old_db + force_fixture_generation + + powers = { 'super' => 'flying', 'normal' => 'galloping' } + + FixtureBuilder.configure do |fbuilder| + fbuilder.files_to_check += Dir[test_path("*.rb")] + fbuilder.factory do + @pegasos = Legendary::Creature.create(name: 'Pegasos', + species: 'wingedhorse', + powers: powers) + end + end + generated_fixture = YAML.load(File.open(test_path("fixtures/my_creatures.yml"))) + assert_equal powers, generated_fixture['pegasos']['powers'] + end + + def test_idless_serialization + create_and_blow_away_old_db + force_fixture_generation + + FixtureBuilder.configure do |fbuilder| + fbuilder.files_to_check += Dir[test_path("*.rb")] + fbuilder.factory do + @enty = MagicalCreature.create(:name => 'Enty', :species => 'ent') + @king_of_gnomes = MagicalCreature.create(:name => 'robert', :species => 'gnome') + @relationship = CreatureRelationship.create(one: @enty, other: @king_of_gnomes) + end + end + generated_fixture = YAML.load(File.open(test_path("fixtures/creature_relationships.yml"))) + assert_equal 1, generated_fixture['creature_relationships_001']['one_id'] + assert_equal 2, generated_fixture['creature_relationships_001']['other_id'] + end + def test_do_not_include_virtual_attributes create_and_blow_away_old_db force_fixture_generation diff --git a/test/test_helper.rb b/test/test_helper.rb index 778720a..332ee4d 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -24,7 +24,7 @@ def create_fixtures(*table_names, &block) Fixtures.create_fixtures(ActiveSupport::TestCase.fixture_path, table_names, {}, &block) end -require 'sqlite3' +require 'pg' require 'fixture_builder' class MagicalCreature < ActiveRecord::Base @@ -40,19 +40,62 @@ class MagicalCreature < ActiveRecord::Base end end + +module Legendary + class Creature < ActiveRecord::Base + self.table_name = 'my_creatures' + validates_presence_of :name, :species + + if ActiveRecord::VERSION::MAJOR >= 4 + default_scope -> { where(deleted: false) } + + attribute :virtual, ActiveRecord::Type::Integer.new + else + default_scope conditions: { deleted: false } + end + end +end + +class MythicalCreature < MagicalCreature +end + +class CreatureRelationship < ActiveRecord::Base + belongs_to :one, class_name: 'MagicalCreature' + belongs_to :other, class_name: 'MagicalCreature' +end + def create_and_blow_away_old_db - ActiveRecord::Base.configurations['test'] = { - 'adapter' => 'sqlite3', - 'database' => 'test.db' + ActiveRecord::Base.configurations = { + test: { + :adapter => 'postgresql', + :database => 'testdb', + :encoding => 'utf8', + :pool => 5 + } } + ActiveRecord::Base.establish_connection(:test) ActiveRecord::Base.connection.create_table(:magical_creatures, :force => true) do |t| t.column :name, :string + t.column :type, :string t.column :species, :string t.column :powers, :string t.column :deleted, :boolean, :default => false, :null => false end + + ActiveRecord::Base.connection.create_table(:my_creatures, force: true) do |t| + t.column :name, :string + t.column :type, :string + t.column :species, :string + t.column :powers, :jsonb + t.column :deleted, :boolean, :default => false, :null => false + end + + ActiveRecord::Base.connection.create_table(:creature_relationships, force: true, id: false) do |t| + t.column :one_id, :integer + t.column :other_id, :integer + end end def force_fixture_generation