class NoBrainer::Matchers::Associations::HaveAssociationMatcher
The `belong_to` matcher is used to ensure that a `belongs_to` association exists on your model.
class Person include NoBrainer::Document belongs_to :organization end # RSpec RSpec.describe Person, type: :model do it { is_expected.to belong_to(:organization) } end
#### Qualifiers
##### class_name
Use `class_name` to test usage of the `:class_name` option. This asserts that the model you're referring to actually exists.
class Person include NoBrainer::Document belongs_to :ancient_city, class_name: 'City' end # RSpec RSpec.describe Person, type: :model do it { is_expected.to belong_to(:ancient_city).class_name('City') } end
##### with_primary_key
Use `with_primary_key` to test usage of the `:primary_key` option.
class Person include NoBrainer::Document belongs_to :great_country, primary_key: 'country_id' end # RSpec RSpec.describe Person, type: :model do it do is_expected.to belong_to(:great_country) .with_primary_key('country_id') end end
##### with_foreign_key
Use `with_foreign_key` to test usage of the `:foreign_key` option.
class Person include NoBrainer::Document belongs_to :great_country, foreign_key: 'country_id' end # RSpec RSpec.describe Person, type: :model do it do is_expected.to belong_to(:great_country) .with_foreign_key('country_id') end end
##### with_dependent
Use `with_dependent` to assert that the `:dependent` option was specified.
class Person include NoBrainer::Document belongs_to :world, dependent: :destroy end # RSpec RSpec.describe Person, type: :model do it { is_expected.to belong_to(:world).with_dependent(:destroy) } end
##### required
Use `required` to assert that the association is not allowed to be nil.
class Person include NoBrainer::Document belongs_to :organization, required: true end # RSpec describe Person it { is_expected.to belong_to(:organization).with_required(true) } end
Public Class Methods
new(name, association_type)
click to toggle source
# File lib/matchers/associations.rb, line 112 def initialize(name, association_type) @association = {} @association[:name] = name.to_sym @association[:type] = association_type @expectation_message = "#{type_description} #{@association[:name].inspect}" @expectation_message += " of type #{@association[:class].inspect}" unless @association[:class].nil? end
Public Instance Methods
class_name(klass)
click to toggle source
# File lib/matchers/associations.rb, line 120 def class_name(klass) @association[:class] = klass @expectation_message += " with class_name #{@association[:class].inspect}" self end
description()
click to toggle source
# File lib/matchers/associations.rb, line 242 def description @expectation_message end
failure_message_for_should()
click to toggle source
# File lib/matchers/associations.rb, line 231 def failure_message_for_should "Expected #{@actual.inspect} to #{@expectation_message}, got #{@negative_result_message}" end
Also aliased as: failure_message
failure_message_for_should_not()
click to toggle source
# File lib/matchers/associations.rb, line 235 def failure_message_for_should_not "Expected #{@actual.inspect} to not #{@expectation_message}, got #{@positive_result_message}" end
Also aliased as: failure_message_when_negated
matches?(actual)
click to toggle source
# File lib/matchers/associations.rb, line 157 def matches?(actual) @actual = actual.is_a?(Class) ? actual : actual.class metadata = @actual.association_metadata[@association[:name]] if metadata.nil? @negative_result_message = "no association named #{@association[:name]}" return false else @positive_result_message = "association named #{@association[:name]}" end relation = metadata.class.name.gsub(/::Metadata$/, '').constantize if relation != @association[:type] @negative_result_message = "#{@actual.inspect} #{type_description(relation, false)} #{@association[:name].inspect}" return false else @positive_result_message = "#{@actual.inspect} #{type_description(relation, false)} #{@association[:name].inspect}" end if !@association[:class].nil? && (@association[:class] != metadata.options[:class_name]) @negative_result_message = "#{@positive_result_message} with class_name #{metadata.options[:class_name].inspect}" return false else @positive_result_message = "#{@positive_result_message}#{" with class_name #{metadata.options[:class_name].inspect}" if @association[:class]}" end if @association[:dependent] if @association[:dependent].to_sym != (metadata.options[:dependent] && metadata.options[:dependent].to_sym) @negative_result_message = "#{@positive_result_message} which specified dependent as #{metadata.options[:dependent]}" return false else @positive_result_message = "#{@positive_result_message} which specified dependent as #{metadata.options[:dependent]}" end end if @association[:primary_key] if metadata.options[:primary_key] != @association[:primary_key] @negative_result_message = "#{@positive_result_message} with primary key #{metadata.options[:primary_key].inspect}" return false else @positive_result_message = "#{@positive_result_message} with primary key #{metadata.options[:primary_key].inspect}" end end if @association[:foreign_key] if metadata.foreign_key != @association[:foreign_key] @negative_result_message = "#{@positive_result_message} with foreign key #{metadata.foreign_key.inspect}" return false else @positive_result_message = "#{@positive_result_message} with foreign key #{metadata.foreign_key.inspect}" end end if @association[:through] if metadata.options[:through] != @association[:through] @negative_result_message = "#{@positive_result_message} through #{metadata.options[:through].inspect}" return false else @positive_result_message = "#{@positive_result_message} through #{metadata.options[:through].inspect}" end end if @association[:required] if metadata.options[:required] != @association[:required] @negative_result_message = "#{@positive_result_message} with required #{metadata.options[:required].inspect}" return false else @positive_result_message = "#{@positive_result_message} with required #{metadata.options[:required].inspect}" end end true end
through(association_key)
click to toggle source
# File lib/matchers/associations.rb, line 126 def through(association_key) @association[:through] = association_key @association[:type] = @association[:type] == HAS_ONE ? HAS_ONE_THROUGH : HAS_MANY_THROUGH @expectation_message += " through #{association_key.inspect}" self end
type_description(type = nil, passive = true)
click to toggle source
# File lib/matchers/associations.rb, line 246 def type_description(type = nil, passive = true) type ||= @association[:type] case type.name when HAS_ONE.name (passive ? 'have one' : 'having one') when HAS_ONE_THROUGH.name (passive ? 'have one through' : 'having one') when HAS_MANY.name (passive ? 'have many' : 'having many') when HAS_MANY_THROUGH.name (passive ? 'have many through' : 'having many') when BELONGS_TO.name (passive ? 'belong to' : 'belonging to') else raise format("Unknown association type #{type}") end end
with_dependent(method_name)
click to toggle source
# File lib/matchers/associations.rb, line 133 def with_dependent(method_name) @association[:dependent] = method_name @expectation_message += " which specifies dependent as #{@association[:dependent]}" self end
with_foreign_key(foreign_key)
click to toggle source
# File lib/matchers/associations.rb, line 145 def with_foreign_key(foreign_key) @association[:foreign_key] = foreign_key.to_sym @expectation_message += " using foreign key #{@association[:foreign_key].inspect}" self end
with_primary_key(primary_key)
click to toggle source
# File lib/matchers/associations.rb, line 139 def with_primary_key(primary_key) @association[:primary_key] = primary_key.to_sym @expectation_message += " using primary key #{@association[:primary_key].inspect}" self end
with_required(required)
click to toggle source
# File lib/matchers/associations.rb, line 151 def with_required(required) @association[:required] = required @expectation_message += " with required #{@association[:required].inspect}" self end
Private Instance Methods
association_kind_of()
click to toggle source
# File lib/matchers/associations.rb, line 266 def association_kind_of Mongoid::Compatibility::Version.mongoid5_or_older? ? Origin::Key : Mongoid::Criteria::Queryable::Key end