test_tube 2.0.0 → 2.1.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b343e487d9f73eb0af9f0aeee5ba11c35cab9f644e7a106b3f8a259f3567d142
4
- data.tar.gz: 9b28e9986b96cc1af7f1db0b9e98715364a4ff08579038d0a9663a67bd6dbf78
3
+ metadata.gz: 27985c322404e783924126aac5671af89d2852979dc9cf10deae5ca2821dada7
4
+ data.tar.gz: a383583d7360975bf5f1e98a0271a566be78f97a293bd8d4cec7437c6e315c4c
5
5
  SHA512:
6
- metadata.gz: 3dd6be662939a33715130137e2ea9c6f5cebf95b9c33c18bf56457f2c08ac5e50e094c7e63eff045a1d7d9b4bfcee1db2652d43bcd1fc0a324e3ad99e3e1d17e
7
- data.tar.gz: 9139defd6aa5d96e1d7b2dcfd676a60757b6bb496fb8ea071164e04c624de3e2d327bede1148e5fd793b5c39c57e7715e69f2982f8de6df9bfc95ed85b7b4c27
6
+ metadata.gz: e71d511063d6f166ddce31450773f149b679ba21f95a70ffad6f92e527c4819fe44d177d676e1b774d5478f71f31ac61cd6c971d4ad1445e89a3dcab2532d59e
7
+ data.tar.gz: bf01ae4ec42fdf5075663b61b91933456bbce5a572c5582faa7c06d35cb857a90a23e18cf8cd4cf3109d1c1e4dbf4b49cd420ec0dbcb92c3517c8c5feaa360a9
data/README.md CHANGED
@@ -39,7 +39,7 @@ require "test_tube"
39
39
  ```
40
40
 
41
41
  Assuming we'd like to experiment on the answer to the Ultimate Question of Life,
42
- the Universe, and Everything with the following _matcher_:
42
+ the Universe, and Everything with the following matcher:
43
43
 
44
44
  ```ruby
45
45
  class BeTheAnswer
@@ -49,21 +49,13 @@ class BeTheAnswer
49
49
  end
50
50
  ```
51
51
 
52
- A _matcher_ is an object that responds to the `matches?` method with a block
53
- parameter representing the _actual value_ to be compared.
54
-
55
- Back to our Ruby experiments, one possibility would be to `invoke` a whole block
56
- of code:
52
+ One possibility would be to `invoke` a whole block of code:
57
53
 
58
54
  ```ruby
59
55
  block_of_code = -> { "101010".to_i(2) }
60
56
 
61
- experiment = TestTube.invoke(
62
- isolation: false,
63
- matcher: BeTheAnswer.new,
64
- negate: false,
65
- &block_of_code
66
- )
57
+ experiment = TestTube.invoke(isolate: false, matcher: BeTheAnswer.new, negate: false, &block_of_code)
58
+ # => <TestTube actual=42 error=nil got=true>
67
59
 
68
60
  experiment.actual # => 42
69
61
  experiment.error # => nil
@@ -75,11 +67,8 @@ An alternative would be to `pass` directly the actual value as a parameter:
75
67
  ```ruby
76
68
  actual_value = "101010".to_i(2)
77
69
 
78
- experiment = TestTube.pass(
79
- actual_value,
80
- matcher: BeTheAnswer.new,
81
- negate: false
82
- )
70
+ experiment = TestTube.pass(actual_value, matcher: BeTheAnswer.new, negate: false)
71
+ # => <TestTube actual=42 error=nil got=true>
83
72
 
84
73
  experiment.actual # => 42
85
74
  experiment.error # => nil
@@ -105,12 +94,11 @@ An example of successful experience:
105
94
 
106
95
  ```ruby
107
96
  experiment = TestTube.invoke(
108
- isolation: false,
109
- matcher: Matchi::Matcher::RaiseException.new(NoMethodError),
110
- negate: false
111
- ) do
112
- "foo".blank?
113
- end
97
+ isolate: false,
98
+ matcher: Matchi::RaiseException.new(:NoMethodError),
99
+ negate: false
100
+ ) { "foo".blank? }
101
+ # => <TestTube actual=#<NoMethodError: undefined method `blank?' for "foo":String> error=nil got=true>
114
102
 
115
103
  experiment.actual # => #<NoMethodError: undefined method `blank?' for "foo":String>
116
104
  experiment.error # => nil
@@ -121,11 +109,11 @@ Another example of an experiment that fails:
121
109
 
