Matchi
Collection of expectation matchers for Rubyists 🤹
Project goals
- Provide a collection of useful generic matchers.
- Adding matchers should be as simple as possible.
- Being framework agnostic and easy to integrate.
Installation
Add this line to your application's Gemfile:
gem "matchi"
And then execute:
bundle
Or install it yourself as:
gem install matchi
Overview
Matchi provides a collection of damn simple expectation matchers.
Usage
To make Matchi available:
require "matchi"
All examples here assume that this has been done.
Anatomy of a matcher
A Matchi matcher is just an object that responds to the matches?
method with a block as argument, and returns a boolean. That's all it is.
But let's see some examples.
Built-in matchers
Equivalence matcher:
matcher = Matchi::Eq.new("foo")
matcher.matches? { "foo" } # => true
Identity matcher:
matcher = Matchi::Be.new(:foo)
matcher.matches? { :foo } # => true
Regular expressions matcher:
matcher = Matchi::Match.new(/^foo$/)
matcher.matches? { "foo" } # => true
Expecting errors matcher:
matcher = Matchi::RaiseException.new(NameError)
matcher.matches? { Boom } # => true
Type/class matcher:
matcher = Matchi::BeAnInstanceOf.new(:String)
matcher.matches? { "foo" } # => true
Change matcher:
object = []
matcher = Matchi::Change.new(object, :length).by(1)
matcher.matches? { object << 1 } # => true
object = []
matcher = Matchi::Change.new(object, :length).by_at_least(1)
matcher.matches? { object << 1 } # => true
object = []
matcher = Matchi::Change.new(object, :length).by_at_most(1)
matcher.matches? { object << 1 } # => true
object = "foo"
matcher = Matchi::Change.new(object, :to_s).from("foo").to("FOO")
matcher.matches? { object.upcase! } # => true
object = "foo"
matcher = Matchi::Change.new(object, :to_s).to("FOO")
matcher.matches? { object.upcase! } # => true
Satisfy matcher:
matcher = Matchi::Satisfy.new { |value| value == 42 }
matcher.matches? { 42 } # => true
Custom matchers
Custom matchers can easily be added to express more specific expectations.
A Be the answer matcher:
module Matchi
class BeTheAnswer
def matches?
42.equal?(yield)
end
end
end
matcher = Matchi::BeTheAnswer.new
matcher.matches? { 42 } # => true
A Be prime matcher:
require "prime"
module Matchi
class BePrime
def matches?
Prime.prime?(yield)
end
end
end
matcher = Matchi::BePrime.new
matcher.matches? { 42 } # => false
A Start with matcher:
module Matchi
class StartWith
attr_reader :expected
def initialize(expected)
@expected = expected
end
def matches?
Regexp.new(/\A#{expected}/).match?(yield)
end
end
end
matcher = Matchi::StartWith.new("foo")
matcher.matches? { "foobar" } # => true
Contact
- Home page: https://github.com/fixrb/matchi
- Bugs/issues: https://github.com/fixrb/matchi/issues
Versioning
Matchi follows Semantic Versioning 2.0.
License
The gem is available as open source under the terms of the MIT License.