ramcrest 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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