ramcrest 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,20 @@
1
+ module Ramcrest
2
+ require 'ramcrest/minitest_assert'
3
+ require 'ramcrest/rspec'
4
+ require 'ramcrest/equal_to'
5
+ require 'ramcrest/comparable'
6
+ require 'ramcrest/is'
7
+ require 'ramcrest/aint'
8
+ require 'ramcrest/anything'
9
+ require 'ramcrest/has_attribute'
10
+ require 'ramcrest/has_size'
11
+ require 'ramcrest/includes'
12
+ require 'ramcrest/includes_exactly'
13
+ require 'ramcrest/includes_in_any_order_exactly'
14
+ require 'ramcrest/such_that'
15
+ require 'ramcrest/matcher_matcher'
16
+
17
+ def self.is_matcher?(possible_matcher)
18
+ possible_matcher.respond_to?(:matches?) && possible_matcher.respond_to?(:description)
19
+ end
20
+ end
@@ -0,0 +1,30 @@
1
+ require 'ramcrest/matcher'
2
+
3
+ module Ramcrest
4
+ module Aint
5
+ module_function
6
+ def aint(expected)
7
+ Matcher.new(Ramcrest::EqualTo.to_matcher(expected))
8
+ end
9
+
10
+ class Matcher
11
+ include Ramcrest::Matcher
12
+
13
+ def initialize(expected)
14
+ @expected = expected
15
+ end
16
+
17
+ def do_match(expected, actual)
18
+ super.negate
19
+ end
20
+
21
+ def mismatch_message(actual, match)
22
+ "<#{actual}>"
23
+ end
24
+
25
+ def description
26
+ "not #{@expected.description}"
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,23 @@
1
+ require 'ramcrest/matcher'
2
+
3
+ module Ramcrest
4
+ module Anything
5
+ module_function
6
+
7
+ def anything
8
+ Matcher.new
9
+ end
10
+
11
+ class Matcher
12
+ include Ramcrest::Matcher
13
+
14
+ def matches?(actual)
15
+ success
16
+ end
17
+
18
+ def description
19
+ "anything"
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,10 @@
1
+ module Ramcrest
2
+ module Assertion
3
+ def self.assert_match(actual, matcher, &failure_handler)
4
+ match = matcher.matches?(actual)
5
+ if not match.matched?
6
+ failure_handler.call("expected: #{matcher.description}\nbut: #{match.description}")
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,47 @@
1
+ require 'ramcrest/matcher'
2
+
3
+ module Ramcrest
4
+ module Enumerable
5
+ class BaseEnumerableMatcher
6
+ include Ramcrest::Matcher
7
+
8
+ def initialize(match_type_description, expected, size_matcher)
9
+ @match_type_description = match_type_description
10
+ @expected = expected
11
+ @size_matcher = Ramcrest::HasSize.has_size(size_matcher)
12
+ end
13
+
14
+ def matches?(actual)
15
+ size_match = @size_matcher.matches?(actual)
16
+ if !size_match.matched?
17
+ return mismatch("an enumerable of #{size_match.description}. Enumerable was #{show(actual)}.")
18
+ end
19
+
20
+ unmatched = unmatched_expectations_from(actual)
21
+ if unmatched.empty?
22
+ success
23
+ else
24
+ mismatch("an enumerable that does not include #{describe(unmatched)}. Enumerable was #{show(actual)}.")
25
+ end
26
+ end
27
+
28
+ def description
29
+ "an enumerable #{@match_type_description} #{description_of_expecteds}"
30
+ end
31
+
32
+ private
33
+
34
+ def show(array)
35
+ "[#{array.join(', ')}]"
36
+ end
37
+
38
+ def description_of_expecteds
39
+ describe(@expected)
40
+ end
41
+
42
+ def describe(matchers)
43
+ show(matchers.collect(&:description))
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,45 @@
1
+ require 'ramcrest/matcher'
2
+
3
+ module Ramcrest
4
+ module Comparable
5
+ module_function
6
+
7
+ def greater_than(expected)
8
+ Matcher.new("greater than", :>, expected)
9
+ end
10
+
11
+ def greater_or_equal_to(expected)
12
+ Matcher.new("greater than or equal to", :>=, expected)
13
+ end
14
+
15
+ def less_than(expected)
16
+ Matcher.new("less than", :<, expected)
17
+ end
18
+
19
+ def less_or_equal_to(expected)
20
+ Matcher.new("less than or equal to", :<=, expected)
21
+ end
22
+
23
+ class Matcher
24
+ include Ramcrest::Matcher
25
+
26
+ def initialize(name, operator, expected)
27
+ @name = name
28
+ @operator = operator
29
+ @expected = expected
30
+ end
31
+
32
+ def matches?(actual)
33
+ if actual.send(@operator, @expected)
34
+ success
35
+ else
36
+ mismatch("was <#{actual}>")
37
+ end
38
+ end
39
+
40
+ def description
41
+ "#{@name} <#{@expected}>"
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,36 @@
1
+ require 'ramcrest/matcher'
2
+
3
+ module Ramcrest
4
+ module EqualTo
5
+ def self.to_matcher(possible_matcher)
6
+ return possible_matcher if Ramcrest.is_matcher?(possible_matcher)
7
+ Ramcrest::EqualTo.equal_to(possible_matcher)
8
+ end
9
+
10
+ module_function
11
+
12
+ def equal_to(expected)
13
+ Matcher.new(expected)
14
+ end
15
+
16
+ class Matcher
17
+ include Ramcrest::Matcher
18
+
19
+ def initialize(expected)
20
+ @expected = expected
21
+ end
22
+
23
+ def do_match(expected, actual)
24
+ MatchResult.new(expected == actual)
25
+ end
26
+
27
+ def mismatch_message(actual, match)
28
+ "#{actual}"
29
+ end
30
+
31
+ def description
32
+ "#{@expected}"
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,38 @@
1
+ require 'ramcrest/matcher'
2
+ require 'ramcrest/anything'
3
+
4
+ module Ramcrest
5
+ module HasAttribute
6
+ module_function
7
+
8
+ def has_attribute(attribute_name, value_matcher = Ramcrest::Anything.anything())
9
+ Matcher.new(attribute_name, value_matcher)
10
+ end
11
+
12
+ class Matcher
13
+ include Ramcrest::Matcher
14
+
15
+ def initialize(attribute_name, value_matcher)
16
+ @attribute_name = attribute_name
17
+ @value_matcher = value_matcher
18
+ end
19
+
20
+ def matches?(actual)
21
+ if actual.respond_to?(@attribute_name)
22
+ match = @value_matcher.matches?(actual.send(@attribute_name))
23
+ if match.matched?
24
+ return success
25
+ else
26
+ return mismatch("object <#{actual}> attribute '#{@attribute_name}' #{match.description}")
27
+ end
28
+ else
29
+ return mismatch("object <#{actual}> was missing attribute '#{@attribute_name}'")
30
+ end
31
+ end
32
+
33
+ def description
34
+ "an object with an attribute named '#{@attribute_name}' and value #{@value_matcher.description}"
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,31 @@
1
+ require 'ramcrest/matcher'
2
+ require 'ramcrest/is'
3
+
4
+ module Ramcrest
5
+ module HasSize
6
+ module_function
7
+ def has_size(expected)
8
+ Matcher.new(Ramcrest::Is.to_matcher(expected))
9
+ end
10
+
11
+ class Matcher
12
+ include Ramcrest::Matcher
13
+
14
+ def initialize(expected)
15
+ @expected = expected
16
+ end
17
+
18
+ def do_match(expected, actual)
19
+ super expected, actual.size
20
+ end
21
+
22
+ def mismatch_message(actual, match)
23
+ "size #{match.description}"
24
+ end
25
+
26
+ def description
27
+ "an enumerable of size #{@expected.description}"
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,37 @@
1
+ require 'ramcrest/base_enumerable_matcher'
2
+
3
+ module Ramcrest
4
+ module Includes
5
+ module_function
6
+
7
+ def includes(*expected)
8
+ expected_matchers = expected.collect(&Ramcrest::EqualTo.method(:to_matcher))
9
+ Matcher.new(expected_matchers)
10
+ end
11
+
12
+ class Matcher < Ramcrest::Enumerable::BaseEnumerableMatcher
13
+ def initialize(expected)
14
+ super("including",
15
+ expected,
16
+ Ramcrest::Comparable.greater_or_equal_to(expected.size))
17
+ end
18
+
19
+ protected
20
+
21
+ def unmatched_expectations_from(actual)
22
+ actual.inject(@expected) do |left_to_expect, value|
23
+ matched = matcher_that_matches(value, left_to_expect)
24
+ no_longer_expect(matched, left_to_expect)
25
+ end
26
+ end
27
+
28
+ def matcher_that_matches(value, expected)
29
+ expected.find { |expect| expect.matches?(value).matched? }
30
+ end
31
+
32
+ def no_longer_expect(matched, expected)
33
+ expected.reject { |expect| expect == matched }
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,29 @@
1
+ require 'ramcrest/base_enumerable_matcher'
2
+
3
+ module Ramcrest
4
+ module IncludesExactly
5
+ module_function
6
+
7
+ def includes_exactly(*expected)
8
+ expected_matchers = expected.collect(&Ramcrest::EqualTo.method(:to_matcher))
9
+ Matcher.new(expected_matchers)
10
+ end
11
+
12
+ class Matcher < Ramcrest::Enumerable::BaseEnumerableMatcher
13
+ def initialize(expected)
14
+ super("including exactly",
15
+ expected,
16
+ Ramcrest::EqualTo.equal_to(expected.size))
17
+ end
18
+
19
+ protected
20
+
21
+ def unmatched_expectations_from(actual)
22
+ unmatched = actual.zip(@expected).drop_while do |pair|
23
+ pair[1].matches?(pair[0]).matched?
24
+ end
25
+ unmatched.collect { |pair| pair[1] }
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,37 @@
1
+ require 'ramcrest/base_enumerable_matcher'
2
+
3
+ module Ramcrest
4
+ module IncludesInAnyOrderExactly
5
+ module_function
6
+
7
+ def includes_in_any_order_exactly(*expected)
8
+ expected_matchers = expected.collect(&Ramcrest::EqualTo.method(:to_matcher))
9
+ Matcher.new(expected_matchers)
10
+ end
11
+
12
+ class Matcher < Ramcrest::Enumerable::BaseEnumerableMatcher
13
+ def initialize(expected)
14
+ super("including in any order exactly",
15
+ expected,
16
+ Ramcrest::EqualTo.equal_to(expected.size))
17
+ end
18
+
19
+ protected
20
+
21
+ def unmatched_expectations_from(actual)
22
+ actual.inject(@expected) do |left_to_expect, value|
23
+ matched = matcher_that_matches(value, left_to_expect)
24
+ no_longer_expect(matched, left_to_expect)
25
+ end
26
+ end
27
+
28
+ def matcher_that_matches(value, expected)
29
+ expected.find { |expect| expect.matches?(value).matched? }
30
+ end
31
+
32
+ def no_longer_expect(matched, expected)
33
+ expected.reject { |expect| expect == matched }
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,43 @@
1
+ require 'ramcrest/matcher'
2
+
3
+ module Ramcrest
4
+ module Is
5
+ def self.to_matcher(possible_matcher)
6
+ return possible_matcher if Ramcrest.is_matcher?(possible_matcher)
7
+ Ramcrest::Is.is(possible_matcher)
8
+ end
9
+
10
+ module_function
11
+
12
+ def is(expected)
13
+ Matcher.new(Ramcrest::EqualTo.to_matcher(expected), Ramcrest.is_matcher?(expected))
14
+ end
15
+
16
+ class Matcher
17
+ include Ramcrest::Matcher
18
+
19
+ def initialize(expected, was_originally_matcher)
20
+ @expected = expected
21
+ @was_originally_matcher = was_originally_matcher
22
+ end
23
+
24
+ def mismatch_message(actual, match)
25
+ "was #{show match.description}"
26
+ end
27
+
28
+ def description
29
+ "is #{show @expected.description}"
30
+ end
31
+
32
+ private
33
+
34
+ def show(text)
35
+ if @was_originally_matcher
36
+ text
37
+ else
38
+ "<#{text}>"
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,60 @@
1
+ module Ramcrest
2
+ module Matcher
3
+
4
+ def do_match(expected, actual)
5
+ expected.matches?(actual)
6
+ end
7
+
8
+ def matches?(actual)
9
+ match = do_match(@expected, actual)
10
+ if match.matched?
11
+ success
12
+ else
13
+ mismatch(mismatch_message(actual, match))
14
+ end
15
+ end
16
+
17
+ def success
18
+ MatchResult::SUCCESS
19
+ end
20
+
21
+ def mismatch(description)
22
+ MatchResult.new(false, description)
23
+ end
24
+
25
+ class MatchResult
26
+ attr_reader :description
27
+
28
+ def initialize(matched, description = nil)
29
+ @matched = matched
30
+ @description = description
31
+ end
32
+
33
+ def negate
34
+ MatchResult.new(!@matched, @description)
35
+ end
36
+
37
+ def or_else(&mismatch_block)
38
+ if matched?
39
+ self
40
+ else
41
+ yield self
42
+ end
43
+ end
44
+
45
+ def and_also(&continue_block)
46
+ if matched?
47
+ yield
48
+ else
49
+ self
50
+ end
51
+ end
52
+
53
+ def matched?
54
+ @matched
55
+ end
56
+
57
+ SUCCESS = MatchResult.new(true)
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,85 @@
1
+ require 'ramcrest/matcher'
2
+
3
+ module Ramcrest
4
+ module MatcherMatcher
5
+ module_function
6
+ def a_matcher_that_matches(value)
7
+ MatcherThatMatchesMatcher.new(value)
8
+ end
9
+
10
+ def a_matcher_described_as(description)
11
+ MatcherDescribedAsMatcher.new(description)
12
+ end
13
+
14
+ def a_matcher_that_mismatches(value, description)
15
+ MatcherThatMismatchesMatcher.new(value, description)
16
+ end
17
+
18
+ class MatcherThatMatchesMatcher
19
+ include Ramcrest::Matcher
20
+
21
+ def initialize(value)
22
+ @value = value
23
+ end
24
+
25
+ def matches?(matcher)
26
+ match = matcher.matches?(@value)
27
+ if match.matched?
28
+ success
29
+ else
30
+ mismatch("a matcher describing itself as <#{matcher.description}> that mismatched with <#{match.description}>")
31
+ end
32
+ end
33
+
34
+ def description
35
+ "a matcher that matches <#{@value}>"
36
+ end
37
+ end
38
+
39
+ class MatcherDescribedAsMatcher
40
+ include Ramcrest::Matcher
41
+
42
+ def initialize(description)
43
+ @description = description
44
+ end
45
+
46
+ def matches?(matcher)
47
+ if matcher.description == @description
48
+ success
49
+ else
50
+ mismatch("a matcher that described itself as \"#{matcher.description}\"")
51
+ end
52
+ end
53
+
54
+ def description
55
+ "a matcher described as \"#{@description}\""
56
+ end
57
+ end
58
+
59
+ class MatcherThatMismatchesMatcher
60
+ include Ramcrest::Matcher
61
+
62
+ def initialize(value, description)
63
+ @value = value
64
+ @description = description
65
+ end
66
+
67
+ def matches?(matcher)
68
+ match = matcher.matches?(@value)
69
+ if match.matched?
70
+ mismatch("the matcher matched")
71
+ else
72
+ if match.description == @description
73
+ success
74
+ else
75
+ mismatch("the mismatch description was \"#{match.description}\"")
76
+ end
77
+ end
78
+ end
79
+
80
+ def description
81
+ "a matcher that mismatches <#{@value}> explained by \"#{@description}\""
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,11 @@
1
+ require 'ramcrest/assertion'
2
+
3
+ module MiniTest
4
+ module Assertions
5
+ def assert_that(object, matcher)
6
+ Ramcrest::Assertion.assert_match(object, matcher) do |description|
7
+ assert false, description
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ require 'ramcrest/assertion'
2
+
3
+ module RSpec
4
+ module Expectations
5
+ class ExpectationTarget
6
+ def that(matcher)
7
+ Ramcrest::Assertion.assert_match(@target, matcher) do |description|
8
+ ::RSpec::Expectations.fail_with(description)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+
@@ -0,0 +1,23 @@
1
+ require 'ramcrest/matcher'
2
+
3
+ module Ramcrest
4
+ module SuchThat
5
+ module_function
6
+
7
+ def such_that(description = "<anonymous such_that>", &matcher_block)
8
+ Matcher.new(description, matcher_block)
9
+ end
10
+
11
+ class Matcher
12
+ include Ramcrest::Matcher
13
+
14
+ attr_reader :description
15
+
16
+ def initialize(description, matcher_block)
17
+ singleton = class << self; self; end
18
+ singleton.send(:define_method, :matches?, matcher_block)
19
+ @description = description
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,24 @@
1
+ require 'minitest/autorun'
2
+ require 'ramcrest'
3
+
4
+ describe Ramcrest::Aint do
5
+ include Ramcrest::Aint
6
+ include Ramcrest::Is
7
+ include Ramcrest::MatcherMatcher
8
+
9
+ it "matches objects that are the different" do
10
+ assert_that aint(is(1)), a_matcher_that_matches(2)
11
+ end
12
+
13
+ it "coerces values into an is() matcher" do
14
+ assert_that aint(1), a_matcher_that_matches(2)
15
+ end
16
+
17
+ it "matches objects that are the different" do
18
+ assert_that aint(is(1)), a_matcher_described_as("not is <1>")
19
+ end
20
+
21
+ it "does not match objects that are the same" do
22
+ assert_that aint(is(1)), a_matcher_that_mismatches(1, "<1>")
23
+ end
24
+ end
@@ -0,0 +1,17 @@
1
+ require 'minitest/autorun'
2
+ require 'ramcrest'
3
+
4
+ describe Ramcrest::Anything do
5
+ include Ramcrest::MatcherMatcher
6
+ include Ramcrest::Anything
7
+
8
+ it "always matches" do
9
+ assert_that anything(), a_matcher_that_matches(nil)
10
+ assert_that anything(), a_matcher_that_matches({})
11
+ end
12
+
13
+ it "describes itself" do
14
+ assert_that anything(), a_matcher_described_as("anything")
15
+ end
16
+ end
17
+
@@ -0,0 +1,19 @@
1
+ require 'minitest/autorun'
2
+ require 'ramcrest'
3
+
4
+ describe "assert_that" do
5
+ include Ramcrest::Is
6
+
7
+ it "passes when the match succeeds" do
8
+ assert_that nil, is(nil)
9
+ end
10
+
11
+ it "raises when the match fails" do
12
+ assert_raises(MiniTest::Assertion) { assert_that 1, is(2) }
13
+ end
14
+
15
+ it "combines the mismatch description with the matchers description for the message" do
16
+ exception = assert_raises(MiniTest::Assertion) { assert_that 1, is(2) }
17
+ assert_equal "expected: is <2>\nbut: was <1>", exception.message
18
+ end
19
+ end
@@ -0,0 +1,33 @@
1
+ require 'minitest/autorun'
2
+ require 'ramcrest'
3
+
4
+ describe Ramcrest::Comparable do
5
+ include Ramcrest::MatcherMatcher
6
+ include Ramcrest::Comparable
7
+
8
+ it "matches greater than" do
9
+ assert_that greater_than(1), a_matcher_that_matches(2)
10
+ assert_that greater_than(1), a_matcher_that_mismatches(1, "was <1>")
11
+ assert_that greater_than(1), a_matcher_described_as("greater than <1>")
12
+ end
13
+
14
+ it "matches less than" do
15
+ assert_that less_than(1), a_matcher_that_matches(0)
16
+ assert_that less_than(1), a_matcher_that_mismatches(1, "was <1>")
17
+ assert_that less_than(1), a_matcher_described_as("less than <1>")
18
+ end
19
+
20
+ it "matches greater than or equal" do
21
+ assert_that greater_or_equal_to(1), a_matcher_that_matches(2)
22
+ assert_that greater_or_equal_to(1), a_matcher_that_matches(1)
23
+ assert_that greater_or_equal_to(1), a_matcher_that_mismatches(0, "was <0>")
24
+ assert_that greater_or_equal_to(1), a_matcher_described_as("greater than or equal to <1>")
25
+ end
26
+
27
+ it "matches less than or equal" do
28
+ assert_that less_or_equal_to(1), a_matcher_that_matches(0)
29
+ assert_that less_or_equal_to(1), a_matcher_that_matches(1)
30
+ assert_that less_or_equal_to(1), a_matcher_that_mismatches(2, "was <2>")
31
+ assert_that less_or_equal_to(1), a_matcher_described_as("less than or equal to <1>")
32
+ end
33
+ end
@@ -0,0 +1,59 @@
1
+ require 'minitest/autorun'
2
+ require 'ramcrest'
3
+
4
+ describe Ramcrest::HasAttribute do
5
+ include Ramcrest::MatcherMatcher
6
+ include Ramcrest::HasAttribute
7
+ include Ramcrest::Is
8
+
9
+ describe "when not matching the value" do
10
+ it "matches an object with the attribute" do
11
+ obj = an_object_with_attribute(:foo)
12
+
13
+ assert_that has_attribute(:foo), a_matcher_that_matches(obj)
14
+ end
15
+
16
+ it "does not match an object that does not have the attribute" do
17
+ obj = an_object_with_attribute(:different)
18
+
19
+ assert_that has_attribute(:foo),
20
+ a_matcher_that_mismatches(obj, "object <#{obj}> was missing attribute 'foo'")
21
+ end
22
+
23
+ it "describes itself" do
24
+ assert_that has_attribute(:foo),
25
+ a_matcher_described_as("an object with an attribute named 'foo' and value anything")
26
+ end
27
+ end
28
+
29
+ describe "when matching the value" do
30
+ it "matches an object with the attribute and the value" do
31
+ obj = an_object_with_attribute(:foo, 1)
32
+
33
+ assert_that has_attribute(:foo, is(1)), a_matcher_that_matches(obj)
34
+ end
35
+
36
+ it "does not match an object that does not have the attribute" do
37
+ obj = an_object_with_attribute(:different)
38
+
39
+ assert_that has_attribute(:foo, is(1)),
40
+ a_matcher_that_mismatches(obj, "object <#{obj}> was missing attribute 'foo'")
41
+ end
42
+
43
+ it "does not match an object that has a different value" do
44
+ obj = an_object_with_attribute(:foo, 2)
45
+
46
+ assert_that has_attribute(:foo, is(1)),
47
+ a_matcher_that_mismatches(obj, "object <#{obj}> attribute 'foo' was <2>")
48
+ end
49
+
50
+ it "describes itself" do
51
+ assert_that has_attribute(:foo, is(1)),
52
+ a_matcher_described_as("an object with an attribute named 'foo' and value is <1>")
53
+ end
54
+ end
55
+
56
+ def an_object_with_attribute(name, value = nil)
57
+ Struct.new(name).new(value)
58
+ end
59
+ end
@@ -0,0 +1,26 @@
1
+ require 'minitest/autorun'
2
+ require 'ramcrest'
3
+
4
+ describe Ramcrest::HasSize do
5
+ include Ramcrest::MatcherMatcher
6
+ include Ramcrest::Is
7
+ include Ramcrest::HasSize
8
+
9
+ it "matches objects with a matching size" do
10
+ assert_that has_size(1), a_matcher_that_matches([1])
11
+ assert_that has_size(1), a_matcher_that_matches({ :a => 1 })
12
+ end
13
+
14
+ it "matches using other matchers" do
15
+ assert_that has_size(Ramcrest::SuchThat.such_that { |size| success }),
16
+ a_matcher_that_matches([2, 3])
17
+ end
18
+
19
+ it "does not match objects that are different size" do
20
+ assert_that has_size(1), a_matcher_that_mismatches([1, 2], "size was <2>")
21
+ end
22
+
23
+ it "describes itself" do
24
+ assert_that has_size(1), a_matcher_described_as("an enumerable of size is <1>")
25
+ end
26
+ end
@@ -0,0 +1,41 @@
1
+ require 'minitest/autorun'
2
+ require 'ramcrest'
3
+
4
+ describe Ramcrest::IncludesExactly do
5
+ include Ramcrest::MatcherMatcher
6
+ include Ramcrest::Is
7
+ include Ramcrest::IncludesExactly
8
+
9
+ it "matches enumerables that have all of the elements in order" do
10
+ assert_that includes_exactly(is(1), is(2)), a_matcher_that_matches([1, 2])
11
+ end
12
+
13
+ it "coerces values into equality matches" do
14
+ assert_that includes_exactly(1, 2), a_matcher_that_matches([1, 2])
15
+ end
16
+
17
+ it "does not match when the elements are out of order" do
18
+ assert_that includes_exactly(is(1), is(2)),
19
+ a_matcher_that_mismatches([2, 1], "an enumerable that does not include [is <1>, is <2>]. Enumerable was [2, 1].")
20
+ end
21
+
22
+ it "does not match when there is an unexpected element" do
23
+ assert_that includes_exactly(is(1), is(2)),
24
+ a_matcher_that_mismatches([1, 3], "an enumerable that does not include [is <2>]. Enumerable was [1, 3].")
25
+ end
26
+
27
+ it "does not match when there are fewer elements than expected" do
28
+ assert_that includes_exactly(is(1), is(2)),
29
+ a_matcher_that_mismatches([1], "an enumerable of size 1. Enumerable was [1].")
30
+ end
31
+
32
+ it "does not match when there are more elements than expected" do
33
+ assert_that includes_exactly(is(1), is(2)),
34
+ a_matcher_that_mismatches([1, 2, 3], "an enumerable of size 3. Enumerable was [1, 2, 3].")
35
+ end
36
+
37
+ it "describes itself" do
38
+ assert_that includes_exactly(is(1), is(2)),
39
+ a_matcher_described_as("an enumerable including exactly [is <1>, is <2>]")
40
+ end
41
+ end
@@ -0,0 +1,36 @@
1
+ require 'minitest/autorun'
2
+ require 'ramcrest'
3
+
4
+ describe Ramcrest::IncludesInAnyOrderExactly do
5
+ include Ramcrest::MatcherMatcher
6
+ include Ramcrest::Is
7
+ include Ramcrest::IncludesInAnyOrderExactly
8
+
9
+ it "matches enumerables that have all of the elements" do
10
+ assert_that includes_in_any_order_exactly(is(1), is(2)), a_matcher_that_matches([2, 1])
11
+ end
12
+
13
+ it "coerces values into equality matches" do
14
+ assert_that includes_in_any_order_exactly(1, 2), a_matcher_that_matches([2, 1])
15
+ end
16
+
17
+ it "does not match when there is an unexpected element" do
18
+ assert_that includes_in_any_order_exactly(is(1), is(2)),
19
+ a_matcher_that_mismatches([1, 3], "an enumerable that does not include [is <2>]. Enumerable was [1, 3].")
20
+ end
21
+
22
+ it "does not match when there are fewer elements than expected" do
23
+ assert_that includes_in_any_order_exactly(is(1), is(2)),
24
+ a_matcher_that_mismatches([1], "an enumerable of size 1. Enumerable was [1].")
25
+ end
26
+
27
+ it "does not match when there are more elements than expected" do
28
+ assert_that includes_in_any_order_exactly(is(1), is(2)),
29
+ a_matcher_that_mismatches([1, 2, 3], "an enumerable of size 3. Enumerable was [1, 2, 3].")
30
+ end
31
+
32
+ it "describes itself" do
33
+ assert_that includes_in_any_order_exactly(is(1), is(2)),
34
+ a_matcher_described_as("an enumerable including in any order exactly [is <1>, is <2>]")
35
+ end
36
+ end
@@ -0,0 +1,31 @@
1
+ require 'minitest/autorun'
2
+ require 'ramcrest'
3
+
4
+ describe Ramcrest::Includes do
5
+ include Ramcrest::MatcherMatcher
6
+ include Ramcrest::Is
7
+ include Ramcrest::Includes
8
+
9
+ it "matches enumerables that have all of the elements" do
10
+ assert_that includes(is(1), is(2)), a_matcher_that_matches([1, 3, 2])
11
+ end
12
+
13
+ it "coerces values into equality matches" do
14
+ assert_that includes(1, 2), a_matcher_that_matches([1, 3, 2])
15
+ end
16
+
17
+ it "does not match when there is an unexpected element" do
18
+ assert_that includes(is(1), is(2)),
19
+ a_matcher_that_mismatches([1, 3], "an enumerable that does not include [is <2>]. Enumerable was [1, 3].")
20
+ end
21
+
22
+ it "does not match when there are fewer elements than expected" do
23
+ assert_that includes(is(1), is(2)),
24
+ a_matcher_that_mismatches([1], "an enumerable of size was <1>. Enumerable was [1].")
25
+ end
26
+
27
+ it "describes itself" do
28
+ assert_that includes(is(1), is(2)),
29
+ a_matcher_described_as("an enumerable including [is <1>, is <2>]")
30
+ end
31
+ end
@@ -0,0 +1,33 @@
1
+ require 'minitest/autorun'
2
+ require 'ramcrest'
3
+
4
+ describe Ramcrest::Is do
5
+ include Ramcrest::MatcherMatcher
6
+ include Ramcrest::Is
7
+
8
+ it "matches objects that are the same" do
9
+ assert_that is(1), a_matcher_that_matches(1)
10
+ end
11
+
12
+ it "matches using other matchers" do
13
+ assert_that is(is(1)), a_matcher_that_matches(1)
14
+ end
15
+
16
+ it "does not match objects that are different" do
17
+ assert_that is(1), a_matcher_that_mismatches(2, "was <2>")
18
+ end
19
+
20
+ it "describes itself" do
21
+ assert_that is(1), a_matcher_described_as("is <1>")
22
+ end
23
+
24
+ describe "when composed with another matcher" do
25
+ it "describes itself without extra marks" do
26
+ assert_that is(is(1)), a_matcher_described_as("is is <1>")
27
+ end
28
+
29
+ it "does not describe a mismatch with extra marks" do
30
+ assert_that is(is(1)), a_matcher_that_mismatches(2, "was was <2>")
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,78 @@
1
+ require 'minitest/autorun'
2
+ require 'ramcrest'
3
+
4
+ describe Ramcrest::MatcherMatcher do
5
+ include Ramcrest::MatcherMatcher
6
+
7
+ INCORRECT_VALUE = 2
8
+ INCORRECT_DESCRIPTION = "wrong description"
9
+ CORRECT_VALUE = 1
10
+
11
+ MATCHER = Ramcrest::Is.is(CORRECT_VALUE)
12
+ MATCHER_DESCRIPTION = MATCHER.description
13
+ MISMATCH_DESCRIPTION = MATCHER.matches?(INCORRECT_VALUE).description
14
+
15
+ describe "#a_matcher_that_matches" do
16
+ it "matches when the tested matcher matches" do
17
+ assert_that MATCHER, a_matcher_that_matches(CORRECT_VALUE)
18
+ end
19
+
20
+ it "mismatches when the tested matcher does not match" do
21
+ match = a_matcher_that_matches(INCORRECT_VALUE).matches?(MATCHER)
22
+
23
+ assert !match.matched?
24
+ end
25
+
26
+ it "describes itself" do
27
+ assert_equal "a matcher that matches <#{CORRECT_VALUE}>", a_matcher_that_matches(CORRECT_VALUE).description
28
+ end
29
+
30
+ it "describes the mismatch when the matcher does not match" do
31
+ assert_equal "a matcher describing itself as <#{MATCHER_DESCRIPTION}> that mismatched with <#{MISMATCH_DESCRIPTION}>", a_matcher_that_matches(INCORRECT_VALUE).matches?(MATCHER).description
32
+ end
33
+ end
34
+
35
+ describe "#a_matcher_described_as" do
36
+ it "matches when the matcher's description matches" do
37
+ assert_that MATCHER, a_matcher_described_as(MATCHER_DESCRIPTION)
38
+ end
39
+
40
+ it "mismatches when the matcher's description does not match" do
41
+ match = a_matcher_described_as(INCORRECT_DESCRIPTION).matches?(MATCHER)
42
+
43
+ assert !match.matched?
44
+ end
45
+
46
+ it "describes itself" do
47
+ assert_equal "a matcher described as \"#{MATCHER_DESCRIPTION}\"", a_matcher_described_as(MATCHER_DESCRIPTION).description
48
+ end
49
+
50
+ it "describes the mismatch when the matcher does not match" do
51
+ assert_equal "a matcher that described itself as \"#{MATCHER_DESCRIPTION}\"", a_matcher_described_as(INCORRECT_DESCRIPTION).matches?(MATCHER).description
52
+ end
53
+ end
54
+
55
+ describe "#a_matcher_that_mismatches" do
56
+ it "matches when the matcher mismatches with the wanted description" do
57
+ assert_that MATCHER, a_matcher_that_mismatches(INCORRECT_VALUE, MISMATCH_DESCRIPTION)
58
+ end
59
+
60
+ it "mismatches when the matcher matches" do
61
+ match = a_matcher_that_mismatches(CORRECT_VALUE, MISMATCH_DESCRIPTION).matches?(MATCHER)
62
+
63
+ assert !match.matched?
64
+ assert_equal "the matcher matched", match.description
65
+ end
66
+
67
+ it "mismatches when the matcher mismatched but provided the wrong mismatch description" do
68
+ match = a_matcher_that_mismatches(INCORRECT_VALUE, "wrong mismatch desc").matches?(MATCHER)
69
+
70
+ assert !match.matched?
71
+ assert_equal "the mismatch description was \"#{MISMATCH_DESCRIPTION}\"", match.description
72
+ end
73
+
74
+ it "describes itself" do
75
+ assert_equal "a matcher that mismatches <#{INCORRECT_VALUE}> explained by \"#{MISMATCH_DESCRIPTION}\"", a_matcher_that_mismatches(INCORRECT_VALUE, MISMATCH_DESCRIPTION).description
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,65 @@
1
+ require 'minitest/autorun'
2
+ require 'ramcrest/matcher'
3
+
4
+ describe Ramcrest::Matcher do
5
+ include Ramcrest::Matcher
6
+
7
+ it "a successful match is equivalent to true" do
8
+ assert_equal true, success.matched?
9
+ end
10
+
11
+ it "an unsuccessful match is equivalent to false" do
12
+ assert_equal false, mismatch("description").matched?
13
+ end
14
+
15
+ it "an unsuccessful match has a description" do
16
+ assert_equal "description", mismatch("description").description
17
+ end
18
+
19
+ it "a successful match has no description" do
20
+ assert_nil success.description
21
+ end
22
+
23
+ describe "#negate" do
24
+ it "inverts the result" do
25
+ assert_equal false, success.negate.matched?
26
+ assert_equal true, mismatch("description").negate.matched?
27
+ end
28
+
29
+ it "does not change the original match" do
30
+ original = mismatch("description")
31
+
32
+ original.negate
33
+
34
+ assert_equal false, original.matched?
35
+ end
36
+ end
37
+
38
+ describe "when results are converted with #or_else" do
39
+ it "returns success from #or_else when it matches" do
40
+ assert_equal true, success.or_else { raise "not reached" }.matched?
41
+ end
42
+
43
+ it "calls the else block when it is a mismatch" do
44
+ assert_raises(RuntimeError, "mismatch discription from block") do
45
+ mismatch("mismatch description").or_else do |mismatch|
46
+ raise RuntimeError, "#{mismatch.description} from block"
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ describe "when chained with another match result via #and_also" do
53
+ it "propogates successful matches" do
54
+ assert_equal true, success.and_also { success }.matched?
55
+ end
56
+
57
+ it "short-circuits on a mismatch" do
58
+ assert_equal false, mismatch("stop").and_also { raise "not reached" }.matched?
59
+ end
60
+
61
+ it "returns the result of the also" do
62
+ assert_equal "the second step", success.and_also { mismatch("the second step") }.description
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,32 @@
1
+ require 'minitest/autorun'
2
+ require 'ramcrest'
3
+
4
+ describe Ramcrest::SuchThat do
5
+ include Ramcrest::MatcherMatcher
6
+ include Ramcrest::SuchThat
7
+
8
+ it "matches when the such that block returns success" do
9
+ assert_that such_that { |value| success }, a_matcher_that_matches(nil)
10
+ end
11
+
12
+ it "mismatches when the such that block returns mismatch" do
13
+ assert_that such_that { |value| mismatch("wrong") }, a_matcher_that_mismatches(nil, "wrong")
14
+ end
15
+
16
+ it "describes itself by default as an anonymous matcher" do
17
+ assert_that such_that { |value| }, a_matcher_described_as("<anonymous such_that>")
18
+ end
19
+
20
+ it "allows for composing with other such_that matchers" do
21
+ base = such_that { |value| if value > 2 then success else mismatch("no") end }
22
+ delegating = such_that { |value| base.matches?(value) }
23
+
24
+ assert_that delegating, a_matcher_that_matches(3)
25
+ assert_that delegating, a_matcher_that_mismatches(2, "no")
26
+ end
27
+
28
+ it "can have a description provided" do
29
+ assert_that such_that("something is true") { |value| },
30
+ a_matcher_described_as("something is true")
31
+ end
32
+ end
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ramcrest
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Andrew Parker
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-07-29 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: ! 'Ramcrest is an implementation of Hamcrest for Ruby. It integrates
15
+ with
16
+
17
+ MinitTest and RSpec. Writing new matchers is easy! Why not give it a try?
18
+
19
+ '
20
+ email:
21
+ - aparker42@gmail.com
22
+ executables: []
23
+ extensions: []
24
+ extra_rdoc_files: []
25
+ files:
26
+ - lib/ramcrest/aint.rb
27
+ - lib/ramcrest/anything.rb
28
+ - lib/ramcrest/assertion.rb
29
+ - lib/ramcrest/base_enumerable_matcher.rb
30
+ - lib/ramcrest/comparable.rb
31
+ - lib/ramcrest/equal_to.rb
32
+ - lib/ramcrest/has_attribute.rb
33
+ - lib/ramcrest/has_size.rb
34
+ - lib/ramcrest/includes.rb
35
+ - lib/ramcrest/includes_exactly.rb
36
+ - lib/ramcrest/includes_in_any_order_exactly.rb
37
+ - lib/ramcrest/is.rb
38
+ - lib/ramcrest/matcher.rb
39
+ - lib/ramcrest/matcher_matcher.rb
40
+ - lib/ramcrest/minitest_assert.rb
41
+ - lib/ramcrest/rspec.rb
42
+ - lib/ramcrest/such_that.rb
43
+ - lib/ramcrest.rb
44
+ - test/aint_test.rb
45
+ - test/anything_test.rb
46
+ - test/assert_that_test.rb
47
+ - test/comparable_test.rb
48
+ - test/has_attribute_test.rb
49
+ - test/has_size_test.rb
50
+ - test/includes_exactly_test.rb
51
+ - test/includes_in_any_order_exactly_test.rb
52
+ - test/includes_test.rb
53
+ - test/is_test.rb
54
+ - test/matcher_matcher_test.rb
55
+ - test/matcher_test.rb
56
+ - test/such_that_test.rb
57
+ homepage: https://github.com/hamcrest/ramcrest
58
+ licenses: []
59
+ post_install_message:
60
+ rdoc_options: []
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ! '>='
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ requirements: []
76
+ rubyforge_project:
77
+ rubygems_version: 1.8.24
78
+ signing_key:
79
+ specification_version: 3
80
+ summary: Powerful, composable matchers for Ruby
81
+ test_files:
82
+ - test/aint_test.rb
83
+ - test/anything_test.rb
84
+ - test/assert_that_test.rb
85
+ - test/comparable_test.rb
86
+ - test/has_attribute_test.rb
87
+ - test/has_size_test.rb
88
+ - test/includes_exactly_test.rb
89
+ - test/includes_in_any_order_exactly_test.rb
90
+ - test/includes_test.rb
91
+ - test/is_test.rb
92
+ - test/matcher_matcher_test.rb
93
+ - test/matcher_test.rb
94
+ - test/such_that_test.rb