fix 1.0.0.beta11 → 1.0.0.beta12

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 +62 -1
  3. data/lib/fix/matcher.rb +38 -230
  4. metadata +4 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 40461f87067aa8b719fc25a6256772961b8ef4c412cd043ddddc51d8b048d014
4
- data.tar.gz: ad050718de8cd7c7fcede3f8c9644b91c33ec2cef4e877fd28773d576b265292
3
+ metadata.gz: 4d32cb2da3e2823f71175074536af7f55c981cba88f1fc39952f5c91ecc27756
4
+ data.tar.gz: bfbf3da66b20085030ecffadbfe908dfe90ea3fe5620fdfaceeedbb5eaec0e9e
5
5
  SHA512:
6
- metadata.gz: 8d83f640bb5a086f530265eea8fab350a74e4209072aae351107b0fab393e6ebb1f3fcd266550fccc3c21cf5b9885e2444731ab28200861fcc06fff4f3facf83
7
- data.tar.gz: 85a1b557e06c39c82c653e4283c0489a6bfb3aec0dff69e1f42617cf93805fe5fbe8ea9a5feb13a853d1969a63ea741c73ba1872b4b8b1939b924e388e0ec377
6
+ metadata.gz: 1e66633ce3e37380f20f83f3747ef158e9baadc0853898850972c7e119fe7615eadd53c3197c9bfbd8e48f341d38991060f8dfba16070f34953a08208eefa5bf
7
+ data.tar.gz: 798abf5941f2fbac379d6b19622d1dfe8fd278c81a715a8e1f55a0f8c91aa6b0b1febfd2a60241ddb9a12f5320ed112a77a0a39f860d3e26e43985277f4d0e99
data/README.md CHANGED
@@ -14,7 +14,7 @@ Fix is a modern Ruby testing framework that emphasizes clear separation between
14
14
  Add to your Gemfile:
15
15
 
16
16
  ```ruby
17
- gem "fix", ">= 1.0.0.beta11"
17
+ gem "fix", ">= 1.0.0.beta12"
18
18
  ```
19
19
 
20
20
  Then execute:
@@ -226,6 +226,67 @@ Running the test:
226
226
  Fix[:Duck].test { Duck.new }
