Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding support to allow_nil option for delegate_method matcher #798

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Appraisals
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
ruby_version = Gem::Version.new(RUBY_VERSION + '')

shared_dependencies = proc do
gem 'rspec-rails', '>= 3.2.0', '< 4'
gem 'rspec-rails', '>= 3.3.0', '< 4'
gem 'shoulda-context', '~> 1.2.0'
gem 'sqlite3', platform: :ruby
gem 'pg', platform: :ruby
Expand Down
4 changes: 2 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ gem 'bundler', '~> 1.1'
gem 'pry', github: 'pry/pry'
gem 'pry-byebug'
gem 'rake', '~> 10.0'
gem 'rspec-core', '>= 3.2.0', '< 4'
gem 'rspec-expectations', '>= 3.2.0', '< 4'
gem 'rspec-core', '>= 3.3.0', '< 4'
gem 'rspec-expectations', '>= 3.3.0', '< 4'

# YARD
gem 'yard'
Expand Down
7 changes: 2 additions & 5 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,6 @@ DEPENDENCIES
pygments.rb
rake (~> 10.0)
redcarpet
rspec-core (>= 3.2.0, < 4)
rspec-expectations (>= 3.2.0, < 4)
rspec-core (>= 3.3.0, < 4)
rspec-expectations (>= 3.3.0, < 4)
yard

BUNDLED WITH
1.10.6
6 changes: 3 additions & 3 deletions gemfiles/4.0.0.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ gem "bundler", "~> 1.1"
gem "pry", :github => "pry/pry"
gem "pry-byebug"
gem "rake", "~> 10.0"
gem "rspec-core", ">= 3.2.0", "< 4"
gem "rspec-expectations", ">= 3.2.0", "< 4"
gem "rspec-core", ">= 3.3.0", "< 4"
gem "rspec-expectations", ">= 3.3.0", "< 4"
gem "yard"
gem "redcarpet"
gem "pygments.rb"
gem "fssm"
gem "rspec-rails", ">= 3.2.0", "< 4"
gem "rspec-rails", ">= 3.3.0", "< 4"
gem "shoulda-context", "~> 1.2.0"
gem "sqlite3", :platform => :ruby
gem "pg", :platform => :ruby
Expand Down
9 changes: 3 additions & 6 deletions gemfiles/4.0.0.gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -199,9 +199,9 @@ DEPENDENCIES
rails (= 4.0.0)
rake (~> 10.0)
redcarpet
rspec-core (>= 3.2.0, < 4)
rspec-expectations (>= 3.2.0, < 4)
rspec-rails (>= 3.2.0, < 4)
rspec-core (>= 3.3.0, < 4)
rspec-expectations (>= 3.3.0, < 4)
rspec-rails (>= 3.3.0, < 4)
sass-rails (~> 4.0.0)
sdoc
shoulda-context (~> 1.2.0)
Expand All @@ -212,6 +212,3 @@ DEPENDENCIES
turbolinks
uglifier (>= 1.3.0)
yard

BUNDLED WITH
1.10.6
6 changes: 3 additions & 3 deletions gemfiles/4.0.1.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ gem "bundler", "~> 1.1"
gem "pry", :github => "pry/pry"
gem "pry-byebug"
gem "rake", "~> 10.0"
gem "rspec-core", ">= 3.2.0", "< 4"
gem "rspec-expectations", ">= 3.2.0", "< 4"
gem "rspec-core", ">= 3.3.0", "< 4"
gem "rspec-expectations", ">= 3.3.0", "< 4"
gem "yard"
gem "redcarpet"
gem "pygments.rb"
gem "fssm"
gem "rspec-rails", ">= 3.2.0", "< 4"
gem "rspec-rails", ">= 3.3.0", "< 4"
gem "shoulda-context", "~> 1.2.0"
gem "sqlite3", :platform => :ruby
gem "pg", :platform => :ruby
Expand Down
9 changes: 3 additions & 6 deletions gemfiles/4.0.1.gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -201,9 +201,9 @@ DEPENDENCIES
rails (= 4.0.1)
rake (~> 10.0)
redcarpet
rspec-core (>= 3.2.0, < 4)
rspec-expectations (>= 3.2.0, < 4)
rspec-rails (>= 3.2.0, < 4)
rspec-core (>= 3.3.0, < 4)
rspec-expectations (>= 3.3.0, < 4)
rspec-rails (>= 3.3.0, < 4)
sass-rails (~> 4.0.0)
sdoc
shoulda-context (~> 1.2.0)
Expand All @@ -214,6 +214,3 @@ DEPENDENCIES
turbolinks
uglifier (>= 1.3.0)
yard

