diff --git a/lib/frozen_record/test_helper.rb b/lib/frozen_record/test_helper.rb index b89b91b..cfd9981 100644 --- a/lib/frozen_record/test_helper.rb +++ b/lib/frozen_record/test_helper.rb @@ -2,6 +2,7 @@ module FrozenRecord module TestHelper + FixtureAttributeMismatch = Class.new(StandardError) NoFixturesLoaded = Class.new(StandardError) class << self @@ -15,10 +16,16 @@ def load_fixture(model_class, alternate_base_path) unload_fixture(model_class) end - @cache[model_class] = base_path_if_file_present(model_class) + old_base_path = base_path_if_file_present(model_class) + expected_attributes = model_class.attributes if old_base_path + @cache[model_class] = old_base_path model_class.base_path = alternate_base_path model_class.load_records(force: true) + ensure_fixture_attributes_match(model_class, expected_attributes) if expected_attributes + rescue FixtureAttributeMismatch + unload_fixture(model_class) + raise end def unload_fixture(model_class) @@ -62,6 +69,19 @@ def ensure_model_class_is_frozenrecord(model_class) raise ArgumentError, "Model class (#{model_class}) does not inherit from #{FrozenRecord::Base}" end end + + def ensure_fixture_attributes_match(model_class, expected_attributes) + actual_attributes = model_class.attributes + missing_attributes = expected_attributes - actual_attributes + unexpected_attributes = actual_attributes - expected_attributes + return if missing_attributes.empty? && unexpected_attributes.empty? + + differences = [] + differences << "missing: #{missing_attributes.to_a.sort.join(', ')}" unless missing_attributes.empty? + differences << "unexpected: #{unexpected_attributes.to_a.sort.join(', ')}" unless unexpected_attributes.empty? + + raise FixtureAttributeMismatch, "#{model_class} fixture attributes do not match (#{differences.join('; ')})" + end end end end diff --git a/spec/fixtures/test_helper/countries.yml.erb b/spec/fixtures/test_helper/countries.yml.erb index 4cbe436..79f2a43 100644 --- a/spec/fixtures/test_helper/countries.yml.erb +++ b/spec/fixtures/test_helper/countries.yml.erb @@ -6,4 +6,6 @@ population: 42 founded_on: 2019-01-01 updated_at: 2019-01-01T19:08:06-05:00 + nato: true king: Bob Smith + continent: Some continent diff --git a/spec/fixtures/test_helper/missing_attributes/countries.yml.erb b/spec/fixtures/test_helper/missing_attributes/countries.yml.erb new file mode 100644 index 0000000..2a494e4 --- /dev/null +++ b/spec/fixtures/test_helper/missing_attributes/countries.yml.erb @@ -0,0 +1,10 @@ +--- +- id: 1 + name: Some country + capital: <%= 'Somewhere' %> + density: 1.0 + population: 42 + founded_on: 2019-01-01 + updated_at: 2019-01-01T19:08:06-05:00 + king: Bob Smith + continent: Some continent diff --git a/spec/fixtures/test_helper/unexpected_attributes/countries.yml.erb b/spec/fixtures/test_helper/unexpected_attributes/countries.yml.erb new file mode 100644 index 0000000..43e8e16 --- /dev/null +++ b/spec/fixtures/test_helper/unexpected_attributes/countries.yml.erb @@ -0,0 +1,12 @@ +--- +- id: 1 + name: Some country + capital: <%= 'Somewhere' %> + density: 1.0 + population: 42 + founded_on: 2019-01-01 + updated_at: 2019-01-01T19:08:06-05:00 + nato: true + king: Bob Smith + continent: Some continent + region_code: SC diff --git a/spec/test_helper_spec.rb b/spec/test_helper_spec.rb index 83becfa..4c8334d 100644 --- a/spec/test_helper_spec.rb +++ b/spec/test_helper_spec.rb @@ -24,6 +24,36 @@ }.to raise_error(ArgumentError) end + it 'raises when alternate fixtures are missing attributes' do + original_base_path = Country.base_path + test_fixtures_base_path = File.join(File.dirname(__FILE__), 'fixtures', 'test_helper', 'missing_attributes') + + expect { + FrozenRecord::TestHelper.load_fixture(Country, test_fixtures_base_path) + }.to raise_error( + FrozenRecord::TestHelper::FixtureAttributeMismatch, + 'Country fixture attributes do not match (missing: nato)' + ) + + expect(Country.base_path).to eq(original_base_path) + expect(Country.count).to be == 3 + end + + it 'raises when alternate fixtures have unexpected attributes' do + original_base_path = Country.base_path + test_fixtures_base_path = File.join(File.dirname(__FILE__), 'fixtures', 'test_helper', 'unexpected_attributes') + + expect { + FrozenRecord::TestHelper.load_fixture(Country, test_fixtures_base_path) + }.to raise_error( + FrozenRecord::TestHelper::FixtureAttributeMismatch, + 'Country fixture attributes do not match (unexpected: region_code)' + ) + + expect(Country.base_path).to eq(original_base_path) + expect(Country.count).to be == 3 + end + it 'is a no-op when called again with the same path' do test_fixtures_base_path = File.join(File.dirname(__FILE__), 'fixtures', 'test_helper') FrozenRecord::TestHelper.load_fixture(Country, test_fixtures_base_path)