matchi 3.2.0 → 3.3.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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +14 -0
  3. data/lib/matchi/predicate.rb +94 -0
  4. metadata +3 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aabf9e773ac6210d1170b3a0f3aa19f38845ea0215bb07280d97c35ef66add16
4
- data.tar.gz: 2900c9b936d50bfbe50ba31c6418dcb1402c1fbef5cfbb9f7a1ce289ff6450c0
3
+ metadata.gz: 5596c7ba2d1153eadaa1ba438b009c0cc17954a360b4192bb6419c674d864822
4
+ data.tar.gz: 0c717e7642961b8707433584c58a1e2369f810c11114caa7530c890563df78a3
5
5
  SHA512:
6
- metadata.gz: e2cfb5b1c32a01b84c1e2eec84cfc3ad34df2a7a17c91ecb1e6012ef84d5b4ef5b11f24817de7dcea77e08006e72c578d0d88947470436f231efef8fed18f061
7
- data.tar.gz: 235a73246185fec310960caf6b8c868cbc2daf7598f29c863def9b560ec66ba7a0f43ab303cd164b04c81b5ebbcbddae3224c5550002f9ab924f8202f58a289f
6
+ metadata.gz: 8e89b77b4f7fd25fc53ea570b865b3479be5a3291bc437f55b3ea126111fdd120afd907439ec87c565bbb28b4fe6e7be34a932a218e55933bb3d4bb890b0edcf
7
+ data.tar.gz: f19a1f799d1b8f9c1f40dc747c00863ae1cd9bf1ed545aabdea774e4c658a242a74d2bd6f03709fe124786f327fd7401b104aa9e567496265b966937c61841e3
data/README.md CHANGED
@@ -114,6 +114,20 @@ matcher.expected # => "String"
114
114
  matcher.matches? { "foo" } # => true
115
115
  ```
116
116
 
117
+ **Predicate** matcher:
118
+
119
+ ```ruby
120
+ matcher = Matchi::Predicate.new(:be_empty)
121
+
122
+ matcher.expected # => [:empty?, [], {}, nil]
123
+ matcher.matches? { [] } # => true
124
+
125
+ matcher = Matchi::Predicate.new(:have_key, :foo)
126
+
127
+ matcher.expected # => [:has_key?, [:foo], {}, nil]
128
+ matcher.matches? { { foo: 42 } } # => true
129
+ ```
130
+
117
131
  **Change** matcher:
118
132
 
119
133
  ```ruby
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Matchi
4
+ # *Predicate* matcher.
5
+ class Predicate
6
+ # Initialize the matcher with a name and arguments.
7
+ #
8
+ # @example
9
+ # require "matchi/predicate"
10
+ #
11
+ # Matchi::Predicate.new(:be_empty)
12
+ #
13
+ # @param name [#to_s] A matcher name.
14
+ # @param args [Array] A list of parameters.
15
+ # @param kwargs [Hash] A list of keyword parameters.
16
+ # @param block [Proc] A block of code.
17
+ def initialize(name, *args, **kwargs, &block)
18
+ @name = String(name)
19
+
20
+ raise ::ArgumentError unless valid_name?
21
+
22
+ @args = args
23
+ @kwargs = kwargs
24
+ @block = block
25
+ end
26
+
27
+ # @return [Array] The method name with any arguments to send to the subject.
28
+ def expected
29
+ [method_name, @args, @kwargs, @block]
30
+ end
31
+
32
+ # Boolean comparison between the actual value and the expected value.
33
+ #
34
+ # @example
35
+ # require "matchi/predicate"
36
+ #
37
+ # matcher = Matchi::Predicate.new(:be_empty)
38
+ #
39
+ # matcher.expected # => [:empty?, [], {}, nil]
40
+ # matcher.matches? { [] } # => true
41
+ #
42
+ # @example
43
+ # require "matchi/predicate"
44
+ #
45
+ # matcher = Matchi::Predicate.new(:have_key, :foo)
46
+ #
47
+ # matcher.expected # => [:has_key?, [:foo], {}, nil]
48
+ # matcher.matches? { { foo: 42 } } # => true
49
+ #
50
+ # @yieldreturn [#object_id] The actual value to receive the method request.
51
+ #
52
+ # @return [Boolean] A boolean returned by the actual value being tested.
53
+ def matches?
54
+ value = yield.send(method_name, *@args, **@kwargs, &@block)
55
+ return value if [false, true].include?(value)
56
+
57
+ raise ::TypeError, "Boolean expected, but #{value.class} instance returned."
58
+ end
59
+
60
+ # A string containing a human-readable representation of the matcher.
61
+ def inspect
62
+ "#{self.class}(#{@name}, *#{@args.inspect}, **#{@kwargs.inspect}, &#{@block.inspect})"
63
+ end
64
+
65
+ # Returns a string representing the matcher.
66
+ def to_s
67
+ (
68
+ "#{@name.tr('_', ' ')} " + [
69
+ @args.map(&:inspect).join(", "),
70
+ @kwargs.map { |k, v| "#{k}: #{v.inspect}" }.join(", "),
71
+ (@block.nil? ? "" : "&block")
72
+ ].reject { |i| i.eql?("") }.join(", ")
73
+ ).strip
74
+ end
75
+
76
+ private
77
+
78
+ # The name of the method to send to the object.
79
+ def method_name
80
+ if @name.start_with?("be_")
81
+ :"#{@name.gsub("be_", "")}?"
82
+ else
83
+ :"#{@name.gsub("have_", "has_")}?"
84
+ end
85
+ end
86
+
87
+ # Verify the matcher name structure.
88
+ def valid_name?
89
+ return false if @name.end_with?("?", "!")
90
+
91
+ @name.start_with?("be_", "have_")
92
+ end
93
+ end
94
+ end
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: 3.2.0
4
+ version: 3.3.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-07-24 00:00:00.000000000 Z
11
+ date: 2021-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -144,6 +144,7 @@ files:
144
144
  - lib/matchi/change/to.rb
145
145
  - lib/matchi/eq.rb
146
146
  - lib/matchi/match.rb
147
+ - lib/matchi/predicate.rb
147
148
  - lib/matchi/raise_exception.rb
148
149
  - lib/matchi/satisfy.rb
149
150
  homepage: https://github.com/fixrb/matchi