BUNDLED WITH
1.10.6
6 changes: 3 additions & 3 deletions gemfiles/4.1.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ gem "bundler", "~> 1.1"
gem "pry", :github => "pry/pry"
gem "pry-byebug"
gem "rake", "~> 10.0"
gem "rspec-core", ">= 3.2.0", "< 4"
gem "rspec-expectations", ">= 3.2.0", "< 4"
gem "rspec-core", ">= 3.3.0", "< 4"
gem "rspec-expectations", ">= 3.3.0", "< 4"
gem "yard"
gem "redcarpet"
gem "pygments.rb"
gem "fssm"
gem "rspec-rails", ">= 3.2.0", "< 4"
gem "rspec-rails", ">= 3.3.0", "< 4"
gem "shoulda-context", "~> 1.2.0"
gem "sqlite3", :platform => :ruby
gem "pg", :platform => :ruby
Expand Down
9 changes: 3 additions & 6 deletions gemfiles/4.1.gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,9 @@ DEPENDENCIES
rails (~> 4.1.0)
rake (~> 10.0)
redcarpet
rspec-core (>= 3.2.0, < 4)
rspec-expectations (>= 3.2.0, < 4)
rspec-rails (>= 3.2.0, < 4)
rspec-core (>= 3.3.0, < 4)
rspec-expectations (>= 3.3.0, < 4)
rspec-rails (>= 3.3.0, < 4)
sass-rails (~> 4.0.3)
sdoc (~> 0.4.0)
shoulda-context (~> 1.2.0)
Expand All @@ -209,6 +209,3 @@ DEPENDENCIES
turbolinks
uglifier (>= 1.3.0)
yard

BUNDLED WITH
1.10.6
6 changes: 3 additions & 3 deletions gemfiles/4.2.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ gem "bundler", "~> 1.1"
gem "pry", :github => "pry/pry"
gem "pry-byebug"
gem "rake", "~> 10.0"
gem "rspec-core", ">= 3.2.0", "< 4"
gem "rspec-expectations", ">= 3.2.0", "< 4"
gem "rspec-core", ">= 3.3.0", "< 4"
gem "rspec-expectations", ">= 3.3.0", "< 4"
gem "yard"
gem "redcarpet"
gem "pygments.rb"
gem "fssm"
gem "rspec-rails", ">= 3.2.0", "< 4"
gem "rspec-rails", ">= 3.3.0", "< 4"
gem "shoulda-context", "~> 1.2.0"
gem "sqlite3", :platform => :ruby
gem "pg", :platform => :ruby
Expand Down
9 changes: 3 additions & 6 deletions gemfiles/4.2.gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -219,9 +219,9 @@ DEPENDENCIES
rails (~> 4.2.0)
rake (~> 10.0)
redcarpet
rspec-core (>= 3.2.0, < 4)
rspec-expectations (>= 3.2.0, < 4)
rspec-rails (>= 3.2.0, < 4)
rspec-core (>= 3.3.0, < 4)
rspec-expectations (>= 3.3.0, < 4)
rspec-rails (>= 3.3.0, < 4)
sass-rails (~> 5.0)
sdoc (~> 0.4.0)
shoulda-context (~> 1.2.0)
Expand All @@ -232,6 +232,3 @@ DEPENDENCIES
turbolinks
uglifier (>= 1.3.0)
yard

BUNDLED WITH
1.10.6
34 changes: 29 additions & 5 deletions lib/shoulda/matchers/independent/delegate_method_matcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,8 @@ def matches?(subject)

subject_has_delegating_method? &&
subject_has_delegate_object_reader_method? &&
subject_delegates_to_delegate_object_correctly?
subject_delegates_to_delegate_object_correctly? &&
subject_delegates_to_nil_delegate_object_correctly?
end

def description
Expand All @@ -191,6 +192,10 @@ def description
string << " passing arguments #{delegated_arguments.inspect}"
end

if delegate_object_is_nil_allowed
string << ' allowing nil'
end

if delegate_method != delegating_method
string << " as #{formatted_delegate_method}"
end
Expand Down Expand Up @@ -220,6 +225,11 @@ def with_prefix(prefix = nil)
self
end

