pretentious 0.1.11 → 0.1.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -22
- data/README.md +98 -157
- data/lib/pretentious/deconstructor.rb +1 -1
- data/lib/pretentious/minitest_generator.rb +3 -2
- data/lib/pretentious/version.rb +1 -1
- data/spec/deconstructor_spec.rb +54 -1
- data/spec/generated/test_class1_spec.rb +1 -1
- data/spec/minitest_generator_spec.rb +46 -0
- data/spec/prententious_spec.rb +1 -1
- data/test/generated/test_fibonacci.rb +4 -0
- data/test/generated/test_test_class1.rb +1 -3
- data/test/generated/test_test_class2.rb +0 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 26d9f83bc47ec838a4083cb9327ddfa3c0406c25
|
4
|
+
data.tar.gz: 1ee258b52ab0f1b314eb48c0d19e26b14239b49a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 827f3f72f561d2cc279ad00a116d0d2872e2d28c4d71e36e5ef927d3f706e2f1ffc22c8eb8d6ae7ccbd4d29d41acc652006c727f0efc080cac4a74f4685e8343
|
7
|
+
data.tar.gz: 6b3bdb1d39be3cb193b7f3da75413464a38c51a310af595d541a4cc5292ca3cff310055a239624b9ca1d354ba8e5a7178514a4ac3bc6522603da6586d0a30445
|
data/CHANGELOG.md
CHANGED
@@ -1,38 +1,32 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# 0.1.12 (2015-12-12)
|
3
2
|
Bugfixes:
|
3
|
+
- fix duplicate specs inside minitest
|
4
|
+
- Attempt to at least initialize unresolvable objects
|
4
5
|
|
5
|
-
|
6
|
+
# 0.1.11 (2015-12-12)
|
7
|
+
Bugfixes:
|
8
|
+
- fix code style
|
6
9
|
|
7
10
|
Features:
|
11
|
+
- matchers should now prefer variable references in assertions if previously declared
|
8
12
|
|
9
|
-
|
10
|
-
|
11
|
-
## 0.1.10 (2015-12-11)
|
12
|
-
|
13
|
+
# 0.1.10 (2015-12-11)
|
13
14
|
Bugfixes:
|
14
|
-
|
15
|
-
- fix regression wherein method_missing is not handled properly
|
15
|
+
- fix regression wherein method_missing is not handled properly
|
16
16
|
|
17
17
|
Features:
|
18
|
+
- Fix weird generated comments
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
## 0.1.9 (2015-12-10)
|
22
|
-
|
20
|
+
# 0.1.9 (2015-12-10)
|
23
21
|
Bugfixes:
|
24
|
-
|
25
|
-
- duplicate assertions are now removed
|
22
|
+
- duplicate assertions are now removed
|
26
23
|
|
27
24
|
Features:
|
25
|
+
- use more realistic variable names for unamed variables
|
28
26
|
|
29
|
-
|
30
|
-
|
31
|
-
## 0.1.8 (2015-12-07)
|
32
|
-
|
27
|
+
# 0.1.8 (2015-12-07)
|
33
28
|
Bugfixes:
|
34
29
|
|
35
30
|
Features:
|
36
|
-
|
37
|
-
|
38
|
-
- generated files are now placed on their own sub folder
|
31
|
+
- renamed ddtgen cli to pretentious
|
32
|
+
- generated files are now placed on their own sub folder
|
data/README.md
CHANGED
@@ -1,35 +1,26 @@
|
|
1
1
|
[![Gem Version](https://badge.fury.io/rb/pretentious.svg)](https://badge.fury.io/rb/pretentious) [![Circle CI](https://circleci.com/gh/jedld/pretentious/tree/master.svg?style=svg)](https://circleci.com/gh/jedld/pretentious/tree/master)
|
2
2
|
|
3
3
|
# Ruby::Pretentious
|
4
|
+
Do you have a pretentious boss or development lead that pushes you to embrace BDD/TDD but for reasons hate it or them? here is a gem to deal with that. Now you CAN write your code first and then GENERATE tests later!! Yes you heard that right! To repeat, this gem allows you to write your code first and then automatically generate tests using the code you've written in a straightfoward manner!
|
4
5
|
|
5
|
-
|
6
|
-
here is a gem to deal with that. Now you CAN write your code first and then GENERATE tests later!! Yes you heard that
|
7
|
-
right! To repeat, this gem allows you to write your code first and then automatically generate tests using the code
|
8
|
-
you've written in a straightfoward manner!
|
9
|
-
|
10
|
-
On a serious note, this gem allows you to generate tests template used for "characterization tests"
|
11
|
-
much better than those generated by default for various frameworks. It is also useful for "recording"
|
12
|
-
current behavior of existing components in order to prepare for refactoring. As a bonus it also exposes
|
13
|
-
an Object Deconstructor which allows you, given any object, to obtain a ruby code on how it was created.
|
14
|
-
|
6
|
+
On a serious note, this gem allows you to generate tests template used for "characterization tests" much better than those generated by default for various frameworks. It is also useful for "recording" current behavior of existing components in order to prepare for refactoring. As a bonus it also exposes an Object Deconstructor which allows you, given any object, to obtain a ruby code on how it was created.
|
15
7
|
|
16
8
|
## Table of Contents
|
9
|
+
1. [Installation](#installation)
|
10
|
+
- [Usage](#usage)
|
11
|
+
1. [Minitest](#minitest)
|
17
12
|
|
18
|
-
|
19
|
-
2.
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
6. [Auto Stubbing](#auto-stubbing)
|
25
|
-
7. [Object Deconstruction Utility](#object-deconstruction-utility)
|
26
|
-
1. [Using the Object deconstructor in rails](#using-the-object-deconstructor-in-rails)
|
27
|
-
8. [Things to do after](#things-to-do-after)
|
28
|
-
9. [Limitations](#limitations)
|
13
|
+
- [Declarative generation without using example files](#declarative-generation-without-using-example-files)
|
14
|
+
2. [Handling complex parameters and object constructors](#handling-complex-parameters-and-object-constructors)
|
15
|
+
3. [Capturing Exceptions](#capturing-exceptions)
|
16
|
+
4. [Auto Stubbing](#auto-stubbing)
|
17
|
+
- [Object Deconstruction Utility](#object-deconstruction-utility)
|
18
|
+
1. [Using the Object deconstructor in rails](#using-the-object-deconstructor-in-rails)
|
29
19
|
|
20
|
+
- [Things to do after](#things-to-do-after)
|
21
|
+
5. [Limitations](#limitations)
|
30
22
|
|
31
23
|
## Installation
|
32
|
-
|
33
24
|
Add this line to your application's Gemfile:
|
34
25
|
|
35
26
|
```ruby
|
@@ -38,16 +29,18 @@ gem 'pretentious'
|
|
38
29
|
|
39
30
|
And then execute:
|
40
31
|
|
41
|
-
|
32
|
+
```
|
33
|
+
$ bundle
|
34
|
+
```
|
42
35
|
|
43
36
|
Or install it yourself as:
|
44
37
|
|
45
|
-
|
38
|
+
```
|
39
|
+
$ gem install pretentious
|
40
|
+
```
|
46
41
|
|
47
42
|
## Usage
|
48
|
-
|
49
|
-
First Create an example file (etc. example.rb) and define the classes that you want to test, if the class is
|
50
|
-
already defined elsewhere just require them. Below is an example:
|
43
|
+
First Create an example file (etc. example.rb) and define the classes that you want to test, if the class is already defined elsewhere just require them. Below is an example:
|
51
44
|
|
52
45
|
```ruby
|
53
46
|
class Fibonacci
|
@@ -66,12 +59,10 @@ class Fibonacci
|
|
66
59
|
end
|
67
60
|
```
|
68
61
|
|
69
|
-
Inside a Pretentious.spec_for(...) block. Just write boring code that instantiates an object as well as calls the methods
|
70
|
-
like how you'd normally use them. Finally Specify the classes that you want to test:
|
62
|
+
Inside a Pretentious.spec_for(...) block. Just write boring code that instantiates an object as well as calls the methods like how you'd normally use them. Finally Specify the classes that you want to test:
|
71
63
|
|
72
64
|
```ruby
|
73
65
|
class Fibonacci
|
74
|
-
|
75
66
|
def fib(n)
|
76
67
|
return 0 if (n == 0)
|
77
68
|
return 1 if (n == 1)
|
@@ -82,12 +73,9 @@ class Fibonacci
|
|
82
73
|
def self.say_hello
|
83
74
|
"hello"
|
84
75
|
end
|
85
|
-
|
86
76
|
end
|
87
77
|
|
88
78
|
Pretentious.spec_for(Fibonacci) do
|
89
|
-
|
90
|
-
|
91
79
|
instance = Fibonacci.new
|
92
80
|
|
93
81
|
(1..10).each do |n|
|
@@ -95,25 +83,24 @@ Pretentious.spec_for(Fibonacci) do
|
|
95
83
|
end
|
96
84
|
|
97
85
|
Fibonacci.say_hello
|
98
|
-
|
99
86
|
end
|
100
87
|
```
|
101
88
|
|
102
89
|
Save your file and then switch to the terminal to invoke:
|
103
90
|
|
104
|
-
|
91
|
+
```
|
92
|
+
$ pretentious example.rb
|
93
|
+
```
|
105
94
|
|
106
95
|
This will automatically generate rspec tests for Fibonacci under /spec of the current working directory.
|
107
96
|
|
108
|
-
You can actually invoke rspec at this point, but the tests will fail. Before you do that you should edit
|
109
|
-
spec/spec_helper.rb and put the necessary requires and definitions there.
|
97
|
+
You can actually invoke rspec at this point, but the tests will fail. Before you do that you should edit spec/spec_helper.rb and put the necessary requires and definitions there.
|
110
98
|
|
111
99
|
For this example place the following into spec_helper.rb:
|
112
100
|
|
113
101
|
```ruby
|
114
102
|
#inside spec_helper.rb
|
115
103
|
class Fibonacci
|
116
|
-
|
117
104
|
def fib(n)
|
118
105
|
return 0 if (n == 0)
|
119
106
|
return 1 if (n == 1)
|
@@ -124,58 +111,48 @@ class Fibonacci
|
|
124
111
|
def self.say_hello
|
125
112
|
"hello"
|
126
113
|
end
|
127
|
-
|
128
114
|
end
|
129
115
|
```
|
130
116
|
|
131
117
|
The generated spec file should look something like this
|
132
118
|
|
133
119
|
```ruby
|
120
|
+
# This file was automatically generated by the pretentious gem
|
134
121
|
require 'spec_helper'
|
135
122
|
|
136
123
|
RSpec.describe Fibonacci do
|
137
|
-
|
138
124
|
context 'Scenario 1' do
|
139
125
|
before do
|
140
|
-
|
141
|
-
|
142
126
|
@fixture = Fibonacci.new
|
143
|
-
|
144
127
|
end
|
145
128
|
|
146
129
|
it 'should pass current expectations' do
|
147
|
-
|
148
130
|
n = 1
|
149
131
|
n_1 = 2
|
150
132
|
n_2 = 3
|
151
133
|
n_3 = 4
|
152
134
|
n_4 = 5
|
153
|
-
|
154
135
|
# Fibonacci#fib when passed n = 1 should return 1
|
155
|
-
expect(
|
136
|
+
expect(@fixture.fib(n)).to eq(n)
|
156
137
|
|
157
138
|
# Fibonacci#fib when passed n = 2 should return 1
|
158
|
-
expect(
|
139
|
+
expect(@fixture.fib(n_1)).to eq(n)
|
159
140
|
|
160
141
|
# Fibonacci#fib when passed n = 3 should return 2
|
161
|
-
expect(
|
142
|
+
expect(@fixture.fib(n_2)).to eq(n_1)
|
162
143
|
|
163
144
|
# Fibonacci#fib when passed n = 4 should return 3
|
164
|
-
expect(
|
145
|
+
expect(@fixture.fib(n_3)).to eq(n_2)
|
165
146
|
|
166
147
|
# Fibonacci#fib when passed n = 5 should return 5
|
167
|
-
expect(
|
168
|
-
|
148
|
+
expect(@fixture.fib(n_4)).to eq(n_4)
|
169
149
|
end
|
170
150
|
end
|
171
151
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
expect( Fibonacci.say_hello ).to eq("hello")
|
177
|
-
|
178
|
-
end
|
152
|
+
it 'should pass current expectations' do
|
153
|
+
# Fibonacci::say_hello should return 'hello'
|
154
|
+
expect(Fibonacci.say_hello).to eq('hello')
|
155
|
+
end
|
179
156
|
end
|
180
157
|
```
|
181
158
|
|
@@ -195,26 +172,21 @@ end
|
|
195
172
|
You should get something like:
|
196
173
|
|
197
174
|
```ruby
|
175
|
+
# This file was automatically generated by the pretentious gem
|
198
176
|
require 'spec_helper'
|
199
177
|
|
200
178
|
RSpec.describe Digest::MD5 do
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
# Digest::MD5::hexdigest when passed "This is the digest" should return 9f12248dcddeda976611d192efaaf72a
|
207
|
-
expect( Digest::MD5.hexdigest(sample) ).to eq("9f12248dcddeda976611d192efaaf72a")
|
208
|
-
|
209
|
-
end
|
179
|
+
it 'should pass current expectations' do
|
180
|
+
sample = 'This is the digest'
|
181
|
+
# Digest::MD5::hexdigest when passed "This is the digest" should return '9f12248dcddeda976611d192efaaf72a'
|
182
|
+
expect(Digest::MD5.hexdigest(sample)).to eq('9f12248dcddeda976611d192efaaf72a')
|
183
|
+
end
|
210
184
|
end
|
211
185
|
```
|
212
186
|
|
213
|
-
Note: If your test subject is already part of a larger application and would like to capture behavior in the manner that
|
214
|
-
the application uses it, please look at [Declarative Generation](#declarative-generation-without-using-example-files).
|
187
|
+
Note: If your test subject is already part of a larger application and would like to capture behavior in the manner that the application uses it, please look at [Declarative Generation](#declarative-generation-without-using-example-files).
|
215
188
|
|
216
189
|
## Minitest
|
217
|
-
|
218
190
|
The minitest test framework is also supported, simply use Pretentious.minitest_for instead
|
219
191
|
|
220
192
|
```ruby
|
@@ -228,43 +200,38 @@ end
|
|
228
200
|
outputs:
|
229
201
|
|
230
202
|
```ruby
|
231
|
-
|
232
|
-
require
|
203
|
+
# This file was automatically generated by the pretentious gem
|
204
|
+
require 'minitest_helper'
|
205
|
+
require 'minitest/autorun'
|
233
206
|
|
234
|
-
class
|
207
|
+
class MemeTest < Minitest::Test
|
235
208
|
end
|
236
209
|
|
237
|
-
class
|
210
|
+
class MemeScenario1 < MemeTest
|
238
211
|
def setup
|
239
212
|
@fixture = Meme.new
|
240
213
|
end
|
241
214
|
|
242
215
|
def test_current_expectation
|
216
|
+
# Meme#i_can_has_cheezburger? should return 'OHAI!'
|
217
|
+
assert_equal 'OHAI!', @fixture.i_can_has_cheezburger?
|
243
218
|
|
244
|
-
|
245
|
-
assert_equal
|
246
|
-
|
247
|
-
# Meme#will_it_blend? should return YES!
|
248
|
-
assert_equal "YES!", @fixture.will_it_blend?
|
249
|
-
|
219
|
+
# Meme#will_it_blend? should return 'YES!'
|
220
|
+
assert_equal 'YES!', @fixture.will_it_blend?
|
250
221
|
end
|
251
222
|
end
|
252
223
|
```
|
253
224
|
|
254
225
|
## Declarative generation without using example files
|
226
|
+
Instead of using Pretentious.spec_for and wrapping the target code around a block, you may declaratively define when test generation should occur beforehand. This allows you to generate tests around code blocks without modifying source codes. This is useful for testing code embedded inside frameworks like rails where your "example" is already embedded inside existing code.
|
255
227
|
|
256
|
-
|
257
|
-
when test generation should occur beforehand. This allows you to generate tests around code blocks without
|
258
|
-
modifying source codes. This is useful for testing code embedded inside frameworks like rails where your
|
259
|
-
"example" is already embedded inside existing code.
|
260
|
-
|
261
|
-
For example lets say you want to generate tests for UserAuthenticaion that is used inside the
|
262
|
-
login method inside the UsersController inside a Rails app. You'd simply define like below:
|
263
|
-
|
228
|
+
For example lets say you want to generate tests for UserAuthenticaion that is used inside the login method inside the UsersController inside a Rails app. You'd simply define like below:
|
264
229
|
|
265
230
|
```ruby
|
266
231
|
# initializers/pretentious.rb
|
267
232
|
|
233
|
+
Pretentious.install_watcher # install watcher if not defined previously
|
234
|
+
|
268
235
|
if Rails.env.test? #IMPORTANT don't run this when you don't need it!
|
269
236
|
Pretentious.on(UsersController).method_called(:login).spec_for(UserAuthentication) #RSPEC
|
270
237
|
Pretentious.on(UsersController).method_called(:login, :logout, ...).minitest_for(UserAuthentication) #minitest
|
@@ -275,14 +242,13 @@ end
|
|
275
242
|
|
276
243
|
The above code is equivalent to adding a spec_for inside the target method.
|
277
244
|
|
278
|
-
Note that you must include the setup code in a place that you know runs before the target code block is run. For
|
279
|
-
example, if you want to test a class that is used inside a controller in rails, it is best to put it in an initializer.
|
280
|
-
It is also recommended to call Pretentious.install_watcher early on to be able to generate better fixtures.
|
245
|
+
Note that you must include the setup code in a place that you know runs before the target code block is run. For example, if you want to test a class that is used inside a controller in rails, it is best to put it in an initializer. It is also recommended to call Pretentious.install_watcher early on to be able to generate better fixtures.
|
281
246
|
|
282
247
|
You can pass a block for manually handling the output, for example
|
283
248
|
|
284
249
|
```ruby
|
285
250
|
# initializers/pretentious.rb
|
251
|
+
Pretentious.install_watcher # install watcher if not defined previously
|
286
252
|
|
287
253
|
if Rails.env.test? #IMPORTANT don't run this when you don't need it!
|
288
254
|
Pretentious.on(UsersController).method_called(:login).spec_for(UserAuthentication) do |results|
|
@@ -297,6 +263,7 @@ or, use the FileWriter utility to write it to a file
|
|
297
263
|
|
298
264
|
```ruby
|
299
265
|
# initializers/pretentious.rb
|
266
|
+
Pretentious.install_watcher # install watcher if not defined previously
|
300
267
|
|
301
268
|
if Rails.env.test? #IMPORTANT don't run this when you don't need it!
|
302
269
|
Pretentious.on(UsersController).method_called(:login).spec_for(UserAuthentication) do |results|
|
@@ -305,13 +272,11 @@ if Rails.env.test? #IMPORTANT don't run this when you don't need it!
|
|
305
272
|
end
|
306
273
|
end
|
307
274
|
```
|
308
|
-
IMPORTANT: If using rails or if it is part of a larger app, make sure to enable this only when you intend to generate specs!
|
309
|
-
delete the initializer or comment the code out when it is not needed.
|
310
275
|
|
311
|
-
|
276
|
+
IMPORTANT: If using rails or if it is part of a larger app, make sure to enable this only when you intend to generate specs! delete the initializer or comment the code out when it is not needed.
|
312
277
|
|
313
|
-
|
314
|
-
see below for an example:
|
278
|
+
## Handling complex parameters and object constructors
|
279
|
+
No need to do anything special, just do as what you would do normally and the pretentious gem will figure it out. see below for an example:
|
315
280
|
|
316
281
|
```ruby
|
317
282
|
class TestClass1
|
@@ -340,7 +305,6 @@ see below for an example:
|
|
340
305
|
end
|
341
306
|
|
342
307
|
class TestClass3
|
343
|
-
|
344
308
|
def initialize(testclass1, testclass2)
|
345
309
|
@class1 = testclass1
|
346
310
|
@class2 = testclass2
|
@@ -351,7 +315,6 @@ see below for an example:
|
|
351
315
|
@class2.print_message
|
352
316
|
"awesome!!!"
|
353
317
|
end
|
354
|
-
|
355
318
|
end
|
356
319
|
```
|
357
320
|
|
@@ -372,38 +335,30 @@ We then instantiate the class using all sorts of weird parameters:
|
|
372
335
|
Creating tests for TestClass3 should yield
|
373
336
|
|
374
337
|
```ruby
|
375
|
-
|
338
|
+
require 'spec_helper'
|
376
339
|
|
340
|
+
RSpec.describe TestClass3 do
|
377
341
|
context 'Scenario 1' do
|
378
342
|
before do
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
args_1 = "This is message 2"
|
385
|
-
test_class_two = TestClass2.new(args_1)
|
386
|
-
|
387
|
-
@fixture = TestClass3.new(test_class_one, test_class_two)
|
388
|
-
|
343
|
+
another_object = TestClass1.new('test')
|
344
|
+
b = { hello: 'world', test: another_object, arr_1: [1, 2, 3, 4, 5, another_object], sub_hash: { yes: true, obj: another_object } }
|
345
|
+
testclass1 = TestClass1.new(b)
|
346
|
+
testclass2 = TestClass2.new('This is message 2', nil)
|
347
|
+
@fixture = TestClass3.new(testclass1, testclass2)
|
389
348
|
end
|
390
349
|
|
391
350
|
it 'should pass current expectations' do
|
392
|
-
|
393
|
-
|
394
|
-
# TestClass3#show_messages when passed should return awesome!!!
|
395
|
-
expect( @fixture.show_messages ).to eq("awesome!!!")
|
396
|
-
|
351
|
+
# TestClass3#show_messages should return 'awesome!!!'
|
352
|
+
expect(@fixture.show_messages).to eq('awesome!!!')
|
397
353
|
end
|
398
354
|
end
|
355
|
+
end
|
399
356
|
```
|
400
357
|
|
401
358
|
Note that creating another instance of TestClass3 will result in the creation of another Scenario
|
402
359
|
|
403
360
|
## Capturing Exceptions
|
404
|
-
|
405
|
-
Exceptions thrown by method calls should generate the appropriate exception test case. Just make sure
|
406
|
-
that you rescue inside your example file like below:
|
361
|
+
Exceptions thrown by method calls should generate the appropriate exception test case. Just make sure that you rescue inside your example file like below:
|
407
362
|
|
408
363
|
```ruby
|
409
364
|
begin
|
@@ -420,23 +375,19 @@ should generate the following in rspec
|
|
420
375
|
```
|
421
376
|
|
422
377
|
## Auto stubbing
|
423
|
-
|
424
378
|
Too lazy to generate rspec-mocks stubs? Let the Pretentious gem do it for you.
|
425
379
|
|
426
|
-
Simply call the _stub method on a class and pass the classes you want to generate
|
427
|
-
stubs for when passing calling spec_for or minitest_for (see below):
|
380
|
+
Simply call the _stub method on a class and pass the classes you want to generate stubs for when passing calling spec_for or minitest_for (see below):
|
428
381
|
|
429
382
|
```ruby
|
430
383
|
Pretentious.spec_for(TestClass._stub(ClassUsedByTestClass)) do
|
431
384
|
instance = TestClass.new
|
432
385
|
instance.method_that_uses_the_class_to_stub
|
433
386
|
end
|
434
|
-
|
435
387
|
```
|
436
388
|
|
437
389
|
should auto generate the stub like this:
|
438
390
|
|
439
|
-
|
440
391
|
```ruby
|
441
392
|
it 'should pass current expectations' do
|
442
393
|
|
@@ -474,8 +425,7 @@ end
|
|
474
425
|
|
475
426
|
Note: Stubbing on minitest requires the minitest-stub_any_instance gem.
|
476
427
|
|
477
|
-
stubs that return different values every call are automatically detected an the appropriate rspec stub return
|
478
|
-
is generated (similar to below):
|
428
|
+
stubs that return different values every call are automatically detected an the appropriate rspec stub return is generated (similar to below):
|
479
429
|
|
480
430
|
```ruby
|
481
431
|
allow_any_instance_of(TestMockSubClass).to receive(:increment_val).and_return(2, 3, 4, 5)
|
@@ -493,11 +443,7 @@ end
|
|
493
443
|
Note: different return values are only supported on RSpec for now
|
494
444
|
|
495
445
|
## Object Deconstruction Utility
|
496
|
-
|
497
|
-
As Pretentious as the gem is, there are other uses other than generating tests specs. Tools are also available to
|
498
|
-
deconstruct objects. Object deconstruction basically means that the components used to create and initialize an object
|
499
|
-
are extracted and decomposed until only primitive types remain. The pretentious gem will also generate the
|
500
|
-
necessary ruby code to create one from scratch. Below is an example:
|
446
|
+
As Pretentious as the gem is, there are other uses other than generating tests specs. Tools are also available to deconstruct objects. Object deconstruction basically means that the components used to create and initialize an object are extracted and decomposed until only primitive types remain. The pretentious gem will also generate the necessary ruby code to create one from scratch. Below is an example:
|
501
447
|
|
502
448
|
Given an instance of an activerecord base connection for example
|
503
449
|
|
@@ -505,7 +451,13 @@ Given an instance of an activerecord base connection for example
|
|
505
451
|
ActiveRecord::Base.connection
|
506
452
|
```
|
507
453
|
|
508
|
-
running deconstruct
|
454
|
+
running deconstruct on ActiveRecord::Base.connection
|
455
|
+
|
456
|
+
```ruby
|
457
|
+
ActiveRecord::Base.connection._deconstruct_to_ruby
|
458
|
+
```
|
459
|
+
|
460
|
+
will generate the output below:
|
509
461
|
|
510
462
|
```ruby
|
511
463
|
var_70301267513280 = #<File:0x007fe094279f80>
|
@@ -514,6 +466,7 @@ connection_options = ["localhost", "root", "password", "test_db", nil, nil, 1310
|
|
514
466
|
config = {adapter: "mysql", encoding: "utf8", reconnect: false, database: "test_db", pool: 5, username: "root", password: "password", host: "localhost"}
|
515
467
|
var_70301281665660 = ActiveRecord::ConnectionAdapters::MysqlAdapter.new(connection, logger, connection_options, config)
|
516
468
|
```
|
469
|
+
|
517
470
|
Note that
|
518
471
|
|
519
472
|
```ruby
|
@@ -523,10 +476,11 @@ var_70301267513280 = #<File:0x007fe094279f80>
|
|
523
476
|
because the pretentious gem was not able to capture its init arguments.
|
524
477
|
|
525
478
|
## How to use
|
526
|
-
|
527
479
|
Simply call:
|
528
480
|
|
529
|
-
|
481
|
+
```
|
482
|
+
Pretentious.install_watcher
|
483
|
+
```
|
530
484
|
|
531
485
|
before all your objects are initalized. This will add the following methods to all objects:
|
532
486
|
|
@@ -534,6 +488,7 @@ before all your objects are initalized. This will add the following methods to a
|
|
534
488
|
object._deconstruct
|
535
489
|
object._deconstruct_to_ruby
|
536
490
|
```
|
491
|
+
|
537
492
|
The _deconstruct method generates a raw deconstruction data structure used by the _deconstruct_to_ruby method.
|
538
493
|
|
539
494
|
Of course _deconstruct_to_ruby generates the ruby code necessary to create the object!
|
@@ -552,7 +507,6 @@ the_object._deconstruct_to_ruby
|
|
552
507
|
Note that the class SomeOtherClass won't get decomposed.
|
553
508
|
|
554
509
|
## Using the Object deconstructor in rails
|
555
|
-
|
556
510
|
In your Gemfile, add the pretentious gem.
|
557
511
|
|
558
512
|
```ruby
|
@@ -563,11 +517,11 @@ end
|
|
563
517
|
|
564
518
|
The do a bundle
|
565
519
|
|
566
|
-
|
567
|
-
|
520
|
+
```
|
521
|
+
$ bundle
|
522
|
+
```
|
568
523
|
|
569
|
-
Note: It is advisable to add it only in the test or development group!
|
570
|
-
The way it logs objects would probably prevent anything from being GC'ed.
|
524
|
+
Note: It is advisable to add it only in the test or development group! The way it logs objects would probably prevent anything from being GC'ed.
|
571
525
|
|
572
526
|
For rails, including inside application.rb may be a good place to start:
|
573
527
|
|
@@ -622,40 +576,27 @@ var_70301339518120 = User::ActiveRecord_Relation.new(klass, table)
|
|
622
576
|
2.2.0 :007 >
|
623
577
|
```
|
624
578
|
|
625
|
-
Note: There are some objects it may fail to deconstruct properly because of certain [limitations](#limitations) or it
|
626
|
-
may have failed to capture object creation early enough.
|
627
|
-
|
579
|
+
Note: There are some objects it may fail to deconstruct properly because of certain [limitations](#limitations) or it may have failed to capture object creation early enough.
|
628
580
|
|
629
581
|
## Things to do after
|
582
|
+
Since your tests are already written, and hopefully nobody notices its written by a machine, you may just leave it at that. Take note of the limitations though.
|
630
583
|
|
631
|
-
|
632
|
-
at that. Take note of the limitations though.
|
633
|
-
|
634
|
-
But if lest your conscience suffers, it is best to go back to the specs and refine them, add more tests and behave like
|
635
|
-
a bdd'er/tdd'er.
|
584
|
+
But if lest your conscience suffers, it is best to go back to the specs and refine them, add more tests and behave like a bdd'er/tdd'er.
|
636
585
|
|
637
586
|
## Limitations
|
587
|
+
Computers are bad at mind reading (for now) and they don't really know your expectation of "correctness", as such it assumes your code is correct and can only use equality based matchers. It can also only reliably match primitive data types, hashes, Procs and arrays to a degree. More complex expectations are unfortunately left for the humans to resolve. This is expected to improve in future versions of the pretentious gem.
|
638
588
|
|
639
|
-
|
640
|
-
it assumes your code is correct and can only use equality based matchers. It can also only reliably match
|
641
|
-
primitive data types, hashes, Procs and arrays to a degree. More complex expectations are unfortunately left for the humans
|
642
|
-
to resolve. This is expected to improve in future versions of the pretentious gem.
|
643
|
-
|
644
|
-
Procs that return a constant value will be resolved properly. However variable return values are currently still
|
645
|
-
not generated properly will return a stub (future versions may use sourcify to resolve Procs for ruby 1.9)
|
589
|
+
Procs that return a constant value will be resolved properly. However variable return values are currently still not generated properly will return a stub (future versions may use sourcify to resolve Procs for ruby 1.9)
|
646
590
|
|
647
|
-
Also do note that it tries its best to determine how your fixtures are created, as well as the types
|
648
|
-
of your parameters and does so by figuring out (recursively) the components that your object needs. Failure can happen during this process.
|
591
|
+
Also do note that it tries its best to determine how your fixtures are created, as well as the types of your parameters and does so by figuring out (recursively) the components that your object needs. Failure can happen during this process.
|
649
592
|
|
650
593
|
Finally, Limit this gem for test environments only.
|
651
594
|
|
652
595
|
## Bugs
|
653
|
-
|
654
596
|
This is the first iteration and a lot of broken things could happen
|
655
597
|
|
656
598
|
## Contributing
|
657
|
-
|
658
|
-
1. Fork it (https://github.com/jedld/pretentious.git)
|
599
|
+
1. Fork it ([https://github.com/jedld/pretentious.git](https://github.com/jedld/pretentious.git))
|
659
600
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
660
601
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
661
602
|
4. Push to the branch (`git push origin my-new-feature`)
|
@@ -345,7 +345,7 @@ module Pretentious
|
|
345
345
|
elsif definition[:value].is_a? Array
|
346
346
|
output_array(context, definition[:value])
|
347
347
|
elsif definition[:value].is_a? UnResolved
|
348
|
-
|
348
|
+
"#{definition[:value].target_object.class.to_s}.new # parameters unresolvable. The watcher needs to be installed before this object is created"
|
349
349
|
else
|
350
350
|
context.value_of(definition[:value])
|
351
351
|
end
|
@@ -140,11 +140,12 @@ module Pretentious
|
|
140
140
|
indentation = ''
|
141
141
|
indentation_level.times { indentation << @_indentation }
|
142
142
|
method_calls.each_key do |k|
|
143
|
-
|
143
|
+
|
144
144
|
info_blocks_arr = method_calls[k]
|
145
145
|
|
146
146
|
info_blocks_arr.each do |block|
|
147
|
-
|
147
|
+
str = ''
|
148
|
+
params_desc_str = if block[:params].size > 0
|
148
149
|
"when passed #{desc_params(block)}"
|
149
150
|
else
|
150
151
|
''
|
data/lib/pretentious/version.rb
CHANGED
data/spec/deconstructor_spec.rb
CHANGED
@@ -7,7 +7,7 @@ RSpec.describe Pretentious::Deconstructor do
|
|
7
7
|
|
8
8
|
describe "#build_tree" do
|
9
9
|
it "should decompose an object" do
|
10
|
-
message =
|
10
|
+
message = 'test'
|
11
11
|
another_object = Pretentious.watch {
|
12
12
|
TestClass1.new(message)
|
13
13
|
}
|
@@ -21,6 +21,36 @@ RSpec.describe Pretentious::Deconstructor do
|
|
21
21
|
params_types: [[:req, :message]])
|
22
22
|
|
23
23
|
end
|
24
|
+
|
25
|
+
context "Special 'native' objects like File" do
|
26
|
+
it "Decomposes properly" do
|
27
|
+
file = nil
|
28
|
+
filename = nil
|
29
|
+
another_object = Pretentious.watch {
|
30
|
+
filename = "example.rb"
|
31
|
+
file = File.new(filename)
|
32
|
+
TestClass1.new(file)
|
33
|
+
}
|
34
|
+
result = @fixture.build_tree(another_object)
|
35
|
+
result[:composition][0][:composition][0][:id] = filename.object_id
|
36
|
+
|
37
|
+
expect(result)
|
38
|
+
.to eq(
|
39
|
+
class: TestClass1,
|
40
|
+
id: another_object.object_id,
|
41
|
+
composition: [
|
42
|
+
{ class: File,
|
43
|
+
id: file.object_id,
|
44
|
+
composition: [
|
45
|
+
{
|
46
|
+
class: String,
|
47
|
+
id: filename.object_id,
|
48
|
+
composition: 'example.rb'
|
49
|
+
}]
|
50
|
+
}],
|
51
|
+
params_types: [[:req, :message]])
|
52
|
+
end
|
53
|
+
end
|
24
54
|
end
|
25
55
|
|
26
56
|
describe "Object#_deconstruct_to_ruby" do
|
@@ -42,6 +72,29 @@ RSpec.describe Pretentious::Deconstructor do
|
|
42
72
|
expect(output).to eq("message = [1, 2, 3, 'hello', { message: 'hello' }, ['subarray', 2, :symbol]]\ntest_class = TestClass1.new(message)\n")
|
43
73
|
end
|
44
74
|
|
75
|
+
it "deconstructs 'native' types" do
|
76
|
+
file = nil
|
77
|
+
filename = nil
|
78
|
+
another_object = Pretentious.watch do
|
79
|
+
filename = "example.rb"
|
80
|
+
file = File.new(filename)
|
81
|
+
test_class = TestClass1.new(file)
|
82
|
+
test_class._deconstruct_to_ruby
|
83
|
+
end
|
84
|
+
expect(another_object).to eq("message = File.new('example.rb')\ntest_class = TestClass1.new(message)\n")
|
85
|
+
end
|
86
|
+
|
87
|
+
it "has special handling for unresolvable types" do
|
88
|
+
# objects outside of the watch scope
|
89
|
+
a = "Some type of string"
|
90
|
+
b = TestClass1.new("Hello world")
|
91
|
+
output = Pretentious.watch do
|
92
|
+
test_class = TestClass3.new(a, b)
|
93
|
+
test_class._deconstruct_to_ruby
|
94
|
+
end
|
95
|
+
expect(output).to eq("a = TestClass1.new # parameters unresolvable. The watcher needs to be installed before this object is created\ntestclass2 = TestClass1.new(a)\ntest_class = TestClass3.new('Some type of string', testclass2)\n")
|
96
|
+
end
|
97
|
+
|
45
98
|
it "deconstructs hash types" do
|
46
99
|
output = Pretentious.watch do
|
47
100
|
hash = { message: "hello", arr: [1, 2, 3], hash: { message2: "msg" } }
|
@@ -54,7 +54,7 @@ RSpec.describe TestClass1 do
|
|
54
54
|
|
55
55
|
it 'should pass current expectations' do
|
56
56
|
another_object = TestClass1.new('test')
|
57
|
-
# TestClass1#return_self when passed message = #<TestClass1:
|
57
|
+
# TestClass1#return_self when passed message = #<TestClass1:0x0000000162b3c0> should return another_object
|
58
58
|
expect(@fixture.return_self(another_object)).to eq(another_object)
|
59
59
|
end
|
60
60
|
end
|
@@ -21,5 +21,51 @@ RSpec.describe Pretentious::Generator do
|
|
21
21
|
expect(result).to eq(Fibonacci => { output: "# This file was automatically generated by the pretentious gem\nrequire 'minitest_helper'\nrequire 'minitest/autorun'\n\nclass FibonacciTest < Minitest::Test\nend\n\nclass FibonacciScenario1 < FibonacciTest\n def test_current_expectation\n # Fibonacci::say_hello should return 'hello'\n assert_equal 'hello', Fibonacci.say_hello\n end\nend",
|
22
22
|
generator: Pretentious::MinitestGenerator })
|
23
23
|
end
|
24
|
+
|
25
|
+
context "proc handling" do
|
26
|
+
it 'handles blocks passed to methods' do
|
27
|
+
result = Pretentious.minitest_for(TestClass1) do
|
28
|
+
test_class = TestClass1.new('message')
|
29
|
+
test_class.set_block do
|
30
|
+
'a string'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
expect(result[TestClass1][:output]).to be < 'expect(@fixture.set_block &c).to eq(a)'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'Makes sure expectations are unique' do
|
38
|
+
result = Pretentious.minitest_for(TestClass1) do
|
39
|
+
test_class = TestClass1.new("message")
|
40
|
+
test_class.message
|
41
|
+
test_class.message
|
42
|
+
end
|
43
|
+
puts result[TestClass1][:output]
|
44
|
+
expect(result[TestClass1][:output]
|
45
|
+
.scan(/assert_equal\ 'message',\ @fixture\.message/).count)
|
46
|
+
.to eq(1)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "handles exceptions" do
|
50
|
+
result = Pretentious.minitest_for(TestClass1) do
|
51
|
+
test_class = TestClass1.new('message')
|
52
|
+
begin
|
53
|
+
test_class.something_is_wrong
|
54
|
+
rescue StandardError => e
|
55
|
+
puts 'something is wrong'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
expect(result[TestClass1][:output]).to match(/assert_raises\(StandardError\) \{ @fixture.something_is_wrong \}/)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "handles method missing" do
|
63
|
+
result = Pretentious.minitest_for(TestClassMethodMissing) do
|
64
|
+
test_class = TestClassMethodMissing.new
|
65
|
+
test_class.handled_by_method_missing
|
66
|
+
end
|
67
|
+
|
68
|
+
expect(result[TestClassMethodMissing][:output]).to match("YOU GOT ME!!!!")
|
69
|
+
end
|
24
70
|
end
|
25
71
|
end
|
data/spec/prententious_spec.rb
CHANGED
@@ -71,7 +71,7 @@ RSpec.describe Pretentious::Generator do
|
|
71
71
|
test_class.handled_by_method_missing
|
72
72
|
end
|
73
73
|
|
74
|
-
|
74
|
+
expect(result[TestClassMethodMissing][:output]).to match("YOU GOT ME!!!!")
|
75
75
|
end
|
76
76
|
|
77
77
|
context "proc handling" do
|
@@ -19,12 +19,16 @@ class FibonacciScenario1 < FibonacciTest
|
|
19
19
|
|
20
20
|
# Fibonacci#fib when passed n = 1 should return 1
|
21
21
|
assert_equal 1, @fixture.fib(n)
|
22
|
+
|
22
23
|
# Fibonacci#fib when passed n = 2 should return 1
|
23
24
|
assert_equal 1, @fixture.fib(n_1)
|
25
|
+
|
24
26
|
# Fibonacci#fib when passed n = 3 should return 2
|
25
27
|
assert_equal 2, @fixture.fib(n_2)
|
28
|
+
|
26
29
|
# Fibonacci#fib when passed n = 4 should return 3
|
27
30
|
assert_equal 3, @fixture.fib(n_3)
|
31
|
+
|
28
32
|
# Fibonacci#fib when passed n = 5 should return 5
|
29
33
|
assert_equal 5, @fixture.fib(n_4)
|
30
34
|
end
|
@@ -34,8 +34,6 @@ class TestClass1Scenario2 < TestClass1Test
|
|
34
34
|
}
|
35
35
|
|
36
36
|
|
37
|
-
# TestClass1#print_message should return nil
|
38
|
-
assert_nil @fixture.print_message
|
39
37
|
# TestClass1#print_message should return nil
|
40
38
|
assert_nil @fixture.print_message
|
41
39
|
|
@@ -61,7 +59,7 @@ class TestClass1Scenario3 < TestClass1Test
|
|
61
59
|
def test_current_expectation
|
62
60
|
another_object = TestClass1.new('test')
|
63
61
|
|
64
|
-
# TestClass1#return_self when passed message = #<TestClass1:
|
62
|
+
# TestClass1#return_self when passed message = #<TestClass1:0x000000014a2eb8> should return another_object
|
65
63
|
assert_equal another_object, @fixture.return_self(another_object)
|
66
64
|
end
|
67
65
|
end
|
@@ -13,8 +13,6 @@ class TestClass2Scenario1 < TestClass2Test
|
|
13
13
|
def test_current_expectation
|
14
14
|
# TestClass2#print_message should return nil
|
15
15
|
assert_nil @fixture.print_message
|
16
|
-
# TestClass2#print_message should return nil
|
17
|
-
assert_nil @fixture.print_message
|
18
16
|
end
|
19
17
|
end
|
20
18
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pretentious
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joseph Emmanuel Dayo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-12-
|
11
|
+
date: 2015-12-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: binding_of_caller
|