122
110
  ```ruby
123
111
  experiment = TestTube.invoke(
124
- isolation: false,
125
- matcher: Matchi::Matcher::Equal.new(0.3),
126
- negate: false,
112
+ isolate: false,
113
+ matcher: Matchi::Be.new(0.3),
114
+ negate: false,
127
115
  &-> { 0.1 + 0.2 }
128
- )
116
+ ) # => <TestTube actual=0.30000000000000004 error=nil got=false>
129
117
 
130
118
  experiment.actual # => 0.30000000000000004
131
119
  experiment.error # => nil
@@ -136,10 +124,11 @@ Finally, an experiment which causes an error:
136
124
 
137
125
  ```ruby
138
126
  experiment = TestTube.invoke(
139
- isolation: false,
140
- matcher: Matchi::Matcher::Match.new(/^foo$/),
141
- negate: false
127
+ isolate: false,
128
+ matcher: Matchi::Match.new(/^foo$/),
129
+ negate: false
142
130
  ) { BOOM }
131
+ # => <TestTube actual=nil error=#<NameError: uninitialized constant BOOM> got=nil>
143
132
 
144
133
  experiment.actual # => nil
145
134
  experiment.error # => #<NameError: uninitialized constant BOOM>
@@ -149,27 +138,25 @@ experiment.got # => nil
149
138
  ### Code isolation
150
139
 
151
140
  When experimenting tests, side-effects may occur. Because they may or may not be
152
- desired, an `isolation` option is available.
141
+ desired, an `isolate` option is available.
153
142
 
154
143
  Let's for instance consider this block of code:
155
144
 
156
145
  ```ruby
157
146
  greeting = "Hello, world!"
158
- block_of_code = -> { greeting.gsub!("world", "Alice") }
147
+ block_of_code = -> { greeting.gsub!("world", "Alice") } # => #<Proc:0x00007f87f71b9690 (irb):42 (lambda)>
159
148
  ```
160
149
 
161
- By setting the `isolation` option to `true`, we can experiment while avoiding
150
+ By setting the `isolate` option to `true`, we can experiment while avoiding
162
151
  side effects:
163
152
 
164
153
  ```ruby
165
154
  experiment = TestTube.invoke(
166
- isolation: true,
167
- matcher: Matchi::Matcher::Eql.new("Hello, Alice!"),
168
- negate: false,
155
+ isolate: true,
156
+ matcher: Matchi::Eq.new("Hello, Alice!"),
157
+ negate: false,
169
158
  &block_of_code
170
- )
171
-
172
- experiment.inspect # => <TestTube actual="Hello, Alice!" error=nil got=true>
159
+ ) # => <TestTube actual="Hello, Alice!" error=nil got=true>
173
160
 
174
161
  greeting # => "Hello, world!"
175
162
  ```
@@ -178,13 +165,11 @@ Otherwise, we can experiment without any code isolation:
178
165
 
179
166
  ```ruby
180
167
  experiment = TestTube.invoke(
181
- isolation: false,
182
- matcher: Matchi::Matcher::Eql.new("Hello, Alice!"),
183
- negate: false,
168
+ isolate: false,
169
+ matcher: Matchi::Eq.new("Hello, Alice!"),
170
+ negate: false,
184
171
  &block_of_code
185
- )
186
-
187
- experiment.inspect # => <TestTube actual="Hello, Alice!" error=nil got=true>
172
+ ) # => <TestTube actual="Hello, Alice!" error=nil got=true>
188
173
 
189
174
  greeting # => "Hello, Alice!"
190
175
  ```
@@ -192,6 +177,8 @@ greeting # => "Hello, Alice!"
192
177
  ## Contact
193
178
 
194
179
  * Source code: https://github.com/fixrb/test_tube
180
+ * Chinese blog post: https://ruby-china.org/topics/41390
181
+ * Japanese blog post: https://qiita.com/cyril/items/36174b619ff1852c80ec
195
182
 
196
183
  ## Versioning
197
184
 
