I've got these two matchers that are identical apart from their names:
RSpec::Matchers.define :be_the_downcased_version_of do |actual|
match do |actual|
@actual = actual
@expected = expected
@actual == @expected.downcase
end
failure_message do |actual|
"Expected #{@actual.inspect} to be the downcased version of #{expected.inspect}.\nIt was not: #{@actual.inspect}"
end
failure_message_when_negated do |actual|
"Expected #{@actual.inspect} to not be the downcased version of #{expected.inspect}.\nIt was: #{@actual.inspect}"
end
description do
"be the downcased version of #{expected.inspect}"
end
end
RSpec::Matchers.define :return_the_downcased_version_of do |actual|
match do |actual|
@actual = actual
@expected = expected
@actual == @expected.downcase
end
failure_message do |actual|
"Expected #{@actual.inspect} to be the downcased version of #{expected.inspect}.\nIt was not: #{@actual.inspect}"
end
failure_message_when_negated do |actual|
"Expected #{@actual.inspect} to not be the downcased version of #{expected.inspect}.\nIt was: #{@actual.inspect}"
end
description do
"be the downcased version of #{expected.inspect}"
end
end
Can I alias them like when aliasing a method with Ruby?
alias_method :foo_meth, :bar_meth
As cbliard commented, you can simply do
RSpec::Matchers.define :be_the_downcased_version_of do |expected|
match do |actual|
# ...
end
# ...
end
RSpec::Matchers.alias_matcher :return_the_downcased_version_of, :be_the_downcased_version_of
to alias the matcher. Which is in my opinion a very clean solution.
Yes, you can alias a matcher defined with RSpec's matcher DSL. The most convenient way that I know to do it is to reopen the example context's class in a before
block and alias the method there.
But first, let's clean up your matcher.
Matchers.define
takes the expected value, not
the actual value, as its argument.In spec/support/be_the_downcased_version_of.rb:
RSpec::Matchers.define :be_the_downcased_version_of do |expected|
match do |actual|
actual == expected.downcase
end
failure_message_for_should do |actual|
"Expected #{actual.inspect} to be the downcased version of #{expected.inspect}.\nIt was not: #{actual.inspect}"
end
failure_message_for_should_not do |actual|
"Expected #{actual.inspect} to not be the downcased version of #{expected.inspect}.\nIt was: #{actual.inspect}"
end
description do
"be the downcased version of #{expected.inspect}"
end
end
To alias the method defined by that matcher, in spec/spec_helper.rb:
config.before :each do
class << self
alias_method :return_the_downcased_version_of, :be_the_downcased_version_of
end
end
Here's an alternate approach. I wouldn't actually do this, because it requires more boilerplate, but it uses less magic than the previous approach so it might be informative. Just implement the matcher without the DSL and alias the method normally. In spec/support/be_the_downcased_version_of.rb:
alias_method :return_the_downcased_version_of, :be_the_downcased_version_of
def be_the_downcased_version_of(actual)
BeTheDowncasedVersionOf.new actual
end
class BeTheDowncasedVersionOf
def initialize(expected)
@expected = expected
end
def matches?(actual)
@actual = actual
@actual == @expected.downcase
end
def failure_message_for_should
"Expected #{@actual.inspect} to be the downcased version of #{@expected.inspect}.\nIt was not: #{@actual.inspect}"
end
def failure_message_for_should_not
"Expected #{@actual.inspect} to not be the downcased version of #{@expected.inspect}.\nIt was: #{@actual.inspect}"
end
def description
"be the downcased version of #{@expected.inspect}"
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With