From 3da8bccd2e7c712f58352c3a05bfe3131c55ea0c Mon Sep 17 00:00:00 2001 From: Rafael Santos Date: Thu, 12 Jan 2017 11:08:23 +1300 Subject: [PATCH 1/2] pass correct object type to association reflection This is to make the association relation receive the expected parameter (a AR instance, not its class). --- .../association_matchers/model_reflection.rb | 4 ++-- .../association_matchers/model_reflector.rb | 6 +++++- .../model_reflection_spec.rb | 19 +++++++++++++++++-- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb b/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb index 882808f42..40eb27f9d 100644 --- a/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb +++ b/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb @@ -35,12 +35,12 @@ def join_table_name join_table_name.to_s end - def association_relation + def association_relation(related_instance) relation = associated_class.all if reflection.scope # Source: AR::Associations::AssociationScope#eval_scope - relation.instance_exec(subject, &reflection.scope) + relation.instance_exec(related_instance, &reflection.scope) else relation end diff --git a/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb b/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb index 0d0503c9b..e54bb1e4c 100644 --- a/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb +++ b/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb @@ -5,7 +5,7 @@ module AssociationMatchers # @private class ModelReflector delegate :associated_class, :through?, :join_table_name, - :association_relation, :polymorphic?, :foreign_key, + :polymorphic?, :foreign_key, :association_foreign_key, to: :reflection def initialize(subject, name) @@ -13,6 +13,10 @@ def initialize(subject, name) @name = name end + def association_relation + reflection.association_relation(subject) + end + def reflection @reflection ||= reflect_on_association(name) end diff --git a/spec/unit/shoulda/matchers/active_record/association_matchers/model_reflection_spec.rb b/spec/unit/shoulda/matchers/active_record/association_matchers/model_reflection_spec.rb index 6be807281..52551275e 100644 --- a/spec/unit/shoulda/matchers/active_record/association_matchers/model_reflection_spec.rb +++ b/spec/unit/shoulda/matchers/active_record/association_matchers/model_reflection_spec.rb @@ -95,10 +95,25 @@ person_model = define_model(:person, country_id: :integer) do belongs_to :country, -> { where(mood: 'nice') } end + person_instance = person_model.new(spirit: 'nice') delegate_reflection = person_model.reflect_on_association(:country) reflection = described_class.new(delegate_reflection) - actual_sql = reflection.association_relation.to_sql + actual_sql = reflection.association_relation(person_instance).to_sql + expected_sql = Country.where(mood: 'nice').to_sql + expect(actual_sql).to eq expected_sql + end + + it 'executes the block in the context of an empty scope parametrised by association source' do + define_model(:country, mood: :string) + person_model = define_model(:person, country_id: :integer, spirit: :string) do + belongs_to :country, -> (person) { where(mood: person.spirit) } + end + person_instance = person_model.new(spirit: 'nice') + delegate_reflection = person_model.reflect_on_association(:country) + reflection = described_class.new(delegate_reflection) + + actual_sql = reflection.association_relation(person_instance).to_sql expected_sql = Country.where(mood: 'nice').to_sql expect(actual_sql).to eq expected_sql end @@ -113,7 +128,7 @@ delegate_reflection = person_model.reflect_on_association(:country) reflection = described_class.new(delegate_reflection) - actual_sql = reflection.association_relation.to_sql + actual_sql = reflection.association_relation(person_model).to_sql expected_sql = Country.all.to_sql expect(actual_sql).to eq expected_sql end From 66d5b5d5716012382c9805dbcc476c840aedf412 Mon Sep 17 00:00:00 2001 From: Rafael Santos Date: Mon, 16 Jan 2017 10:25:26 +1300 Subject: [PATCH 2/2] update test to test only the block param --- .../association_matchers/model_reflection_spec.rb | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/spec/unit/shoulda/matchers/active_record/association_matchers/model_reflection_spec.rb b/spec/unit/shoulda/matchers/active_record/association_matchers/model_reflection_spec.rb index 52551275e..d47b0894d 100644 --- a/spec/unit/shoulda/matchers/active_record/association_matchers/model_reflection_spec.rb +++ b/spec/unit/shoulda/matchers/active_record/association_matchers/model_reflection_spec.rb @@ -104,18 +104,19 @@ expect(actual_sql).to eq expected_sql end - it 'executes the block in the context of an empty scope parametrised by association source' do + it 'pass instance of association source to block' do + spy = spy('spy') define_model(:country, mood: :string) - person_model = define_model(:person, country_id: :integer, spirit: :string) do - belongs_to :country, -> (person) { where(mood: person.spirit) } + person_model = define_model(:person, country_id: :integer) do + belongs_to :country, ->(person) { spy.who(person) } end person_instance = person_model.new(spirit: 'nice') delegate_reflection = person_model.reflect_on_association(:country) reflection = described_class.new(delegate_reflection) - actual_sql = reflection.association_relation(person_instance).to_sql - expected_sql = Country.where(mood: 'nice').to_sql - expect(actual_sql).to eq expected_sql + reflection.association_relation(person_instance) + + expect(spy).to have_received(:who).with(person_instance) end end