# ramcrest-ruby **Repository Path**: mirrors/ramcrest-ruby ## Basic Information - **Project Name**: ramcrest-ruby - **Description**: Hamcrest in Ruby - **Primary Language**: Ruby - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 7 - **Forks**: 0 - **Created**: 2019-08-08 - **Last Updated**: 2025-09-06 ## Categories & Tags **Categories**: testing **Tags**: None ## README Ramcrest: a Ruby port of Hamcrest [![Build Status](https://secure.travis-ci.org/hamcrest/ramcrest.png?branch=master)](http://travis-ci.org/hamcrest/ramcrest) --------------------------------- Hamcrest is a powerful set of classes and functions that allow building up complicated matching expressions. The matchers provide useful descriptions of what they are trying to match, as well as a description of why a particular object is not matched (a mismatch description). The tests for the various matchers should provide great examples of usage because each matcher is actually tested using the Ramcrest framework. There are integrations into MiniTest via `assert_that(actual, matcher)` and into RSpec 2.11 via `expect(actual).that matcher`. How do I use this? ------------------ In your tests you need to ````ruby require 'ramcrest' ```` which will bring in all of the base Ramcrest matchers and give you a new `assert_that(subject, matcher)` assertion for your MiniTest tests. Once you have loaded the matchers you can now `include` them in your tests and start matching away! ````ruby describe My::Funky::Class do include Ramcrest::HasAttribute include Ramcrest::IncludesExactly it "only knows the funky chicken by default" do assert_that My::Funky::Class.new, has_attribute(:dances, includes_exactly(:funky_chicken)) end end ```` This matches an object that has an attribute (actually just a no arg method) called `dances` where the result of calling that method is an `Enumerable` that includes only the symbol `:funky_chicken`. What matchers are included? --------------------------- This is the list of current matchers. This list will grow over time and some names might change in order to allow for integration into various testing frameworks. * `Ramcrest::Aint` - Logical negation. ````ruby assert_that 1, aint(2) assert_that [2], aint(includes_exactly(1)) ```` * `Ramcrest::Anything` - Everything's OK! ````ruby assert_that "a value", anything ```` * `Ramcrest::Comparable` - Matchers for ordering comparisons. ````ruby assert_that 1, greater_than(0) assert_that 2, less_than(3) assert_that 3, greater_or_equal_to(3) assert_that 4, less_or_equal_to(4) ```` * `Ramcrest::EqualTo` - Equality (via `==`). ````ruby assert_that "my value", equal_to("my value") ```` * `Ramcrest::HasAttribute` - Object attribute matching. ````ruby dance = Struct.new(:twist).new(2) assert_that dance, has_attribute(:funk) # the attribute exits assert_that dance, has_attribute(:funk, equal_to(2)) # the attribute exists with a value ```` * `Ramcrest::HasSize` - Collection size. ````ruby assert_that [1, 2], has_size(2) assert_that { :a => 1 }, has_size(less_or_equal_to(3)) ```` * `Ramcrest::Includes` - Enumerable inclusion. ````ruby assert_that [1, 2, 3], includes(2, 3) assert_that [6, 7, 2], includes(6, greater_than(6)) ```` * `Ramcrest::IncludesExactly` - Enumerable equality. ````ruby assert_that [1, 2, 3], includes_exactly(1, 2, 3) assert_that [3, 2, 1], aint(includes_exactly(1, 2, 3)) assert_that [1], aint(includes_exactly(1, 2)) ```` * `Ramcrest::IncludesInAnyOrderExactly` - Enumerable set equality. ````ruby assert_that [2, 1, 3], includes_in_any_order_exactly(1, 2, 3) assert_that [1, 3, 4], aint(includes_in_any_order_exactly(1, 3)) ```` * `Ramcrest::Is` - Syntactic sugar for equality. ````ruby assert_that 1, is(1) assert_that 2, is(greater_than(1)) ```` * `Ramcrest::SuchThat` - Ad hoc matchers. ````ruby assert_that "my string", such_that do |value| value =~ /string/ ? success : mismatch("didn't contain 'string'") end ```` Writing your own matchers ------------------------- The simplest way to get started writing your own own matchers is to just make ad-hoc matchers using `such_that` and chained match results. For example to put together a matcher for a certain type that has two properties you can simply do: ````ruby def a_token(with_attributes) name = has_attribute(:name, equal_to(with_attributes[:named])) string = has_attribute(:string, equal_to(with_attributes[:string])) description = "a token named <#{with_attributes[:named]}> with string <#{with_attributes[:string]}>" such_that(description) do |actual| name.matches?(actual).and_also { string.matches?(actual) } end end ```` Using `such_that` should be able to allow you to write any matcher that you want in a simple and straight-forward way. If you outgrow these kinds of matchers and want to move onto much larger possiblities, then you just need to implement a class with two methods: `matches?(actual)` and `descriptionf`. The `matches?` method needs to return either `success` or `mismatch(description)`. ````ruby class AToken include Ramcrest::Matcher def initialize(name) @matchers = [Ramcrest::HasAttribute.has_attribute(:name, equal_to(name))] end def with_string(string) @matchers << Ramcrest::HasAttribute.has_attribute(:string, equal_to(string)) self end def matches?(actual) @matchers. collect { |matcher| matcher.matches?(actual) }. find(method(:success)) { |result| !result.matched? } end def description "a token that #{@matchers.collect(&:description).join(' and ')}" end end def a_token_named(name) AToken.new(name) end assert_that something, is(a_token_named("foo").with_string("bar")) assert_that something_else, is(a_token_named("baz")) ````