pretentious 0.1.6 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +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
|