rspec-varys 0.0.3 → 0.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 +5 -5
- data/.ruby-version +1 -1
- data/.tool-versions +1 -0
- data/.travis.yml +17 -0
- data/Gemfile +1 -2
- data/README.md +76 -4
- data/Rakefile +12 -0
- data/bin/genspecs +2 -0
- data/config/cucumber.yml +1 -0
- data/features/generating_specs.feature +212 -57
- data/features/readme.md +25 -2
- data/features/support/{env.rb → external.rb} +2 -0
- data/lib/rspec/varys.rb +47 -71
- data/lib/rspec/varys/rspec_generator.rb +67 -0
- data/lib/rspec/varys/version.rb +1 -1
- data/rspec-varys.gemspec +5 -4
- data/spec/rspec/varys_spec.rb +19 -44
- data/spec/spec_helper.rb +4 -0
- data/spec/varys/rspec_generator_spec.rb +78 -0
- metadata +44 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 84ad5d3575e590204e17a0dc39078c65bb0305b37bf817119fd754b2535dd504
|
4
|
+
data.tar.gz: d63f46eaa21e08baeafb492d02f710e23ed9a8a4064f24ccb6a832c5af50cb4a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 88d00f04f6bfed58a6937e26648f13f467efbf1ad7492bf06895419ef7607586b39ec6f7b05c81c40e14afd634f21493a41cf3095b176290f85add0257b1b589
|
7
|
+
data.tar.gz: f1308ced4b06f2def0f3c733cb6e707c58d477352a32c82fd7b007ac552f1b5b80492f62816b3fc3e178fbd3f98488dbfd340a32c405947add4d21cc50ff0d16
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
3.0.1
|
data/.tool-versions
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby 3.0.1
|
data/.travis.yml
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
language: ruby
|
2
|
+
bundler_args:
|
3
|
+
rvm:
|
4
|
+
- 2.1.2
|
5
|
+
|
6
|
+
addons:
|
7
|
+
code_climate:
|
8
|
+
repo_token: dbd468edcfe120e56aec92ebf99ff6c030becc1910a8d1684102c6fa2e907439
|
9
|
+
|
10
|
+
deploy:
|
11
|
+
provider: rubygems
|
12
|
+
api_key:
|
13
|
+
secure: WLQzsGZ6aPzqsyS1Mu4YCZjer4ZXRFQo5j1XPkTdR/bYmip2GBQAoVIUihlIXrcTSDKRk4VVZ62GkVSOkTA41vAVvD69ARGNIgwSDzLfoVp7RWEIi7peUBdYhzOoQM8eFnOKa3UeZbEqjolsTjtQfMQISNCeL9TCmdRcyLa/avk=
|
14
|
+
gem: rspec-varys
|
15
|
+
on:
|
16
|
+
tags: true
|
17
|
+
repo: ritchiey/rspec-varys
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,10 +1,56 @@
|
|
1
|
-
[](http://badge.fury.io/rb/rspec-varys)
|
1
|
+
[](http://badge.fury.io/rb/rspec-varys) [](https://travis-ci.org/ritchiey/rspec-varys) [](https://codeclimate.com/github/ritchiey/rspec-varys)
|
2
2
|
|
3
3
|
# Rspec::Varys
|
4
4
|
|
5
|
-
Generate RSpec specs from intelligence gathered from doubles and spies.
|
5
|
+
Generate RSpec specs from intelligence gathered from doubles and spies. This is an experiment to see if a top-down TDD work-flow can be improved by partially automating the creation of lower level specs.
|
6
6
|
|
7
|
-
|
7
|
+
When you define a test-double in your spec:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
describe ExampleClass, "#max_margin_for" do
|
11
|
+
it "returns the maximum margin for the supplied text" do
|
12
|
+
allow(subject).to receive(:margin_for).and_return(2, 4)
|
13
|
+
expect(subject.max_margin_for(" unindent line\n indented line\n")).to eq(4)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
```
|
17
|
+
|
18
|
+
And your code calls it:
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
class ExampleClass
|
22
|
+
def max_margin_for(text)
|
23
|
+
text.split("\n").map {|line| margin_for(line)}.max
|
24
|
+
end
|
25
|
+
end
|
26
|
+
```
|
27
|
+
|
28
|
+
|
29
|
+
Varys will generate the corresponding specs so you can verify the validity of your test-doubles:
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
# Generated by Varys:
|
33
|
+
|
34
|
+
describe ExampleClass, "#margin_for" do
|
35
|
+
it "returns something" do
|
36
|
+
confirm(subject).can receive(:margin_for).with(" unindent line").and_return(2)
|
37
|
+
skip "remove this line once implemented"
|
38
|
+
expect(subject.margin_for(" unindent line")).to eq(2)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe ExampleClass, "#margin_for" do
|
43
|
+
it "returns something" do
|
44
|
+
confirm(subject).can receive(:margin_for).with(" indented line").and_return(4)
|
45
|
+
skip "remove this line once implemented"
|
46
|
+
expect(subject.margin_for(" indented line")).to eq(4)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
```
|
50
|
+
|
51
|
+
## Limitations
|
52
|
+
|
53
|
+
Varys is very early release software and it has many limitations. If you find one, please check the Github issues and add it if it's not already listed.
|
8
54
|
|
9
55
|
## Installation
|
10
56
|
|
@@ -20,9 +66,35 @@ Or install it yourself as:
|
|
20
66
|
|
21
67
|
$ gem install rspec-varys
|
22
68
|
|
69
|
+
## Configuration
|
70
|
+
|
71
|
+
Add these lines to your `spec/spec_helper.rb`:
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
require "rspec/varys"
|
75
|
+
require "rspec/varys/rspec_generator"
|
76
|
+
|
77
|
+
RSpec.configure do |config|
|
78
|
+
config.include RSpec::Varys::DSL
|
79
|
+
|
80
|
+
config.before(:suite) do
|
81
|
+
RSpec::Varys.reset
|
82
|
+
end
|
83
|
+
|
84
|
+
config.after(:suite) do
|
85
|
+
# Required: create varys.yml
|
86
|
+
RSpec::Varys.print_report
|
87
|
+
|
88
|
+
# Optional: create generated_specs.yml from varys.yml
|
89
|
+
RSpec::Varys::RSpecGenerator.run
|
90
|
+
end
|
91
|
+
end
|
92
|
+
```
|
93
|
+
|
23
94
|
## Usage
|
24
95
|
|
25
|
-
See the [Cucumber features](https://relishapp.com/spechero/rspec-varys/docs) for examples of intended usage.
|
96
|
+
See the [Cucumber features](https://relishapp.com/spechero/rspec-varys/docs) for examples of intended usage or watch [this screencast](https://vimeo.com/119725799) for a simple tutorial.
|
97
|
+
|
26
98
|
|
27
99
|
## Contributing
|
28
100
|
|
data/Rakefile
CHANGED
@@ -1,2 +1,14 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
|
3
|
+
require 'rubygems'
|
4
|
+
require 'cucumber'
|
5
|
+
require 'cucumber/rake/task'
|
6
|
+
require 'rspec/core/rake_task'
|
7
|
+
|
8
|
+
|
9
|
+
Cucumber::Rake::Task.new(:features) do |t|
|
10
|
+
t.cucumber_opts = "features --format pretty"
|
11
|
+
end
|
12
|
+
|
13
|
+
task :default => [:spec, :features]
|
14
|
+
RSpec::Core::RakeTask.new
|
data/bin/genspecs
ADDED
data/config/cucumber.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
default: --publish-quiet
|
@@ -6,6 +6,7 @@ Feature: Generating an RSpec Spec from an RSpec Expectation
|
|
6
6
|
$:.unshift File.expand_path('../../lib', File.dirname(__FILE__))
|
7
7
|
|
8
8
|
require "rspec/varys"
|
9
|
+
require "rspec/varys/rspec_generator"
|
9
10
|
|
10
11
|
RSpec.configure do |config|
|
11
12
|
|
@@ -17,11 +18,138 @@ Feature: Generating an RSpec Spec from an RSpec Expectation
|
|
17
18
|
|
18
19
|
config.after(:suite) do
|
19
20
|
RSpec::Varys.print_report
|
21
|
+
RSpec::Varys::RSpecGenerator.run
|
20
22
|
end
|
21
23
|
end
|
22
24
|
"""
|
23
25
|
|
24
26
|
|
27
|
+
Scenario: For a test double
|
28
|
+
Given a file named "top_level_spec.rb" with:
|
29
|
+
"""ruby
|
30
|
+
require_relative 'spec_helper'
|
31
|
+
require_relative 'person'
|
32
|
+
|
33
|
+
describe "First day at work" do
|
34
|
+
|
35
|
+
it "starts with an introduction" do
|
36
|
+
name = double('Name', full_name: "Dick Jones")
|
37
|
+
boss = Person.new(name)
|
38
|
+
expect(boss.welcome).to eq "Welcome to OCP, I'm Dick Jones"
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
"""
|
43
|
+
And a file named "person.rb" with:
|
44
|
+
"""ruby
|
45
|
+
class Person
|
46
|
+
|
47
|
+
def initialize(name)
|
48
|
+
@name = name
|
49
|
+
end
|
50
|
+
|
51
|
+
def welcome
|
52
|
+
"Welcome to OCP, I'm #{@name.full_name}"
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
"""
|
57
|
+
|
58
|
+
When I run `rspec top_level_spec.rb`
|
59
|
+
Then it should pass with:
|
60
|
+
"""ruby
|
61
|
+
Specs have been generated based on mocks you aren't currently testing.
|
62
|
+
"""
|
63
|
+
And the file "varys.yaml" should contain:
|
64
|
+
"""yaml
|
65
|
+
---
|
66
|
+
:untested_stubs:
|
67
|
+
- :class_name: Name
|
68
|
+
:type: instance
|
69
|
+
:method: full_name
|
70
|
+
:returns: Dick Jones
|
71
|
+
"""
|
72
|
+
|
73
|
+
And the file "generated_specs.rb" should contain:
|
74
|
+
"""ruby
|
75
|
+
describe Name, "#full_name" do
|
76
|
+
|
77
|
+
it "returns something" do
|
78
|
+
confirm(subject).can receive(:full_name).and_return("Dick Jones")
|
79
|
+
skip "remove this line once implemented"
|
80
|
+
expect(subject.full_name).to eq("Dick Jones")
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
"""
|
87
|
+
Scenario: For a class method
|
88
|
+
Given a file named "top_level_spec.rb" with:
|
89
|
+
"""ruby
|
90
|
+
require_relative 'spec_helper'
|
91
|
+
require_relative 'person'
|
92
|
+
|
93
|
+
describe "First day at work" do
|
94
|
+
|
95
|
+
it "starts with an introduction" do
|
96
|
+
boss = Person.new('Dick', 'Jones')
|
97
|
+
allow(Person).to receive(:full_name).with("Dick", "Jones").and_return("Dick Jones")
|
98
|
+
expect(boss.welcome).to eq "Welcome to OCP, I'm Dick Jones"
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
"""
|
103
|
+
And a file named "person.rb" with:
|
104
|
+
"""ruby
|
105
|
+
class Person
|
106
|
+
|
107
|
+
def initialize(firstname, lastname)
|
108
|
+
@firstname = firstname
|
109
|
+
@lastname = lastname
|
110
|
+
end
|
111
|
+
|
112
|
+
def welcome
|
113
|
+
"Welcome to OCP, I'm #{Person.full_name(@firstname, @lastname)}"
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
"""
|
118
|
+
|
119
|
+
When I run `rspec top_level_spec.rb`
|
120
|
+
Then it should pass with:
|
121
|
+
"""ruby
|
122
|
+
Specs have been generated based on mocks you aren't currently testing.
|
123
|
+
"""
|
124
|
+
And the file "varys.yaml" should contain:
|
125
|
+
"""yaml
|
126
|
+
---
|
127
|
+
:untested_stubs:
|
128
|
+
- :class_name: Person
|
129
|
+
:type: class
|
130
|
+
:method: full_name
|
131
|
+
:returns: Dick Jones
|
132
|
+
:arguments:
|
133
|
+
- Dick
|
134
|
+
- Jones
|
135
|
+
"""
|
136
|
+
|
137
|
+
And the file "generated_specs.rb" should contain:
|
138
|
+
"""ruby
|
139
|
+
describe Person, ".full_name" do
|
140
|
+
|
141
|
+
it "returns something" do
|
142
|
+
confirm(described_class).can receive(:full_name).with("Dick", "Jones").and_return("Dick Jones")
|
143
|
+
skip "remove this line once implemented"
|
144
|
+
expect(described_class.full_name("Dick", "Jones")).to eq("Dick Jones")
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
|
150
|
+
"""
|
151
|
+
|
152
|
+
|
25
153
|
Scenario: For a single unmatched expectation
|
26
154
|
Given a file named "top_level_spec.rb" with:
|
27
155
|
"""ruby
|
@@ -54,24 +182,32 @@ Feature: Generating an RSpec Spec from an RSpec Expectation
|
|
54
182
|
|
55
183
|
When I run `rspec top_level_spec.rb`
|
56
184
|
Then it should pass with:
|
57
|
-
"""
|
185
|
+
"""ruby
|
58
186
|
Specs have been generated based on mocks you aren't currently testing.
|
59
187
|
"""
|
60
|
-
And the file "
|
188
|
+
And the file "varys.yaml" should contain:
|
189
|
+
"""yaml
|
190
|
+
---
|
191
|
+
:untested_stubs:
|
192
|
+
- :class_name: Person
|
193
|
+
:type: instance
|
194
|
+
:method: full_name
|
195
|
+
:returns: Dick Jones
|
61
196
|
"""
|
62
|
-
describe Person do
|
63
197
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
pending
|
68
|
-
confirm(subject).can receive(:full_name).and_return("Dick Jones")
|
69
|
-
expect(subject.full_name).to eq("Dick Jones")
|
70
|
-
end
|
198
|
+
And the file "generated_specs.rb" should contain:
|
199
|
+
"""ruby
|
200
|
+
describe Person, "#full_name" do
|
71
201
|
|
202
|
+
it "returns something" do
|
203
|
+
confirm(subject).can receive(:full_name).and_return("Dick Jones")
|
204
|
+
skip "remove this line once implemented"
|
205
|
+
expect(subject.full_name).to eq("Dick Jones")
|
72
206
|
end
|
73
207
|
|
74
208
|
end
|
209
|
+
|
210
|
+
|
75
211
|
"""
|
76
212
|
|
77
213
|
|
@@ -108,36 +244,50 @@ Feature: Generating an RSpec Spec from an RSpec Expectation
|
|
108
244
|
|
109
245
|
When I run `rspec top_level_spec.rb`
|
110
246
|
Then it should pass with:
|
111
|
-
"""
|
247
|
+
"""ruby
|
112
248
|
Specs have been generated based on mocks you aren't currently testing.
|
113
249
|
"""
|
114
|
-
And the file "
|
250
|
+
And the file "varys.yaml" should contain:
|
251
|
+
"""yaml
|
252
|
+
---
|
253
|
+
:untested_stubs:
|
254
|
+
- :class_name: Person
|
255
|
+
:type: instance
|
256
|
+
:method: title
|
257
|
+
:returns: Vice President
|
258
|
+
- :class_name: Person
|
259
|
+
:type: instance
|
260
|
+
:method: full_name
|
261
|
+
:returns: Dick Jones
|
115
262
|
"""
|
116
|
-
describe Person do
|
117
|
-
|
118
|
-
describe "#title" do
|
119
263
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
expect(subject.title).to eq("Vice President")
|
124
|
-
end
|
264
|
+
And the file "generated_specs.rb" should contain:
|
265
|
+
"""ruby
|
266
|
+
describe Person, "#title" do
|
125
267
|
|
268
|
+
it "returns something" do
|
269
|
+
confirm(subject).can receive(:title).and_return("Vice President")
|
270
|
+
skip "remove this line once implemented"
|
271
|
+
expect(subject.title).to eq("Vice President")
|
126
272
|
end
|
127
273
|
|
128
|
-
|
274
|
+
end
|
129
275
|
|
130
|
-
it "returns the correct value" do
|
131
|
-
pending
|
132
|
-
confirm(subject).can receive(:full_name).and_return("Dick Jones")
|
133
|
-
expect(subject.full_name).to eq("Dick Jones")
|
134
|
-
end
|
135
276
|
|
277
|
+
describe Person, "#full_name" do
|
278
|
+
|
279
|
+
it "returns something" do
|
280
|
+
confirm(subject).can receive(:full_name).and_return("Dick Jones")
|
281
|
+
skip "remove this line once implemented"
|
282
|
+
expect(subject.full_name).to eq("Dick Jones")
|
136
283
|
end
|
137
284
|
|
138
285
|
end
|
286
|
+
|
287
|
+
|
139
288
|
"""
|
140
289
|
|
290
|
+
|
141
291
|
Scenario: For one matched and one unmatched expectation
|
142
292
|
Given a file named "top_level_spec.rb" with:
|
143
293
|
"""ruby
|
@@ -148,8 +298,8 @@ Feature: Generating an RSpec Spec from an RSpec Expectation
|
|
148
298
|
|
149
299
|
it "starts with an introduction" do
|
150
300
|
boss = Person.new('Dick', 'Jones')
|
151
|
-
|
152
|
-
|
301
|
+
allow(boss).to receive(:full_name).and_return("Dick Jones")
|
302
|
+
allow(boss).to receive(:title).and_return("Vice President")
|
153
303
|
expect(boss.welcome).to eq "Welcome to OCP, I'm Vice President Dick Jones"
|
154
304
|
end
|
155
305
|
|
@@ -162,7 +312,6 @@ Feature: Generating an RSpec Spec from an RSpec Expectation
|
|
162
312
|
describe "#full_name" do
|
163
313
|
|
164
314
|
it "returns the correct value" do
|
165
|
-
pending
|
166
315
|
confirm(subject).can receive(:full_name).and_return("Dick Jones")
|
167
316
|
# ...
|
168
317
|
end
|
@@ -188,24 +337,17 @@ Feature: Generating an RSpec Spec from an RSpec Expectation
|
|
188
337
|
|
189
338
|
When I run `rspec top_level_spec.rb`
|
190
339
|
Then it should pass with:
|
191
|
-
"""
|
340
|
+
"""ruby
|
192
341
|
Specs have been generated based on mocks you aren't currently testing.
|
193
342
|
"""
|
194
|
-
And the file "
|
195
|
-
"""
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
confirm(subject).can receive(:title).and_return("Vice President")
|
203
|
-
expect(subject.title).to eq("Vice President")
|
204
|
-
end
|
205
|
-
|
206
|
-
end
|
207
|
-
|
208
|
-
end
|
343
|
+
And the file "varys.yaml" should contain:
|
344
|
+
"""yaml
|
345
|
+
---
|
346
|
+
:untested_stubs:
|
347
|
+
- :class_name: Person
|
348
|
+
:type: instance
|
349
|
+
:method: title
|
350
|
+
:returns: Vice President
|
209
351
|
"""
|
210
352
|
|
211
353
|
Scenario: For an expectation with parameters
|
@@ -221,8 +363,6 @@ Feature: Generating an RSpec Spec from an RSpec Expectation
|
|
221
363
|
describe "#full_name" do
|
222
364
|
|
223
365
|
it "returns the correct value" do
|
224
|
-
pending
|
225
|
-
confirm(subject).can receive(:full_name).and_return("Dick Jones")
|
226
366
|
expect(subject).to receive(:join_names).with("Dick", "Jones").and_return("Dick Jones")
|
227
367
|
subject.full_name
|
228
368
|
end
|
@@ -254,22 +394,37 @@ Feature: Generating an RSpec Spec from an RSpec Expectation
|
|
254
394
|
|
255
395
|
When I run `rspec top_level_spec.rb`
|
256
396
|
Then it should pass with:
|
257
|
-
"""
|
397
|
+
"""ruby
|
258
398
|
Specs have been generated based on mocks you aren't currently testing.
|
259
399
|
"""
|
260
|
-
And the file "
|
400
|
+
And the file "varys.yaml" should contain:
|
401
|
+
"""yaml
|
402
|
+
---
|
403
|
+
:untested_stubs:
|
404
|
+
- :class_name: Person
|
405
|
+
:type: instance
|
406
|
+
:method: join_names
|
407
|
+
:returns: Dick Jones
|
408
|
+
:arguments:
|
409
|
+
- Dick
|
410
|
+
- Jones
|
261
411
|
"""
|
262
|
-
describe Person do
|
263
412
|
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
pending
|
268
|
-
confirm(subject).can receive(:join_names).with("Dick", "Jones").and_return("Dick Jones")
|
269
|
-
expect(subject.join_names("Dick", "Jones")).to eq("Dick Jones")
|
270
|
-
end
|
413
|
+
And the file "generated_specs.rb" should contain:
|
414
|
+
"""ruby
|
415
|
+
describe Person, "#join_names" do
|
271
416
|
|
417
|
+
it "returns something" do
|
418
|
+
confirm(subject).can receive(:join_names).with("Dick", "Jones").and_return("Dick Jones")
|
419
|
+
skip "remove this line once implemented"
|
420
|
+
expect(subject.join_names("Dick", "Jones")).to eq("Dick Jones")
|
272
421
|
end
|
273
422
|
|
274
423
|
end
|
424
|
+
|
425
|
+
|
275
426
|
"""
|
427
|
+
|
428
|
+
|
429
|
+
|
430
|
+
|
data/features/readme.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
*Everything should be built top-down, except the first time
|
1
|
+
*Everything should be built top-down, except the first time 1. Alan
|
2
2
|
Perlis*
|
3
3
|
|
4
4
|
RSpec-Varys automatically generates RSpec specs from your mocked methods each time your suite is run.
|
@@ -7,4 +7,27 @@ This enables you to build your program from the top-down (or outside-in if
|
|
7
7
|
your prefer) without having to manually keep track of which mocks have
|
8
8
|
been validated.
|
9
9
|
|
10
|
-
|
10
|
+
Installation instructions can be found [here](https://github.com/ritchiey/rspec-varys).
|
11
|
+
|
12
|
+
A typical workflow using rspec-varys looks like this. Note, I haven't
|
13
|
+
written "and run your specs again" at the end of each step, that's
|
14
|
+
implied.
|
15
|
+
|
16
|
+
- if you have no failing specs and you need some new functionality, write a new top-level spec.
|
17
|
+
|
18
|
+
- if your specs are failing because your **spec** calls a non-existent function,
|
19
|
+
write the code for that function. Feel free to call methods that
|
20
|
+
don't exist yet.
|
21
|
+
|
22
|
+
- if your specs are failing because your **code** calls a non-existent function
|
23
|
+
stub that function out in the spec using `allow`.
|
24
|
+
|
25
|
+
- if your specs pass but varys generates new specs for untested stubs,
|
26
|
+
copy the generated specs into the appropriate spec file.
|
27
|
+
|
28
|
+
- if varys warns you about unneeded specs, delete those specs and any
|
29
|
+
code that can be removed without making other specs fail.
|
30
|
+
|
31
|
+
- if your specs pass but there are pending specs, pick one and remove
|
32
|
+
the `pending` statement.
|
33
|
+
|
data/lib/rspec/varys.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "rspec/varys/version"
|
2
2
|
require "fileutils"
|
3
|
+
require 'yaml'
|
3
4
|
|
4
5
|
module RSpec
|
5
6
|
module Varys
|
@@ -26,11 +27,25 @@ module RSpec
|
|
26
27
|
{
|
27
28
|
class_name: class_name,
|
28
29
|
message: message,
|
29
|
-
args:
|
30
|
-
return_value:
|
30
|
+
args: args,
|
31
|
+
return_value: return_value
|
31
32
|
}
|
32
33
|
end
|
33
34
|
|
35
|
+
def args
|
36
|
+
customization = customizations.find{|c| c.instance_variable_get('@method_name') == :with}
|
37
|
+
(customization && customization.instance_variable_get('@args')) || []
|
38
|
+
end
|
39
|
+
|
40
|
+
def return_value
|
41
|
+
customization = customizations.find{|c| c.instance_variable_get('@method_name') == :and_return}
|
42
|
+
customization && customization.instance_variable_get('@args').first
|
43
|
+
end
|
44
|
+
|
45
|
+
def customizations
|
46
|
+
@ability.instance_variable_get('@recorded_customizations')
|
47
|
+
end
|
48
|
+
|
34
49
|
def class_name
|
35
50
|
@object.class.name
|
36
51
|
end
|
@@ -68,10 +83,6 @@ module RSpec::Varys
|
|
68
83
|
@recorded_messages
|
69
84
|
end
|
70
85
|
|
71
|
-
def self.generated_specs
|
72
|
-
@generated_specs ||= generate_specs
|
73
|
-
end
|
74
|
-
|
75
86
|
def self.reset
|
76
87
|
@recorded_messages = []
|
77
88
|
@generated_specs = nil
|
@@ -80,96 +91,61 @@ module RSpec::Varys
|
|
80
91
|
|
81
92
|
def self.record(object, message, args, block, return_value)
|
82
93
|
@recorded_messages << {
|
83
|
-
class_name: object
|
94
|
+
class_name: class_name_for(object),
|
95
|
+
type: type_for(object),
|
84
96
|
message: message,
|
85
97
|
args: args,
|
86
98
|
return_value: return_value
|
87
99
|
}
|
88
100
|
end
|
89
101
|
|
90
|
-
def self.
|
91
|
-
|
92
|
-
unconfirmed_messages.each do |s|
|
93
|
-
generated_specs[s[:class_name]] ||= []
|
94
|
-
generated_specs[s[:class_name]] << generate_spec(s)
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
|
100
|
-
def self.generate_spec(s)
|
101
|
-
<<-GENERATED
|
102
|
-
describe "##{s[:message]}" do
|
103
|
-
|
104
|
-
it "returns the correct value" do
|
105
|
-
pending
|
106
|
-
confirm(subject).can receive(:#{s[:message]})#{with_parameters(s)}.and_return(#{serialize s[:return_value]})
|
107
|
-
expect(subject.#{s[:message]}#{parameters(s)}).to eq(#{serialize s[:return_value]})
|
108
|
-
end
|
109
|
-
|
110
|
-
end
|
111
|
-
|
112
|
-
GENERATED
|
102
|
+
def self.type_for(object)
|
103
|
+
object.kind_of?(Class) ? 'class' : 'instance'
|
113
104
|
end
|
114
105
|
|
115
|
-
def self.
|
116
|
-
if
|
117
|
-
|
106
|
+
def self.class_name_for(object)
|
107
|
+
if object.kind_of? RSpec::Mocks::Double
|
108
|
+
'Name'
|
118
109
|
else
|
119
|
-
|
110
|
+
object.kind_of?(Class) ? object.name : object.class.name
|
120
111
|
end
|
121
112
|
end
|
122
113
|
|
123
|
-
def self.params(args)
|
124
|
-
args.map{|a| serialize(a)}.join(", ")
|
125
|
-
end
|
126
|
-
|
127
|
-
def self.parameters(spec)
|
128
|
-
if spec[:args].length > 0
|
129
|
-
%Q[(#{params spec[:args]})]
|
130
|
-
else
|
131
|
-
""
|
132
|
-
end
|
133
|
-
end
|
134
114
|
|
135
115
|
def self.print_report
|
136
|
-
|
137
|
-
|
138
|
-
generated_specs.each do |class_name, specs|
|
139
|
-
File.open("#{dest_path}/#{underscore class_name}_spec.rb", 'w') do |file|
|
140
|
-
file.write "describe #{class_name} do\n\n"
|
141
|
-
specs.each do |spec|
|
142
|
-
file.write(spec)
|
143
|
-
end
|
144
|
-
file.write "end"
|
145
|
-
end
|
116
|
+
open_yaml_file do |yaml_file|
|
117
|
+
yaml_file.write YAML.dump(report)
|
146
118
|
end
|
147
119
|
puts "Specs have been generated based on mocks you aren't currently testing."
|
148
120
|
end
|
149
121
|
|
150
|
-
def self.
|
151
|
-
|
122
|
+
def self.report
|
123
|
+
{
|
124
|
+
untested_stubs: unconfirmed_messages.map do |call|
|
125
|
+
{
|
126
|
+
class_name: call[:class_name],
|
127
|
+
type: call[:type],
|
128
|
+
method: call[:message].to_s,
|
129
|
+
returns: call[:return_value]
|
130
|
+
}.merge(arguments_if_any(call))
|
131
|
+
end
|
132
|
+
}
|
152
133
|
end
|
153
134
|
|
154
|
-
def self.
|
155
|
-
|
135
|
+
def self.arguments_if_any(call)
|
136
|
+
call[:args].length > 0 ? { arguments: call[:args] } : { }
|
156
137
|
end
|
157
138
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
if %w(Array Hash Float Fixnum String).include? arg.class.name
|
162
|
-
arg.pretty_inspect.chop
|
163
|
-
else
|
164
|
-
guess_constructor arg
|
139
|
+
def self.open_yaml_file
|
140
|
+
File.open("varys.yaml", 'w') do |io|
|
141
|
+
yield io
|
165
142
|
end
|
166
143
|
end
|
167
144
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
def self.guess_constructor(arg)
|
172
|
-
"#{arg.class.name}.new(#{serialize(arg.to_s)})"
|
145
|
+
|
146
|
+
def self.unconfirmed_messages
|
147
|
+
recorded_messages - confirmed_messages
|
173
148
|
end
|
149
|
+
|
174
150
|
end
|
175
151
|
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'pp'
|
2
|
+
|
3
|
+
class RSpec::Varys::RSpecGenerator
|
4
|
+
|
5
|
+
def self.run
|
6
|
+
|
7
|
+
specs = YAML.load(File.read "varys.yaml")
|
8
|
+
|
9
|
+
File.open('generated_specs.rb', 'w') do |file|
|
10
|
+
process_specs(specs, file)
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.process_specs(specs, file)
|
16
|
+
specs[:untested_stubs].each do |spec|
|
17
|
+
file.puts <<-EOF
|
18
|
+
describe #{spec[:class_name]}, "#{class_method?(spec) ? '.' : '#'}#{spec[:method]}" do
|
19
|
+
|
20
|
+
it "returns something" do
|
21
|
+
confirm(#{sut(spec)}).can receive(:#{spec[:method]})#{with_args_if_any(spec)}.and_return(#{serialize spec[:returns]})
|
22
|
+
skip "remove this line once implemented"
|
23
|
+
expect(#{sut(spec)}.#{spec[:method]}#{args_if_any(spec)}).to eq(#{serialize spec[:returns]})
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
EOF
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.with_args_if_any(call)
|
34
|
+
args_if_any(call, ".with")
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.args_if_any(call, prefix="")
|
38
|
+
args = call[:arguments]
|
39
|
+
(args && args.length > 0) ? "#{prefix}(#{args.map{|a| serialize a}.join ', '})" : ""
|
40
|
+
end
|
41
|
+
|
42
|
+
# Attempt to recreate the source-code to represent this argument in the setup
|
43
|
+
# for our generated spec.
|
44
|
+
def self.serialize(arg)
|
45
|
+
if %w(Array Hash Float Fixnum String NilClass TrueClass FalseClass).include? arg.class.name
|
46
|
+
arg.pretty_inspect.chop
|
47
|
+
else
|
48
|
+
guess_constructor arg
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Don't recognise the type so we don't know how to recreate it
|
53
|
+
# in source code. So we'll take a guess at what might work and
|
54
|
+
# let the user fix it up if necessary.
|
55
|
+
def self.guess_constructor(arg)
|
56
|
+
"#{arg.class.name}.new(#{serialize(arg.to_s)})"
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.class_method?(call)
|
60
|
+
call[:type] == 'class'
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.sut(call)
|
64
|
+
class_method?(call) ? "described_class" : "subject"
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
data/lib/rspec/varys/version.rb
CHANGED
data/rspec-varys.gemspec
CHANGED
@@ -18,9 +18,10 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_development_dependency "bundler", "~>
|
22
|
-
spec.add_development_dependency "rake", '~>
|
21
|
+
spec.add_development_dependency "bundler", "~> 2.2"
|
22
|
+
spec.add_development_dependency "rake", '~> 13.0', ">= 13.0"
|
23
23
|
spec.add_development_dependency "rspec", '~> 3.1', ">= 3.1.0"
|
24
|
-
spec.add_development_dependency "cucumber", '~> 1
|
25
|
-
spec.add_development_dependency "aruba", '~> 0.
|
24
|
+
spec.add_development_dependency "cucumber", '~> 6.1', ">= 6.1.0"
|
25
|
+
spec.add_development_dependency "aruba", '~> 0.1', '>= 0.1.1'
|
26
|
+
spec.add_dependency 'pp', '~> 0.2.0'
|
26
27
|
end
|
data/spec/rspec/varys_spec.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'rspec'
|
2
2
|
require 'rspec/varys'
|
3
|
-
|
3
|
+
|
4
4
|
|
5
5
|
class Person
|
6
6
|
|
@@ -34,6 +34,7 @@ describe RSpec::Varys do
|
|
34
34
|
{ class_name: 'Object', message: :a_message, args: [:a_parameter], return_value: 42 }
|
35
35
|
])
|
36
36
|
end
|
37
|
+
|
37
38
|
end
|
38
39
|
|
39
40
|
describe ".confirmed_messages" do
|
@@ -50,6 +51,17 @@ describe RSpec::Varys do
|
|
50
51
|
}])
|
51
52
|
end
|
52
53
|
|
54
|
+
it "parses parameters" do
|
55
|
+
described_class.reset
|
56
|
+
confirm(Person.new 'Dick', 'Jones').can receive(:full_name).with(:blah).and_return("Dick Jones")
|
57
|
+
expect(described_class.confirmed_messages).to match_array([{
|
58
|
+
class_name: 'Person',
|
59
|
+
message: :full_name,
|
60
|
+
args: [:blah],
|
61
|
+
return_value: "Dick Jones"
|
62
|
+
}])
|
63
|
+
end
|
64
|
+
|
53
65
|
end
|
54
66
|
|
55
67
|
it "records the messages sent to a spy" do
|
@@ -61,6 +73,7 @@ describe RSpec::Varys do
|
|
61
73
|
|
62
74
|
expect(described_class.recorded_messages).to match_array([{
|
63
75
|
class_name: 'Object',
|
76
|
+
type: 'instance',
|
64
77
|
message: :a_message,
|
65
78
|
args: [:a_parameter],
|
66
79
|
return_value: 42
|
@@ -69,27 +82,13 @@ describe RSpec::Varys do
|
|
69
82
|
|
70
83
|
|
71
84
|
context "given the test-suite calls a mocked method" do
|
72
|
-
context "with no
|
73
|
-
|
74
|
-
let(:expected_spec) do
|
75
|
-
<<GENERATED
|
76
|
-
describe "#full_name" do
|
77
|
-
|
78
|
-
it "returns the correct value" do
|
79
|
-
pending
|
80
|
-
confirm(subject).can receive(:full_name).and_return("Dick Jones")
|
81
|
-
expect(subject.full_name).to eq("Dick Jones")
|
82
|
-
end
|
83
|
-
|
84
|
-
end
|
85
|
-
|
86
|
-
GENERATED
|
87
|
-
end
|
85
|
+
context "with no parameters" do
|
88
86
|
|
89
87
|
let(:recognised_specs) {
|
90
88
|
[
|
91
89
|
{
|
92
90
|
class_name: 'Person',
|
91
|
+
type: 'instance',
|
93
92
|
message: :full_name,
|
94
93
|
args: [],
|
95
94
|
return_value: "Dick Jones"
|
@@ -105,38 +104,19 @@ GENERATED
|
|
105
104
|
expect(dick.welcome).to eq "Welcome to OCP, I'm Dick Jones"
|
106
105
|
end
|
107
106
|
|
108
|
-
it "
|
109
|
-
# did it correctly record the method called
|
107
|
+
it "record the methods called" do
|
110
108
|
expect(described_class.recorded_messages).to match_array(recognised_specs)
|
111
|
-
|
112
|
-
# did it generate an in-memory version of the specs?
|
113
|
-
expect(described_class.generated_specs).to eq('Person' => [ expected_spec ])
|
114
|
-
|
115
109
|
end
|
116
110
|
|
117
111
|
end
|
118
112
|
|
119
113
|
context "with parameters" do
|
120
114
|
|
121
|
-
let(:expected_spec) do
|
122
|
-
<<GENERATED
|
123
|
-
describe "#join_names" do
|
124
|
-
|
125
|
-
it "returns the correct value" do
|
126
|
-
pending
|
127
|
-
confirm(subject).can receive(:join_names).with("Dick", "Jones").and_return("Dick Jones")
|
128
|
-
expect(subject.join_names("Dick", "Jones")).to eq("Dick Jones")
|
129
|
-
end
|
130
|
-
|
131
|
-
end
|
132
|
-
|
133
|
-
GENERATED
|
134
|
-
end
|
135
|
-
|
136
115
|
let(:recognised_specs) {
|
137
116
|
[
|
138
117
|
{
|
139
118
|
class_name: 'Person',
|
119
|
+
type: 'instance',
|
140
120
|
message: :join_names,
|
141
121
|
args: ["Dick", "Jones"],
|
142
122
|
return_value: "Dick Jones"
|
@@ -152,13 +132,8 @@ GENERATED
|
|
152
132
|
expect(dick.welcome).to eq "Welcome to OCP, I'm Dick Jones"
|
153
133
|
end
|
154
134
|
|
155
|
-
it "
|
156
|
-
# did it correctly record the method called
|
135
|
+
it "records that the method was called" do
|
157
136
|
expect(described_class.recorded_messages).to match_array(recognised_specs)
|
158
|
-
|
159
|
-
# did it generate an in-memory version of the specs?
|
160
|
-
expect(described_class.generated_specs).to eq('Person' => [ expected_spec ])
|
161
|
-
|
162
137
|
end
|
163
138
|
|
164
139
|
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require_relative '../../lib/rspec/varys/rspec_generator'
|
3
|
+
|
4
|
+
describe RSpec::Varys::RSpecGenerator do
|
5
|
+
|
6
|
+
describe ".process_specs" do
|
7
|
+
|
8
|
+
context "given a file YAML file with one missing spec with arguments" do
|
9
|
+
let(:specs) {
|
10
|
+
YAML.load <<-SPECS
|
11
|
+
---
|
12
|
+
:untested_stubs:
|
13
|
+
- :class_name: Person
|
14
|
+
:method: full_name
|
15
|
+
:arguments:
|
16
|
+
- Dick
|
17
|
+
- Jones
|
18
|
+
:returns: Dick Jones
|
19
|
+
SPECS
|
20
|
+
}
|
21
|
+
|
22
|
+
it "generates the spec" do
|
23
|
+
output = ""
|
24
|
+
StringIO.open(output, 'w') do |file|
|
25
|
+
described_class.process_specs(specs, file)
|
26
|
+
end
|
27
|
+
expect(output).to eq <<-EOF
|
28
|
+
describe Person, "#full_name" do
|
29
|
+
|
30
|
+
it "returns something" do
|
31
|
+
confirm(subject).can receive(:full_name).with("Dick", "Jones").and_return("Dick Jones")
|
32
|
+
skip "remove this line once implemented"
|
33
|
+
expect(subject.full_name("Dick", "Jones")).to eq("Dick Jones")
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
EOF
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
context "given a file YAML file with one missing spec" do
|
45
|
+
let(:specs) {
|
46
|
+
YAML.load <<-SPECS
|
47
|
+
---
|
48
|
+
:untested_stubs:
|
49
|
+
- :class_name: Person
|
50
|
+
:method: full_name
|
51
|
+
:returns: Dick Jones
|
52
|
+
SPECS
|
53
|
+
}
|
54
|
+
|
55
|
+
it "generates the spec" do
|
56
|
+
output = ""
|
57
|
+
StringIO.open(output, 'w') do |file|
|
58
|
+
described_class.process_specs(specs, file)
|
59
|
+
end
|
60
|
+
expect(output).to eq <<-EOF
|
61
|
+
describe Person, "#full_name" do
|
62
|
+
|
63
|
+
it "returns something" do
|
64
|
+
confirm(subject).can receive(:full_name).and_return("Dick Jones")
|
65
|
+
skip "remove this line once implemented"
|
66
|
+
expect(subject.full_name).to eq("Dick Jones")
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
EOF
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-varys
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ritchie Young
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-06-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -16,34 +16,34 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '2.2'
|
20
20
|
type: :development
|
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: '
|
26
|
+
version: '2.2'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '13.0'
|
34
34
|
- - ">="
|
35
35
|
- !ruby/object:Gem::Version
|
36
|
-
version: '
|
36
|
+
version: '13.0'
|
37
37
|
type: :development
|
38
38
|
prerelease: false
|
39
39
|
version_requirements: !ruby/object:Gem::Requirement
|
40
40
|
requirements:
|
41
41
|
- - "~>"
|
42
42
|
- !ruby/object:Gem::Version
|
43
|
-
version: '
|
43
|
+
version: '13.0'
|
44
44
|
- - ">="
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: '
|
46
|
+
version: '13.0'
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rspec
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -70,62 +70,83 @@ dependencies:
|
|
70
70
|
requirements:
|
71
71
|
- - "~>"
|
72
72
|
- !ruby/object:Gem::Version
|
73
|
-
version: '1
|
73
|
+
version: '6.1'
|
74
74
|
- - ">="
|
75
75
|
- !ruby/object:Gem::Version
|
76
|
-
version: 1.
|
76
|
+
version: 6.1.0
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
79
|
version_requirements: !ruby/object:Gem::Requirement
|
80
80
|
requirements:
|
81
81
|
- - "~>"
|
82
82
|
- !ruby/object:Gem::Version
|
83
|
-
version: '1
|
83
|
+
version: '6.1'
|
84
84
|
- - ">="
|
85
85
|
- !ruby/object:Gem::Version
|
86
|
-
version: 1.
|
86
|
+
version: 6.1.0
|
87
87
|
- !ruby/object:Gem::Dependency
|
88
88
|
name: aruba
|
89
89
|
requirement: !ruby/object:Gem::Requirement
|
90
90
|
requirements:
|
91
91
|
- - "~>"
|
92
92
|
- !ruby/object:Gem::Version
|
93
|
-
version: '0.
|
93
|
+
version: '0.1'
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: 0.
|
96
|
+
version: 0.1.1
|
97
97
|
type: :development
|
98
98
|
prerelease: false
|
99
99
|
version_requirements: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: '0.
|
103
|
+
version: '0.1'
|
104
104
|
- - ">="
|
105
105
|
- !ruby/object:Gem::Version
|
106
|
-
version: 0.
|
106
|
+
version: 0.1.1
|
107
|
+
- !ruby/object:Gem::Dependency
|
108
|
+
name: pp
|
109
|
+
requirement: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - "~>"
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: 0.2.0
|
114
|
+
type: :runtime
|
115
|
+
prerelease: false
|
116
|
+
version_requirements: !ruby/object:Gem::Requirement
|
117
|
+
requirements:
|
118
|
+
- - "~>"
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: 0.2.0
|
107
121
|
description: Automatically track which assumptions you've made in the form or mocks
|
108
122
|
and stubs actually work.
|
109
123
|
email:
|
110
124
|
- ritchiey@gmail.com
|
111
|
-
executables:
|
125
|
+
executables:
|
126
|
+
- genspecs
|
112
127
|
extensions: []
|
113
128
|
extra_rdoc_files: []
|
114
129
|
files:
|
115
130
|
- ".gitignore"
|
116
131
|
- ".ruby-version"
|
132
|
+
- ".tool-versions"
|
133
|
+
- ".travis.yml"
|
117
134
|
- Gemfile
|
118
|
-
- Gemfile.lock
|
119
135
|
- LICENSE.txt
|
120
136
|
- README.md
|
121
137
|
- Rakefile
|
138
|
+
- bin/genspecs
|
139
|
+
- config/cucumber.yml
|
122
140
|
- features/generating_specs.feature
|
123
141
|
- features/readme.md
|
124
|
-
- features/support/
|
142
|
+
- features/support/external.rb
|
125
143
|
- lib/rspec/varys.rb
|
144
|
+
- lib/rspec/varys/rspec_generator.rb
|
126
145
|
- lib/rspec/varys/version.rb
|
127
146
|
- rspec-varys.gemspec
|
128
147
|
- spec/rspec/varys_spec.rb
|
148
|
+
- spec/spec_helper.rb
|
149
|
+
- spec/varys/rspec_generator_spec.rb
|
129
150
|
homepage: https://github.com/ritchiey/rspec-varys
|
130
151
|
licenses:
|
131
152
|
- MIT
|
@@ -145,14 +166,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
145
166
|
- !ruby/object:Gem::Version
|
146
167
|
version: '0'
|
147
168
|
requirements: []
|
148
|
-
|
149
|
-
rubygems_version: 2.2.2
|
169
|
+
rubygems_version: 3.2.15
|
150
170
|
signing_key:
|
151
171
|
specification_version: 4
|
152
172
|
summary: Generate RSpec specs from intelligence gathered from doubles and spies.
|
153
173
|
test_files:
|
154
174
|
- features/generating_specs.feature
|
155
175
|
- features/readme.md
|
156
|
-
- features/support/
|
176
|
+
- features/support/external.rb
|
157
177
|
- spec/rspec/varys_spec.rb
|
158
|
-
|
178
|
+
- spec/spec_helper.rb
|
179
|
+
- spec/varys/rspec_generator_spec.rb
|