blob: 4fc2c06ba691a4fff004d3f470a32dfd68eeec10 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
# frozen_string_literal: true
# Example usage:
#
# expect(Result.ok(1)).to be_ok_result(1)
#
# expect(Result.err('hello')).to be_err_result do |result_value|
# expect(result_value).to match(/hello/i)
# end
#
# Argument to matcher is the expected value to be matched via '=='.
# For more complex matching, pass a block to the matcher which will receive the result value as an argument.
module ResultMatchers
def be_ok_result(expected_value = nil)
BeResult.new(ok_or_err: :ok, expected_value: expected_value)
end
def be_err_result(expected_value = nil)
BeResult.new(ok_or_err: :err, expected_value: expected_value)
end
class BeResult
attr_reader :ok_or_err, :actual, :failure_message_suffix, :expected_value
def initialize(ok_or_err:, expected_value:)
@ok_or_err = ok_or_err
@expected_value = expected_value
end
def matches?(actual, &block)
@actual = actual
raise "#{actual} must be a #{::Result}, but it was a #{actual.class}" unless actual.is_a?(::Result)
@failure_message_suffix = "be an '#{ok_or_err}' type"
return false unless actual.ok? == ok?
actual_value = actual.ok? ? actual.unwrap : actual.unwrap_err
if expected_value
@failure_message_suffix =
"have a value of #{expected_value.inspect}, but it was #{actual_value.inspect}"
return false unless actual_value == expected_value
end
# NOTE: A block can be passed to the matcher to perform more sophisticated matching,
# or to provide more concise and specific failure messages.
block ? block.yield(actual_value) : true
end
def failure_message
"expected #{actual.inspect} to #{failure_message_suffix}"
end
def failure_message_when_negated
"expected #{actual.inspect} not to #{failure_message_suffix}"
end
private
def ok?
ok_or_err == :ok
end
end
end
|