@@ -199,7 +186,7 @@ __Test Tube__ follows [Semantic Versioning 2.0](https://semver.org/).
199
186
 
200
187
  ## License
201
188
 
202
- The [gem](https://rubygems.org/gems/test_tube) is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
189
+ The [gem](https://rubygems.org/gems/test_tube) is available as open source under the terms of the [MIT License](https://github.com/fixrb/test_tube/raw/main/LICENSE.md).
203
190
 
204
191
  ***
205
192
 
data/lib/test_tube.rb CHANGED
@@ -7,10 +7,10 @@ require_relative File.join("test_tube", "passer")
7
7
  #
8
8
  # @api public
9
9
  module TestTube
10
- # @param isolation [Boolean] Compute in isolation or not.
11
- # @param matcher [#matches?] A matcher.
12
- # @param negate [Boolean] Invert the matcher or not.
13
- # @param input [Proc] The callable object to test.
10
+ # @param isolate [Boolean] Compute in a subprocess.
11
+ # @param matcher [#matches?] A matcher.
12
+ # @param negate [Boolean] Invert the matcher or not.
13
+ # @param input [Proc] The callable object to test.
14
14
  #
15
15
  # @example
16
16
  # require "test_tube"
@@ -21,18 +21,18 @@ module TestTube
21
21
  # end
22
22
  # end
23
23
  #
24
- # TestTube.invoke(isolation: false, matcher: BeTheAnswer.new, negate: false) do
24
+ # TestTube.invoke(isolate: false, matcher: BeTheAnswer.new, negate: false) do
25
25
  # "101010".to_i(2)
26
26
  # end
27
27
  #
28
28
  # @return [Invoker] A software experiment.
29
- def self.invoke(isolation:, matcher:, negate:, &input)
30
- Invoker.new(isolation: isolation, matcher: matcher, negate: negate, &input)
29
+ def self.invoke(isolate:, matcher:, negate:, &input)
30
+ Invoker.new(isolate: isolate, matcher: matcher, negate: negate, &input)
31
31
  end
32
32
 
33
- # @param input [#object_id] The callable object to test.
34
- # @param matcher [#matches?] A matcher.
35
- # @param negate [Boolean] Invert the matcher or not.
33
+ # @param input [#object_id] The actual value to test.
34
+ # @param matcher [#matches?] A matcher.
35
+ # @param negate [Boolean] Invert the matcher or not.
36
36
  #
37
37
  # @example
38
38
  # require "test_tube"
@@ -4,25 +4,33 @@ module TestTube
4
4
  # Abstract class representing the state of an experiment.
5
5
  #
6
6
  # @api private
7
- class Base
7
+ class Base < ::BasicObject
8
8
  # Expectation's actual value.
9
9
  #
10
10
  # @return [#object_id] The actual value.
11
+ #
12
+ # @api public
11
13
  attr_reader :actual
12
14
 
13
15
  # Expectation's raised error.
14
16
  #
15
17
  # @return [Exception, nil] The raised error.
18
+ #
19
+ # @api public
16
20
  attr_reader :error
17
21
 
18
22
  # Expectation's returned boolean value.
19
23
  #
20
24
  # @return [Boolean, nil] The returned boolean value.
25
+ #
26
+ # @api public
21
27
  attr_reader :got
22
28
 
23
29
  # A string containing a human-readable representation of the experiment.
24
30
  #
25
31
  # @return [String] The human-readable representation of the experiment.
32
+ #
33
+ # @api public
26
34
  def inspect
27
35
  "<TestTube actual=#{actual.inspect} error=#{error.inspect} got=#{got.inspect}>"
28
36
  end
@@ -9,19 +9,19 @@ module TestTube
9
9
  #
10
10
  # @api private
11
11
  class Invoker < Base
12
- # Class initializer.
13
- #
14
12
  # rubocop:disable Lint/RescueException, Metrics/MethodLength
13
+
14
+ # Class initializer.
15
15
  #
16
- # @param isolation [Boolean] Compute in isolation or not.
17
- # @param matcher [#matches?] A matcher.
18
- # @param negate [Boolean] Invert the matcher or not.
19
- # @param input [Proc] The callable object to test.
20
- def initialize(isolation:, matcher:, negate:, &input)
16
+ # @param isolate [Boolean] Compute in a subprocess.
17
+ # @param matcher [#matches?] A matcher.
18
+ # @param negate [Boolean] Invert the matcher or not.
19
+ # @param input [Proc] The callable object to test.
20
+ def initialize(isolate:, matcher:, negate:, &input)
21
21
  super()
22
22
 
23
23
  @got = negate ^ matcher.matches? do
24
- value = if isolation
24
+ value = if isolate
25
25
  send_call.to!(input)
26
26
  else
27
27
  send_call.to(input)
@@ -34,6 +34,7 @@ module TestTube
34
34
  @actual = nil
35
35
  @error = e
36
36
  end
37
+
37
38
  # rubocop:enable Lint/RescueException, Metrics/MethodLength
38
39
 
39
40
  private
@@ -9,7 +9,7 @@ module TestTube
9
9
  class Passer < Base
10
10
  # Class initializer.
11
11
  #
12
- # @param input [#object_id] An actual value to test.
12
+ # @param input [#object_id] The actual value to test.
13
13
  # @param matcher [#matches?] A matcher.
14
14
  # @param negate [Boolean] Invert the matcher or not.
15
15
  def initialize(input, matcher:, negate:)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: test_tube
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.3
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-11 00:00:00.000000000 Z
11
+ date: 2021-08-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: defi
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 2.0.5
19
+ version: 2.0.6
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 2.0.5
26
+ version: 2.0.6
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: brutal
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: matchi
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rake
57
71
  requirement: !ruby/object:Gem::Requirement