pretentious 0.1.6 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,15 @@
1
1
  module Pretentious
2
+ # base class for spec generators
2
3
  class GeneratorBase
4
+ def initialize(options = {})
5
+ @deconstructor = Pretentious::Deconstructor.new
6
+ indentation_count = options[:indentation] || 2
7
+ @output_buffer = ''
8
+ @_indentation = ''
9
+ indentation_count.times do
10
+ @_indentation << ' '
11
+ end
12
+ end
3
13
 
4
14
  def buffer(line, level = 0)
5
15
  @output_buffer << "#{indentation(level)}#{line}\n"
@@ -9,25 +19,76 @@ module Pretentious
9
19
  buffer << "#{indentation(level)}#{line}\n"
10
20
  end
11
21
 
22
+ def buffer_inline_to_string(buffer, line, level = 0)
23
+ buffer << "#{indentation(level)}#{line}"
24
+ end
25
+
12
26
  def buffer_inline(line, level = 0)
13
27
  @output_buffer << "#{indentation(level)}#{line}"
14
28
  end
15
29
 
16
30
  def setup_fixture(fixture)
17
- variable_map = fixture.let_variables.merge({ fixture.object_id => '@fixture'})
18
- top_declarations = {}
19
- global_declared_names = {}
31
+ variable_map = fixture.let_variables.merge(fixture.object_id => '@fixture')
32
+ context = Pretentious::Context.new(variable_map)
33
+ declarations, _dependencies = @deconstructor.generate_declarations(context, [], fixture)
34
+
35
+ [context, declarations]
36
+ end
37
+
38
+ protected
20
39
 
21
- declarations, dependencies = @deconstructor.generate_declarations(variable_map, {}, [], fixture)
40
+ def declare_dependencies(context, args, level)
41
+ deconstructor = Pretentious::Deconstructor.new
22
42
 
23
- declarations[:declaration].each do |d|
24
- if (d[:used_by] != :inline)
25
- top_declarations[d[:id]] = Pretentious::Deconstructor.pick_name(variable_map, d[:id], global_declared_names)
43
+ args = remove_primitives(args, context.variable_map)
44
+ deconstructor.deconstruct_to_ruby(context, level * @_indentation.length, *args)
45
+ end
46
+
47
+ def remove_primitives(args, let_lookup)
48
+ args.select { |a| let_lookup.include?(a.object_id) || !Pretentious::Deconstructor.primitive?(a) }
49
+ end
50
+
51
+ def params_generator(context, args)
52
+ params = []
53
+ args.each do |arg|
54
+ if context.variable_map[arg.object_id]
55
+ params << context.pick_name(arg.object_id)
56
+ else
57
+ params << context.value_of(arg)
26
58
  end
27
59
  end
60
+ params.join(', ')
61
+ end
62
+
63
+ def desc_params(block)
64
+ params = []
65
+ args = block[:params]
66
+ names = block[:names]
67
+ # puts args.inspect
68
+ return '' if args.nil?
28
69
 
29
- [top_declarations, declarations, variable_map, global_declared_names]
70
+ args.each_with_index do |arg, index|
71
+ param_name = names[index][1].to_s
72
+ arg_value = (arg.is_a? String) ? "#{arg.dump}" : "#{arg}"
73
+ if param_name.empty?
74
+ params << "#{arg_value}"
75
+ else
76
+ params << "#{param_name} = #{arg_value}"
77
+ end
78
+ end
79
+ params.join(' ,')
30
80
  end
31
81
 
82
+ def indentation(level)
83
+ buffer = ''
84
+ level.times do
85
+ buffer << @_indentation
86
+ end
87
+ buffer
88
+ end
89
+
90
+ def whitespace(level = 0)
91
+ @output_buffer << "#{indentation(level)}\n"
92
+ end
32
93
  end
