r_spec-clone 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6d314d17896138ce2ff2b6d7eb389a1ba2316690f40923684c68632227692a5f
4
- data.tar.gz: af8efe2d9ab1b773db062263503221dd56b6b7a604e73d5f1a84baf0ccbf2b35
3
+ metadata.gz: 0e923f4f11f83ba71f2c7267393691edf8bf8ea9be1ae3598f57cb637d71c411
4
+ data.tar.gz: 18d34b05058e5f17eca7c874f03d52fdac54e995858e1531ee5acff77ceed552
5
5
  SHA512:
6
- metadata.gz: a57d31c77a3da5d120651efbbc1f6d28f808fa47d9c7184e04f79723273df0ce6d84ba08628bc2f60c98c7756a0f2cf1d46774f42d1c505ca9f4e522f418e404
7
- data.tar.gz: 2b2cb13a1620fd98107b3f82e8d7427ae11eb054e9e4bd8c36fe21402efc9dc38af0f6aa41850dc65c05eeba9cfc918a23dfcdea743658963459ef9e5b35c689
6
+ metadata.gz: 80419c1141a6efc61b8f47294d08c8932a416b8c983419a63afdab4bbf8a593d865c37ecb37f84e186459004cd7f807d87d5f99e5625ded0bb8fa885b2ad50d0
7
+ data.tar.gz: 7796a4e33df45136434543f1f2dc2a0ae32a8d93d61bf11515ab0b8d3df7b300b78bd4f5976c913b777ea75da9500b85389268c51f4851eaf30fbe6012aa25fc
data/README.md CHANGED
@@ -14,16 +14,15 @@ A minimalist __RSpec clone__ with all the essentials.
14
14
 
15
15
  ## Project goals
16
16
 
17
- 1. Keep a low level of code complexity and ensure thread safety.
18
- 2. The interface must translate into atomic and simple Ruby objects.
17
+ 1. Keep a low level of code complexity, avoid false negatives and false positives.
18
+ 2. Translate specification documents into atomic and thread safe Ruby objects.
19
19
  3. Avoid overloading the interface with additional alternative syntaxes.
20
20
  4. Provide most of RSpec's DSL to express expected outcomes of a code example.
21
21
 
22
22
  ## Some differences
23
23
 
24
- * Spec files can be executed with `ruby` directly.
25
24
  * There is no option to activate monkey-patching.
