r_spec-clone 1.5.0 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE.md +1 -1
- data/README.md +9 -28
- data/lib/r_spec/clone/dsl.rb +4 -169
- data/lib/r_spec.rb +0 -87
- metadata +20 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d2e7a16588ed11ac0ab9cd7eebcb01c3d6e914d351c5041cfbed6015c88128ea
|
4
|
+
data.tar.gz: 96dfc31819a59b319c06c777a63aa09daf5630a3db7cf5860c59474b1809f94c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f34d7820173f21ffdafe71d206314aee90904ab7b9a46c29511aed5e4191742e87a14ef2e9da512e48917c080c97d52b5618ce545519f49955fb3edc6b20022d
|
7
|
+
data.tar.gz: d2ad326e9150e95b19f9f62994568e5a44474b6567727e15c38020ede970f1c20b4bd0ddc1d1ab450f968fedfd109ed795accda5724b0424ef666fe09e31e92c
|
data/LICENSE.md
CHANGED
data/README.md
CHANGED
@@ -32,7 +32,8 @@ A minimalist __RSpec clone__ with all the essentials.
|
|
32
32
|
* The `let` method defines a helper method rather than a memoized helper method.
|
33
33
|
* The one-liner `is_expected` syntax also works with block expectations.
|
34
34
|
* `subject`, `before`, `after` and `let` definitions must come before examples.
|
35
|
-
*
|
35
|
+
* The execution of the test suite stops as soon as an error is detected.
|
36
|
+
* The order of the unit tests does not matter because they are executed in isolation.
|
36
37
|
|
37
38
|
## Installation
|
38
39
|
|
@@ -72,9 +73,10 @@ To use the `RSpec` module and its DSL, you need to add `require "r_spec"` to you
|
|
72
73
|
Many projects use a custom spec helper which organizes these includes.
|
73
74
|
|
74
75
|
Concrete test cases are defined in `it` blocks.
|
75
|
-
An optional descriptive string
|
76
|
+
An optional (but recommended) descriptive string or module indicates the purpose of the test and a block contains the main logic of the test.
|
76
77
|
|
77
|
-
Test cases that have been defined or outlined but are not yet expected to work can be defined using `pending` instead of `it`.
|
78
|
+
Test cases that have been defined or outlined but are not yet expected to work can be defined using `pending` instead of `it`.
|
79
|
+
They will not be run but show up in the spec report as pending.
|
78
80
|
|
79
81
|
An `it` block contains an example that should invoke the code to be tested and define what is expected of it.
|
80
82
|
Each example can contain multiple expectations, but it should test only one specific behaviour.
|
@@ -96,28 +98,7 @@ For unit tests, it is recommended to follow the conventions for method names:
|
|
96
98
|
|
97
99
|
To establish certain contexts — think _empty array_ versus _array with elements_ — the `context` method may be used to communicate this to the reader.
|
98
100
|
|
99
|
-
|
100
|
-
|
101
|
-
```ruby
|
102
|
-
app = "foo"
|
103
|
-
|
104
|
-
RSpec.describe "Side effects per example" do
|
105
|
-
it! "runs the example in isolation" do
|
106
|
-
expect { app.gsub!("foo", "bar") }.to eq "bar"
|
107
|
-
expect(app).to eq "bar"
|
108
|
-
end
|
109
|
-
|
110
|
-
it "runs the example" do
|
111
|
-
expect(app).to eq "foo"
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
# Success: expected to eq "bar".
|
116
|
-
# Success: expected to eq "bar".
|
117
|
-
# Success: expected to eq "foo".
|
118
|
-
```
|
119
|
-
|
120
|
-
Note: if you are wondering what the Ruby code generated by using the DSL might look like, an article presents the correspondence between each method via simple examples, available in [English](https://dev.to/cyri_/what-ruby-code-to-expect-from-a-testing-dsl-4oe1), [Chinese](https://ruby-china.org/topics/41441) and [Japanese](https://qiita.com/cyril/items/17ee758e162bae144a07).
|
101
|
+
Note: if you are wondering what kind of code might be generated by the DSL, an article that shows the dynamic transcription of the main methods with simple examples is available in [Chinese](https://ruby-china.org/topics/41441), in [English](https://dev.to/cyri_/what-ruby-code-to-expect-from-a-testing-dsl-4oe1) and in [Japanese](https://qiita.com/cyril/items/17ee758e162bae144a07).
|
121
102
|
|
122
103
|
### Expectations
|
123
104
|
|
@@ -296,7 +277,7 @@ __RSpec clone__'s specifications are self-described here: [spec/](https://github
|
|
296
277
|
|
297
278
|
* Home page: [https://r-spec.dev/](https://r-spec.dev/)
|
298
279
|
* Cheatsheet: [https://r-spec.dev/cheatsheet.html](https://r-spec.dev/cheatsheet.html)
|
299
|
-
* Blog post: [https://
|
280
|
+
* Blog post: [https://cyrilllllll.medium.com/introducing-a-new-rspec-850d48c0f901](https://cyrilllllll.medium.com/introducing-a-new-rspec-850d48c0f901)
|
300
281
|
* Source code: [https://github.com/cyril/r_spec-clone.rb](https://github.com/cyril/r_spec-clone.rb)
|
301
282
|
* API Doc: [https://rubydoc.info/gems/r_spec-clone](https://rubydoc.info/gems/r_spec-clone)
|
302
283
|
* Twitter: [https://twitter.com/cyri\_](https://twitter.com/cyri\_)
|
@@ -310,9 +291,9 @@ Without RSpec, this clone would not have been possible.
|
|
310
291
|
|
311
292
|
## Buy me a coffee ☕
|
312
293
|
|
313
|
-
If you like this project, please consider making a small donation
|
294
|
+
If you like this project, please consider making a small donation.
|
314
295
|
|
315
|
-
[![Donate](https://img.shields.io/badge/Donate-
|
296
|
+
[![Donate](https://img.shields.io/badge/Donate-cyr.eth-purple.svg)](https://etherscan.io/address/cyr.eth)
|
316
297
|
|
317
298
|
## Versioning
|
318
299
|
|
data/lib/r_spec/clone/dsl.rb
CHANGED
@@ -173,47 +173,6 @@ module RSpec
|
|
173
173
|
|
174
174
|
# :nocov:
|
175
175
|
|
176
|
-
# Runs a describe example group in a subprocess to isolate side effects.
|
177
|
-
#
|
178
|
-
# @example
|
179
|
-
# $app = "foo"
|
180
|
-
#
|
181
|
-
# require "r_spec"
|
182
|
-
#
|
183
|
-
# RSpec.describe "Scoped side effects" do
|
184
|
-
# describe! "#gsub!" do
|
185
|
-
# before do
|
186
|
-
# $app.gsub!("o", "0")
|
187
|
-
# end
|
188
|
-
#
|
189
|
-
# context! "when isolated in the context" do
|
190
|
-
# before do
|
191
|
-
# $app.gsub!("f", "F")
|
192
|
-
# end
|
193
|
-
#
|
194
|
-
# it { expect($app).to eq "F00" }
|
195
|
-
# end
|
196
|
-
#
|
197
|
-
# it { expect($app).to eq "f00" }
|
198
|
-
# end
|
199
|
-
#
|
200
|
-
# it { expect($app).to eq "foo" }
|
201
|
-
# end
|
202
|
-
#
|
203
|
-
# # Output to the console
|
204
|
-
# # Success: expected to eq "F00".
|
205
|
-
# # Success: expected to eq "f00".
|
206
|
-
# # Success: expected to eq "foo".
|
207
|
-
#
|
208
|
-
# @param (see #describe)
|
209
|
-
#
|
210
|
-
# @api public
|
211
|
-
def self.describe!(const, &block)
|
212
|
-
fork! { describe(const, &block) }
|
213
|
-
end
|
214
|
-
|
215
|
-
# :nocov:
|
216
|
-
|
217
176
|
# Defines an example group that establishes a specific context, like
|
218
177
|
# _empty array_ versus _array with elements_.
|
219
178
|
#
|
@@ -246,48 +205,6 @@ module RSpec
|
|
246
205
|
|
247
206
|
# :nocov:
|
248
207
|
|
249
|
-
# Runs a context example group in a subprocess to isolate side effects.
|
250
|
-
#
|
251
|
-
# @example
|
252
|
-
# app = "Hello, world!"
|
253
|
-
#
|
254
|
-
# require "r_spec"
|
255
|
-
#
|
256
|
-
# RSpec.describe String do
|
257
|
-
# subject do
|
258
|
-
# app
|
259
|
-
# end
|
260
|
-
#
|
261
|
-
# before do
|
262
|
-
# subject.gsub!("world", person)
|
263
|
-
# end
|
264
|
-
#
|
265
|
-
# context! "when Alice is greeted" do
|
266
|
-
# let(:person) { "Alice" }
|
267
|
-
#
|
268
|
-
# it { is_expected.to eq "Hello, Alice!" }
|
269
|
-
# end
|
270
|
-
#
|
271
|
-
# context! "when Bob is greeted" do
|
272
|
-
# let(:person) { "Bob" }
|
273
|
-
#
|
274
|
-
# it { is_expected.to eq "Hello, Bob!" }
|
275
|
-
# end
|
276
|
-
# end
|
277
|
-
#
|
278
|
-
# # Output to the console
|
279
|
-
# # Success: expected to eq "Hello, Alice!".
|
280
|
-
# # Success: expected to eq "Hello, Bob!".
|
281
|
-
#
|
282
|
-
# @param (see #context)
|
283
|
-
#
|
284
|
-
# @api public
|
285
|
-
def self.context!(description, &block)
|
286
|
-
fork! { context(description, &block) }
|
287
|
-
end
|
288
|
-
|
289
|
-
# :nocov:
|
290
|
-
|
291
208
|
# Defines a concrete test case.
|
292
209
|
#
|
293
210
|
# The test is performed by the block supplied to `&block`.
|
@@ -329,42 +246,7 @@ module RSpec
|
|
329
246
|
#
|
330
247
|
# @api public
|
331
248
|
def self.it(_name = nil, &block)
|
332
|
-
run(example_without_attribute.new, &block)
|
333
|
-
end
|
334
|
-
|
335
|
-
# :nocov:
|
336
|
-
|
337
|
-
# Runs a concrete test case in a subprocess to isolate side effects.
|
338
|
-
#
|
339
|
-
# @example
|
340
|
-
# app = "foo"
|
341
|
-
#
|
342
|
-
# require "r_spec"
|
343
|
-
#
|
344
|
-
# RSpec.describe "Side effects per example" do
|
345
|
-
# it! "runs the example in isolation" do
|
346
|
-
# expect { app.gsub!("foo", "bar") }.to eq "bar"
|
347
|
-
# expect(app).to eq "bar"
|
348
|
-
# end
|
349
|
-
#
|
350
|
-
# it "runs the example" do
|
351
|
-
# expect(app).to eq "foo"
|
352
|
-
# end
|
353
|
-
# end
|
354
|
-
#
|
355
|
-
# # Output to the console
|
356
|
-
# # Success: expected to eq "bar".
|
357
|
-
# # Success: expected to eq "bar".
|
358
|
-
# # Success: expected to eq "foo".
|
359
|
-
#
|
360
|
-
# @param (see #it)
|
361
|
-
#
|
362
|
-
# @raise (see ExpectationTarget::Base#result)
|
363
|
-
# @return (see ExpectationTarget::Base#result)
|
364
|
-
#
|
365
|
-
# @api public
|
366
|
-
def self.it!(name = nil, &block)
|
367
|
-
fork! { it(name, &block) }
|
249
|
+
exit false unless ::Aw.fork? { run(example_without_attribute.new, &block) }
|
368
250
|
end
|
369
251
|
|
370
252
|
# :nocov:
|
@@ -416,43 +298,7 @@ module RSpec
|
|
416
298
|
#
|
417
299
|
# @api public
|
418
300
|
def self.its(attribute, *args, **kwargs, &block)
|
419
|
-
run(example_with_attribute(attribute, *args, **kwargs).new, &block)
|
420
|
-
end
|
421
|
-
|
422
|
-
# :nocov:
|
423
|
-
|
424
|
-
# Runs a single concrete test case in a subprocess to isolate side
|
425
|
-
# effects.
|
426
|
-
#
|
427
|
-
# @example
|
428
|
-
# app = "foo"
|
429
|
-
#
|
430
|
-
# require "r_spec"
|
431
|
-
#
|
432
|
-
# RSpec.describe "Isolated side effect" do
|
433
|
-
# subject do
|
434
|
-
# app
|
435
|
-
# end
|
436
|
-
#
|
437
|
-
# its!(:upcase) { is_expected.to eq "FOO" }
|
438
|
-
#
|
439
|
-
# it "tests the original value" do
|
440
|
-
# expect(app).to eq "foo"
|
441
|
-
# end
|
442
|
-
# end
|
443
|
-
#
|
444
|
-
# # Output to the console
|
445
|
-
# # Success: expected to eq "FOO".
|
446
|
-
# # Success: expected to eq "foo".
|
447
|
-
#
|
448
|
-
# @param (see #it)
|
449
|
-
#
|
450
|
-
# @raise (see ExpectationTarget::Base#result)
|
451
|
-
# @return (see ExpectationTarget::Base#result)
|
452
|
-
#
|
453
|
-
# @api public
|
454
|
-
def self.its!(attribute, *args, **kwargs, &block)
|
455
|
-
fork! { its(attribute, *args, **kwargs, &block) }
|
301
|
+
exit false unless ::Aw.fork? { run(example_with_attribute(attribute, *args, **kwargs).new, &block) }
|
456
302
|
end
|
457
303
|
|
458
304
|
# :nocov:
|
@@ -505,26 +351,15 @@ module RSpec
|
|
505
351
|
end
|
506
352
|
end
|
507
353
|
|
508
|
-
# Creates a subprocess and runs the block inside.
|
509
|
-
def self.fork!(&block)
|
510
|
-
pid = fork(&block)
|
511
|
-
thread = ::Process.detach(pid)
|
512
|
-
exitstatus = thread.join.value.exitstatus
|
513
|
-
exit false unless exitstatus.zero?
|
514
|
-
end
|
515
|
-
|
516
354
|
# Execution of specifications.
|
517
355
|
def self.run(example, &block)
|
518
|
-
example.instance_eval(&block)
|
519
|
-
rescue ::SystemExit
|
520
356
|
Console.source(*block.source_location)
|
521
|
-
|
522
|
-
exit false
|
357
|
+
exit false unless ::Aw.fork? { example.instance_eval(&block) }
|
523
358
|
ensure
|
524
359
|
example&.send(AFTER_METHOD)
|
525
360
|
end
|
526
361
|
|
527
|
-
private_class_method :example_without_attribute, :example_with_attribute, :
|
362
|
+
private_class_method :example_without_attribute, :example_with_attribute, :run
|
528
363
|
|
529
364
|
private
|
530
365
|
|
data/lib/r_spec.rb
CHANGED
@@ -89,36 +89,6 @@ module RSpec
|
|
89
89
|
|
90
90
|
# :nocov:
|
91
91
|
|
92
|
-
# Runs a context example group in a subprocess to isolate side effects.
|
93
|
-
#
|
94
|
-
# @example
|
95
|
-
# str = "Hello, world!"
|
96
|
-
#
|
97
|
-
# require "r_spec"
|
98
|
-
#
|
99
|
-
# RSpec.context! "when a string becomes uppercase" do
|
100
|
-
# before do
|
101
|
-
# str.upcase!
|
102
|
-
# end
|
103
|
-
#
|
104
|
-
# it { expect(str).to eq "HELLO, WORLD!" }
|
105
|
-
# end
|
106
|
-
#
|
107
|
-
# # Output to the console
|
108
|
-
# # Success: expected to eq "HELLO, WORLD!".
|
109
|
-
#
|
110
|
-
# RSpec.it { expect(str).to eq "Hello, world!" }
|
111
|
-
#
|
112
|
-
# # Output to the console
|
113
|
-
# # Success: expected to eq "Hello, world!".
|
114
|
-
#
|
115
|
-
# @param (see #context)
|
116
|
-
def self.context!(description, &block)
|
117
|
-
Clone::Dsl.context!(description, &block)
|
118
|
-
end
|
119
|
-
|
120
|
-
# :nocov:
|
121
|
-
|
122
92
|
# Defines an example group that describes a unit to be tested.
|
123
93
|
#
|
124
94
|
# @example
|
@@ -153,36 +123,6 @@ module RSpec
|
|
153
123
|
|
154
124
|
# :nocov:
|
155
125
|
|
156
|
-
# Runs a describe example group in a subprocess to isolate side effects.
|
157
|
-
#
|
158
|
-
# @example
|
159
|
-
# $app = "foo"
|
160
|
-
#
|
161
|
-
# require "r_spec"
|
162
|
-
#
|
163
|
-
# RSpec.describe! "#gsub!" do
|
164
|
-
# before do
|
165
|
-
# $app.gsub!("o", "0")
|
166
|
-
# end
|
167
|
-
#
|
168
|
-
# it { expect($app).to eq "f00" }
|
169
|
-
# end
|
170
|
-
#
|
171
|
-
# # Output to the console
|
172
|
-
# # Success: expected to eq "f00".
|
173
|
-
#
|
174
|
-
# RSpec.it { expect($app).to eq "foo" }
|
175
|
-
#
|
176
|
-
# # Output to the console
|
177
|
-
# # Success: expected to eq "foo".
|
178
|
-
#
|
179
|
-
# @param (see #describe)
|
180
|
-
def self.describe!(const, &block)
|
181
|
-
Clone::Dsl.describe!(const, &block)
|
182
|
-
end
|
183
|
-
|
184
|
-
# :nocov:
|
185
|
-
|
186
126
|
# Defines a concrete test case.
|
187
127
|
#
|
188
128
|
# The test is performed by the block supplied to &block.
|
@@ -209,33 +149,6 @@ module RSpec
|
|
209
149
|
|
210
150
|
# :nocov:
|
211
151
|
|
212
|
-
# Runs a concrete test case in a subprocess to isolate side effects.
|
213
|
-
#
|
214
|
-
# @example
|
215
|
-
# app = "Hello, world!"
|
216
|
-
#
|
217
|
-
# require "r_spec"
|
218
|
-
#
|
219
|
-
# RSpec.it! { expect(app.gsub!("world", "Alice")).to eq "Hello, Alice!" }
|
220
|
-
#
|
221
|
-
# # Output to the console
|
222
|
-
# # Success: expected to eq "Hello, Alice!".
|
223
|
-
#
|
224
|
-
# RSpec.it { expect(app).to eq "Hello, world!" }
|
225
|
-
#
|
226
|
-
# # Output to the console
|
227
|
-
# # Success: expected to eq "Hello, world!".
|
228
|
-
#
|
229
|
-
# @param (see #it)
|
230
|
-
#
|
231
|
-
# @raise (see ExpectationTarget::Base#result)
|
232
|
-
# @return (see ExpectationTarget::Base#result)
|
233
|
-
def self.it!(name = nil, &block)
|
234
|
-
Clone::Dsl.it!(name, &block)
|
235
|
-
end
|
236
|
-
|
237
|
-
# :nocov:
|
238
|
-
|
239
152
|
# Defines a pending test case.
|
240
153
|
#
|
241
154
|
# `&block` is never evaluated. It can be used to describe behaviour that is
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: r_spec-clone
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.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:
|
11
|
+
date: 2022-04-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: aw
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.2.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.2.0
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: expresenter
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -44,14 +58,14 @@ dependencies:
|
|
44
58
|
requirements:
|
45
59
|
- - "~>"
|
46
60
|
- !ruby/object:Gem::Version
|
47
|
-
version: 2.1.
|
61
|
+
version: 2.1.3
|
48
62
|
type: :runtime
|
49
63
|
prerelease: false
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
52
66
|
- - "~>"
|
53
67
|
- !ruby/object:Gem::Version
|
54
|
-
version: 2.1.
|
68
|
+
version: 2.1.3
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: bundler
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -211,6 +225,7 @@ metadata:
|
|
211
225
|
documentation_uri: https://rubydoc.info/gems/r_spec-clone
|
212
226
|
source_code_uri: https://github.com/cyril/r_spec-clone.rb
|
213
227
|
wiki_uri: https://github.com/cyril/r_spec-clone.rb/wiki
|
228
|
+
rubygems_mfa_required: 'true'
|
214
229
|
post_install_message:
|
215
230
|
rdoc_options: []
|
216
231
|
require_paths:
|
@@ -219,7 +234,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
219
234
|
requirements:
|
220
235
|
- - ">="
|
221
236
|
- !ruby/object:Gem::Version
|
222
|
-
version: 2.7.
|
237
|
+
version: 2.7.5
|
223
238
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
224
239
|
requirements:
|
225
240
|
- - ">="
|