sus 0.34.0 → 0.35.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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/context/getting-started.md +352 -0
- data/context/index.yaml +9 -0
- data/context/mocking.md +100 -30
- data/context/{shared.md → shared-contexts.md} +29 -2
- data/lib/sus/assertions.rb +91 -18
- data/lib/sus/base.rb +13 -1
- data/lib/sus/be.rb +84 -0
- data/lib/sus/be_truthy.rb +16 -0
- data/lib/sus/be_within.rb +25 -0
- data/lib/sus/clock.rb +21 -0
- data/lib/sus/config.rb +58 -1
- data/lib/sus/context.rb +28 -5
- data/lib/sus/describe.rb +14 -0
- data/lib/sus/expect.rb +23 -0
- data/lib/sus/file.rb +38 -0
- data/lib/sus/filter.rb +21 -0
- data/lib/sus/fixtures/temporary_directory_context.rb +27 -0
- data/lib/sus/fixtures.rb +1 -0
- data/lib/sus/have/all.rb +8 -0
- data/lib/sus/have/any.rb +8 -0
- data/lib/sus/have.rb +42 -0
- data/lib/sus/have_duration.rb +16 -0
- data/lib/sus/identity.rb +44 -1
- data/lib/sus/integrations.rb +1 -0
- data/lib/sus/it.rb +33 -0
- data/lib/sus/it_behaves_like.rb +16 -0
- data/lib/sus/let.rb +3 -0
- data/lib/sus/mock.rb +39 -1
- data/lib/sus/output/backtrace.rb +31 -1
- data/lib/sus/output/bar.rb +17 -0
- data/lib/sus/output/buffered.rb +32 -1
- data/lib/sus/output/lines.rb +10 -0
- data/lib/sus/output/messages.rb +26 -3
- data/lib/sus/output/null.rb +16 -2
- data/lib/sus/output/progress.rb +29 -1
- data/lib/sus/output/status.rb +13 -0
- data/lib/sus/output/structured.rb +14 -1
- data/lib/sus/output/text.rb +33 -1
- data/lib/sus/output/xterm.rb +11 -1
- data/lib/sus/output.rb +9 -0
- data/lib/sus/raise_exception.rb +16 -0
- data/lib/sus/receive.rb +82 -0
- data/lib/sus/registry.rb +20 -1
- data/lib/sus/respond_to.rb +29 -2
- data/lib/sus/shared.rb +16 -0
- data/lib/sus/tree.rb +10 -0
- data/lib/sus/version.rb +2 -1
- data/lib/sus/with.rb +18 -0
- data/readme.md +8 -0
- data/releases.md +4 -0
- data.tar.gz.sig +0 -0
- metadata +3 -3
- metadata.gz.sig +0 -0
- data/context/usage.md +0 -380
data/lib/sus/assertions.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
# Released under the MIT License.
|
|
4
|
-
# Copyright, 2021-
|
|
4
|
+
# Copyright, 2021-2025, by Samuel Williams.
|
|
5
5
|
|
|
6
6
|
require_relative "output"
|
|
7
7
|
require_relative "clock"
|
|
@@ -9,13 +9,25 @@ require_relative "clock"
|
|
|
9
9
|
require_relative "output/backtrace"
|
|
10
10
|
|
|
11
11
|
module Sus
|
|
12
|
+
# Represents a collection of test assertions and their results. Tracks passed, failed, skipped, and errored assertions.
|
|
12
13
|
class Assertions
|
|
14
|
+
# Create a new assertions instance with default options.
|
|
15
|
+
# @parameter options [Hash] Options to pass to {#initialize}.
|
|
16
|
+
# @returns [Assertions] A new assertions instance.
|
|
13
17
|
def self.default(**options)
|
|
14
18
|
self.new(**options)
|
|
15
19
|
end
|
|
16
20
|
|
|
17
|
-
#
|
|
21
|
+
# Initialize a new assertions instance.
|
|
22
|
+
# @parameter identity [Identity, nil] The identity used to identify this set of assertions.
|
|
23
|
+
# @parameter target [Object, nil] The specific target of the assertions, e.g. the test case or nested test assertions.
|
|
24
|
+
# @parameter output [Output] The output buffer used to capture output from the assertions.
|
|
18
25
|
# @parameter inverted [Boolean] Whether the assertions are inverted with respect to the parent.
|
|
26
|
+
# @parameter orientation [Boolean] Whether the assertions are positive or negative in general.
|
|
27
|
+
# @parameter isolated [Boolean] Whether this set of assertions is isolated from the parent.
|
|
28
|
+
# @parameter distinct [Boolean] Whether this set of assertions should be treated as a single statement.
|
|
29
|
+
# @parameter measure [Boolean] Whether to measure execution time.
|
|
30
|
+
# @parameter verbose [Boolean] Whether to output verbose information.
|
|
19
31
|
def initialize(identity: nil, target: nil, output: Output.buffered, inverted: false, orientation: true, isolated: false, distinct: false, measure: false, verbose: false)
|
|
20
32
|
# In theory, the target could carry the identity of the assertion group, but it's not really necessary, so we just handle it explicitly and pass it into any nested assertions.
|
|
21
33
|
@identity = identity
|
|
@@ -42,53 +54,60 @@ module Sus
|
|
|
42
54
|
@count = 0
|
|
43
55
|
end
|
|
44
56
|
|
|
45
|
-
# The identity that is used to identify this set of assertions.
|
|
57
|
+
# @attribute [Identity, nil] The identity that is used to identify this set of assertions.
|
|
46
58
|
attr :identity
|
|
47
59
|
|
|
48
|
-
# The specific target of the assertions, e.g. the test case or nested test assertions.
|
|
60
|
+
# @attribute [Object, nil] The specific target of the assertions, e.g. the test case or nested test assertions.
|
|
49
61
|
attr :target
|
|
50
62
|
|
|
51
|
-
# The output buffer used to capture output from the assertions.
|
|
63
|
+
# @attribute [Output] The output buffer used to capture output from the assertions.
|
|
52
64
|
attr :output
|
|
53
65
|
|
|
54
|
-
# The nesting level of this set of assertions.
|
|
66
|
+
# @attribute [Integer, nil] The nesting level of this set of assertions.
|
|
55
67
|
attr :level
|
|
56
68
|
|
|
57
|
-
# Whether this
|
|
69
|
+
# @attribute [Boolean] Whether this set of assertions is inverted, i.e. the assertions are expected to fail relative to the parent. Used for grouping assertions and ensuring they are added to the parent passed/failed array correctly.
|
|
58
70
|
attr :inverted
|
|
59
71
|
|
|
60
|
-
# The absolute orientation of this set of assertions, i.e. whether the assertions are expected to pass or fail regardless of the parent. Used for correctly formatting the output.
|
|
72
|
+
# @attribute [Boolean] The absolute orientation of this set of assertions, i.e. whether the assertions are expected to pass or fail regardless of the parent. Used for correctly formatting the output.
|
|
61
73
|
attr :orientation
|
|
62
74
|
|
|
63
|
-
# Whether this set of assertions is isolated from the parent. This is used to ensure that any deferred assertions are
|
|
75
|
+
# @attribute [Boolean] Whether this set of assertions is isolated from the parent. This is used to ensure that any deferred assertions are completed before the parent is completed. This is used by `receive` assertions which are deferred until the user code of the test has completed.
|
|
64
76
|
attr :isolated
|
|
65
77
|
|
|
66
|
-
# Distinct is used to identify a set of assertions as a single statement for the purpose of user feedback. It's used by top level ensure statements to ensure that error messages are captured and reported on those statements.
|
|
78
|
+
# @attribute [Boolean] Distinct is used to identify a set of assertions as a single statement for the purpose of user feedback. It's used by top level ensure statements to ensure that error messages are captured and reported on those statements.
|
|
67
79
|
attr :distinct
|
|
68
80
|
|
|
81
|
+
# @attribute [Boolean] Whether to output verbose information.
|
|
69
82
|
attr :verbose
|
|
70
83
|
|
|
84
|
+
# @attribute [Clock, nil] The clock used to measure execution time, if measurement is enabled.
|
|
71
85
|
attr :clock
|
|
72
86
|
|
|
73
|
-
# Nested assertions that have passed.
|
|
87
|
+
# @attribute [Array] Nested assertions that have passed.
|
|
74
88
|
attr :passed
|
|
75
89
|
|
|
76
|
-
# Nested assertions that have failed.
|
|
90
|
+
# @attribute [Array] Nested assertions that have failed.
|
|
77
91
|
attr :failed
|
|
78
92
|
|
|
79
|
-
# Nested assertions have been deferred.
|
|
93
|
+
# @attribute [Array] Nested assertions that have been deferred.
|
|
80
94
|
attr :deferred
|
|
81
95
|
|
|
96
|
+
# @attribute [Array] Nested assertions that have been skipped.
|
|
82
97
|
attr :skipped
|
|
98
|
+
|
|
99
|
+
# @attribute [Array] Nested assertions that have errored.
|
|
83
100
|
attr :errored
|
|
84
101
|
|
|
85
|
-
# The total number of assertions performed
|
|
102
|
+
# @attribute [Integer] The total number of assertions performed.
|
|
86
103
|
attr :count
|
|
87
104
|
|
|
105
|
+
# @returns [String] A string representation of the assertions instance.
|
|
88
106
|
def inspect
|
|
89
107
|
"\#<#{self.class} #{@passed.size} passed #{@failed.size} failed #{@deferred.size} deferred #{@skipped.size} skipped #{@errored.size} errored>"
|
|
90
108
|
end
|
|
91
109
|
|
|
110
|
+
# @returns [Hash] A hash containing the output text and location of the assertions.
|
|
92
111
|
def message
|
|
93
112
|
{
|
|
94
113
|
text: @output.string,
|
|
@@ -96,10 +115,14 @@ module Sus
|
|
|
96
115
|
}
|
|
97
116
|
end
|
|
98
117
|
|
|
118
|
+
# @returns [Integer] The total number of assertions (passed, failed, deferred, skipped, and errored).
|
|
99
119
|
def total
|
|
100
120
|
@passed.size + @failed.size + @deferred.size + @skipped.size + @errored.size
|
|
101
121
|
end
|
|
102
122
|
|
|
123
|
+
# Print a summary of the assertions to the output.
|
|
124
|
+
# @parameter output [Output] The output target.
|
|
125
|
+
# @parameter verbose [Boolean] Whether to include verbose information.
|
|
103
126
|
def print(output, verbose: @verbose)
|
|
104
127
|
if verbose && @target
|
|
105
128
|
@target.print(output)
|
|
@@ -133,14 +156,18 @@ module Sus
|
|
|
133
156
|
end
|
|
134
157
|
end
|
|
135
158
|
|
|
159
|
+
# Print a message to the output buffer.
|
|
160
|
+
# @parameter message [Array] The message parts to print.
|
|
136
161
|
def puts(*message)
|
|
137
162
|
@output.puts(:indent, *message)
|
|
138
163
|
end
|
|
139
164
|
|
|
165
|
+
# @returns [Boolean] Whether there are no assertions (passed, failed, deferred, skipped, or errored).
|
|
140
166
|
def empty?
|
|
141
167
|
@passed.empty? and @failed.empty? and @deferred.empty? and @skipped.empty? and @errored.empty?
|
|
142
168
|
end
|
|
143
169
|
|
|
170
|
+
# @returns [Boolean] Whether all assertions passed and none errored.
|
|
144
171
|
def passed?
|
|
145
172
|
if @inverted
|
|
146
173
|
# Inverted assertions:
|
|
@@ -151,29 +178,43 @@ module Sus
|
|
|
151
178
|
end
|
|
152
179
|
end
|
|
153
180
|
|
|
181
|
+
# @returns [Boolean] Whether any assertions failed or errored.
|
|
154
182
|
def failed?
|
|
155
183
|
!self.passed?
|
|
156
184
|
end
|
|
157
185
|
|
|
186
|
+
# @returns [Boolean] Whether any assertions errored.
|
|
158
187
|
def errored?
|
|
159
188
|
@errored.any?
|
|
160
189
|
end
|
|
161
190
|
|
|
191
|
+
# Represents a single assertion result.
|
|
162
192
|
class Assert
|
|
193
|
+
# Initialize a new assertion result.
|
|
194
|
+
# @parameter identity [Identity, nil] The identity of the assertion.
|
|
195
|
+
# @parameter backtrace [Array] The backtrace where the assertion was made.
|
|
196
|
+
# @parameter assertions [Assertions] The assertions instance that contains this assertion.
|
|
163
197
|
def initialize(identity, backtrace, assertions)
|
|
164
198
|
@identity = identity
|
|
165
199
|
@backtrace = backtrace
|
|
166
200
|
@assertions = assertions
|
|
167
201
|
end
|
|
168
202
|
|
|
203
|
+
# @attribute [Identity, nil] The identity of the assertion.
|
|
169
204
|
attr :identity
|
|
205
|
+
|
|
206
|
+
# @attribute [Array] The backtrace where the assertion was made.
|
|
170
207
|
attr :backtrace
|
|
208
|
+
|
|
209
|
+
# @attribute [Assertions] The assertions instance that contains this assertion.
|
|
171
210
|
attr :assertions
|
|
172
211
|
|
|
212
|
+
# @yields {|assert| ...} Yields this assertion as a failure.
|
|
173
213
|
def each_failure(&block)
|
|
174
214
|
yield self
|
|
175
215
|
end
|
|
176
216
|
|
|
217
|
+
# @returns [Hash] A hash containing the output text and location of the assertion.
|
|
177
218
|
def message
|
|
178
219
|
{
|
|
179
220
|
# It's possible that several Assert instances might share the same output text. This is because the output is buffered for each test and each top-level test expectation.
|
|
@@ -183,6 +224,9 @@ module Sus
|
|
|
183
224
|
end
|
|
184
225
|
end
|
|
185
226
|
|
|
227
|
+
# Make an assertion about a condition.
|
|
228
|
+
# @parameter condition [Boolean] The condition to assert.
|
|
229
|
+
# @parameter message [String | Nil] Optional message describing the assertion.
|
|
186
230
|
def assert(condition, message = nil)
|
|
187
231
|
@count += 1
|
|
188
232
|
|
|
@@ -199,6 +243,9 @@ module Sus
|
|
|
199
243
|
end
|
|
200
244
|
end
|
|
201
245
|
|
|
246
|
+
# Iterate over all failures in this assertions instance.
|
|
247
|
+
# @yields {|failure| ...} Each failure (failed assertion or error).
|
|
248
|
+
# @returns [Enumerator] An enumerator if no block is given.
|
|
202
249
|
def each_failure(&block)
|
|
203
250
|
return to_enum(__method__) unless block_given?
|
|
204
251
|
|
|
@@ -215,12 +262,16 @@ module Sus
|
|
|
215
262
|
end
|
|
216
263
|
end
|
|
217
264
|
|
|
265
|
+
# Skip this set of assertions with a reason.
|
|
266
|
+
# @parameter reason [String] The reason for skipping.
|
|
218
267
|
def skip(reason)
|
|
219
268
|
@output.skip(reason, @identity&.scoped)
|
|
220
269
|
|
|
221
270
|
@skipped << self
|
|
222
271
|
end
|
|
223
272
|
|
|
273
|
+
# Print an informational message during test execution.
|
|
274
|
+
# @parameter message [String | Nil] The message to print, or a block that returns a message.
|
|
224
275
|
def inform(message = nil)
|
|
225
276
|
if message.nil? and block_given?
|
|
226
277
|
begin
|
|
@@ -233,17 +284,18 @@ module Sus
|
|
|
233
284
|
@output.inform(message, @identity&.scoped)
|
|
234
285
|
end
|
|
235
286
|
|
|
236
|
-
# Add deferred
|
|
287
|
+
# Add a deferred assertion that will be resolved later.
|
|
288
|
+
# @yields {|assertions| ...} The block that will be called to resolve the deferred assertion.
|
|
237
289
|
def defer(&block)
|
|
238
290
|
@deferred << block
|
|
239
291
|
end
|
|
240
292
|
|
|
241
|
-
# Whether there are any deferred assertions.
|
|
293
|
+
# @returns [Boolean] Whether there are any deferred assertions.
|
|
242
294
|
def deferred?
|
|
243
295
|
@deferred.any?
|
|
244
296
|
end
|
|
245
297
|
|
|
246
|
-
#
|
|
298
|
+
# Resolve all deferred assertions in order.
|
|
247
299
|
def resolve!
|
|
248
300
|
@output.indented do
|
|
249
301
|
while block = @deferred.shift
|
|
@@ -252,19 +304,28 @@ module Sus
|
|
|
252
304
|
end
|
|
253
305
|
end
|
|
254
306
|
|
|
307
|
+
# Represents an error that occurred during test execution.
|
|
255
308
|
class Error
|
|
309
|
+
# Initialize a new error result.
|
|
310
|
+
# @parameter identity [Identity, nil] The identity where the error occurred.
|
|
311
|
+
# @parameter error [Exception] The exception that was raised.
|
|
256
312
|
def initialize(identity, error)
|
|
257
313
|
@identity = identity
|
|
258
314
|
@error = error
|
|
259
315
|
end
|
|
260
316
|
|
|
317
|
+
# @attribute [Identity, nil] The identity where the error occurred.
|
|
261
318
|
attr :identity
|
|
319
|
+
|
|
320
|
+
# @attribute [Exception] The exception that was raised.
|
|
262
321
|
attr :error
|
|
263
322
|
|
|
323
|
+
# @yields {|error| ...} Yields this error as a failure.
|
|
264
324
|
def each_failure(&block)
|
|
265
325
|
yield self
|
|
266
326
|
end
|
|
267
327
|
|
|
328
|
+
# @returns [Hash] A hash containing the error message and location.
|
|
268
329
|
def message
|
|
269
330
|
{
|
|
270
331
|
text: @error.full_message,
|
|
@@ -273,6 +334,8 @@ module Sus
|
|
|
273
334
|
end
|
|
274
335
|
end
|
|
275
336
|
|
|
337
|
+
# Record an error that occurred during test execution.
|
|
338
|
+
# @parameter error [Exception] The exception that was raised.
|
|
276
339
|
def error!(error)
|
|
277
340
|
identity = @identity&.scoped(error.backtrace_locations)
|
|
278
341
|
|
|
@@ -282,6 +345,15 @@ module Sus
|
|
|
282
345
|
@output.error(error, @identity)
|
|
283
346
|
end
|
|
284
347
|
|
|
348
|
+
# Create a nested set of assertions.
|
|
349
|
+
# @parameter target [Object] The target object for the nested assertions.
|
|
350
|
+
# @parameter identity [Identity, nil] The identity for the nested assertions.
|
|
351
|
+
# @parameter isolated [Boolean] Whether the nested assertions are isolated from the parent.
|
|
352
|
+
# @parameter distinct [Boolean] Whether the nested assertions should be treated as a single statement.
|
|
353
|
+
# @parameter inverted [Boolean] Whether the nested assertions are inverted.
|
|
354
|
+
# @parameter options [Hash] Additional options to pass to the nested assertions instance.
|
|
355
|
+
# @yields {|assertions| ...} The nested assertions instance.
|
|
356
|
+
# @returns [Object] The result of the block.
|
|
285
357
|
def nested(target, identity: @identity, isolated: false, distinct: false, inverted: false, **options)
|
|
286
358
|
result = nil
|
|
287
359
|
|
|
@@ -317,7 +389,8 @@ module Sus
|
|
|
317
389
|
return result
|
|
318
390
|
end
|
|
319
391
|
|
|
320
|
-
# Add
|
|
392
|
+
# Add child assertions that were nested to this instance.
|
|
393
|
+
# @parameter assertions [Assertions] The child assertions to add.
|
|
321
394
|
def add(assertions)
|
|
322
395
|
# All child assertions should be resolved by this point:
|
|
323
396
|
raise "Nested assertions must be fully resolved!" if assertions.deferred?
|
data/lib/sus/base.rb
CHANGED
|
@@ -6,12 +6,15 @@
|
|
|
6
6
|
require_relative "context"
|
|
7
7
|
|
|
8
8
|
module Sus
|
|
9
|
-
#
|
|
9
|
+
# Represents the base test case class. Provides core functionality for test execution including hooks for setup and teardown.
|
|
10
10
|
class Base
|
|
11
|
+
# Initialize a new test case instance.
|
|
12
|
+
# @parameter assertions [Assertions] The assertions instance used to track test results.
|
|
11
13
|
def initialize(assertions)
|
|
12
14
|
@__assertions__ = assertions
|
|
13
15
|
end
|
|
14
16
|
|
|
17
|
+
# @returns [String] A string representation of the test case.
|
|
15
18
|
def inspect
|
|
16
19
|
"\#<Sus::Base for #{self.class.description.inspect}>"
|
|
17
20
|
end
|
|
@@ -43,15 +46,24 @@ module Sus
|
|
|
43
46
|
self.after(error)
|
|
44
47
|
end
|
|
45
48
|
|
|
49
|
+
# Make an assertion about a condition.
|
|
50
|
+
# @parameter condition [Boolean] The condition to assert.
|
|
51
|
+
# @parameter message [String | Nil] Optional message describing the assertion.
|
|
46
52
|
def assert(...)
|
|
47
53
|
@__assertions__.assert(...)
|
|
48
54
|
end
|
|
49
55
|
|
|
56
|
+
# Print an informational message during test execution.
|
|
57
|
+
# @parameter message [String | Nil] The message to print, or a block that returns a message.
|
|
50
58
|
def inform(...)
|
|
51
59
|
@__assertions__.inform(...)
|
|
52
60
|
end
|
|
53
61
|
end
|
|
54
62
|
|
|
63
|
+
# Create a new base test class with the given description.
|
|
64
|
+
# @parameter description [String | Nil] Optional description for the test class.
|
|
65
|
+
# @parameter root [String | Nil] Optional root path for the test identity.
|
|
66
|
+
# @returns [Class] A new test class that extends {Base}.
|
|
55
67
|
def self.base(description = nil, root: nil)
|
|
56
68
|
base = Class.new(Base)
|
|
57
69
|
|
data/lib/sus/be.rb
CHANGED
|
@@ -4,12 +4,18 @@
|
|
|
4
4
|
# Copyright, 2021-2024, by Samuel Williams.
|
|
5
5
|
|
|
6
6
|
module Sus
|
|
7
|
+
# Represents a predicate matcher that can be used with `expect(...).to be(...)`.
|
|
7
8
|
class Be
|
|
9
|
+
# Represents a logical AND combination of multiple predicates.
|
|
8
10
|
class And
|
|
11
|
+
# Initialize a new AND predicate.
|
|
12
|
+
# @parameter predicates [Array] The predicates to combine with AND logic.
|
|
9
13
|
def initialize(predicates)
|
|
10
14
|
@predicates = predicates
|
|
11
15
|
end
|
|
12
16
|
|
|
17
|
+
# Print a representation of this predicate.
|
|
18
|
+
# @parameter output [Output] The output target.
|
|
13
19
|
def print(output)
|
|
14
20
|
@predicates.each_with_index do |predicate, index|
|
|
15
21
|
if index > 0
|
|
@@ -20,26 +26,40 @@ module Sus
|
|
|
20
26
|
end
|
|
21
27
|
end
|
|
22
28
|
|
|
29
|
+
# Evaluate this predicate against a subject.
|
|
30
|
+
# @parameter assertions [Assertions] The assertions instance to use.
|
|
31
|
+
# @parameter subject [Object] The subject to evaluate.
|
|
23
32
|
def call(assertions, subject)
|
|
24
33
|
@predicates.each do |predicate|
|
|
25
34
|
predicate.call(assertions, subject)
|
|
26
35
|
end
|
|
27
36
|
end
|
|
28
37
|
|
|
38
|
+
# Combine this predicate with another using AND logic.
|
|
39
|
+
# @parameter other [Object] Another predicate to combine.
|
|
40
|
+
# @returns [And] A new AND predicate.
|
|
29
41
|
def &(other)
|
|
30
42
|
And.new(@predicates + [other])
|
|
31
43
|
end
|
|
32
44
|
|
|
45
|
+
# Combine this predicate with another using OR logic.
|
|
46
|
+
# @parameter other [Object] Another predicate to combine.
|
|
47
|
+
# @returns [Or] A new OR predicate.
|
|
33
48
|
def |(other)
|
|
34
49
|
Or.new(self, other)
|
|
35
50
|
end
|
|
36
51
|
end
|
|
37
52
|
|
|
53
|
+
# Represents a logical OR combination of multiple predicates.
|
|
38
54
|
class Or
|
|
55
|
+
# Initialize a new OR predicate.
|
|
56
|
+
# @parameter predicates [Array] The predicates to combine with OR logic.
|
|
39
57
|
def initialize(predicates)
|
|
40
58
|
@predicates = predicates
|
|
41
59
|
end
|
|
42
60
|
|
|
61
|
+
# Print a representation of this predicate.
|
|
62
|
+
# @parameter output [Output] The output target.
|
|
43
63
|
def print(output)
|
|
44
64
|
@predicates.each_with_index do |predicate, index|
|
|
45
65
|
if index > 0
|
|
@@ -50,6 +70,9 @@ module Sus
|
|
|
50
70
|
end
|
|
51
71
|
end
|
|
52
72
|
|
|
73
|
+
# Evaluate this predicate against a subject.
|
|
74
|
+
# @parameter assertions [Assertions] The assertions instance to use.
|
|
75
|
+
# @parameter subject [Object] The subject to evaluate.
|
|
53
76
|
def call(assertions, subject)
|
|
54
77
|
assertions.nested(self) do |assertions|
|
|
55
78
|
@predicates.each do |predicate|
|
|
@@ -66,35 +89,57 @@ module Sus
|
|
|
66
89
|
end
|
|
67
90
|
end
|
|
68
91
|
|
|
92
|
+
# Combine this predicate with another using AND logic.
|
|
93
|
+
# @parameter other [Object] Another predicate to combine.
|
|
94
|
+
# @returns [And] A new AND predicate.
|
|
69
95
|
def &(other)
|
|
70
96
|
And.new(self, other)
|
|
71
97
|
end
|
|
72
98
|
|
|
99
|
+
# Combine this predicate with another using OR logic.
|
|
100
|
+
# @parameter other [Object] Another predicate to combine.
|
|
101
|
+
# @returns [Or] A new OR predicate.
|
|
73
102
|
def |(other)
|
|
74
103
|
Or.new(@predicates + [other])
|
|
75
104
|
end
|
|
76
105
|
end
|
|
77
106
|
|
|
107
|
+
# Initialize a new Be predicate.
|
|
108
|
+
# @parameter arguments [Array] The method name and arguments to call on the subject.
|
|
78
109
|
def initialize(*arguments)
|
|
79
110
|
@arguments = arguments
|
|
80
111
|
end
|
|
81
112
|
|
|
113
|
+
# Combine this predicate with another using OR logic.
|
|
114
|
+
# @parameter other [Object] Another predicate to combine.
|
|
115
|
+
# @returns [Or] A new OR predicate.
|
|
82
116
|
def |(other)
|
|
83
117
|
Or.new([self, other])
|
|
84
118
|
end
|
|
85
119
|
|
|
120
|
+
# Combine this predicate with others using OR logic.
|
|
121
|
+
# @parameter others [Array] Other predicates to combine.
|
|
122
|
+
# @returns [Or] A new OR predicate.
|
|
86
123
|
def or(*others)
|
|
87
124
|
Or.new([self, *others])
|
|
88
125
|
end
|
|
89
126
|
|
|
127
|
+
# Combine this predicate with another using AND logic.
|
|
128
|
+
# @parameter other [Object] Another predicate to combine.
|
|
129
|
+
# @returns [And] A new AND predicate.
|
|
90
130
|
def &(other)
|
|
91
131
|
And.new([self, other])
|
|
92
132
|
end
|
|
93
133
|
|
|
134
|
+
# Combine this predicate with others using AND logic.
|
|
135
|
+
# @parameter others [Array] Other predicates to combine.
|
|
136
|
+
# @returns [And] A new AND predicate.
|
|
94
137
|
def and(*others)
|
|
95
138
|
And.new([self, *others])
|
|
96
139
|
end
|
|
97
140
|
|
|
141
|
+
# Print a representation of this predicate.
|
|
142
|
+
# @parameter output [Output] The output target.
|
|
98
143
|
def print(output)
|
|
99
144
|
operation, *arguments = *@arguments
|
|
100
145
|
|
|
@@ -105,6 +150,9 @@ module Sus
|
|
|
105
150
|
end
|
|
106
151
|
end
|
|
107
152
|
|
|
153
|
+
# Evaluate this predicate against a subject.
|
|
154
|
+
# @parameter assertions [Assertions] The assertions instance to use.
|
|
155
|
+
# @parameter subject [Object] The subject to evaluate.
|
|
108
156
|
def call(assertions, subject)
|
|
109
157
|
assertions.nested(self) do |assertions|
|
|
110
158
|
assertions.assert(subject.public_send(*@arguments))
|
|
@@ -112,43 +160,71 @@ module Sus
|
|
|
112
160
|
end
|
|
113
161
|
|
|
114
162
|
class << self
|
|
163
|
+
# Create a predicate that checks equality.
|
|
164
|
+
# @parameter value [Object] The value to compare against.
|
|
165
|
+
# @returns [Be] A new Be predicate.
|
|
115
166
|
def == value
|
|
116
167
|
Be.new(:==, value)
|
|
117
168
|
end
|
|
118
169
|
|
|
170
|
+
# Create a predicate that checks inequality.
|
|
171
|
+
# @parameter value [Object] The value to compare against.
|
|
172
|
+
# @returns [Be] A new Be predicate.
|
|
119
173
|
def != value
|
|
120
174
|
Be.new(:!=, value)
|
|
121
175
|
end
|
|
122
176
|
|
|
177
|
+
# Create a predicate that checks if the subject is greater than a value.
|
|
178
|
+
# @parameter value [Object] The value to compare against.
|
|
179
|
+
# @returns [Be] A new Be predicate.
|
|
123
180
|
def > value
|
|
124
181
|
Be.new(:>, value)
|
|
125
182
|
end
|
|
126
183
|
|
|
184
|
+
# Create a predicate that checks if the subject is greater than or equal to a value.
|
|
185
|
+
# @parameter value [Object] The value to compare against.
|
|
186
|
+
# @returns [Be] A new Be predicate.
|
|
127
187
|
def >= value
|
|
128
188
|
Be.new(:>=, value)
|
|
129
189
|
end
|
|
130
190
|
|
|
191
|
+
# Create a predicate that checks if the subject is less than a value.
|
|
192
|
+
# @parameter value [Object] The value to compare against.
|
|
193
|
+
# @returns [Be] A new Be predicate.
|
|
131
194
|
def < value
|
|
132
195
|
Be.new(:<, value)
|
|
133
196
|
end
|
|
134
197
|
|
|
198
|
+
# Create a predicate that checks if the subject is less than or equal to a value.
|
|
199
|
+
# @parameter value [Object] The value to compare against.
|
|
200
|
+
# @returns [Be] A new Be predicate.
|
|
135
201
|
def <= value
|
|
136
202
|
Be.new(:<=, value)
|
|
137
203
|
end
|
|
138
204
|
|
|
205
|
+
# Create a predicate that checks if the subject matches a pattern.
|
|
206
|
+
# @parameter value [Regexp, Object] The pattern to match against.
|
|
207
|
+
# @returns [Be] A new Be predicate.
|
|
139
208
|
def =~ value
|
|
140
209
|
Be.new(:=~, value)
|
|
141
210
|
end
|
|
142
211
|
|
|
212
|
+
# Create a predicate that checks case equality.
|
|
213
|
+
# @parameter value [Object] The value to compare against.
|
|
214
|
+
# @returns [Be] A new Be predicate.
|
|
143
215
|
def === value
|
|
144
216
|
Be.new(:===, value)
|
|
145
217
|
end
|
|
146
218
|
end
|
|
147
219
|
|
|
220
|
+
# A predicate that checks if the subject is nil.
|
|
148
221
|
NIL = Be.new(:nil?)
|
|
149
222
|
end
|
|
150
223
|
|
|
151
224
|
class Base
|
|
225
|
+
# Create a Be predicate matcher.
|
|
226
|
+
# @parameter arguments [Array] Optional method name and arguments to call on the subject.
|
|
227
|
+
# @returns [Be, Class] A Be predicate if arguments are provided, otherwise the Be class.
|
|
152
228
|
def be(*arguments)
|
|
153
229
|
if arguments.any?
|
|
154
230
|
Be.new(*arguments)
|
|
@@ -157,14 +233,22 @@ module Sus
|
|
|
157
233
|
end
|
|
158
234
|
end
|
|
159
235
|
|
|
236
|
+
# Create a predicate that checks if the subject is an instance of a class.
|
|
237
|
+
# @parameter klass [Class] The class to check against.
|
|
238
|
+
# @returns [Be] A new Be predicate.
|
|
160
239
|
def be_a(klass)
|
|
161
240
|
Be.new(:is_a?, klass)
|
|
162
241
|
end
|
|
163
242
|
|
|
243
|
+
# Create a predicate that checks if the subject is nil.
|
|
244
|
+
# @returns [Be] A Be predicate that checks for nil.
|
|
164
245
|
def be_nil
|
|
165
246
|
Be::NIL
|
|
166
247
|
end
|
|
167
248
|
|
|
249
|
+
# Create a predicate that checks object identity equality.
|
|
250
|
+
# @parameter other [Object] The object to compare against.
|
|
251
|
+
# @returns [Be] A new Be predicate.
|
|
168
252
|
def be_equal(other)
|
|
169
253
|
Be.new(:equal?, other)
|
|
170
254
|
end
|
data/lib/sus/be_truthy.rb
CHANGED
|
@@ -4,11 +4,17 @@
|
|
|
4
4
|
# Copyright, 2022-2023, by Samuel Williams.
|
|
5
5
|
|
|
6
6
|
module Sus
|
|
7
|
+
# Represents a predicate that checks if the subject is truthy.
|
|
7
8
|
module BeTruthy
|
|
9
|
+
# Print a representation of this predicate.
|
|
10
|
+
# @parameter output [Output] The output target.
|
|
8
11
|
def self.print(output)
|
|
9
12
|
output.write("be truthy")
|
|
10
13
|
end
|
|
11
14
|
|
|
15
|
+
# Evaluate this predicate against a subject.
|
|
16
|
+
# @parameter assertions [Assertions] The assertions instance to use.
|
|
17
|
+
# @parameter subject [Object] The subject to evaluate.
|
|
12
18
|
def self.call(assertions, subject)
|
|
13
19
|
assertions.nested(self) do |assertions|
|
|
14
20
|
assertions.assert(subject, self)
|
|
@@ -16,11 +22,17 @@ module Sus
|
|
|
16
22
|
end
|
|
17
23
|
end
|
|
18
24
|
|
|
25
|
+
# Represents a predicate that checks if the subject is falsey.
|
|
19
26
|
module BeFalsey
|
|
27
|
+
# Print a representation of this predicate.
|
|
28
|
+
# @parameter output [Output] The output target.
|
|
20
29
|
def self.print(output)
|
|
21
30
|
output.write("be falsey")
|
|
22
31
|
end
|
|
23
32
|
|
|
33
|
+
# Evaluate this predicate against a subject.
|
|
34
|
+
# @parameter assertions [Assertions] The assertions instance to use.
|
|
35
|
+
# @parameter subject [Object] The subject to evaluate.
|
|
24
36
|
def self.call(assertions, subject)
|
|
25
37
|
assertions.nested(self) do |assertions|
|
|
26
38
|
assertions.assert(!subject, self)
|
|
@@ -29,10 +41,14 @@ module Sus
|
|
|
29
41
|
end
|
|
30
42
|
|
|
31
43
|
class Base
|
|
44
|
+
# Create a predicate that checks if the subject is truthy.
|
|
45
|
+
# @returns [BeTruthy] A BeTruthy predicate.
|
|
32
46
|
def be_truthy
|
|
33
47
|
BeTruthy
|
|
34
48
|
end
|
|
35
49
|
|
|
50
|
+
# Create a predicate that checks if the subject is falsey.
|
|
51
|
+
# @returns [BeFalsey] A BeFalsey predicate.
|
|
36
52
|
def be_falsey
|
|
37
53
|
BeFalsey
|
|
38
54
|
end
|