33
- end
94
+ end
@@ -1,338 +1,222 @@
1
- class Pretentious::MinitestGenerator < Pretentious::GeneratorBase
2
-
3
- def initialize(options = {})
4
- @deconstructor = Pretentious::Deconstructor.new
5
- indentation_count = options[:indentation] || 2
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
- def whitespace(level = 0)
22
- @output_buffer << "#{indentation(level)}\n"
23
- end
24
-
25
- def begin_spec(test_class)
26
- @test_class = test_class
27
- buffer("#This file was automatically generated by the pretentious gem")
28
- buffer("require 'minitest_helper'")
29
- buffer('require "minitest/autorun"')
30
- whitespace
31
- buffer("class #{test_class.name}Test < Minitest::Test")
32
- buffer("end")
33
- whitespace
34
- end
35
-
36
- def end_spec
37
- end
38
-
39
- def output
40
- @output_buffer
41
- end
42
-
43
- def generate(test_instance, instance_count)
44
- global_variable_declaration = {}
45
- if (test_instance.is_a? Class)
46
- buffer("class #{test_instance.test_class.name}Scenario#{instance_count} < #{@test_class.name}Test",0)
47
-
48
- #class methods
49
- class_method_calls = test_instance.method_calls_by_method
50
- buffer(generate_specs("#{test_instance.test_class.name}::",test_instance.test_class.name, class_method_calls, test_instance.let_variables,
51
- global_variable_declaration, {}))
52
-
53
- buffer('end',0)
54
- else
55
- buffer("class #{test_instance.test_class.name}Scenario#{instance_count} < #{@test_class.name}Test",0)
56
-
57
- buffer("def setup",1)
58
-
59
-
60
- top_declarations, declarations, variable_map, global_declared_names = setup_fixture(test_instance)
61
-
62
- method_calls = test_instance.method_calls_by_method
63
- specs_buffer = generate_specs("#{test_instance.test_class.name}#", "@fixture", method_calls, variable_map,
64
- global_variable_declaration, top_declarations)
65
- buffer_inline(@deconstructor.build_output(3 * @_indentation.length, variable_map, declarations, global_variable_declaration, {}))
66
- buffer("end", 1)
1
+ module Pretentious
2
+ # Generator that outputs minitest specs
3
+ class MinitestGenerator < Pretentious::GeneratorBase
4
+ def begin_spec(test_class)
5
+ @test_class = test_class
6
+ buffer('# This file was automatically generated by the pretentious gem')
7
+ buffer("require 'minitest_helper'")
8
+ buffer('require "minitest/autorun"')
67
9
  whitespace
68
-
69
- buffer_inline(specs_buffer)
70
-
71
- buffer('end',0)
10
+ buffer("class #{test_class.name}Test < Minitest::Test")
11
+ buffer('end')
72
12
  whitespace
73
13
  end
74
14
 
75
- end
76
-
77
- private
78
-
79
-
80
-
81
- def proc_function_generator(block, method)
82
- "func_#{method.to_s}(#{Pretentious::Deconstructor.block_params_generator(block)})"
83
- end
84
-
85
- def get_block_source(block,let_variables, declared,indentation)
86
- #output = ''
87
- #output << "{ #{Pretentious::Deconstructor.block_params_generator(block)}\n"
88
- #output << Pretentious::Deconstructor.proc_body(block, let_variables, declared,indentation)
89
- #output << "#{indentation}}"
90
- #output
91
- " &#{Pretentious::Deconstructor.pick_name(let_variables, block.target_proc.object_id, declared)}"
92
- end
15
+ def end_spec
16
+ end
93
17
 
94
- def generate_expectation(fixture, method, let_variables, declarations, params, block, result)
95
- str = ""
96
- block_source = if !block.nil? && block.is_a?(Pretentious::RecordedProc)
97
- get_block_source(block, let_variables, declarations, @_indentation * 2)
98
- else
99
- ''
100
- end
101
-
102
- statement = if params.size > 0
103
- "#{fixture}.#{method.to_s}(#{params_generator(params, let_variables, declarations)})#{block_source}"
104
- else
105
- stmt = []
106
- m_stmt = "#{fixture}.#{method.to_s}"
107
- m_stmt << "(#{block_source})" unless block_source.empty?
108
- stmt << m_stmt
109
- stmt.join(' ')
110
- end
111
-
112
- if (result.kind_of? Exception)
113
- str << pick_matcher(statement, result, let_variables, declarations)
114
- else
115
- str << pick_matcher(statement, result, let_variables, declarations)
18
+ def output
19
+ @output_buffer
116
20
  end
