r_spec-clone 1.1.0 → 1.2.0
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 +4 -4
- data/README.md +21 -7
- data/lib/r_spec.rb +46 -0
- data/lib/r_spec/clone/dsl.rb +54 -8
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0e923f4f11f83ba71f2c7267393691edf8bf8ea9be1ae3598f57cb637d71c411
|
4
|
+
data.tar.gz: 18d34b05058e5f17eca7c874f03d52fdac54e995858e1531ee5acff77ceed552
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
18
|
-
2.
|
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
|
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
|
-
*
|
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
|
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
|
+

|
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
|
-

|
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
|
data/lib/r_spec/clone/dsl.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
#
|
228
|
-
#
|
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
|
-
|
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.
|
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-
|
11
|
+
date: 2021-07-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: expresenter
|