r_spec-clone 1.0.0.rc1 → 1.2.2
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 +44 -16
- data/lib/r_spec.rb +115 -21
- data/lib/r_spec/clone/console.rb +0 -2
- data/lib/r_spec/clone/dsl.rb +246 -48
- data/lib/r_spec/clone/error.rb +0 -2
- data/lib/r_spec/clone/error/pending_expectation.rb +0 -2
- data/lib/r_spec/clone/error/reserved_method.rb +0 -2
- data/lib/r_spec/clone/error/undefined_described_class.rb +0 -2
- data/lib/r_spec/clone/error/undefined_subject.rb +0 -2
- data/lib/r_spec/clone/expectation_helper/it.rb +3 -3
- data/lib/r_spec/clone/expectation_helper/its.rb +1 -1
- data/lib/r_spec/clone/expectation_helper/shared.rb +2 -4
- data/lib/r_spec/clone/expectation_target.rb +2 -4
- data/lib/r_spec/clone/expectation_target/base.rb +35 -7
- data/lib/r_spec/clone/expectation_target/block.rb +6 -17
- data/lib/r_spec/clone/expectation_target/value.rb +6 -16
- metadata +7 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7ca7e0d020bebba8aec767197a6c765fa4c0ded5bb96fb58723e5de8321ba1bf
|
4
|
+
data.tar.gz: 3e9fd96ec29c5341bb5b8f8a3fb60c9672a816e3dd22e1d80d7593ef78689f74
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7ae195dc7673cdd06068d376763ca3b67904eb1bea7ec502cdaf74424ffacb2d44c685988e7c22db21e7be2295a9d3de3b93d587e1c0d8696739dfdb8f37216d
|
7
|
+
data.tar.gz: 2b3522c31de373f4b9dc3a5d88a9a8e2ec7443d11205d6f93eae91f43a136bead79774333d3d8bac04b96cd07f89eb8c9792c379af0eb380b644da0931d639b4
|
data/README.md
CHANGED
@@ -6,25 +6,25 @@ A minimalist __RSpec clone__ with all the essentials.
|
|
6
6
|
|
7
7
|
## Status
|
8
8
|
|
9
|
+
[](https://r-spec.dev/)
|
9
10
|
[](https://github.com/cyril/r_spec-clone.rb/releases)
|
10
|
-
[](https://rubydoc.info/github/cyril/r_spec-clone.rb/main)
|
11
|
+
[](https://rubydoc.info/github/cyril/r_spec-clone.rb/main)
|
11
12
|
[](https://github.com/cyril/r_spec-clone.rb/actions?query=workflow%3Aci+branch%3Amain)
|
12
13
|
[](https://github.com/cyril/r_spec-clone.rb/actions?query=workflow%3Arubocop+branch%3Amain)
|
13
14
|
[](https://github.com/cyril/r_spec-clone.rb/raw/main/LICENSE.md)
|
14
15
|
|
15
16
|
## Project goals
|
16
17
|
|
17
|
-
1. Keep a low level of code complexity and
|
18
|
-
2.
|
18
|
+
1. Keep a low level of code complexity, avoid false negatives and false positives.
|
19
|
+
2. Translate specification documents into atomic and thread safe Ruby objects.
|
19
20
|
3. Avoid overloading the interface with additional alternative syntaxes.
|
20
21
|
4. Provide most of RSpec's DSL to express expected outcomes of a code example.
|
21
22
|
|
22
23
|
## Some differences
|
23
24
|
|
24
|
-
* Spec files can be executed with `ruby` directly.
|
25
25
|
* There is no option to activate monkey-patching.
|
26
|
-
* It does not rely on hacks such as
|
27
|
-
*
|
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.
|
27
|
+
* Malicious _actual values_ cannot [hack results](https://asciinema.org/a/423547?autoplay=1&speed=2).
|
28
28
|
* If no `subject` has been explicitly determined, none is defined.
|
29
29
|
* If no described class is set, `described_class` is undefined instead of `nil`.
|
30
30
|
* Expectations cannot be added inside a `before` block.
|
@@ -32,14 +32,14 @@ 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
|
+
* Runs much faster.
|
36
36
|
|
37
37
|
## Installation
|
38
38
|
|
39
39
|
Add this line to your application's Gemfile:
|
40
40
|
|
41
41
|
```ruby
|
42
|
-
gem "r_spec-clone"
|
42
|
+
gem "r_spec-clone"
|
43
43
|
```
|
44
44
|
|
45
45
|
And then execute:
|
@@ -51,7 +51,7 @@ bundle
|
|
51
51
|
Or install it yourself as:
|
52
52
|
|
53
53
|
```sh
|
54
|
-
gem install r_spec-clone
|
54
|
+
gem install r_spec-clone
|
55
55
|
```
|
56
56
|
|
57
57
|
## Overview
|
@@ -68,7 +68,7 @@ A basic spec looks something like this:
|
|
68
68
|
|
69
69
|
### Anatomy of a spec file
|
70
70
|
|
71
|
-
To use the `RSpec` module and its DSL, you need to add `require "r_spec
|
71
|
+
To use the `RSpec` module and its DSL, you need to add `require "r_spec"` to your spec files.
|
72
72
|
Many projects use a custom spec helper which organizes these includes.
|
73
73
|
|
74
74
|
Concrete test cases are defined in `it` blocks.
|
@@ -79,6 +79,8 @@ Test cases that have been defined or outlined but are not yet expected to work c
|
|
79
79
|
An `it` block contains an example that should invoke the code to be tested and define what is expected of it.
|
80
80
|
Each example can contain multiple expectations, but it should test only one specific behaviour.
|
81
81
|
|
82
|
+
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`.
|
83
|
+
|
82
84
|
To express an expectation, wrap an object or block in `expect`, call `to` (or `not_to`) and pass it a matcher object.
|
83
85
|
If the expectation is met, code execution continues.
|
84
86
|
Otherwise the example has _failed_ and other code will not be executed.
|
@@ -93,8 +95,27 @@ For unit tests, it is recommended to follow the conventions for method names:
|
|
93
95
|
* instance methods are prefixed with `#`, class methods with `.`.
|
94
96
|
|
95
97
|
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
|
+
|
99
|
+
To execute unit tests while isolating side effects in a sub-process, declined methods can be used: `describe!`, `context!`, `it!`, `its!`. Here is an example:
|
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
|
+
```
|
98
119
|
|
99
120
|
### Expectations
|
100
121
|
|
@@ -211,11 +232,17 @@ bundle exec rake
|
|
211
232
|
|
212
233
|
## Performance
|
213
234
|
|
214
|
-
###
|
235
|
+
### Boot time
|
236
|
+
|
237
|
+
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).
|
238
|
+
|
239
|
+

|
240
|
+
|
241
|
+
### Run time
|
215
242
|
|
216
|
-
Benchmark against [
|
243
|
+
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).
|
217
244
|
|
218
|
-

|
219
246
|
|
220
247
|
## Test suite
|
221
248
|
|
@@ -224,7 +251,8 @@ __RSpec clone__'s specifications are self-described here: [spec/](https://github
|
|
224
251
|
## Contact
|
225
252
|
|
226
253
|
* Home page: [https://r-spec.dev/](https://r-spec.dev/)
|
227
|
-
* Cheatsheet: [https://
|
254
|
+
* Cheatsheet: [https://r-spec.dev/cheatsheet.html](https://r-spec.dev/cheatsheet.html)
|
255
|
+
* Blog post: [https://batman.buzz/introducing-a-new-rspec-850d48c0f901](https://batman.buzz/introducing-a-new-rspec-850d48c0f901)
|
228
256
|
* Source code: [https://github.com/cyril/r_spec-clone.rb](https://github.com/cyril/r_spec-clone.rb)
|
229
257
|
* API Doc: [https://rubydoc.info/gems/r_spec-clone](https://rubydoc.info/gems/r_spec-clone)
|
230
258
|
* Twitter: [https://twitter.com/cyri\_](https://twitter.com/cyri\_)
|
data/lib/r_spec.rb
CHANGED
@@ -5,7 +5,7 @@ require_relative File.join("r_spec", "clone", "dsl")
|
|
5
5
|
# Top level namespace for the RSpec clone.
|
6
6
|
#
|
7
7
|
# @example The true from the false
|
8
|
-
# require "r_spec
|
8
|
+
# require "r_spec"
|
9
9
|
#
|
10
10
|
# RSpec.describe "The true from the false" do
|
11
11
|
# it { expect(false).not_to be true }
|
@@ -15,7 +15,7 @@ require_relative File.join("r_spec", "clone", "dsl")
|
|
15
15
|
# # Success: expected false not to be true.
|
16
16
|
#
|
17
17
|
# @example The basic behavior of arrays
|
18
|
-
# require "r_spec
|
18
|
+
# require "r_spec"
|
19
19
|
#
|
20
20
|
# RSpec.describe Array do
|
21
21
|
# describe "#size" do
|
@@ -41,7 +41,7 @@ require_relative File.join("r_spec", "clone", "dsl")
|
|
41
41
|
# # Success: expected false to be false.
|
42
42
|
#
|
43
43
|
# @example An inherited definition of let
|
44
|
-
# require "r_spec
|
44
|
+
# require "r_spec"
|
45
45
|
#
|
46
46
|
# RSpec.describe Integer do
|
47
47
|
# let(:answer) { 42 }
|
@@ -68,11 +68,8 @@ module RSpec
|
|
68
68
|
# Defines an example group that establishes a specific context, like _empty
|
69
69
|
# array_ versus _array with elements_.
|
70
70
|
#
|
71
|
-
# Unlike {.describe}, the block is evaluated in isolation in order to scope
|
72
|
-
# possible side effects inside its context.
|
73
|
-
#
|
74
71
|
# @example
|
75
|
-
# require "r_spec
|
72
|
+
# require "r_spec"
|
76
73
|
#
|
77
74
|
# RSpec.context "when divided by zero" do
|
78
75
|
# subject { 42 / 0 }
|
@@ -86,20 +83,62 @@ module RSpec
|
|
86
83
|
# @param description [String] A description that usually begins with "when",
|
87
84
|
# "with" or "without".
|
88
85
|
# @param block [Proc] The block to define the specs.
|
89
|
-
#
|
90
|
-
# @api public
|
91
86
|
def self.context(description, &block)
|
92
87
|
Clone::Dsl.context(description, &block)
|
93
88
|
end
|
94
89
|
|
90
|
+
# :nocov:
|
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
|
+
|
95
122
|
# Defines an example group that describes a unit to be tested.
|
96
123
|
#
|
97
124
|
# @example
|
98
|
-
# require "r_spec
|
125
|
+
# require "r_spec"
|
99
126
|
#
|
100
127
|
# RSpec.describe String do
|
128
|
+
# it { expect(described_class).to be String }
|
129
|
+
# end
|
130
|
+
#
|
131
|
+
# # Output to the console
|
132
|
+
# # Success: expected to be String.
|
133
|
+
#
|
134
|
+
# @example
|
135
|
+
# require "r_spec"
|
136
|
+
#
|
137
|
+
# RSpec.describe String do
|
138
|
+
# let(:foo) { "foo" }
|
139
|
+
#
|
101
140
|
# describe "+" do
|
102
|
-
# it("concats") { expect(
|
141
|
+
# it("concats") { expect(foo + "bar").to eq "foobar" }
|
103
142
|
# end
|
104
143
|
# end
|
105
144
|
#
|
@@ -108,18 +147,48 @@ module RSpec
|
|
108
147
|
#
|
109
148
|
# @param const [Module, String] A module to include in block context.
|
110
149
|
# @param block [Proc] The block to define the specs.
|
111
|
-
#
|
112
|
-
# @api public
|
113
150
|
def self.describe(const, &block)
|
114
151
|
Clone::Dsl.describe(const, &block)
|
115
152
|
end
|
116
153
|
|
154
|
+
# :nocov:
|
155
|
+
|
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
|
+
|
117
186
|
# Defines a concrete test case.
|
118
187
|
#
|
119
188
|
# The test is performed by the block supplied to &block.
|
120
189
|
#
|
121
190
|
# @example The integer after 41
|
122
|
-
# require "r_spec
|
191
|
+
# require "r_spec"
|
123
192
|
#
|
124
193
|
# RSpec.it { expect(41.next).to be 42 }
|
125
194
|
#
|
@@ -132,21 +201,48 @@ module RSpec
|
|
132
201
|
# @param name [String, nil] The name of the spec.
|
133
202
|
# @param block [Proc] An expectation to evaluate.
|
134
203
|
#
|
135
|
-
# @raise (see RSpec::ExpectationTarget::Base#result)
|
136
|
-
# @return (see RSpec::ExpectationTarget::Base#result)
|
137
|
-
#
|
138
|
-
# @api public
|
204
|
+
# @raise (see RSpec::Clone::ExpectationTarget::Base#result)
|
205
|
+
# @return (see RSpec::Clone::ExpectationTarget::Base#result)
|
139
206
|
def self.it(name = nil, &block)
|
140
207
|
Clone::Dsl.it(name, &block)
|
141
208
|
end
|
142
209
|
|
210
|
+
# :nocov:
|
211
|
+
|
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
|
+
|
143
239
|
# Defines a pending test case.
|
144
240
|
#
|
145
241
|
# `&block` is never evaluated. It can be used to describe behaviour that is
|
146
242
|
# not yet implemented.
|
147
243
|
#
|
148
244
|
# @example
|
149
|
-
# require "r_spec
|
245
|
+
# require "r_spec"
|
150
246
|
#
|
151
247
|
# RSpec.pending "is implemented but waiting" do
|
152
248
|
# expect something to be finished
|
@@ -164,8 +260,6 @@ module RSpec
|
|
164
260
|
# @param message [String] The reason why the example is pending.
|
165
261
|
#
|
166
262
|
# @return [nil] Write a message to STDOUT.
|
167
|
-
#
|
168
|
-
# @api public
|
169
263
|
def self.pending(message)
|
170
264
|
Clone::Dsl.pending(message)
|
171
265
|
end
|
data/lib/r_spec/clone/console.rb
CHANGED
data/lib/r_spec/clone/dsl.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "aw"
|
4
|
-
|
5
3
|
require_relative "console"
|
6
4
|
require_relative "error"
|
7
5
|
require_relative "expectation_helper"
|
@@ -18,7 +16,7 @@ module RSpec
|
|
18
16
|
# Executes the given block before each spec in the current context runs.
|
19
17
|
#
|
20
18
|
# @example
|
21
|
-
# require "r_spec
|
19
|
+
# require "r_spec"
|
22
20
|
#
|
23
21
|
# RSpec.describe Integer do
|
24
22
|
# before do
|
@@ -44,6 +42,8 @@ module RSpec
|
|
44
42
|
# # Success: expected to be 123.
|
45
43
|
#
|
46
44
|
# @param block [Proc] The content to execute at the class initialization.
|
45
|
+
#
|
46
|
+
# @api public
|
47
47
|
def self.before(&block)
|
48
48
|
define_method(BEFORE_METHOD) do
|
49
49
|
super()
|
@@ -56,7 +56,7 @@ module RSpec
|
|
56
56
|
# Executes the given block after each spec in the current context runs.
|
57
57
|
#
|
58
58
|
# @example
|
59
|
-
# require "r_spec
|
59
|
+
# require "r_spec"
|
60
60
|
#
|
61
61
|
# RSpec.describe Integer do
|
62
62
|
# after do
|
@@ -71,6 +71,8 @@ module RSpec
|
|
71
71
|
# # That is the answer to everything.
|
72
72
|
#
|
73
73
|
# @param block [Proc] The content to execute at the class initialization.
|
74
|
+
#
|
75
|
+
# @api public
|
74
76
|
def self.after(&block)
|
75
77
|
define_method(AFTER_METHOD) do
|
76
78
|
instance_exec(&block)
|
@@ -83,7 +85,7 @@ module RSpec
|
|
83
85
|
# Sets a user-defined property.
|
84
86
|
#
|
85
87
|
# @example
|
86
|
-
# require "r_spec
|
88
|
+
# require "r_spec"
|
87
89
|
#
|
88
90
|
# RSpec.describe "Name stories" do
|
89
91
|
# let(:name) { "Bob" }
|
@@ -105,6 +107,8 @@ module RSpec
|
|
105
107
|
# @param block [Proc] The content of the method to define.
|
106
108
|
#
|
107
109
|
# @return [Symbol] A private method that define the block content.
|
110
|
+
#
|
111
|
+
# @api public
|
108
112
|
def self.let(name, *args, **kwargs, &block)
|
109
113
|
raise Error::ReservedMethod if [BEFORE_METHOD, AFTER_METHOD].include?(name.to_sym)
|
110
114
|
|
@@ -114,7 +118,7 @@ module RSpec
|
|
114
118
|
# Sets a user-defined property named {#subject}.
|
115
119
|
#
|
116
120
|
# @example
|
117
|
-
# require "r_spec
|
121
|
+
# require "r_spec"
|
118
122
|
#
|
119
123
|
# RSpec.describe Array do
|
120
124
|
# subject { [1, 2, 3] }
|
@@ -122,13 +126,23 @@ module RSpec
|
|
122
126
|
# it "has the prescribed elements" do
|
123
127
|
# expect(subject).to eq([1, 2, 3])
|
124
128
|
# end
|
129
|
+
#
|
130
|
+
# it { is_expected.to be_an_instance_of described_class }
|
131
|
+
#
|
132
|
+
# its(:size) { is_expected.to be 3 }
|
133
|
+
# its(:downcase) { is_expected.to raise_exception NoMethodError }
|
125
134
|
# end
|
126
135
|
#
|
127
136
|
# # Output to the console
|
128
137
|
# # Success: expected to eq [1, 2, 3].
|
138
|
+
# # Success: expected [1, 2, 3] to be an instance of Array.
|
139
|
+
# # Success: expected to be 3.
|
140
|
+
# # Success: undefined method `downcase' for [1, 2, 3]:Array.
|
129
141
|
#
|
130
142
|
# @param block [Proc] The subject to set.
|
131
143
|
# @return [Symbol] A {#subject} method that define the block content.
|
144
|
+
#
|
145
|
+
# @api public
|
132
146
|
def self.subject(&block)
|
133
147
|
let(__method__, &block)
|
134
148
|
end
|
@@ -136,7 +150,7 @@ module RSpec
|
|
136
150
|
# Defines an example group that describes a unit to be tested.
|
137
151
|
#
|
138
152
|
# @example
|
139
|
-
# require "r_spec
|
153
|
+
# require "r_spec"
|
140
154
|
#
|
141
155
|
# RSpec.describe String do
|
142
156
|
# describe "+" do
|
@@ -149,20 +163,62 @@ module RSpec
|
|
149
163
|
#
|
150
164
|
# @param const [Module, String] A module to include in block context.
|
151
165
|
# @param block [Proc] The block to define the specs.
|
166
|
+
#
|
167
|
+
# @api public
|
152
168
|
def self.describe(const, &block)
|
153
169
|
desc = ::Class.new(self)
|
154
170
|
desc.let(:described_class) { const } if const.is_a?(::Module)
|
155
171
|
desc.instance_eval(&block)
|
156
172
|
end
|
157
173
|
|
158
|
-
#
|
159
|
-
|
174
|
+
# :nocov:
|
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"
|
160
182
|
#
|
161
|
-
#
|
162
|
-
#
|
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
|
+
# Defines an example group that establishes a specific context, like
|
218
|
+
# _empty array_ versus _array with elements_.
|
163
219
|
#
|
164
220
|
# @example
|
165
|
-
# require "r_spec
|
221
|
+
# require "r_spec"
|
166
222
|
#
|
167
223
|
# RSpec.describe "web resource" do
|
168
224
|
# context "when resource is not found" do
|
@@ -181,17 +237,63 @@ module RSpec
|
|
181
237
|
# @param _description [String] A description that usually begins with
|
182
238
|
# "when", "with" or "without".
|
183
239
|
# @param block [Proc] The block to define the specs.
|
240
|
+
#
|
241
|
+
# @api public
|
184
242
|
def self.context(_description, &block)
|
185
243
|
desc = ::Class.new(self)
|
186
|
-
|
244
|
+
desc.instance_eval(&block)
|
245
|
+
end
|
246
|
+
|
247
|
+
# :nocov:
|
248
|
+
|
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) }
|
187
287
|
end
|
188
288
|
|
289
|
+
# :nocov:
|
290
|
+
|
189
291
|
# Defines a concrete test case.
|
190
292
|
#
|
191
293
|
# The test is performed by the block supplied to `&block`.
|
192
294
|
#
|
193
295
|
# @example The integer after 41
|
194
|
-
# require "r_spec
|
296
|
+
# require "r_spec"
|
195
297
|
#
|
196
298
|
# RSpec.describe Integer do
|
197
299
|
# it { expect(41.next).to be 42 }
|
@@ -201,7 +303,7 @@ module RSpec
|
|
201
303
|
# # Success: expected to be 42.
|
202
304
|
#
|
203
305
|
# @example A division by zero
|
204
|
-
# require "r_spec
|
306
|
+
# require "r_spec"
|
205
307
|
#
|
206
308
|
# RSpec.describe Integer do
|
207
309
|
# subject { 41 }
|
@@ -224,25 +326,54 @@ module RSpec
|
|
224
326
|
#
|
225
327
|
# @raise (see ExpectationTarget::Base#result)
|
226
328
|
# @return (see ExpectationTarget::Base#result)
|
329
|
+
#
|
330
|
+
# @api public
|
227
331
|
def self.it(_name = nil, &block)
|
228
|
-
|
332
|
+
run(example_without_attribute.new, &block)
|
333
|
+
end
|
229
334
|
|
230
|
-
|
231
|
-
example.instance_eval(&block)
|
232
|
-
rescue ::SystemExit
|
233
|
-
Console.source(*block.source_location)
|
335
|
+
# :nocov:
|
234
336
|
|
235
|
-
|
236
|
-
|
237
|
-
|
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) }
|
238
368
|
end
|
239
369
|
|
240
|
-
#
|
241
|
-
|
242
|
-
#
|
370
|
+
# :nocov:
|
371
|
+
|
372
|
+
# Defines a single concrete test case that specifies the actual value of
|
373
|
+
# an attribute of the subject using {ExpectationHelper::Its#is_expected}.
|
243
374
|
#
|
244
375
|
# @example The integer after 41
|
245
|
-
# require "r_spec
|
376
|
+
# require "r_spec"
|
246
377
|
#
|
247
378
|
# RSpec.describe Integer do
|
248
379
|
# subject { 41 }
|
@@ -254,7 +385,7 @@ module RSpec
|
|
254
385
|
# # Success: expected to be 42.
|
255
386
|
#
|
256
387
|
# @example A division by zero
|
257
|
-
# require "r_spec
|
388
|
+
# require "r_spec"
|
258
389
|
#
|
259
390
|
# RSpec.describe Integer do
|
260
391
|
# subject { 41 }
|
@@ -266,10 +397,10 @@ module RSpec
|
|
266
397
|
# # Success: divided by 0.
|
267
398
|
#
|
268
399
|
# @example A spec without subject
|
269
|
-
# require "r_spec
|
400
|
+
# require "r_spec"
|
270
401
|
#
|
271
402
|
# RSpec.describe Integer do
|
272
|
-
# its(:
|
403
|
+
# its(:abs) { is_expected.to raise_exception RSpec::Clone::Error::UndefinedSubject }
|
273
404
|
# end
|
274
405
|
#
|
275
406
|
# # Output to the console
|
@@ -282,33 +413,57 @@ module RSpec
|
|
282
413
|
#
|
283
414
|
# @raise (see ExpectationTarget::Base#result)
|
284
415
|
# @return (see ExpectationTarget::Base#result)
|
416
|
+
#
|
417
|
+
# @api public
|
285
418
|
def self.its(attribute, *args, **kwargs, &block)
|
286
|
-
|
287
|
-
|
288
|
-
example = ::Class.new(self) do
|
289
|
-
include ExpectationHelper::Its
|
290
|
-
|
291
|
-
define_method(:actual) do
|
292
|
-
subject.public_send(attribute, *args, **kwargs)
|
293
|
-
end
|
294
|
-
end.new
|
419
|
+
run(example_with_attribute(attribute, *args, **kwargs).new, &block)
|
420
|
+
end
|
295
421
|
|
296
|
-
|
297
|
-
rescue ::SystemExit
|
298
|
-
Console.source(*block.source_location)
|
422
|
+
# :nocov:
|
299
423
|
|
300
|
-
|
301
|
-
|
302
|
-
|
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) }
|
303
456
|
end
|
304
457
|
|
458
|
+
# :nocov:
|
459
|
+
|
305
460
|
# Defines a pending test case.
|
306
461
|
#
|
307
|
-
# `&block` is never evaluated. It can be used to describe behaviour that
|
308
|
-
# not yet implemented.
|
462
|
+
# `&block` is never evaluated. It can be used to describe behaviour that
|
463
|
+
# is not yet implemented.
|
309
464
|
#
|
310
465
|
# @example
|
311
|
-
# require "r_spec
|
466
|
+
# require "r_spec"
|
312
467
|
#
|
313
468
|
# RSpec.describe "an example" do
|
314
469
|
# pending "is implemented but waiting" do
|
@@ -331,13 +486,56 @@ module RSpec
|
|
331
486
|
Console.passed_spec Error::PendingExpectation.result(message)
|
332
487
|
end
|
333
488
|
|
489
|
+
# Example class for concrete test case.
|
490
|
+
def self.example_without_attribute
|
491
|
+
::Class.new(self) do
|
492
|
+
prepend ExpectationHelper::It
|
493
|
+
end
|
494
|
+
end
|
495
|
+
|
496
|
+
# Example class for concrete test case that specifies the actual value of
|
497
|
+
# an attribute of the subject.
|
498
|
+
def self.example_with_attribute(attribute, *args, **kwargs)
|
499
|
+
::Class.new(self) do
|
500
|
+
prepend ExpectationHelper::Its
|
501
|
+
|
502
|
+
define_method(:actual) do
|
503
|
+
subject.public_send(attribute, *args, **kwargs)
|
504
|
+
end
|
505
|
+
end
|
506
|
+
end
|
507
|
+
|
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
|
+
# Execution of specifications.
|
517
|
+
def self.run(example, &block)
|
518
|
+
example.instance_eval(&block)
|
519
|
+
rescue ::SystemExit
|
520
|
+
Console.source(*block.source_location)
|
521
|
+
|
522
|
+
exit false
|
523
|
+
ensure
|
524
|
+
example&.send(AFTER_METHOD)
|
525
|
+
end
|
526
|
+
|
527
|
+
private_class_method :example_without_attribute, :example_with_attribute, :fork!, :run
|
528
|
+
|
334
529
|
private
|
335
530
|
|
531
|
+
# If the first argument to a {.describe} definition is a class (or a
|
532
|
+
# module), this method will be overridden to return it.
|
336
533
|
def described_class
|
337
534
|
raise Error::UndefinedDescribedClass,
|
338
535
|
"the first argument to at least one example group must be a module"
|
339
536
|
end
|
340
537
|
|
538
|
+
# If a subject is defined, this method will be overridden to return it.
|
341
539
|
def subject
|
342
540
|
raise Error::UndefinedSubject, "subject not explicitly defined"
|
343
541
|
end
|
data/lib/r_spec/clone/error.rb
CHANGED
@@ -18,8 +18,8 @@ module RSpec
|
|
18
18
|
# @return [Block, Value] The wrapped target of an expectation.
|
19
19
|
#
|
20
20
|
# @example
|
21
|
-
# expect("foo") # => #<RSpec::ExpectationTarget::Value:
|
22
|
-
# expect { Boom } # => #<RSpec::ExpectationTarget::Block:
|
21
|
+
# expect("foo") # => #<RSpec::Clone::ExpectationTarget::Value:0x00007f @actual="foo">
|
22
|
+
# expect { Boom } # => #<RSpec::Clone::ExpectationTarget::Block:0x00007f @callable=#<Proc:0x00007f>>
|
23
23
|
#
|
24
24
|
# @api public
|
25
25
|
def expect(value = self.class.superclass, &block)
|
@@ -31,7 +31,7 @@ module RSpec
|
|
31
31
|
# @return [Block] The wrapped target of an expectation.
|
32
32
|
#
|
33
33
|
# @example
|
34
|
-
# is_expected # => #<RSpec::ExpectationTarget::Block:
|
34
|
+
# is_expected # => #<RSpec::Clone::ExpectationTarget::Block:0x00007fb6b8 @callable=#<Proc:0x00007fb6b8>>
|
35
35
|
#
|
36
36
|
# @api public
|
37
37
|
def is_expected
|
@@ -15,7 +15,7 @@ module RSpec
|
|
15
15
|
# @return [Block] The wrapped target of an expectation.
|
16
16
|
#
|
17
17
|
# @example
|
18
|
-
# is_expected # => #<RSpec::ExpectationTarget::Block:
|
18
|
+
# is_expected # => #<RSpec::Clone::ExpectationTarget::Block:0x00007f @callable=#<Proc:0x00007f>>
|
19
19
|
#
|
20
20
|
# @api public
|
21
21
|
def is_expected
|
@@ -2,15 +2,13 @@
|
|
2
2
|
|
3
3
|
require "matchi/rspec"
|
4
4
|
|
5
|
-
require_relative File.join("..", "error", "pending_expectation")
|
6
|
-
|
7
5
|
module RSpec
|
8
6
|
module Clone
|
9
7
|
module ExpectationHelper
|
10
8
|
# Abstract expectation helper base module.
|
11
9
|
#
|
12
|
-
# This module defines a number of methods to create expectations, which
|
13
|
-
# automatically included into examples.
|
10
|
+
# This module defines a number of methods to create expectations, which
|
11
|
+
# are automatically included into examples.
|
14
12
|
#
|
15
13
|
# It also includes a collection of expectation matchers 🤹
|
16
14
|
#
|
@@ -6,12 +6,10 @@ require_relative File.join("expectation_target", "value")
|
|
6
6
|
module RSpec
|
7
7
|
module Clone
|
8
8
|
# Wraps the target of an expectation.
|
9
|
-
#
|
10
|
-
# @api private
|
11
9
|
module ExpectationTarget
|
12
10
|
# @param undefined_value A sentinel value to be able to tell when the user
|
13
|
-
# did not pass an argument. We can't use `nil` for that because `nil` is
|
14
|
-
# valid value to pass.
|
11
|
+
# did not pass an argument. We can't use `nil` for that because `nil` is
|
12
|
+
# a valid value to pass.
|
15
13
|
# @param value [#object_id, nil] An actual value.
|
16
14
|
# @param block [#call, nil] A code to evaluate.
|
17
15
|
#
|
@@ -10,14 +10,14 @@ module RSpec
|
|
10
10
|
module ExpectationTarget
|
11
11
|
# Abstract expectation target base class.
|
12
12
|
#
|
13
|
-
# @note `RSpec::ExpectationTarget::Base` is not intended to be
|
14
|
-
# directly by users. Use `expect` instead.
|
13
|
+
# @note `RSpec::Clone::ExpectationTarget::Base` is not intended to be
|
14
|
+
# instantiated directly by users. Use `expect` instead.
|
15
15
|
class Base
|
16
16
|
# Instantiate a new expectation target.
|
17
17
|
#
|
18
|
-
# @param
|
19
|
-
def initialize(
|
20
|
-
@
|
18
|
+
# @param input [#object_id, Proc] The code to evaluate.
|
19
|
+
def initialize(input)
|
20
|
+
@input = input
|
21
21
|
end
|
22
22
|
|
23
23
|
# Runs the given expectation, passing if `matcher` returns true.
|
@@ -52,6 +52,36 @@ module RSpec
|
|
52
52
|
|
53
53
|
protected
|
54
54
|
|
55
|
+
# @param test [::TestTube::Base] The state of the experiment.
|
56
|
+
# @param matcher [#matches?] The matcher.
|
57
|
+
# @param negate [Boolean] The assertion is positive or negative.
|
58
|
+
#
|
59
|
+
# @return [nil] Write a message to STDOUT.
|
60
|
+
#
|
61
|
+
# @raise [SystemExit] Terminate execution immediately by calling
|
62
|
+
# `Kernel.exit(false)` with a failure message written to STDERR.
|
63
|
+
def absolute_requirement(test, matcher:, negate:)
|
64
|
+
result(
|
65
|
+
passed?(test),
|
66
|
+
actual: test.actual,
|
67
|
+
error: test.error,
|
68
|
+
got: test.got,
|
69
|
+
matcher: matcher,
|
70
|
+
negate: negate
|
71
|
+
)
|
72
|
+
end
|
73
|
+
|
74
|
+
# Code experiment result.
|
75
|
+
#
|
76
|
+
# @param test [::TestTube::Base] The state of the experiment.
|
77
|
+
#
|
78
|
+
# @see https://github.com/fixrb/test_tube
|
79
|
+
#
|
80
|
+
# @return [Boolean] The result of the test (passed or failed).
|
81
|
+
def passed?(test)
|
82
|
+
test.got.equal?(true)
|
83
|
+
end
|
84
|
+
|
55
85
|
# @param passed [Boolean] The high expectation passed or failed.
|
56
86
|
# @param actual [#object_id] The actual value.
|
57
87
|
# @param error [Exception, nil] Any raised exception.
|
@@ -63,8 +93,6 @@ module RSpec
|
|
63
93
|
#
|
64
94
|
# @raise [SystemExit] Terminate execution immediately by calling
|
65
95
|
# `Kernel.exit(false)` with a failure message written to STDERR.
|
66
|
-
#
|
67
|
-
# @api private
|
68
96
|
def result(passed, actual:, error:, got:, matcher:, negate:)
|
69
97
|
Console.passed_spec ::Expresenter.call(passed).with(
|
70
98
|
actual: actual,
|
@@ -16,31 +16,20 @@ module RSpec
|
|
16
16
|
# # with `not_to`
|
17
17
|
# expect { actual }.not_to be(4)
|
18
18
|
#
|
19
|
-
# @note `RSpec::ExpectationTarget::Block` is not intended to be
|
20
|
-
# directly by users. Use `expect` instead.
|
19
|
+
# @note `RSpec::Clone::ExpectationTarget::Block` is not intended to be
|
20
|
+
# instantiated directly by users. Use `expect` instead.
|
21
21
|
class Block < Base
|
22
22
|
protected
|
23
23
|
|
24
24
|
# @param matcher [#matches?] The matcher.
|
25
25
|
# @param negate [Boolean] The assertion is positive or negative.
|
26
26
|
#
|
27
|
-
# @return
|
27
|
+
# @return (see Base#absolute_requirement)
|
28
28
|
#
|
29
|
-
# @raise
|
30
|
-
# `Kernel.exit(false)` with a failure message written to STDERR.
|
29
|
+
# @raise (see Base#absolute_requirement)
|
31
30
|
def absolute_requirement(matcher:, negate:)
|
32
|
-
|
33
|
-
|
34
|
-
isolation: false,
|
35
|
-
matcher: matcher,
|
36
|
-
negate: negate
|
37
|
-
)
|
38
|
-
|
39
|
-
result(
|
40
|
-
experiment.got.equal?(true),
|
41
|
-
actual: experiment.actual,
|
42
|
-
error: experiment.error,
|
43
|
-
got: experiment.got,
|
31
|
+
super(
|
32
|
+
::TestTube.invoke(isolation: false, matcher: matcher, negate: negate, &@input),
|
44
33
|
matcher: matcher,
|
45
34
|
negate: negate
|
46
35
|
)
|
@@ -16,30 +16,20 @@ module RSpec
|
|
16
16
|
# # with `not_to`
|
17
17
|
# expect(actual).not_to be(4)
|
18
18
|
#
|
19
|
-
# @note `RSpec::ExpectationTarget::Value` is not intended to be
|
20
|
-
# directly by users. Use `expect` instead.
|
19
|
+
# @note `RSpec::Clone::ExpectationTarget::Value` is not intended to be
|
20
|
+
# instantiated directly by users. Use `expect` instead.
|
21
21
|
class Value < Base
|
22
22
|
protected
|
23
23
|
|
24
24
|
# @param matcher [#matches?] The matcher.
|
25
25
|
# @param negate [Boolean] The assertion is positive or negative.
|
26
26
|
#
|
27
|
-
# @return
|
27
|
+
# @return (see Base#absolute_requirement)
|
28
28
|
#
|
29
|
-
# @raise
|
30
|
-
# `Kernel.exit(false)` with a failure message written to STDERR.
|
29
|
+
# @raise (see Base#absolute_requirement)
|
31
30
|
def absolute_requirement(matcher:, negate:)
|
32
|
-
|
33
|
-
@
|
34
|
-
matcher: matcher,
|
35
|
-
negate: negate
|
36
|
-
)
|
37
|
-
|
38
|
-
result(
|
39
|
-
experiment.got.equal?(true),
|
40
|
-
actual: experiment.actual,
|
41
|
-
error: experiment.error,
|
42
|
-
got: experiment.got,
|
31
|
+
super(
|
32
|
+
::TestTube.pass(@input, matcher: matcher, negate: negate),
|
43
33
|
matcher: matcher,
|
44
34
|
negate: negate
|
45
35
|
)
|
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
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.2
|
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-12 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.1.12
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: 0.1.12
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: expresenter
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -58,14 +44,14 @@ dependencies:
|
|
58
44
|
requirements:
|
59
45
|
- - "~>"
|
60
46
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
47
|
+
version: 2.0.0
|
62
48
|
type: :runtime
|
63
49
|
prerelease: false
|
64
50
|
version_requirements: !ruby/object:Gem::Requirement
|
65
51
|
requirements:
|
66
52
|
- - "~>"
|
67
53
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
54
|
+
version: 2.0.0
|
69
55
|
- !ruby/object:Gem::Dependency
|
70
56
|
name: bundler
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -217,7 +203,7 @@ files:
|
|
217
203
|
- lib/r_spec/clone/expectation_target/base.rb
|
218
204
|
- lib/r_spec/clone/expectation_target/block.rb
|
219
205
|
- lib/r_spec/clone/expectation_target/value.rb
|
220
|
-
homepage: https://
|
206
|
+
homepage: https://r-spec.dev/
|
221
207
|
licenses:
|
222
208
|
- MIT
|
223
209
|
metadata:
|
@@ -236,9 +222,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
236
222
|
version: 2.7.0
|
237
223
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
238
224
|
requirements:
|
239
|
-
- - "
|
225
|
+
- - ">="
|
240
226
|
- !ruby/object:Gem::Version
|
241
|
-
version:
|
227
|
+
version: '0'
|
242
228
|
requirements: []
|
243
229
|
rubygems_version: 3.1.6
|
244
230
|
signing_key:
|