117
- str
118
- end
119
21
 
120
- def generate_specs(context_prefix, fixture, method_calls, let_variables, declaration, previous_declaration)
121
- output = ""
122
- buffer_to_string(output, "def test_current_expectation", 1)
123
- #collect all params
124
- params_collection = []
125
- mocks_collection = {}
126
-
127
- method_calls.each_key do |k|
128
- info_blocks_arr = method_calls[k]
129
- info_blocks_arr.each do |block|
130
- params_collection = params_collection | block[:params]
131
- if (!Pretentious::Deconstructor.is_primitive?(block[:result]) && !block[:result].kind_of?(Exception))
132
- params_collection << block[:result]
133
- end
22
+ def generate(test_instance, instance_count)
23
+ if test_instance.is_a? Class
24
+ buffer("class #{test_instance.test_class.name}Scenario#{instance_count} < #{@test_class.name}Test", 0)
134
25
 
135
- unless (block[:block].nil?)
136
- params_collection << block[:block]
137
- end
26
+ # class methods
27
+ class_method_calls = test_instance.method_calls_by_method
28
+ context = Pretentious::Context.new(test_instance.let_variables)
29
+ buffer(generate_specs(context, "#{test_instance.test_class.name}::",
30
+ test_instance.test_class.name, class_method_calls))
138
31
 
139
- block[:context][:calls].each do |mock_block|
140
- k = "#{mock_block[:class]}_#{mock_block[:method]}"
32
+ buffer('end', 0)
33
+ else
34
+ buffer("class #{test_instance.test_class.name}Scenario#{instance_count} < #{@test_class.name}Test", 0)
141
35
 
142
- if mocks_collection[k].nil?
143
- mocks_collection[k] = []
144
- end
36
+ buffer('def setup', 1)
145
37
 
146
- mocks_collection[k] << mock_block
147
- params_collection << mock_block[:result]
38
+ context, declarations = setup_fixture(test_instance)
148
39
 
149
- end if block[:context]
40
+ method_calls = test_instance.method_calls_by_method
41
+ specs_buffer = generate_specs(context.subcontext(declarations[:declaration]), "#{test_instance.test_class.name}#",
42
+ '@fixture', method_calls)
43
+ context.declared_names = {}
44
+ buffer_inline(@deconstructor.build_output(context, 2 * @_indentation.length, declarations))
45
+ buffer('end', 1)
46
+ whitespace
150
47
 
48
+ buffer_inline(specs_buffer)
151
49
 
50
+ buffer('end', 0)
51
+ whitespace
152
52
  end
153
-
154
53
  end
155
54
 
156
- if (params_collection.size > 0)
157
- deps = declare_dependencies(params_collection, let_variables, 2, declaration, previous_declaration)
158
- buffer_to_string(output, deps) if deps.strip!=''
55
+ private
56
+
57
+ def proc_function_generator(block, method)
58
+ "func_#{method}(#{Pretentious::Deconstructor.block_params_generator(block)})"
159
59
  end
160
60
 
161
- if (mocks_collection.keys.size > 0)
162
- buffer_to_string(output, generate_minitest_stub(mocks_collection, let_variables, 2, declaration) { |indentation|
163
- generate_test_scenarios(fixture, method_calls, context_prefix, let_variables, declaration, indentation)
164
- }, 0)
165
- else
166
- buffer_to_string(output, generate_test_scenarios(fixture, method_calls, context_prefix, let_variables, declaration, 2), 0)
61
+ def get_block_source(context, block)
62
+ " &#{context.pick_name(block.target_proc.object_id)}"
167
63
  end
168
64
 
169
- buffer_to_string(output, "end", 1)
170
- output
171
- end
65
+ def generate_expectation(context, fixture, method, params, block, result)
66
+ str = ''
67
+ block_source = if !block.nil? && block.is_a?(Pretentious::RecordedProc)
68
+ get_block_source(context, block)
69
+ else
70
+ ''
71
+ end
72
+
73
+ statement = if params.size > 0
74
+ "#{fixture}.#{method}(#{params_generator(context, params)})#{block_source}"
75
+ else
76
+ stmt = []
77
+ m_stmt = "#{fixture}.#{method}"
78
+ m_stmt << "(#{block_source})" unless block_source.empty?
79
+ stmt << m_stmt
80
+ stmt.join(' ')
81
+ end
82
+
83
+ if result.is_a? Exception
84
+ str << pick_matcher(context, statement, result)
85
+ else
86
+ str << pick_matcher(context, statement, result)
87
+ end
88
+ str
89
+ end
172
90
 
173
- def generate_test_scenarios(fixture, method_calls, context_prefix, let_variables, declaration, indentation_level)
174
- str = ""
175
- indentation = ""
176
- indentation_level.times {
177
- indentation << @_indentation
178
- }
179
- method_calls.each_key do |k|
180
- info_blocks_arr = method_calls[k]
91
+ def generate_specs(context, context_prefix, fixture, method_calls)
92
+ output = ''
93
+ buffer_to_string(output, 'def test_current_expectation', 1)
94
+ # collect all params
95
+ params_collection = []
96
+ mocks_collection = {}
97
+
98
+ method_calls.each_key do |k|
99
+ info_blocks_arr = method_calls[k]
100
+ info_blocks_arr.each do |block|
101
+ params_collection |= block[:params]
102
+ if !Pretentious::Deconstructor.primitive?(block[:result]) && !block[:result].is_a?(Exception)
103
+ params_collection << block[:result]
104
+ end
181
105
 
182
- info_blocks_arr.each do |block|
106
+ params_collection << block[:block] unless block[:block].nil?
183
107
 
184
- params_desc_str = if block[:params].size > 0
185
- "when passed #{desc_params(block)}"
186
- else
187
- ""
188
- end
108
+ block[:context][:calls].each do |mock_block|
109
+ k = "#{mock_block[:class]}_#{mock_block[:method]}"
189
110
 
190
- str << "#{indentation}##{context_prefix}#{k} #{params_desc_str} should return #{block[:result]}\n"
191
- str << "#{indentation}#{generate_expectation(fixture, k, let_variables, declaration, block[:params], block[:block], block[:result])}\n\n"
111
+ mocks_collection[k] = [] if mocks_collection[k].nil?
192
112
 
113
+ mocks_collection[k] << mock_block
114
+ params_collection << mock_block[:result]
115
+ end if block[:context]
116
+ end
193
117
  end
194
- end
195
- str
196
- end
197
118
 
198
- def generate_minitest_stub(mocks_collection, let_variables, indentation_level , declaration, &block)
119
+ if params_collection.size > 0
120
+ deps = declare_dependencies(context, params_collection, 2)
121
+ buffer_to_string(output, deps) if deps.strip != ''
122
+ end
199
123
 
200
- str = ""
201
- current_indentation = indentation_level
124
+ if mocks_collection.keys.size > 0
125
+ minitest_stub = generate_minitest_stub(context, mocks_collection, 2) do |indentation|
126
+ generate_test_scenarios(context, fixture, method_calls, context_prefix, indentation)
127
+ end
128
+ buffer_to_string(output, minitest_stub, 0)
129
+ else
130
+ buffer_inline_to_string(output, generate_test_scenarios(context, fixture, method_calls, context_prefix, 2), 0)
131
+ end
202
132
 
203
- mocks_collection.each do |k,values|
204
- indentation = ""
205
- current_indentation.times {
206
- indentation << @_indentation
207
- }
208
- vals = values.collect { |v| Pretentious::value_ize(v[:result], let_variables, declaration) }
209
- str << "#{indentation}#{values[0][:class].to_s}.stub_any_instance(:#{values[0][:method].to_s}, #{vals[0]}) do\n"
210
- current_indentation+=1
133
+ buffer_to_string(output, 'end', 1)
134
+ output
211
135
  end
