matchi 2.4.0 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Matchi
4
+ class BeWithin
5
+ # *BeWithin of* matcher.
6
+ class Of
7
+ # @return [Numeric] An expected value.
8
+ attr_reader :expected
9
+
10
+ # Initialize the matcher with a delta and an expected value.
11
+ #
12
+ # @example
13
+ # require "matchi/be_within/of"
14
+ #
15
+ # Matchi::BeWithin::Of.new(1, 41)
16
+ #
17
+ # @param delta [Numeric] The accepted variation of the actual value.
18
+ # @param expected [Numeric] The expected value.
19
+ def initialize(delta, expected)
20
+ @delta = delta
21
+ @expected = expected
22
+ end
23
+
24
+ # Boolean comparison on the expected be_within by comparing the actual
25
+ # value and the expected value.
26
+ #
27
+ # @example
28
+ # require "matchi/be_within/of"
29
+ #
30
+ # matcher = Matchi::BeWithin::Of.new(1, 41)
31
+ #
32
+ # matcher.expected # => 41
33
+ # matcher.matches? { 42 } # => true
34
+ #
35
+ # @yieldreturn [Numeric] The block of code to execute.
36
+ #
37
+ # @return [Boolean] Comparison between the actual and the expected values.
38
+ def matches?
39
+ (expected - yield).abs <= @delta
40
+ end
41
+
42
+ # A string containing a human-readable representation of the matcher.
43
+ def inspect
44
+ "#{self.class}(#{@delta}, #{expected})"
45
+ end
46
+
47
+ # Returns a string representing the matcher.
48
+ def to_s
49
+ "be within #{@delta} of #{expected}"
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative File.join("change", "by_at_least")
4
+ require_relative File.join("change", "by_at_most")
5
+ require_relative File.join("change", "by")
6
+ require_relative File.join("change", "from")
7
+ require_relative File.join("change", "to")
8
+
9
+ module Matchi
10
+ # Wraps the target of a change matcher.
11
+ class Change
12
+ # Initialize a wrapper of the change matcher with an object and the name of
13
+ # one of its methods.
14
+ #
15
+ # @example
16
+ # require "matchi/change"
17
+ #
18
+ # Matchi::Change.new("foo", :to_s)
19
+ #
20
+ # @param object [#object_id] An object.
21
+ # @param method [Symbol] The name of a method.
22
+ # @param args [Array] A list of arguments.
23
+ # @param kwargs [Hash] A list of keyword arguments.
24
+ def initialize(object, method, *args, **kwargs, &block)
25
+ @state = -> { object.send(method, *args, **kwargs, &block) }
26
+ end
27
+
28
+ # Specifies a minimum delta of the expected change.
29
+ #
30
+ # @example
31
+ # require "matchi/change"
32
+ #
33
+ # object = []
34
+ #
35
+ # change_wrapper = Matchi::Change.new(object, :length)
36
+ # change_wrapper.by_at_least(1)
37
+ #
38
+ # @param minimum_delta [#object_id] The minimum delta of the expected change.
39
+ #
40
+ # @return [#matches?] A *change by at least* matcher.
41
+ def by_at_least(minimum_delta)
42
+ ByAtLeast.new(minimum_delta, &@state)
43
+ end
44
+
45
+ # Specifies a maximum delta of the expected change.
46
+ #
47
+ # @example
48
+ # require "matchi/change"
49
+ #
50
+ # object = []
51
+ #
52
+ # change_wrapper = Matchi::Change.new(object, :length)
53
+ # change_wrapper.by_at_most(1)
54
+ #
55
+ # @param maximum_delta [#object_id] The maximum delta of the expected change.
56
+ #
57
+ # @return [#matches?] A *change by at most* matcher.
58
+ def by_at_most(maximum_delta)
59
+ ByAtMost.new(maximum_delta, &@state)
60
+ end
61
+
62
+ # Specifies the delta of the expected change.
63
+ #
64
+ # @example
65
+ # require "matchi/change"
66
+ #
67
+ # object = []
68
+ #
69
+ # change_wrapper = Matchi::Change.new(object, :length)
70
+ # change_wrapper.by(1)
71
+ #
72
+ # @param delta [#object_id] The delta of the expected change.
73
+ #
74
+ # @return [#matches?] A *change by* matcher.
75
+ def by(delta)
76
+ By.new(delta, &@state)
77
+ end
78
+
79
+ # Specifies the original value.
80
+ #
81
+ # @example
82
+ # require "matchi/change"
83
+ #
84
+ # change_wrapper = Matchi::Change.new("foo", :to_s)
85
+ # change_wrapper.from("foo")
86
+ #
87
+ # @param old_value [#object_id] The original value.
88
+ #
89
+ # @return [#matches?] A *change from* wrapper.
90
+ def from(old_value)
91
+ From.new(old_value, &@state)
92
+ end
93
+
94
+ # Specifies the new value to expect.
95
+ #
96
+ # @example
97
+ # require "matchi/change"
98
+ #
99
+ # change_wrapper = Matchi::Change.new("foo", :to_s)
100
+ # change_wrapper.to("FOO")
101
+ #
102
+ # @param new_value [#object_id] The new value to expect.
103
+ #
104
+ # @return [#matches?] A *change to* matcher.
105
+ def to(new_value)
106
+ To.new(new_value, &@state)
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Matchi
4
+ class Change
5
+ # *Change by* matcher.
6
+ class By
7
+ # @return [#object_id] An expected delta.
8
+ attr_reader :expected
9
+
10
+ # Initialize the matcher with an object and a block.
11
+ #
12
+ # @example
13
+ # require "matchi/change/by"
14
+ #
15
+ # object = []
16
+ #
17
+ # Matchi::Change::By.new(1) { object.length }
18
+ #
19
+ # @param expected [#object_id] An expected delta.
20
+ # @param state [Proc] A block of code to execute to get the
21
+ # state of the object.
22
+ def initialize(expected, &state)
23
+ @expected = expected
24
+ @state = state
25
+ end
26
+
27
+ # Boolean comparison on the expected change by comparing the value
28
+ # before and after the code execution.
29
+ #
30
+ # @example
31
+ # require "matchi/change/by"
32
+ #
33
+ # object = []
34
+ #
35
+ # matcher = Matchi::Change::By.new(1) { object.length }
36
+ #
37
+ # matcher.expected # => 1
38
+ # matcher.matches? { object << "foo" } # => true
39
+ #
40
+ # @yieldreturn [#object_id] The block of code to execute.
41
+ #
42
+ # @return [Boolean] Comparison between the value before and after the
43
+ # code execution.
44
+ def matches?
45
+ value_before = @state.call
46
+ yield
47
+ value_after = @state.call
48
+
49
+ expected == (value_after - value_before)
50
+ end
51
+
52
+ # A string containing a human-readable representation of the matcher.
53
+ def inspect
54
+ "#{self.class}(#{expected.inspect})"
55
+ end
56
+
57
+ # Returns a string representing the matcher.
58
+ def to_s
59
+ "change by #{expected.inspect}"
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Matchi
4
+ class Change
5
+ # *Change by at least* matcher.
6
+ class ByAtLeast
7
+ # @return [#object_id] An expected delta.
8
+ attr_reader :expected
9
+
10
+ # Initialize the matcher with an object and a block.
11
+ #
12
+ # @example
13
+ # require "matchi/change/by_at_least"
14
+ #
15
+ # object = []
16
+ #
17
+ # Matchi::Change::ByAtLeast.new(1) { object.length }
18
+ #
19
+ # @param expected [#object_id] An expected delta.
20
+ # @param state [Proc] A block of code to execute to get the
21
+ # state of the object.
22
+ def initialize(expected, &state)
23
+ @expected = expected
24
+ @state = state
25
+ end
26
+
27
+ # Boolean comparison on the expected change by comparing the value
28
+ # before and after the code execution.
29
+ #
30
+ # @example
31
+ # require "matchi/change/by_at_least"
32
+ #
33
+ # object = []
34
+ #
35
+ # matcher = Matchi::Change::ByAtLeast.new(1) { object.length }
36
+ #
37
+ # matcher.expected # => 1
38
+ # matcher.matches? { object << "foo" } # => true
39
+ #
40
+ # @yieldreturn [#object_id] The block of code to execute.
41
+ #
42
+ # @return [Boolean] Comparison between the value before and after the
43
+ # code execution.
44
+ def matches?
45
+ value_before = @state.call
46
+ yield
47
+ value_after = @state.call
48
+
49
+ expected <= (value_after - value_before)
50
+ end
51
+
52
+ # A string containing a human-readable representation of the matcher.
53
+ def inspect
54
+ "#{self.class}(#{expected.inspect})"
55
+ end
56
+
57
+ # Returns a string representing the matcher.
58
+ def to_s
59
+ "change by at least #{expected.inspect}"
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Matchi
4
+ class Change
5
+ # *Change by at most* matcher.
6
+ class ByAtMost
7
+ # @return [#object_id] An expected delta.
8
+ attr_reader :expected
9
+
10
+ # Initialize the matcher with an object and a block.
11
+ #
12
+ # @example
13
+ # require "matchi/change/by_at_most"
14
+ #
15
+ # object = []
16
+ #
17
+ # Matchi::Change::ByAtMost.new(1) { object.length }
18
+ #
19
+ # @param expected [#object_id] An expected delta.
20
+ # @param state [Proc] A block of code to execute to get the
21
+ # state of the object.
22
+ def initialize(expected, &state)
23
+ @expected = expected
24
+ @state = state
25
+ end
26
+
27
+ # Boolean comparison on the expected change by comparing the value
28
+ # before and after the code execution.
29
+ #
30
+ # @example
31
+ # require "matchi/change/by_at_most"
32
+ #
33
+ # object = []
34
+ #
35
+ # matcher = Matchi::Change::ByAtMost.new(1) { object.length }
36
+ #
37
+ # matcher.expected # => 1
38
+ # matcher.matches? { object << "foo" } # => true
39
+ #
40
+ # @yieldreturn [#object_id] The block of code to execute.
41
+ #
42
+ # @return [Boolean] Comparison between the value before and after the
43
+ # code execution.
44
+ def matches?
45
+ value_before = @state.call
46
+ yield
47
+ value_after = @state.call
48
+
49
+ expected >= (value_after - value_before)
50
+ end
51
+
52
+ # A string containing a human-readable representation of the matcher.
53
+ def inspect
54
+ "#{self.class}(#{expected.inspect})"
55
+ end
56
+
57
+ # Returns a string representing the matcher.
58
+ def to_s
59
+ "change by at most #{expected.inspect}"
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative File.join("from", "to")
4
+
5
+ module Matchi
6
+ class Change
7
+ # *Change from to* wrapper.
8
+ class From
9
+ # Initialize the wrapper with an object and a block.
10
+ #
11
+ # @example
12
+ # require "matchi/change/from"
13
+ #
14
+ # object = "foo"
15
+ #
16
+ # Matchi::Change::From.new("foo") { object.to_s }
17
+ #
18
+ # @param expected [#object_id] An expected initial value.
19
+ # @param state [Proc] A block of code to execute to get the
20
+ # state of the object.
21
+ def initialize(expected, &state)
22
+ @expected = expected
23
+ @state = state
24
+ end
25
+
26
+ # Specifies the new value to expect.
27
+ #
28
+ # @example
29
+ # require "matchi/change/from"
30
+ #
31
+ # object = "foo"
32
+ #
33
+ # change_from_wrapper = Matchi::Change::From.new("foo") { object.to_s }
34
+ # change_from_wrapper.to("FOO")
35
+ #
36
+ # @param expected_new_value [#object_id] The new value to expect.
37
+ #
38
+ # @return [#matches?] A *change from to* matcher.
39
+ def to(expected_new_value)
40
+ To.new(@expected, expected_new_value, &@state)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Matchi
4
+ class Change
5
+ class From
6
+ # *Change from to* matcher.
7
+ class To
8
+ # @return [#object_id] An expected new value.
9
+ attr_reader :expected
10
+
11
+ # Initialize the matcher with two objects and a block.
12
+ #
13
+ # @example
14
+ # require "matchi/change/from/to"
15
+ #
16
+ # object = "foo"
17
+ #
18
+ # Matchi::Change::From::To.new("foo", "FOO") { object.to_s }
19
+ #
20
+ # @param expected_init [#object_id] An expected initial value.
21
+ # @param expected_new_value [#object_id] An expected new value.
22
+ # @param state [Proc] A block of code to execute to
23
+ # get the state of the object.
24
+ def initialize(expected_init, expected_new_value, &state)
25
+ @expected_init = expected_init
26
+ @expected = expected_new_value
27
+ @state = state
28
+ end
29
+
30
+ # Boolean comparison on the expected change by comparing the value
31
+ # before and after the code execution.
32
+ #
33
+ # @example
34
+ # require "matchi/change/from/to"
35
+ #
36
+ # object = "foo"
37
+ #
38
+ # matcher = Matchi::Change::From::To.new("foo", "FOO") { object.to_s }
39
+ #
40
+ # matcher.expected # => "FOO"
41
+ # matcher.matches? { object.upcase! } # => true
42
+ #
43
+ # @yieldreturn [#object_id] The block of code to execute.
44
+ #
45
+ # @return [Boolean] Comparison between the value before and after the
46
+ # code execution.
47
+ def matches?
48
+ value_before = @state.call
49
+ return false unless @expected_init == value_before
50
+
51
+ yield
52
+ value_after = @state.call
53
+
54
+ expected == value_after
55
+ end
56
+
57
+ # A string containing a human-readable representation of the matcher.
58
+ def inspect
59
+ "#{self.class}(#{@expected_init.inspect}, #{expected.inspect})"
60
+ end
61
+
62
+ # Returns a string representing the matcher.
63
+ def to_s
64
+ "change from #{@expected_init.inspect} to #{expected.inspect}"
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end