rspec-varys 0.0.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
[![Gem Version](https://badge.fury.io/rb/rspec-varys.svg)](http://badge.fury.io/rb/rspec-varys)
|
1
|
+
[![Gem Version](https://badge.fury.io/rb/rspec-varys.svg)](http://badge.fury.io/rb/rspec-varys) [![Build Status](https://travis-ci.org/ritchiey/rspec-varys.svg?branch=master)](https://travis-ci.org/ritchiey/rspec-varys) [![Code Climate](https://codeclimate.com/github/ritchiey/rspec-varys/badges/gpa.svg)](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
|