212
136
 
213
- str << block.call(current_indentation)
214
-
215
- current_indentation -= 1
216
-
217
- mocks_collection.each do |k, values|
218
- indentation = ""
219
- current_indentation.times {
220
- indentation << @_indentation
221
- }
222
- str << "#{indentation}end\n"
223
- current_indentation -= 1
137
+ def generate_test_scenarios(context, fixture, method_calls, context_prefix, indentation_level)
138
+ expectations = []
139
+ indentation = ''
140
+ indentation_level.times { indentation << @_indentation }
141
+ method_calls.each_key do |k|
142
+ str = ''
143
+ info_blocks_arr = method_calls[k]
144
+
145
+ info_blocks_arr.each do |block|
146
+ params_desc_str = if block[:params].size > 0
147
+ "when passed #{desc_params(block)}"
148
+ else
149
+ ''
150
+ end
151
+
152
+ str << "#{indentation}# #{context_prefix}#{k} #{params_desc_str} should return #{block[:result]}\n"
153
+ str << "#{indentation}#{generate_expectation(context, fixture, k, block[:params], block[:block], block[:result])}\n\n"
154
+ expectations << str
155
+ end
156
+ end
157
+ expectations.join("\n")
224
158
  end
225
- str
226
- end
227
159
 
228
- #def generate_specs(context_prefix, fixture, method_calls, let_variables)
229
- # method_calls.each_key do |k|
230
- # info_blocks_arr = method_calls[k]
231
- #
232
- # buffer("context \"#{context_prefix}#{k}\" do", 1)
233
- #
234
- # whitespace
235
- # info_blocks_arr.each do |block|
236
- # buffer("it '#{desc_params(block)} returns #{block[:result]}' do",2)
237
- # whitespace
238
- # if block[:params].size > 0
239
- # buffer(declare_dependencies(block[:params], let_variables, 3))
240
- # buffer("expect(#{fixture}.#{k.to_s}(#{params_generator(block[:params], let_variables)})).to #{pick_matcher(block[:result])}",3)
241
- # else
242
- # buffer("expect(#{fixture}.#{k.to_s}).to #{pick_matcher(block[:result])}",3)
243
- # end
244
- # whitespace
245
- # buffer("end",2)
246
- # whitespace
247
- # end
248
- #
249
- # buffer("end", 1)
250
- # whitespace
251
- # end
252
- #end
253
-
254
- def pick_matcher(statement, result, let_variables, declarations)
255
- if result.is_a? TrueClass
256
- "assert #{statement}"
257
- elsif result.is_a? FalseClass
258
- "refute #{statement}"
259
- elsif result.nil?
260
- "assert_nil #{statement}"
261
- elsif result.kind_of? Exception
262
- "assert_raises(#{result.class.to_s}) { #{statement} }"
263
- elsif let_variables && let_variables[result.object_id]
264
- "assert_equal #{Pretentious::value_ize(result, let_variables, declarations)}, #{statement}"
265
- else
266
- "assert_equal #{Pretentious::value_ize(result, nil, nil)}, #{statement}"
267
- end
268
- end
160
+ def generate_minitest_stub(context, mocks_collection, indentation_level, &block)
161
+ str = ''
162
+ current_indentation = indentation_level
269
163
 
164
+ mocks_collection.each do |_k, values|
165
+ indentation = ''
166
+ current_indentation.times { indentation << @_indentation }
167
+ vals = values.collect { |v| context.value_of(v[:result]) }
168
+ str << "#{indentation}#{values[0][:class]}.stub_any_instance(:#{values[0][:method]}, #{vals[0]}) do\n"
169
+ current_indentation += 1
170
+ end
270
171
 
172
+ str << block.call(current_indentation)
271
173
 
272
- def desc_params(block)
273
- params = []
274
- args = block[:params]
275
- names = block[:names]
276
- n = 0
277
- #puts args.inspect
278
- return "" if args.nil?
174
+ current_indentation -= 1
279
175
 
