matchi 3.2.0 → 3.3.0

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