Skip to content

Instantly share code, notes, and snippets.

@r7kamura
Last active November 11, 2023 06:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save r7kamura/19991db53e77d638ade11e4abce1e055 to your computer and use it in GitHub Desktop.
Save r7kamura/19991db53e77d638ade11e4abce1e055 to your computer and use it in GitHub Desktop.
RSpec matcher with pattern-matching.
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'rspec'
end
require 'rspec/autorun'
RSpec::Matchers.matcher :match_pattern do |expected|
match do |actual|
eval(<<~RUBY, binding, __FILE__, __LINE__ + 1)
actual in #{expected.inspect}
RUBY
end
failure_message do |actual|
<<~TEXT
expected #{actual.inspect} to match pattern #{expected.inspect}
TEXT
end
end
RSpec.describe '#match_pattern' do
context 'when pattern-matching succeeds' do
it 'succeeds' do
expect([1, 2, 3]).to match_pattern([Integer, Integer, Integer])
end
end
context 'when pattern-matching fails' do
it 'fails' do
expect([1, 2, 3]).to match_pattern([Integer, Integer, String])
end
end
context 'when a pattern is passed that cannot be used as pattern-matching' do
it 'raises SyntaxError' do
expect([1, 2, 3]).to match_pattern(Object.new)
end
end
end
@r7kamura
Copy link
Author

r7kamura commented Nov 11, 2023

$ ruby rspec-match_pattern.rb --format documentation

#match_pattern
  when pattern-matching succeeds
    succeeds
  when pattern-matching fails
    fails (FAILED - 1)
  when a pattern is passed that cannot be used as pattern-matching
    raises SyntaxError (FAILED - 2)

Failures:

  1) #match_pattern when pattern-matching fails fails
     Failure/Error: expect([1, 2, 3]).to match_pattern([Integer, Integer, String])
       expected [1, 2, 3] to match pattern [Integer, Integer, String]
     # rspec-match_pattern.rb:34:in `block (3 levels) in <main>'

  2) #match_pattern when a pattern is passed that cannot be used as pattern-matching raises SyntaxError
     Failure/Error:
       eval(<<~RUBY, binding, __FILE__, __LINE__ + 1)
         actual in #{expected.inspect}
       RUBY

     SyntaxError:
       rspec-match_pattern.rb:14: syntax error, unexpected end-of-input
       ...in #<Object:0x00007ff26bf5aab8>
       ...                               ^
     # rspec-match_pattern.rb:13:in `eval'
     # rspec-match_pattern.rb:13:in `block (2 levels) in <main>'
     # rspec-match_pattern.rb:40:in `block (3 levels) in <main>'

Finished in 0.00586 seconds (files took 0.04452 seconds to load)
3 examples, 2 failures

Failed examples:

rspec rspec-match_pattern.rb:33 # #match_pattern when pattern-matching fails fails
rspec rspec-match_pattern.rb:39 # #match_pattern when a pattern is passed that cannot be used as pattern-matching raises SyntaxError

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment