matchi 2.0.1 → 2.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a9afc0e3e02c4150637f3d1080cf6eacd470ad7dec335417bda0e79ee60ecdea
4
- data.tar.gz: d62e283556fc4f9d4a6d93bde1efb518861d482dba734786f00b57a166f4ade6
3
+ metadata.gz: 5a3c186895362318fd2c0497d3fb4b124b291a582d37ff16d02cb454f9dd52ca
4
+ data.tar.gz: 2fff123c60074a43feb8b81428d1dd61cb0d9e736e223531499113e794c2a2d0
5
5
  SHA512:
6
- metadata.gz: 50d45962387971730773221e8756fa543457ebd1375f7205538040d2fb115eb1fae0784c1e9949794e9c990efc7788fda49ce03f8096918005eae384ed460a13
7
- data.tar.gz: 12071d2d5462243d42eac25ca3d70fc5a236cd79b8cbdd20a608e4d2ceeacdbdddbaeeba06f30218c30d1cbf0c6f16279be655eead7a42dcf6b9cecdf1c645cf
6
+ metadata.gz: 95e61bb5d94221542d1b3c95e67d5616f90ffbb08a501edc997ed29bf57795a5ab398f2cb6f7edc59a32c9ed3482738246028e3ae35394c84788268fefc4b049
7
+ data.tar.gz: bec13c5814a7e007bbff9ae3f47ed3a3b162bc4fe26e5bf941a668fbb9310b7ef9de021dd85fa4fa89d4ef68f1c35bbf7572de0f6bcd799a951c115b6ed6f345
data/README.md CHANGED
@@ -1,12 +1,14 @@
1
1
  # Matchi
2
2
 