26
- * It does not rely on hacks such as [`at_exit` hook](https://blog.arkency.com/2013/06/are-we-abusing-at-exit/) to trigger the tests.
25
+ * It does not rely on [hacks such as `at_exit` hook](https://blog.arkency.com/2013/06/are-we-abusing-at-exit/) to trigger the tests.
27
26
  * Built-in matchers [do not trust _actual_](https://asciinema.org/a/29172?autoplay=1&speed=2) and do not send it messages.
28
27
  * If no `subject` has been explicitly determined, none is defined.
29
28
  * If no described class is set, `described_class` is undefined instead of `nil`.
@@ -32,7 +31,7 @@ A minimalist __RSpec clone__ with all the essentials.
32
31
  * The `let` method defines a helper method rather than a memoized helper method.
33
32
  * The one-liner `is_expected` syntax also works with block expectations.
34
33
  * `subject`, `before`, `after` and `let` definitions must come before examples.
35
- * Groups and examples are _executed in subprocesses_ the order they are defined.
34
+ * Runs much faster.
36
35
 
37
36
  ## Installation
38
37
 
@@ -79,6 +78,8 @@ Test cases that have been defined or outlined but are not yet expected to work c
79
78
  An `it` block contains an example that should invoke the code to be tested and define what is expected of it.
80
79
  Each example can contain multiple expectations, but it should test only one specific behaviour.
81
80
 
81
+ The `its` method can also be used to generate a nested example group with a single example that specifies the expected value (or the block expectations) of an attribute of the subject using `is_expected`.
82
+
82
83
  To express an expectation, wrap an object or block in `expect`, call `to` (or `not_to`) and pass it a matcher object.
83
84
  If the expectation is met, code execution continues.
84
85
  Otherwise the example has _failed_ and other code will not be executed.
@@ -94,6 +95,13 @@ For unit tests, it is recommended to follow the conventions for method names:
94
95
 
95
96
  To establish certain contexts — think _empty array_ versus _array with elements_ — the `context` method may be used to communicate this to the reader.
96
97
 
98
+ Finally, each block of code can be run in a subprocess to isolate side effects with the equivalent methods:
99
+
100
+ * `describe!`
101
+ * `context!`
102
+ * `it!`
103
+ * `its!`
104
+
97
105
  ### Expectations
98
106
 
99
107
  Expectations define if the value being tested (_actual_) matches a certain value or specific criteria.
@@ -211,9 +219,15 @@ bundle exec rake
211
219
 
212
220
  ### Boot time
213
221
 
214
- Benchmark against [100 executions of a file containing one expectation](https://github.com/cyril/r_spec-clone.rb/blob/main/benchmark/) (lower is better).
222
+ Benchmark against [100 executions of a file containing 1 expectation](https://github.com/cyril/r_spec-clone.rb/blob/main/benchmark/boot_time/) (lower is better).
223
+
224
+ ![Boot time](https://r-spec.dev/benchmark-boot-time.svg)
225
+
226
+ ### Run time
227
+
228
+ Benchmark against [1 execution of a file containing 1,000,000 expectations](https://github.com/cyril/r_spec-clone.rb/blob/main/benchmark/run_time/) (lower is better).
215
229
 
216
- ![Runtime](https://r-spec.dev/benchmark-boot-time.svg)
230
+ ![Run time](https://r-spec.dev/benchmark-run-time.svg)
217
231
 
218
232
  ## Test suite
219
233
 
data/lib/r_spec.rb CHANGED
@@ -89,6 +89,16 @@ module RSpec
89
89
  Clone::Dsl.context(description, &block)
90
90
  end
91
91
 
92
+ # :nocov:
93
+ #
94
+ # Runs a context example group in a subprocess to isolate side effects.
95
+ #
96
+ # @param (see #context)
97
+ def self.context!(description, &block)
98
+ Clone::Dsl.context!(description, &block)
99
+ end
100
+ # :nocov:
101
+
92
102
  # Defines an example group that describes a unit to be tested.
93
103
  #
94
104
  # @example
@@ -111,6 +121,16 @@ module RSpec
111
121
  Clone::Dsl.describe(const, &block)
112
122
  end
113
123
 
124
+ # :nocov:
125
+ #
126
+ # Runs a describe example group in a subprocess to isolate side effects.
127
+ #
128
+ # @param (see #describe)
129
+ def self.describe!(const, &block)
130
+ Clone::Dsl.describe!(const, &block)
131
+ end
132
+ # :nocov:
133
+
114
134
  # Defines a concrete test case.
115
135
  #
116
136
  # The test is performed by the block supplied to &block.
@@ -137,6 +157,32 @@ module RSpec
137
157
  Clone::Dsl.it(name, &block)
138
158
  end
139
159
 
160
+ # :nocov:
161
+ #
162
+ # Runs a concrete test case in a subprocess to isolate side effects.
163
+ #
164
+ # @example
165
+ # app = "Hello, world!"
166
+ #
167
+ # RSpec.it! { expect(app.gsub!("world", "Alice")).to eq "Hello, Alice!" }
168
+ #
169
+ # # Output to the console
170
+ # # Success: expected to eq "Hello, Alice!".
171
+ #
172
+ # RSpec.it { expect(app).to eq "Hello, world!" }
173
+ #
174
+ # # Output to the console
175
+ # # Success: expected to eq "Hello, world!".
176
+ #
177
+ # @param (see #it)
178
+ #
179
+ # @raise (see ExpectationTarget::Base#result)
180
+ # @return (see ExpectationTarget::Base#result)
181
+ def self.it!(name = nil, &block)
182
+ Clone::Dsl.it!(name, &block)
183
+ end
184
+ # :nocov:
185
+
140
186
  # Defines a pending test case.
141
187
  #
142
188
  # `&block` is never evaluated. It can be used to describe behaviour that is
@@ -150,9 +150,19 @@ module RSpec
150
150
  def self.describe(const, &block)
151
151
  desc = ::Class.new(self)
152
152
  desc.let(:described_class) { const } if const.is_a?(::Module)
153
- fork! { desc.instance_eval(&block) }
153
+ desc.instance_eval(&block)
154
154
  end
155
155
 
156
+ # :nocov:
157
+ #
158
+ # Runs a describe example group in a subprocess to isolate side effects.
159
+ #
160
+ # @param (see #describe)
161
+ def self.describe!(const, &block)
162
+ fork! { describe(const, &block) }
163
+ end
164
+ # :nocov:
165
+
156
166
  # Defines an example group that establishes a specific context, like
157
167
  # _empty array_ versus _array with elements_.
158
168
  #
@@ -178,9 +188,19 @@ module RSpec
178
188
  # @param block [Proc] The block to define the specs.
179
189
  def self.context(_description, &block)
180
190
  desc = ::Class.new(self)
181
- fork! { desc.instance_eval(&block) }
191
+ desc.instance_eval(&block)
182
192
  end
183
193
 
194
+ # :nocov:
195
+ #
196
+ # Runs a context example group in a subprocess to isolate side effects.
197
+ #
198
+ # @param (see #context)
199
+ def self.context!(description, &block)
200
+ fork! { context(description, &block) }
201
+ end
202
+ # :nocov:
203
+
184
204
  # Defines a concrete test case.
185
205
  #
186
206
  # The test is performed by the block supplied to `&block`.
@@ -221,12 +241,24 @@ module RSpec
221
241
  # @return (see ExpectationTarget::Base#result)
222
242
  def self.it(_name = nil, &block)
223
243
  example = ::Class.new(self) { include ExpectationHelper::It }.new
224
- fork! { run(example, &block) }
244
+ run(example, &block)
245
+ end
246
+
247
+ # :nocov:
248
+ #
249
+ # Runs a concrete test case in a subprocess to isolate side effects.
250
+ #
251
+ # @param (see #it)
252
+ #
253
+ # @raise (see ExpectationTarget::Base#result)
254
+ # @return (see ExpectationTarget::Base#result)
255
+ def self.it!(name = nil, &block)
256
+ fork! { it(name, &block) }
225
257
  end
258
+ # :nocov:
226
259
 
227
- # Use the {.its} method to define a single spec that specifies the actual
228
- # value of an attribute of the subject using
229
- # {ExpectationHelper::Its#is_expected}.
260
+ # Defines a single concrete test case that specifies the actual value of
261
+ # an attribute of the subject using {ExpectationHelper::Its#is_expected}.
230
262
  #
231
263
  # @example The integer after 41
232
264
  # require "r_spec/clone"
@@ -256,7 +288,7 @@ module RSpec
256
288
  # require "r_spec/clone"
257
289
  #
258
290
  # RSpec.describe Integer do
259
- # its(:boom) { is_expected.to raise_exception RSpec::Error::UndefinedSubject }
291
+ # its(:boom) { is_expected.to raise_exception RSpec::Clone::Error::UndefinedSubject }
260
292
  # end
261
293
  #
262
294
  # # Output to the console
@@ -278,8 +310,22 @@ module RSpec
278
310
  end
279
311
  end.new
280
312
 
281
- fork! { run(example, &block) }
313
+ run(example, &block)
314
+ end
315
+
316
+ # :nocov:
317
+ #
318
+ # Runs a single concrete test case in a subprocess to isolate side
319
+ # effects.
320
+ #
321
+ # @param (see #it)
322
+ #
323
+ # @raise (see ExpectationTarget::Base#result)
324
+ # @return (see ExpectationTarget::Base#result)
325
+ def self.its!(attribute, *args, **kwargs, &block)
326
+ fork! { its(attribute, *args, **kwargs, &block) }
282
327
  end
328
+ # :nocov:
283
329
 
284
330
  # Defines a pending test case.
285
331
  #
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: r_spec-clone
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
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-06-30 00:00:00.000000000 Z
11
+ date: 2021-07-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: expresenter