pretentious 0.1.6 → 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +14 -5
- data/bin/ddtgen +13 -19
- data/lib/pretentious.rb +31 -31
- data/lib/pretentious/context.rb +86 -0
- data/lib/pretentious/deconstructor.rb +305 -368
- data/lib/pretentious/generator.rb +122 -149
- data/lib/pretentious/generator_base.rb +70 -9
- data/lib/pretentious/minitest_generator.rb +172 -288
- data/lib/pretentious/recorded_proc.rb +4 -16
- data/lib/pretentious/rspec_generator.rb +151 -262
- data/lib/pretentious/trigger.rb +30 -30
- data/lib/pretentious/version.rb +2 -1
- data/pretentious.gemspec +3 -0
- data/run_test.sh +1 -1
- data/spec/deconstructor_spec.rb +34 -20
- data/spec/fibonacci_spec.rb +7 -14
- data/spec/generator_spec.rb +1 -1
- data/spec/m_d5_spec.rb +3 -7
- data/spec/minitest_generator_spec.rb +2 -2
- data/spec/prententious_spec.rb +14 -4
- data/spec/spec_helper.rb +3 -1
- data/spec/test_class1_spec.rb +23 -38
- data/spec/test_class2_spec.rb +7 -16
- data/spec/test_class3_spec.rb +11 -18
- data/spec/test_class4_spec.rb +4 -7
- data/spec/test_class_for_auto_stub_spec.rb +5 -10
- data/spec/test_class_for_mocks_spec.rb +10 -19
- data/test/test_fibonacci.rb +72 -10
- data/test/test_m_d5.rb +4 -5
- data/test/test_meme.rb +6 -6
- data/test/test_test_class1.rb +36 -29
- data/test/test_test_class2.rb +16 -12
- data/test/test_test_class3.rb +15 -17
- data/test/test_test_class4.rb +6 -7
- data/test/test_test_class_for_mocks.rb +19 -16
- metadata +46 -4
@@ -1,6 +1,7 @@
|
|
1
1
|
module Pretentious
|
2
|
-
|
2
|
+
# Sublass of Proc that records whatever was passed to it and whatever it returns
|
3
3
|
class RecordedProc < Proc
|
4
|
+
attr_reader :target_proc, :return_value
|
4
5
|
|
5
6
|
def initialize(target_proc, is_given_block = false)
|
6
7
|
@target_proc = target_proc
|
@@ -14,14 +15,6 @@ module Pretentious
|
|
14
15
|
@given_block
|
15
16
|
end
|
16
17
|
|
17
|
-
def target_proc
|
18
|
-
@target_proc
|
19
|
-
end
|
20
|
-
|
21
|
-
def return_value
|
22
|
-
@return_value
|
23
|
-
end
|
24
|
-
|
25
18
|
def is_called?
|
26
19
|
@called
|
27
20
|
end
|
@@ -31,13 +24,8 @@ module Pretentious
|
|
31
24
|
@args << args
|
32
25
|
return_value = @target_proc.call(*args, &block)
|
33
26
|
|
34
|
-
unless @return_value.include? return_value
|
35
|
-
@return_value << return_value
|
36
|
-
end
|
37
|
-
|
27
|
+
@return_value << return_value unless @return_value.include? return_value
|
38
28
|
return_value
|
39
29
|
end
|
40
|
-
|
41
30
|
end
|
42
|
-
|
43
|
-
end
|
31
|
+
end
|
@@ -1,306 +1,195 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
@output_buffer = ""
|
7
|
-
@_indentation = ""
|
8
|
-
indentation_count.times do
|
9
|
-
@_indentation << " "
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def indentation(level)
|
14
|
-
buffer = ""
|
15
|
-
level.times do
|
16
|
-
buffer << @_indentation
|
17
|
-
end
|
18
|
-
buffer
|
19
|
-
end
|
20
|
-
|
21
|
-
|
22
|
-
def whitespace(level = 0)
|
23
|
-
@output_buffer << "#{indentation(level)}\n"
|
24
|
-
end
|
25
|
-
|
26
|
-
def begin_spec(test_class)
|
27
|
-
buffer("#This file was automatically generated by the pretentious gem")
|
28
|
-
buffer("require 'spec_helper'")
|
29
|
-
whitespace
|
30
|
-
buffer("RSpec.describe #{test_class.name} do")
|
31
|
-
whitespace
|
32
|
-
end
|
33
|
-
|
34
|
-
def end_spec
|
35
|
-
buffer("end")
|
36
|
-
end
|
37
|
-
|
38
|
-
def output
|
39
|
-
@output_buffer
|
40
|
-
end
|
41
|
-
|
42
|
-
def generate(test_instance, instance_count)
|
43
|
-
global_variable_declaration = {}
|
44
|
-
if (test_instance.is_a? Class)
|
45
|
-
#class methods
|
46
|
-
class_method_calls = test_instance.method_calls_by_method
|
47
|
-
buffer(generate_specs("#{test_instance.test_class.name}::", test_instance.test_class.name,
|
48
|
-
class_method_calls, test_instance.let_variables, global_variable_declaration, {}))
|
49
|
-
else
|
50
|
-
buffer("context 'Scenario #{instance_count}' do",1)
|
51
|
-
|
52
|
-
buffer("before do",2)
|
53
|
-
|
54
|
-
top_declarations, declarations, variable_map, global_declared_names = setup_fixture(test_instance)
|
55
|
-
method_calls = test_instance.method_calls_by_method
|
56
|
-
specs_buffer = generate_specs("#{test_instance.test_class.name}#", "@fixture", method_calls, variable_map,
|
57
|
-
global_variable_declaration, top_declarations)
|
58
|
-
buffer_inline(@deconstructor.build_output(3 * @_indentation.length, variable_map, declarations, global_variable_declaration, {}))
|
59
|
-
buffer("end",2)
|
60
|
-
whitespace
|
61
|
-
buffer(specs_buffer)
|
62
|
-
buffer('end',1)
|
1
|
+
module Pretentious
|
2
|
+
class RspecGenerator < Pretentious::GeneratorBase
|
3
|
+
def begin_spec(test_class)
|
4
|
+
buffer('# This file was automatically generated by the pretentious gem')
|
5
|
+
buffer("require 'spec_helper'")
|
63
6
|
whitespace
|
7
|
+
buffer("RSpec.describe #{test_class.name} do")
|
64
8
|
end
|
65
9
|
|
66
|
-
|
67
|
-
|
68
|
-
private
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
def proc_function_generator(block, method)
|
73
|
-
"func_#{method.to_s}(#{Pretentious::Deconstructor.block_params_generator(block)})"
|
74
|
-
end
|
75
|
-
|
76
|
-
def get_block_source(block,let_variables, declared,indentation)
|
77
|
-
#output = ''
|
78
|
-
#output << "{ #{Pretentious::Deconstructor.block_params_generator(block)}\n"
|
79
|
-
#output << Pretentious::Deconstructor.proc_body(block, let_variables, declared,indentation)
|
80
|
-
#output << "#{indentation}}"
|
81
|
-
#output
|
82
|
-
" &#{Pretentious::Deconstructor.pick_name(let_variables, block.target_proc.object_id, declared)}"
|
83
|
-
end
|
84
|
-
|
85
|
-
def generate_expectation(fixture, method, let_variables, declarations, params, block, result)
|
86
|
-
output = ""
|
87
|
-
block_source = if !block.nil? && block.is_a?(Pretentious::RecordedProc)
|
88
|
-
get_block_source(block, let_variables, declarations, @_indentation * 3)
|
89
|
-
else
|
90
|
-
''
|
10
|
+
def end_spec
|
11
|
+
buffer('end')
|
91
12
|
end
|
92
13
|
|
93
|
-
|
94
|
-
|
95
|
-
else
|
96
|
-
stmt = []
|
97
|
-
stmt << "#{fixture}.#{method.to_s}"
|
98
|
-
stmt << "#{block_source}" unless block_source.empty?
|
99
|
-
stmt.join(' ')
|
14
|
+
def output
|
15
|
+
@output_buffer
|
100
16
|
end
|
101
17
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
18
|
+
def generate(test_instance, instance_count)
|
19
|
+
if test_instance.is_a? Class
|
20
|
+
context = Pretentious::Context.new(test_instance.let_variables)
|
21
|
+
# class methods
|
22
|
+
class_method_calls = test_instance.method_calls_by_method
|
23
|
+
buffer(generate_specs(context, "#{test_instance.test_class.name}::", test_instance.test_class.name,
|
24
|
+
class_method_calls))
|
25
|
+
else
|
26
|
+
buffer("context 'Scenario #{instance_count}' do", 1)
|
27
|
+
|
28
|
+
buffer('before do', 2)
|
29
|
+
|
30
|
+
context, declarations = setup_fixture(test_instance)
|
31
|
+
method_calls = test_instance.method_calls_by_method
|
32
|
+
spec_context = context.subcontext(declarations[:declaration])
|
33
|
+
specs_buffer = generate_specs(spec_context, "#{test_instance.test_class.name}#", "@fixture", method_calls)
|
34
|
+
context.declared_names = {}
|
35
|
+
deconstruct_output = @deconstructor.build_output(context, 3 * @_indentation.length, declarations)
|
36
|
+
|
37
|
+
buffer_inline(deconstruct_output)
|
38
|
+
buffer('end', 2)
|
39
|
+
whitespace
|
40
|
+
buffer_inline(specs_buffer)
|
41
|
+
buffer('end', 1)
|
42
|
+
whitespace
|
43
|
+
end
|
106
44
|
end
|
107
|
-
output
|
108
|
-
end
|
109
|
-
|
110
|
-
def generate_specs(context_prefix, fixture, method_calls, let_variables, declaration, previous_declaration)
|
111
|
-
output = ""
|
112
|
-
buffer_to_string(output, "it 'should pass current expectations' do\n", 2)
|
113
|
-
#collect all params
|
114
|
-
params_collection = []
|
115
|
-
mocks_collection = {}
|
116
|
-
method_call_collection = []
|
117
|
-
|
118
|
-
method_calls.each_key do |k|
|
119
|
-
info_blocks_arr = method_calls[k]
|
120
|
-
info_blocks_arr.each do |block|
|
121
|
-
method_call_collection << block
|
122
|
-
params_collection = params_collection | block[:params]
|
123
|
-
if (!Pretentious::Deconstructor.is_primitive?(block[:result]) && !block[:result].kind_of?(Exception))
|
124
|
-
params_collection << block[:result]
|
125
|
-
end
|
126
|
-
|
127
|
-
unless (block[:block].nil?)
|
128
|
-
params_collection << block[:block]
|
129
|
-
end
|
130
|
-
|
131
|
-
block[:context][:calls].each do |mock_block|
|
132
|
-
k = "#{mock_block[:class]}_#{mock_block[:method]}"
|
133
|
-
|
134
|
-
if mocks_collection[k].nil?
|
135
|
-
mocks_collection[k] = []
|
136
|
-
end
|
137
45
|
|
138
|
-
|
139
|
-
params_collection << mock_block[:result]
|
140
|
-
|
141
|
-
end if block[:context]
|
142
|
-
|
143
|
-
|
144
|
-
end
|
46
|
+
private
|
145
47
|
|
48
|
+
def proc_function_generator(block, method)
|
49
|
+
"func_#{method}(#{Pretentious::Deconstructor.block_params_generator(block)})"
|
146
50
|
end
|
147
51
|
|
148
|
-
|
149
|
-
|
150
|
-
[], previous_declaration)
|
151
|
-
buffer_to_string(output, deps) if deps!=''
|
52
|
+
def get_block_source(context, block)
|
53
|
+
" &#{context.pick_name(block.target_proc.object_id)}"
|
152
54
|
end
|
153
55
|
|
154
|
-
|
155
|
-
|
56
|
+
def generate_expectation(context, fixture, method, params, block, result)
|
57
|
+
output = ''
|
58
|
+
block_source = if !block.nil? && block.is_a?(Pretentious::RecordedProc)
|
59
|
+
get_block_source(context, block)
|
60
|
+
else
|
61
|
+
''
|
62
|
+
end
|
63
|
+
|
64
|
+
statement = if params.size > 0
|
65
|
+
"#{fixture}.#{method}(#{params_generator(context, params)})#{block_source}"
|
66
|
+
else
|
67
|
+
stmt = []
|
68
|
+
stmt << "#{fixture}.#{method}"
|
69
|
+
stmt << "#{block_source}" unless block_source.empty?
|
70
|
+
stmt.join(' ')
|
71
|
+
end
|
72
|
+
|
73
|
+
if result.is_a? Exception
|
74
|
+
buffer_to_string(output, "expect { #{statement} }.to #{pick_matcher(context, result)}",3)
|
75
|
+
else
|
76
|
+
buffer_to_string(output, "expect(#{statement}).to #{pick_matcher(context, result)}",3)
|
77
|
+
end
|
78
|
+
output
|
156
79
|
end
|
157
80
|
|
158
|
-
|
159
|
-
|
81
|
+
def generate_specs(context, context_prefix, fixture, method_calls)
|
82
|
+
output = ''
|
83
|
+
buffer_to_string(output, "it 'should pass current expectations' do", 2)
|
84
|
+
# collect all params
|
85
|
+
params_collection = []
|
86
|
+
mocks_collection = {}
|
87
|
+
method_call_collection = []
|
88
|
+
|
89
|
+
method_calls.each_key do |k|
|
90
|
+
info_blocks_arr = method_calls[k]
|
91
|
+
info_blocks_arr.each do |block|
|
92
|
+
method_call_collection << block
|
93
|
+
params_collection |= block[:params]
|
94
|
+
if !Pretentious::Deconstructor.primitive?(block[:result]) && !block[:result].kind_of?(Exception)
|
95
|
+
params_collection << block[:result]
|
96
|
+
end
|
160
97
|
|
161
|
-
|
98
|
+
params_collection << block[:block] unless block[:block].nil?
|
162
99
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
""
|
167
|
-
end
|
100
|
+
next unless block[:context]
|
101
|
+
block[:context][:calls].each do |mock_block|
|
102
|
+
k = "#{mock_block[:class]}_#{mock_block[:method]}"
|
168
103
|
|
169
|
-
|
104
|
+
mocks_collection[k] = [] if mocks_collection[k].nil?
|
170
105
|
|
171
|
-
|
106
|
+
mocks_collection[k] << mock_block
|
107
|
+
params_collection << mock_block[:result]
|
108
|
+
end
|
109
|
+
end
|
172
110
|
end
|
173
|
-
end
|
174
111
|
|
175
|
-
|
176
|
-
|
177
|
-
|
112
|
+
if params_collection.size > 0
|
113
|
+
deps = declare_dependencies(context, params_collection, 3)
|
114
|
+
buffer_inline_to_string(output, deps) if deps != ''
|
115
|
+
end
|
178
116
|
|
179
|
-
|
180
|
-
|
117
|
+
if mocks_collection.keys.size > 0
|
118
|
+
buffer_to_string(output, generate_rspec_stub(context, mocks_collection,
|
119
|
+
3 * @_indentation.length))
|
120
|
+
end
|
181
121
|
|
182
|
-
|
183
|
-
|
184
|
-
}
|
185
|
-
str = ""
|
186
|
-
mocks_collection.each do |k,values|
|
187
|
-
vals = values.collect { |v| Pretentious::value_ize(v[:result], let_variables, declaration) }
|
122
|
+
expectations = []
|
123
|
+
method_calls.each_key do |k|
|
188
124
|
|
189
|
-
|
190
|
-
vals = [vals[0]] if vals.uniq.size == 1
|
125
|
+
info_blocks_arr = method_calls[k]
|
191
126
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
127
|
+
info_blocks_arr.each do |block|
|
128
|
+
str = ''
|
129
|
+
params_desc_str = if block[:params].size > 0
|
130
|
+
"when passed #{desc_params(block)}"
|
131
|
+
else
|
132
|
+
''
|
133
|
+
end
|
196
134
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
# buffer("it '#{desc_params(block)} returns #{block[:result]}' do",2)
|
206
|
-
# whitespace
|
207
|
-
# if block[:params].size > 0
|
208
|
-
# buffer(declare_dependencies(block[:params], let_variables, 3))
|
209
|
-
# buffer("expect(#{fixture}.#{k.to_s}(#{params_generator(block[:params], let_variables)})).to #{pick_matcher(block[:result])}",3)
|
210
|
-
# else
|
211
|
-
# buffer("expect(#{fixture}.#{k.to_s}).to #{pick_matcher(block[:result])}",3)
|
212
|
-
# end
|
213
|
-
# whitespace
|
214
|
-
# buffer("end",2)
|
215
|
-
# whitespace
|
216
|
-
# end
|
217
|
-
#
|
218
|
-
# buffer("end", 1)
|
219
|
-
# whitespace
|
220
|
-
# end
|
221
|
-
#end
|
222
|
-
|
223
|
-
def pick_matcher(result, let_variables, declared_names)
|
224
|
-
if result.is_a? TrueClass
|
225
|
-
'be true'
|
226
|
-
elsif result.is_a? FalseClass
|
227
|
-
'be false'
|
228
|
-
elsif result.nil?
|
229
|
-
'be_nil'
|
230
|
-
elsif result.kind_of? Exception
|
231
|
-
'raise_error'
|
232
|
-
elsif let_variables && let_variables[result.object_id]
|
233
|
-
"eq(#{Pretentious::value_ize(result, let_variables, declared_names)})"
|
234
|
-
else
|
235
|
-
"eq(#{Pretentious::value_ize(result, nil, nil)})"
|
135
|
+
buffer_to_string(str, "# #{context_prefix}#{k} #{params_desc_str} should return #{block[:result]}", 3)
|
136
|
+
buffer_inline_to_string(str, generate_expectation(context, fixture, k, block[:params], block[:block], block[:result]))
|
137
|
+
expectations << str
|
138
|
+
end
|
139
|
+
end
|
140
|
+
buffer_inline_to_string(output, expectations.join("\n"))
|
141
|
+
buffer_to_string(output, 'end', 2)
|
142
|
+
output
|
236
143
|
end
|
237
|
-
end
|
238
144
|
|
145
|
+
def generate_rspec_stub(context, mocks_collection, indentation_level)
|
146
|
+
indentation = ''
|
239
147
|
|
148
|
+
indentation_level.times { indentation << ' ' }
|
149
|
+
str = ''
|
150
|
+
mocks_collection.each do |_k, values|
|
151
|
+
vals = values.collect { |v| context.value_of(v[:result]) }
|
240
152
|
|
241
|
-
|
242
|
-
|
243
|
-
args = block[:params]
|
244
|
-
names = block[:names]
|
245
|
-
n = 0
|
246
|
-
#puts args.inspect
|
247
|
-
return "" if args.nil?
|
153
|
+
# check if all vals are the same and just use one
|
154
|
+
vals = [vals[0]] if vals.uniq.size == 1
|
248
155
|
|
249
|
-
|
250
|
-
param_name = names[n][1].to_s
|
251
|
-
arg_value = (arg.is_a? String) ? "#{arg.dump}" : "#{arg.to_s}"
|
252
|
-
if (param_name.empty?)
|
253
|
-
params << "#{arg_value}"
|
254
|
-
else
|
255
|
-
params << "#{param_name} = #{arg_value}"
|
156
|
+
str << "#{indentation}allow_any_instance_of(#{values[0][:class]}).to receive(:#{values[0][:method]}).and_return(#{vals.join(', ')})\n"
|
256
157
|
end
|
257
|
-
|
258
|
-
n+=1
|
158
|
+
str
|
259
159
|
end
|
260
|
-
params.join(" ,")
|
261
|
-
end
|
262
160
|
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
def params_generator(args, let_variables, declared_names)
|
275
|
-
params = []
|
276
|
-
args.each do |arg|
|
277
|
-
if (!let_variables.nil? && let_variables[arg.object_id])
|
278
|
-
params << Pretentious::Deconstructor.pick_name(let_variables, arg.object_id, declared_names)
|
161
|
+
def pick_matcher(context, result)
|
162
|
+
if result.is_a? TrueClass
|
163
|
+
'be true'
|
164
|
+
elsif result.is_a? FalseClass
|
165
|
+
'be false'
|
166
|
+
elsif result.nil?
|
167
|
+
'be_nil'
|
168
|
+
elsif result.is_a? Exception
|
169
|
+
'raise_error'
|
170
|
+
elsif context.variable_map[result.object_id]
|
171
|
+
"eq(#{context.value_of(result)})"
|
279
172
|
else
|
280
|
-
|
173
|
+
"eq(#{Pretentious.value_ize(Pretentious::Context.new, result)})"
|
281
174
|
end
|
282
|
-
|
283
175
|
end
|
284
|
-
params.join(", ")
|
285
|
-
end
|
286
176
|
|
287
|
-
|
288
|
-
|
289
|
-
|
177
|
+
def self.location(output_folder)
|
178
|
+
output_folder.nil? ? 'spec' : File.join(output_folder, 'spec')
|
179
|
+
end
|
290
180
|
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
181
|
+
def self.naming(output_folder, klass)
|
182
|
+
klass_name_parts = klass.name.split('::')
|
183
|
+
last_part = klass_name_parts.pop
|
184
|
+
File.join(output_folder, "#{Pretentious::DdtUtils.to_underscore(last_part)}_spec.rb")
|
185
|
+
end
|
296
186
|
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
puts "#{filename}"
|
187
|
+
def self.helper(output_folder)
|
188
|
+
filename = File.join(output_folder, 'spec_helper.rb')
|
189
|
+
unless File.exist?(filename)
|
190
|
+
File.open(filename, 'w') { |f| f.write('# Place your requires here') }
|
191
|
+
puts "#{filename}"
|
192
|
+
end
|
304
193
|
end
|
305
194
|
end
|
306
195
|
end
|