280
- args.each do |arg|
281
- param_name = names[n][1].to_s
282
- arg_value = (arg.is_a? String) ? "#{arg.dump}" : "#{arg.to_s}"
283
- if (param_name.empty?)
284
- params << "#{arg_value}"
285
- else
286
- params << "#{param_name} = #{arg_value}"
176
+ mocks_collection.each do
177
+ indentation = ''
178
+ current_indentation.times { indentation << @_indentation }
179
+ str << "#{indentation}end\n"
180
+ current_indentation -= 1
287
181
  end
288
-
289
- n+=1
182
+ str
290
183
  end
291
- params.join(" ,")
292
- end
293
-
294
- def declare_dependencies(args, variable_map, level, declarations, previous_declaration)
295
- deconstructor = Pretentious::Deconstructor.new
296
184
 
297
- args = remove_primitives(args, variable_map)
298
- deconstructor.deconstruct_to_ruby(level * @_indentation.length, variable_map, declarations, previous_declaration, [], *args)
299
- end
300
-
301
- def remove_primitives(args, let_lookup)
302
- args.select { |a| let_lookup.include?(a.object_id) || !Pretentious::Deconstructor.is_primitive?(a) }
303
- end
304
-
305
- def params_generator(args, let_variables, declared_names)
306
- params = []
307
- args.each do |arg|
308
- if (!let_variables.nil? && let_variables[arg.object_id])
309
- params << Pretentious::Deconstructor.pick_name(let_variables, arg.object_id, declared_names)
185
+ def pick_matcher(context, statement, result)
186
+ if result.is_a? TrueClass
187
+ "assert #{statement}"
188
+ elsif result.is_a? FalseClass
189
+ "refute #{statement}"
190
+ elsif result.nil?
191
+ "assert_nil #{statement}"
192
+ elsif result.is_a? Exception
193
+ "assert_raises(#{result.class}) { #{statement} }"
194
+ elsif context.variable_map[result.object_id]
195
+ "assert_equal #{context.value_of(result)}, #{statement}"
310
196
  else
311
- params << Pretentious::value_ize(arg, let_variables, declared_names)
197
+ "assert_equal #{Pretentious.value_ize(Pretentious::Context.new, result)}, #{statement}"
312
198
  end
313
-
314
199
  end
315
- params.join(", ")
316
- end
317
200
 
318
- def self.location(output_folder)
319
- output_folder.nil? ? "test" : File.join(output_folder, "test")
320
- end
201
+ def self.location(output_folder)
202
+ output_folder.nil? ? 'test' : File.join(output_folder, 'test')
203
+ end
321
204
 
322
- def self.naming(output_folder, klass)
323
- klass_name_parts = klass.name.split('::')
324
- last_part = klass_name_parts.pop
325
- File.join(output_folder, "test_#{Pretentious::DdtUtils.to_underscore(last_part)}.rb")
326
- end
205
+ def self.naming(output_folder, klass)
206
+ klass_name_parts = klass.name.split('::')
207
+ last_part = klass_name_parts.pop
208
+ File.join(output_folder, "test_#{Pretentious::DdtUtils.to_underscore(last_part)}.rb")
209
+ end
327
210
 
328
- def self.helper(output_folder)
329
- filename = File.join(output_folder,"minitest_helper.rb")
330
- unless File.exists?(filename)
331
- File.open(filename, 'w') { |f|
332
- f.write("# Place your requires here\n")
333
- f.write("require 'minitest/stub_any_instance'\n")
334
- }
335
- puts "#{filename}"
211
+ def self.helper(output_folder)
212
+ filename = File.join(output_folder, 'minitest_helper.rb')
213
+ unless File.exist?(filename)
214
+ File.open(filename, 'w') do |f|
215
+ f.write("# Place your requires here\n")
216
+ f.write("require 'minitest/stub_any_instance'\n")
217
+ end
218
+ puts "#{filename}"
219
+ end
336
220
  end
337
221
  end
338
222
  end