227
227
  ```
228
228
 
229
+ ## Available Matchers
230
+
231
+ Fix includes a comprehensive set of matchers through its integration with the [Matchi library](https://github.com/fixrb/matchi):
232
+
233
+ ### Basic Comparison Matchers
234
+ - `eq(expected)` - Tests equality using `eql?`
235
+ - `be(expected)` - Tests object identity using `equal?`
236
+
237
+ ### Type Checking Matchers
238
+ - `be_an_instance_of(class)` - Verifies exact class match
239
+ - `be_a_kind_of(class)` - Checks class inheritance and module inclusion
240
+
241
+ ### Change Testing Matchers
242
+ - `change(object, method)` - Base matcher for state changes
243
+ - `.by(n)` - Expects exact change by n
244
+ - `.by_at_least(n)` - Expects minimum change by n
245
+ - `.by_at_most(n)` - Expects maximum change by n
246
+ - `.from(old).to(new)` - Expects change from old to new value
247
+ - `.to(new)` - Expects change to new value
248
+
249
+ ### Numeric Matchers
250
+ - `be_within(delta).of(value)` - Tests if a value is within ±delta of expected value
251
+
252
+ ### Pattern Matchers
253
+ - `match(regex)` - Tests string against regular expression pattern
254
+ - `satisfy { |value| ... }` - Custom matching with block
255
+
256
+ ### State Matchers
257
+ - `be_true` - Tests for true
258
+ - `be_false` - Tests for false
259
+ - `be_nil` - Tests for nil
260
+
261
+ ### Exception Matchers
262
+ - `raise_exception(class)` - Tests if code raises specified exception
263
+
264
+ ### Dynamic Predicate Matchers
265
+ - `be_*` - Dynamically matches `object.*?` methods (e.g., `be_empty` calls `empty?`)
266
+ - `have_*` - Dynamically matches `object.has_*?` methods (e.g., `have_key` calls `has_key?`)
267
+
268
+ Example usage:
269
+
270
+ ```ruby
271
+ Fix :Calculator do
272
+ it MUST be_an_instance_of Calculator
273
+
274
+ on :add, 2, 3 do
275
+ it MUST eq 5
276
+ it MUST be_within(0.001).of(5.0)
277
+ end
278
+
279
+ on :divide, 1, 0 do
280
+ it MUST raise_exception ZeroDivisionError
281
+ end
282
+
283
+ with numbers: [1, 2, 3] do
284
+ it MUST_NOT be_empty
285
+ it MUST satisfy { |result| result.all? { |n| n.positive? } }
286
+ end
287
+ end
288
+ ```
289
+
229
290
  ## Why Choose Fix?
230
291
 
231
292
  Fix brings several unique advantages to Ruby testing that set it apart from traditional testing frameworks:
data/lib/fix/matcher.rb CHANGED
@@ -5,237 +5,45 @@ require "matchi"
5
5
  module Fix
6
6
  # Collection of expectation matchers.
7
7
  #
8
+ # The following matchers are available:
9
+ #
10
+ # Basic Comparison:
11
+ # - eq(expected) # Checks equality using eql?
12
+ # - eql(expected) # Alias for eq
13
+ # - be(expected) # Checks exact object identity using equal?
14
+ # - equal(expected) # Alias for be
15
+ #
16
+ # Type Checking:
17
+ # - be_an_instance_of(class) # Checks exact class match
18
+ # - be_a_kind_of(class) # Checks class inheritance and module inclusion
19
+ #
20
+ # State & Changes:
21
+ # - change(object, method) # Base for checking state changes
22
+ # .by(n) # Exact change by n
23
+ # .by_at_least(n) # Minimum change by n
24
+ # .by_at_most(n) # Maximum change by n
25
+ # .from(old).to(new) # Change from old to new value
26
+ # .to(new) # Change to new value
27
+ #
28
+ # Value Testing:
29
+ # - be_within(delta).of(value) # Checks numeric value within delta
30
+ # - match(regex) # Tests against regular expression
31
+ # - satisfy { |value| ... } # Custom matcher with block
32
+ #
33
+ # Exceptions:
34
+ # - raise_exception(class) # Checks if code raises exception
35
+ #
36
+ # State Testing:
37
+ # - be_true # Tests for true
38
+ # - be_false # Tests for false
39
+ # - be_nil # Tests for nil
40
+ #
41
+ # Predicate Matchers:
42
+ # - be_* # Matches object.*? method
43
+ # - have_* # Matches object.has_*? method
44
+ #
8
45
  # @api private
9
46
  module Matcher
10
- # Equivalence matcher
11
- #
12
- # @example
13
- # matcher = eq("foo")
14
- # matcher.match? { "foo" } # => true
15
- # matcher.match? { "bar" } # => false
16
- #
17
- # @param expected [#eql?] An expected equivalent object.
18
- #
19
- # @return [#match?] An equivalence matcher.
20
- #
21
- # @api public
22
- def eq(expected)
23
- ::Matchi::Eq.new(expected)
24
- end
25
-
26
- alias eql eq
27
-
28
- # Identity matcher
29
- #
30
- # @example
31
- # object = "foo"
32
- # matcher = be(object)
33
- # matcher.match? { object } # => true
34
- # matcher.match? { "foo" } # => false
35
- #
36
- # @param expected [#equal?] The expected identical object.
37
- #
38
- # @return [#match?] An identity matcher.
39
- #
40
- # @api public
41
- def be(expected)
42
- ::Matchi::Be.new(expected)
43
- end
44
-
45
- alias equal be
46
-
47
- # Comparisons matcher
48
- #
49
- # @example
50
- # matcher = be_within(1).of(41)
51
- # matcher.match? { 42 } # => true
52
- # matcher.match? { 43 } # => false
53
- #
54
- # @param delta [Numeric] A numeric value.
55
- #
56
- # @return [#match?] A comparison matcher.
57
- #
58
- # @api public
59
- def be_within(delta)
60
- ::Matchi::BeWithin.new(delta)
61
- end
62
-
63
- # Regular expressions matcher
64
- #
65
- # @example
66
- # matcher = match(/^foo$/)
67
- # matcher.match? { "foo" } # => true
68
- # matcher.match? { "bar" } # => false
69
- #
70
- # @param expected [#match] A regular expression.
71
- #
72
- # @return [#match?] A regular expression matcher.
73
- #
74
- # @api public
75
- def match(expected)
76
- ::Matchi::Match.new(expected)
77
- end
78
-
79
- # Expecting errors matcher
80
- #
81
- # @example
82
- # matcher = raise_exception(NameError)
83
- # matcher.match? { Boom } # => true
84
- # matcher.match? { true } # => false
85
- #
86
- # @param expected [Exception, #to_s] The expected exception name.
87
- #
88
- # @return [#match?] An error matcher.
89
- #
90
- # @api public
91
- def raise_exception(expected)
92
- ::Matchi::RaiseException.new(expected)
93
- end
94
-
95
- # True matcher
96
- #
97
- # @example
98
- # matcher = be_true
99
- # matcher.match? { true } # => true
100
- # matcher.match? { false } # => false
101
- # matcher.match? { nil } # => false
102
- # matcher.match? { 4 } # => false
103
- #
104
- # @return [#match?] A `true` matcher.
105
- #
106
- # @api public
107
- def be_true
108
- be(true)
109
- end
110
-
111
- # False matcher
112
- #
113
- # @example
114
- # matcher = be_false
115
- # matcher.match? { false } # => true
116
- # matcher.match? { true } # => false
117
- # matcher.match? { nil } # => false
118
- # matcher.match? { 4 } # => false
119
- #
120
- # @return [#match?] A `false` matcher.
121
- #
122
- # @api public
123
- def be_false
124
- be(false)
125
- end
126
-
127
- # Nil matcher
128
- #
129
- # @example
130
- # matcher = be_nil
131
- # matcher.match? { nil } # => true
132
- # matcher.match? { false } # => false
133
- # matcher.match? { true } # => false
134
- # matcher.match? { 4 } # => false
135
- #
136
- # @return [#match?] A `nil` matcher.
137
- #
138
- # @api public
139
- def be_nil
140
- be(nil)
141
- end
142
-
143
- # Type/class matcher
144
- #
145
- # @example
146
- # matcher = be_an_instance_of(String)
147
- # matcher.match? { "foo" } # => true
148
- # matcher.match? { 4 } # => false
149
- #
150
- # @param expected [Class, #to_s] The expected class name.
151
- #
152
- # @return [#match?] A type/class matcher.
153
- #
154
- # @api public
155
- def be_an_instance_of(expected)
156
- ::Matchi::BeAnInstanceOf.new(expected)
157
- end
158
-
159
- # Change matcher
160
- #
161
- # @example
162
- # object = []
163
- # matcher = change(object, :length).by(1)
164
- # matcher.match? { object << 1 } # => true
165
- #
166
- # object = []
167
- # matcher = change(object, :length).by_at_least(1)
168
- # matcher.match? { object << 1 } # => true
169
- #
170
- # object = []
171
- # matcher = change(object, :length).by_at_most(1)
172
- # matcher.match? { object << 1 } # => true
173
- #
174
- # object = "foo"
175
- # matcher = change(object, :to_s).from("foo").to("FOO")
176
- # matcher.match? { object.upcase! } # => true
177
- #
178
- # object = "foo"
179
- # matcher = change(object, :to_s).to("FOO")
180
- # matcher.match? { object.upcase! } # => true
181
- #
182
- # @param object [#object_id] An object.
183
- # @param method [Symbol] The name of a method.
184
- #
185
- # @return [#match?] A change matcher.
186
- #
187
- # @api public
188
- def change(object, method, ...)
189
- ::Matchi::Change.new(object, method, ...)
190
- end
191
-
192
- # Satisfy matcher
193
- #
194
- # @example
195
- # matcher = satisfy { |value| value == 42 }
196
- # matcher.match? { 42 } # => true
197
- #
198
- # @yield [value] A block that defines the satisfaction criteria
199
- # @yieldparam value The value to test
200
- # @yieldreturn [Boolean] true if the value satisfies the criteria
201
- #
202
- # @return [#match?] A satisfy matcher.
203
- #
204
- # @api public
205
- def satisfy(&)
206
- ::Matchi::Satisfy.new(&)
207
- end
208
-
209
- private
210
-
211
- # Predicate matcher, or default method missing behavior.
212
- #
213
- # @example Empty predicate matcher
214
- # matcher = be_empty
215
- # matcher.match? { [] } # => true
216
- # matcher.match? { [4] } # => false
217
- def method_missing(name, ...)
218
- return super unless predicate_matcher_name?(name)
219
-
220
- ::Matchi::Predicate.new(name, ...)
221
- end
222
-
223
- # :nocov:
224
-
225
- # Hook method to return whether the obj can respond to id method or not.
226
- def respond_to_missing?(name, include_private = false)
227
- predicate_matcher_name?(name) || super
228
- end
229
-
230
- # :nocov:
231
-
232
- # Predicate matcher name detector.
233
- #
234
- # @param name [Array, Symbol] The name of a potential predicate matcher.
235
- #
236
- # @return [Boolean] Indicates if it is a predicate matcher name or not.
237
- def predicate_matcher_name?(name)
238
- name.start_with?("be_", "have_") && !name.end_with?("!", "?")
239
- end
47
+ include Matchi
240
48
  end
241
49
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fix
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.beta11
4
+ version: 1.0.0.beta12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cyril Kato
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2024-12-30 00:00:00.000000000 Z
10
+ date: 2024-12-31 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: defi
@@ -29,14 +29,14 @@ dependencies:
29
29
  requirements:
30
30
  - - "~>"
31
31
  - !ruby/object:Gem::Version
32
- version: 4.0.0
32
+ version: 4.1.0
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: 4.0.0
39
+ version: 4.1.0
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: spectus
42
42
  requirement: !ruby/object:Gem::Requirement