def allow_nil
@delegate_object_is_nil_allowed = true
self
end

def build_delegating_method_prefix(prefix)
case prefix
when true, nil then delegate_object_reader_method
Expand Down Expand Up @@ -248,7 +258,8 @@ def failure_message_when_negated
:delegate_method,
:subject_double_collection,
:delegate_object,
:delegate_object_reader_method
:delegate_object_reader_method,
:delegate_object_is_nil_allowed

def subject
@subject
Expand Down Expand Up @@ -328,8 +339,21 @@ def ensure_delegate_object_has_been_specified!
end
end

def subject_delegates_to_nil_delegate_object_correctly?
return true unless delegate_object_is_nil_allowed
register_subject_double_collection_to(nil)

Doublespeak.with_doubles_activated do
begin
subject.public_send(delegating_method, *delegated_arguments).nil?
rescue
false
end
end
end

def subject_delegates_to_delegate_object_correctly?
register_subject_double_collection
register_subject_double_collection_to(delegate_object)

Doublespeak.with_doubles_activated do
subject.public_send(delegating_method, *delegated_arguments)
Expand All @@ -342,11 +366,11 @@ def subject_delegates_to_delegate_object_correctly?
end
end

def register_subject_double_collection
def register_subject_double_collection_to(returned_object)
double_collection =
Doublespeak.double_collection_for(subject.singleton_class)
double_collection.register_stub(delegate_object_reader_method).
to_return(delegate_object)
to_return(returned_object)

@subject_double_collection = double_collection
end
Expand Down
105 changes: 105 additions & 0 deletions spec/unit/shoulda/matchers/independent/delegate_method_matcher_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -514,4 +514,109 @@ def country
end
end
end

context 'qualified with #allow_nil' do
context 'when using delegate from rails' do
context 'when delegate call allows nil' do
it 'accepts' do
define_class('Person') do
delegate :hello, to: :country, allow_nil: true
def country; end
end

person = Person.new
expect(person).to delegate_method(:hello).to(:country).allow_nil
end
end

context 'when delegate call does not allow nil' do
it 'rejects with the correct failure message' do
define_class('Person') do
delegate :hello, to: :country
def country; end
end

message = [
'Expected Person to delegate #hello to #country'\
' object allowing nil',
'Method calls sent to Person#country:',
].join("\n")

person = Person.new

expect do
expect(person).to delegate_method(:hello).to(:country).allow_nil
end.to fail_including(message)
end
end
end
context 'when using Forwardable' do
context 'when delegate object is nil' do
it 'rejects with the correct failure message' do
define_class('Person') do
extend Forwardable

def_delegators :country, :hello

def country; end
end

message = [
'Expected Person to delegate #hello to #country'\
' object allowing nil',
'Method calls sent to Person#country:',
'1) hello()',
].join("\n")

person = Person.new

expect do
expect(person).to delegate_method(:hello).to(:country).allow_nil
end.to fail_with_message(message)
end
end
end
context 'when using methods' do
context 'when supports nil delegate object' do
it 'accepts' do
define_class('Person') do
def country; end

def hello
return unless country
country.hello
end
end

person = Person.new
expect(person).to delegate_method(:hello).to(:country).allow_nil
end
end

context 'when does not supports nil delegate object' do
it 'rejects with the correct failure message' do
define_class('Person') do
def country; end

def hello
country.hello
end
end

message = [
'Expected Person to delegate #hello to #country'\
' object allowing nil',
'Method calls sent to Person#country:',
'1) hello()',
].join("\n")

person = Person.new

expect do
expect(person).to delegate_method(:hello).to(:country).allow_nil
end.to fail_with_message(message)
end
end
end
end
end
2 changes: 2 additions & 0 deletions spec/unit_spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
ENV['RAILS_ENV'] = 'test'

require 'rspec/rails'
require 'rspec/matchers/fail_matchers'
require 'shoulda-matchers'

PROJECT_ROOT = File.expand_path('../..', __FILE__)
Expand Down Expand Up @@ -59,6 +60,7 @@
UnitTests::ColumnTypeHelpers.configure_example_group(config)

config.include UnitTests::Matchers
config.include RSpec::Matchers::FailMatchers
end

ActiveSupport::Deprecation.behavior = :stderr
Expand Down