3
- [![Build Status](https://api.travis-ci.org/fixrb/matchi.svg?branch=main)][travis]
4
- [![Code Climate](https://codeclimate.com/github/fixrb/matchi/badges/gpa.svg)][codeclimate]
5
- [![Gem Version](https://badge.fury.io/rb/matchi.svg)][gem]
6
- [![Inline docs](https://inch-ci.org/github/fixrb/matchi.svg?branch=main)][inchpages]
7
- [![Documentation](https://img.shields.io/:yard-docs-38c800.svg)][rubydoc]
3
+ [![Version](https://img.shields.io/github/v/tag/fixrb/matchi?label=Version&logo=github)](https://github.com/fixrb/matchi/releases)
4
+ [![Yard documentation](https://img.shields.io/badge/Yard-documentation-blue.svg?logo=github)](https://rubydoc.info/github/fixrb/matchi/main)
5
+ [![CI](https://github.com/fixrb/matchi/workflows/CI/badge.svg?branch=main)](https://github.com/fixrb/matchi/actions?query=workflow%3Aci+branch%3Amain)
6
+ [![RuboCop](https://github.com/fixrb/matchi/workflows/RuboCop/badge.svg?branch=main)](https://github.com/fixrb/matchi/actions?query=workflow%3Arubocop+branch%3Amain)
7
+ [![License](https://img.shields.io/github/license/fixrb/matchi?label=License&logo=github)](https://github.com/fixrb/matchi/raw/main/LICENSE.md)
8
8
 
9
- > Collection of expectation matchers for Ruby.
9
+ > Collection of expectation matchers for Ruby 🤹
10
+
11
+ ![A rubyist juggling between colored balls representing expectation matchers](https://github.com/fixrb/matchi/raw/main/img/matchi.jpg)
10
12
 
11
13
  ## Installation
12
14
 
@@ -18,14 +20,30 @@ gem "matchi"
18
20
 
19
21
  And then execute:
20
22
 
21
- $ bundle
23
+ ```sh
24
+ bundle
25
+ ```
22
26
 
23
27
  Or install it yourself as:
24
28
 
25
- $ gem install matchi
29
+ ```sh
30
+ gem install matchi
31
+ ```
32
+
33
+ ## Overview
34
+
35
+ __Matchi__ provides a collection of damn simple expectation matchers.
26
36
 
27
37
  ## Usage
28
38
 
39
+ To make __Matchi__ available:
40
+
41
+ ```ruby
42
+ require "matchi"
43
+ ```
44
+
45
+ All examples here assume that this has been done.
46
+
29
47
  ### Built-in matchers
30
48
 
31
49
  **Equivalence** matcher:
@@ -77,9 +95,17 @@ be_nil = Matchi::Matcher::BeNil.new
77
95
  be_nil.matches? { nil } # => true
78
96
  ```
79
97
 
98
+ **Type/class** matcher:
99
+
100
+ ```ruby
101
+ be_an_instance_of = Matchi::Matcher::BeAnInstanceOf.new(:String)
102
+ be_an_instance_of.matches? { "foo" } # => true
103
+ ```
104
+
80
105
  ### Custom matchers
81
106
 
82
- Custom matchers can easily be defined for expressing expectations. They can be any Ruby class that responds to `matches?`, `to_s` and `to_h` instance methods.
107
+ Custom matchers can easily be defined for expressing expectations.
108
+ They can be any Ruby class that responds to `matches?` instance method with a block.
83
109
 
84
110
  A **Be the answer** matcher:
85
111
 
@@ -88,7 +114,7 @@ module Matchi
88
114
  module Matcher
89
115
  class BeTheAnswer < ::Matchi::Matcher::Base
90
116
  def matches?
91
- 42.equal? yield
117
+ 42.equal?(yield)
92
118
  end
93
119
  end
94
120
  end
@@ -107,7 +133,7 @@ module Matchi
107
133
  module Matcher
108
134
  class BePrime < ::Matchi::Matcher::Base
109
135
  def matches?
110
- Prime.prime? yield
136
+ Prime.prime?(yield)
111
137
  end
112
138
  end
113
139
  end
@@ -129,7 +155,7 @@ module Matchi
129
155
  end
130
156
 
131
157
  def matches?
132
- !Regexp.new("^#{expected}").match(yield).nil?
158
+ Regexp.new(/\A#{expected}/).match?(yield)
133
159
  end
134
160
  end
135
161
  end
@@ -139,24 +165,39 @@ start_with = Matchi::Matcher::StartWith.new("foo")
139
165
  start_with.matches? { "foobar" } # => true
140
166
  ```
141
167
 
168
+ ### Helper methods
169
+
170
+ For convenience, it is possible to instantiate a matcher with a method rather than with its class.
171
+ To do so, the `Helper` module can be included like this:
172
+
173
+ ```ruby
174
+ require "matchi/helper"
175
+
176
+ class MatcherCollection
177
+ include ::Matchi::Helper
178
+ end
179
+ ```
180
+
181
+ The set of loaded matcher then becomes accessible via a dynamically generated instance method, like these:
182
+
183
+ ```ruby
184
+ matcher = MatcherCollection.new
185
+ matcher.equal(42).matches? { 44 } # => false
186
+ matcher.be_an_instance_of(String).matches? { "안녕하세요" } # => true
187
+ ```
188
+
142
189
  ## Contact
143
190
 
144
191
  * Home page: https://github.com/fixrb/matchi
145
192
  * Bugs/issues: https://github.com/fixrb/matchi/issues
146
193
 
147
- ## Rubies
148
-
149
- * [MRI](https://www.ruby-lang.org/)
150
- * [Rubinius](https://rubinius.com/)
151
- * [JRuby](https://www.jruby.org/)
152
-
153
194
  ## Versioning
154
195
 
155
196
  __Matchi__ follows [Semantic Versioning 2.0](https://semver.org/).
156
197
 
157
198
  ## License
158
199
 
159
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
200
+ The [gem](https://rubygems.org/gems/matchi) is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
160
201
 
161
202
  ***
162
203
 
@@ -166,9 +207,3 @@ The gem is available as open source under the terms of the [MIT License](https:/
166
207
  src="https://github.com/fixrb/matchi/raw/main/img/sashite.png"
167
208
  alt="Sashite" /></a>
168
209
  </p>
169
-
170
- [gem]: https://rubygems.org/gems/matchi
171
- [travis]: https://travis-ci.org/fixrb/matchi
172
- [codeclimate]: https://codeclimate.com/github/fixrb/matchi
173
- [inchpages]: https://inch-ci.org/github/fixrb/matchi
174
- [rubydoc]: https://rubydoc.info/gems/matchi/frames
data/lib/matchi/helper.rb CHANGED
@@ -3,23 +3,35 @@
3
3
  require_relative "matcher"
4
4
 
5
5
  module Matchi
6
- # Collection of helper methods.
6
+ # When included, this module defines a helper instance method per matcher.
7
+ #
8
+ # @example Define and use the dynamic helper instance method of a custom matcher
9
+ # require "matchi/matcher/base"
10
+ #
11
+ # module Matchi
12
+ # module Matcher
13
+ # class BeTheAnswer < ::Matchi::Matcher::Base
14
+ # def matches?
15
+ # 42.equal?(yield)
16
+ # end
17
+ # end
18
+ # end
19
+ # end
20
+ #
21
+ # require "matchi/helper"
22
+ #
23
+ # class MatcherBase
24
+ # include ::Matchi::Helper
25
+ # end
26
+ #
27
+ # matcher_base = MatcherBase.new
28
+ # matcher_base.be_the_answer.matches? { 42 } # => true
7
29
  module Helper
8
30
  ::Matchi::Matcher.constants.each do |matcher_const|
9
31
  next if matcher_const.equal?(:Base)
10
32
 
11
33
  matcher_klass = ::Matchi::Matcher.const_get(matcher_const)
12
34
 
13
- # Define a method for the given matcher.
14
- #
15
- # @example Given the `Matchi::Matchers::Equal::Matcher` matcher, its
16
- # method would be:
17
- #
18
- # def equal(expected)
19
- # Matchi::Matchers::Equal::Matcher.new(expected)
20
- # end
21
- #
22
- # @return [#matches?] The matcher.
23
35
  define_method(matcher_klass.to_sym) do |*args|
24
36
  matcher_klass.new(*args)
25
37
  end
@@ -4,9 +4,16 @@ module Matchi
4
4
  module Matcher
5
5
  # Abstract matcher class.
6
6
  class Base
7
+ # Returns a symbol identifying the matcher.
8
+ #
9
+ # @example The readable definition of a FooBar matcher class.
10
+ # matcher_class = Matchi::Matcher::FooBar
11
+ # matcher_class.to_sym # => "foo_bar"
12
+ #
7
13
  # @return [Symbol] A symbol identifying the matcher.
8
14
  def self.to_sym
9
- name.delete_prefix("Matchi::Matcher::")
15
+ name.split("::")
16
+ .fetch(-1)
10
17
  .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
11
18
  .gsub(/([a-z\d])([A-Z])/, '\1_\2')
12
19
  .downcase
@@ -18,6 +25,10 @@ module Matchi
18
25
 
19
26
  # A string containing a human-readable representation of the matcher.
20
27
  #
28
+ # @example The human-readable representation of a FooBar matcher instance.
29
+ # matcher = Matchi::Matcher::FooBar.new(42)
30
+ # matcher.inspect # => "Matchi::Matcher::FooBar(42)"
31
+ #
21
32
  # @return [String] The human-readable representation of the matcher.
22
33
  def inspect
23
34
  "#{self.class}(#{expected&.inspect})"
@@ -25,18 +36,25 @@ module Matchi
25
36
 
26
37
  # Abstract matcher class.
27
38
  #
28
- # @raise [NotImplementedError] Override me inside a matcher.
39
+ # @example Test the equivalence between two "foo" strings.
40
+ # eql = Matchi::Matcher::Eql.new("foo")
41
+ # eql.matches? { "foo" } # => true
42
+ #
43
+ # @yieldreturn [#object_id] The actual value to compare to the expected
44
+ # one.
45
+ #
46
+ # @raise [NotImplementedError] Override this method inside a matcher.
29
47
  def matches?
30
48
  raise ::NotImplementedError, "matcher MUST respond to this method."
31
49
  end
32
50
 
33
- # Returns a string representing the matcher.
51
+ # Returns a string representing the matcher instance.
34
52
  #
35
- # @example The readable definition of a FooBar matcher.
53
+ # @example The readable definition of a FooBar matcher instance.
36
54
  # matcher = Matchi::Matcher::FooBar.new(42)
37
55
  # matcher.to_s # => "foo_bar 42"
38
56
  #
39
- # @return [String] A string representing the matcher.
57
+ # @return [String] A string representing the matcher instance.
40
58
  def to_s
41
59
  [self.class.to_sym, expected&.inspect].compact.join(" ")
42
60
  end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ module Matchi
6
+ module Matcher
7
+ # *Type/class* matcher.
8
+ class BeAnInstanceOf < ::Matchi::Matcher::Base
9
+ # Initialize the matcher with an object.
10
+ #
11
+ # @example A string matcher
12
+ # Matchi::Matcher::BeAnInstanceOf.new(String)
13
+ #
14
+ # @param expected [#to_s] The name of a module.
15
+ def initialize(expected)
16
+ super()
17
+ @expected = self.class.const_get String(expected)
18
+ end
19
+
20
+ # Boolean comparison between the class of the actual value and the
21
+ # expected class.
22
+ #
23
+ # @example Is it an instance of string?
24
+ # be_an_instance_of = Matchi::Matcher::BeInstanceOf.new(String)
25
+ # be_an_instance_of.matches? { "foo" } # => true
26
+ #
27
+ # be_an_instance_of = Matchi::Matcher::BeInstanceOf.new(:String)
28
+ # be_an_instance_of.matches? { "foo" } # => true
29
+ #
30
+ # be_an_instance_of = Matchi::Matcher::BeInstanceOf.new("String")
31
+ # be_an_instance_of.matches? { "foo" } # => true
32
+ #
33
+ # @yieldreturn [#class] the actual value to compare to the expected one.
34
+ #
35
+ # @return [Boolean] Comparison between actual and expected values.
36
+ def matches?(*, **)
37
+ expected.equal?(yield.class)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -4,7 +4,7 @@ require_relative "base"
4
4
 
5
5
  module Matchi
6
6
  module Matcher
7
- # **Untruth** matcher.
7
+ # *Untruth* matcher.
8
8
  class BeFalse < ::Matchi::Matcher::Base
9
9
  # Boolean comparison between the actual value and the expected value.
10
10
  #
@@ -4,7 +4,7 @@ require_relative "base"
4
4
 
5
5
  module Matchi
6
6
  module Matcher
7
- # **Nil** matcher.
7
+ # *Nil* matcher.
8
8
  class BeNil < ::Matchi::Matcher::Base
9
9
  # Boolean comparison between the actual value and the expected value.
10
10
  #
@@ -4,7 +4,7 @@ require_relative "base"
4
4
 
5
5
  module Matchi
6
6
  module Matcher
7
- # **Truth** matcher.
7
+ # *Truth* matcher.
8
8
  class BeTrue < ::Matchi::Matcher::Base
9
9
  # Boolean comparison between the actual value and the expected value.
10
10
  #
@@ -4,12 +4,12 @@ require_relative "base"
4
4
 
5
5
  module Matchi
6
6
  module Matcher
7
- # **Equivalence** matcher.
7
+ # *Equivalence* matcher.
8
8
  class Eql < ::Matchi::Matcher::Base
9
9
  # Initialize the matcher with an object.
10
10
  #
11
- # @example The string 'foo' matcher.
12
- # Matchi::Matcher::Eql.new('foo')
11
+ # @example The string "foo" matcher.
12
+ # Matchi::Matcher::Eql.new("foo")
13
13
  #
14
14
  # @param expected [#eql?] An expected equivalent object.
15
15
  def initialize(expected)
@@ -19,9 +19,9 @@ module Matchi
19
19
 
20
20
  # Boolean comparison between the actual value and the expected value.
21
21
  #
22
- # @example Is it equivalent to 'foo'?
23
- # eql = Matchi::Matcher::Eql.new('foo')
24
- # eql.matches? { 'foo' } # => true
22
+ # @example Is it equivalent to "foo"?
23
+ # eql = Matchi::Matcher::Eql.new("foo")
24
+ # eql.matches? { "foo" } # => true
25
25
  #
26
26
  # @yieldreturn [#object_id] The actual value to compare to the expected
27
27
  # one.
@@ -4,7 +4,7 @@ require_relative "base"
4
4
 
5
5
  module Matchi
6
6
  module Matcher
7
- # **Identity** matcher.
7
+ # *Identity* matcher.
8
8
  class Equal < ::Matchi::Matcher::Base
9
9
  # Initialize the matcher with an object.
10
10
  #
@@ -4,7 +4,7 @@ require_relative "base"
4
4
 
5
5
  module Matchi
6
6
  module Matcher
7
- # **Regular expressions** matcher.
7
+ # *Regular expressions* matcher.
8
8
  class Match < ::Matchi::Matcher::Base
9
9
  # Initialize the matcher with an instance of Regexp.
10
10
  #
@@ -21,14 +21,14 @@ module Matchi
21
21
  #
22
22
  # @example Is it matching /^foo$/ regex?
23
23
  # match = Matchi::Matcher::Match.new(/^foo$/)
24
- # match.matches? { 'foo' } # => true
24
+ # match.matches? { "foo" } # => true
25
25
  #
26
26
  # @yieldreturn [#object_id] The actual value to compare to the expected
27
27
  # one.
28
28
  #
29
29
  # @return [Boolean] Comparison between actual and expected values.
30
30
  def matches?(*, **)
31
- expected.match(yield).nil?.equal?(false)
31
+ expected.match?(yield)
32
32
  end
33
33
  end
34
34
  end
@@ -4,7 +4,7 @@ require_relative "base"
4
4
 
5
5
  module Matchi
6
6
  module Matcher
7
- # **Expecting errors** matcher.
7
+ # *Expecting errors* matcher.
8
8
  class RaiseException < ::Matchi::Matcher::Base
9
9
  # Initialize the matcher with a descendant of class Exception.
10
10
  #
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: matchi
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cyril Kato
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-12 00:00:00.000000000 Z
11
+ date: 2021-07-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -122,7 +122,7 @@ dependencies:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
- description: Collection of expectation matchers for Ruby.
125
+ description: "Collection of expectation matchers for Ruby \U0001F939"
126
126
  email: contact@cyril.email
127
127
  executables: []
128
128
  extensions: []
@@ -134,6 +134,7 @@ files:
134
134
  - lib/matchi/helper.rb
135
135
  - lib/matchi/matcher.rb
136
136
  - lib/matchi/matcher/base.rb
137
+ - lib/matchi/matcher/be_an_instance_of.rb
137
138
  - lib/matchi/matcher/be_false.rb
138
139
  - lib/matchi/matcher/be_nil.rb
139
140
  - lib/matchi/matcher/be_true.rb
@@ -160,8 +161,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
160
161
  - !ruby/object:Gem::Version
161
162
  version: '0'
162
163
  requirements: []
163
- rubygems_version: 3.1.4
164
+ rubygems_version: 3.1.6
164
165
  signing_key:
165
166
  specification_version: 4
166
- summary: Collection of expectation matchers for Ruby.
167
+ summary: "Collection of expectation matchers for Ruby \U0001F939"
167
168
  test_files: []