Skip to content

Commit

Permalink
Support block snippet extraction with aliases of #change and #satisfy
Browse files Browse the repository at this point in the history
  • Loading branch information
yujinakayama committed May 4, 2017
1 parent 9f72ce3 commit 8b81a0e
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 18 deletions.
39 changes: 23 additions & 16 deletions lib/rspec/matchers/built_in/change.rb
Expand Up @@ -8,46 +8,46 @@ class Change < BaseMatcher
# @api public
# Specifies the delta of the expected change.
def by(expected_delta)
ChangeRelatively.new(@change_details, expected_delta, :by) do |actual_delta|
ChangeRelatively.new(change_details, expected_delta, :by) do |actual_delta|
values_match?(expected_delta, actual_delta)
end
end

# @api public
# Specifies a minimum delta of the expected change.
def by_at_least(minimum)
ChangeRelatively.new(@change_details, minimum, :by_at_least) do |actual_delta|
ChangeRelatively.new(change_details, minimum, :by_at_least) do |actual_delta|
actual_delta >= minimum
end
end

# @api public
# Specifies a maximum delta of the expected change.
def by_at_most(maximum)
ChangeRelatively.new(@change_details, maximum, :by_at_most) do |actual_delta|
ChangeRelatively.new(change_details, maximum, :by_at_most) do |actual_delta|
actual_delta <= maximum
end
end

# @api public
# Specifies the new value you expect.
def to(value)
ChangeToValue.new(@change_details, value)
ChangeToValue.new(change_details, value)
end

# @api public
# Specifies the original value.
def from(value)
ChangeFromValue.new(@change_details, value)
ChangeFromValue.new(change_details, value)
end

# @private
def matches?(event_proc)
@event_proc = event_proc
return false unless Proc === event_proc
raise_block_syntax_error if block_given?
@change_details.perform_change(event_proc)
@change_details.changed?
change_details.perform_change(event_proc)
change_details.changed?
end

def does_not_match?(event_proc)
Expand All @@ -58,21 +58,21 @@ def does_not_match?(event_proc)
# @api private
# @return [String]
def failure_message
"expected #{@change_details.value_representation} to have changed, " \
"expected #{change_details.value_representation} to have changed, " \
"but #{positive_failure_reason}"
end

# @api private
# @return [String]
def failure_message_when_negated
"expected #{@change_details.value_representation} not to have changed, " \
"expected #{change_details.value_representation} not to have changed, " \
"but #{negative_failure_reason}"
end

# @api private
# @return [String]
def description
"change #{@change_details.value_representation}"
"change #{change_details.value_representation}"
end

# @private
Expand All @@ -83,7 +83,13 @@ def supports_block_expectations?
private

def initialize(receiver=nil, message=nil, &block)
@change_details = ChangeDetails.new(receiver, message, &block)
@receiver = receiver
@message = message
@block = block
end

def change_details
@change_details ||= ChangeDetails.new(matcher_name, @receiver, @message, &@block)
end

def raise_block_syntax_error
Expand All @@ -93,13 +99,13 @@ def raise_block_syntax_error

def positive_failure_reason
return "was not given a block" unless Proc === @event_proc
"is still #{description_of @change_details.actual_before}"
"is still #{description_of change_details.actual_before}"
end

def negative_failure_reason
return "was not given a block" unless Proc === @event_proc
"did change from #{description_of @change_details.actual_before} " \
"to #{description_of @change_details.actual_after}"
"did change from #{description_of change_details.actual_before} " \
"to #{description_of change_details.actual_after}"
end
end

Expand Down Expand Up @@ -309,7 +315,7 @@ def change_description
class ChangeDetails
attr_reader :actual_before, :actual_after

def initialize(receiver=nil, message=nil, &block)
def initialize(matcher_name, receiver=nil, message=nil, &block)
if receiver && !message
raise(
ArgumentError,
Expand All @@ -319,6 +325,7 @@ def initialize(receiver=nil, message=nil, &block)
)
end

@matcher_name = matcher_name
@receiver = receiver
@message = message
@value_proc = block
Expand Down Expand Up @@ -367,7 +374,7 @@ def evaluate_value_proc
if RSpec::Support::RubyFeatures.ripper_supported?
def extract_value_block_snippet
return nil unless @value_proc
Expectations::BlockSnippetExtractor.try_extracting_single_line_body_of(@value_proc, 'change')
Expectations::BlockSnippetExtractor.try_extracting_single_line_body_of(@value_proc, @matcher_name)
end
else
def extract_value_block_snippet
Expand Down
2 changes: 1 addition & 1 deletion lib/rspec/matchers/built_in/satisfy.rb
Expand Up @@ -47,7 +47,7 @@ def block_representation

def extract_block_snippet
return nil unless @block
Expectations::BlockSnippetExtractor.try_extracting_single_line_body_of(@block, 'satisfy')
Expectations::BlockSnippetExtractor.try_extracting_single_line_body_of(@block, matcher_name)
end
else
def block_representation
Expand Down
2 changes: 1 addition & 1 deletion spec/rspec/matchers/built_in/change_spec.rb
Expand Up @@ -287,7 +287,7 @@ def @instance.reload
context 'when used with an alias name' do
alias_matcher :modify, :change

pending 'can extract the block snippet' do
it 'can extract the block snippet' do
expect(modify { @instance.some_value }.description).to eq "modify `@instance.some_value`"
end
end
Expand Down
10 changes: 10 additions & 0 deletions spec/rspec/matchers/built_in/satisfy_spec.rb
Expand Up @@ -27,6 +27,16 @@
end
end.to fail_with("expected false to satisfy expression `val`")
end

context 'when used with an alias name' do
alias_matcher :fulfill, :satisfy

it 'can extract the block snippet' do
expect {
expect(false).to fulfill { |val| val }
}.to fail_with("expected false to fulfill expression `val`")
end
end
end

context 'in Ripper unsupported environment', :unless => RSpec::Support::RubyFeatures.ripper_supported? do
Expand Down

0 comments on commit 8b81a0e

Please sign in to comment.