active_mocker 1.8.4 → 2.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +13 -0
  3. data/README.md +4 -2
  4. data/lib/active_mocker.rb +9 -25
  5. data/lib/active_mocker/config.rb +26 -46
  6. data/lib/active_mocker/generate.rb +115 -110
  7. data/lib/active_mocker/loaded_mocks.rb +76 -65
  8. data/lib/active_mocker/mock/base.rb +283 -287
  9. data/lib/active_mocker/mock/has_many.rb +2 -0
  10. data/lib/active_mocker/mock_creator.rb +262 -0
  11. data/lib/active_mocker/mock_template.erb +9 -186
  12. data/lib/active_mocker/mock_template/_associations.erb +82 -0
  13. data/lib/active_mocker/mock_template/_attributes.erb +11 -0
  14. data/lib/active_mocker/mock_template/_class_methods.erb +41 -0
  15. data/lib/active_mocker/mock_template/_defined_methods.erb +10 -0
  16. data/lib/active_mocker/mock_template/_modules_constants.erb +10 -0
  17. data/lib/active_mocker/mock_template/_scopes.erb +23 -0
  18. data/lib/active_mocker/null_progress.rb +9 -0
  19. data/lib/active_mocker/output_capture.rb +32 -0
  20. data/lib/active_mocker/parent_class.rb +64 -0
  21. data/lib/active_mocker/progress.rb +13 -0
  22. data/lib/active_mocker/public_methods.rb +15 -23
  23. data/lib/active_mocker/rspec.rb +16 -0
  24. data/lib/active_mocker/rspec_helper.rb +10 -8
  25. data/lib/active_mocker/task.rake +6 -1
  26. data/lib/active_mocker/template_creator.rb +22 -0
  27. data/lib/active_mocker/version.rb +1 -1
  28. metadata +43 -103
  29. data/lib/active_mocker/active_record.rb +0 -74
  30. data/lib/active_mocker/active_record/field.rb +0 -39
  31. data/lib/active_mocker/active_record/relationships.rb +0 -110
  32. data/lib/active_mocker/active_record/schema.rb +0 -81
  33. data/lib/active_mocker/active_record/scope.rb +0 -22
  34. data/lib/active_mocker/active_record/table.rb +0 -26
  35. data/lib/active_mocker/active_record/unknown_class_method.rb +0 -17
  36. data/lib/active_mocker/active_record/unknown_module.rb +0 -30
  37. data/lib/active_mocker/db_to_ruby_type.rb +0 -29
  38. data/lib/active_mocker/file_reader.rb +0 -11
  39. data/lib/active_mocker/model_reader.rb +0 -191
  40. data/lib/active_mocker/model_schema.rb +0 -285
  41. data/lib/active_mocker/model_schema/assemble.rb +0 -220
  42. data/lib/active_mocker/reparameterize.rb +0 -41
  43. data/lib/active_mocker/ruby_parse.rb +0 -68
  44. data/lib/active_mocker/schema_reader.rb +0 -30
  45. data/lib/active_mocker/string_reader.rb +0 -18
@@ -32,12 +32,14 @@ module Mock
32
32
  def build(options={}, &block)
33
33
  new_record = relation_class.new(init_options.merge!(options), &block)
34
34
 
35
+ # @private
35
36
  def new_record._belongs_to(collection)
36
37
  @belongs_to_collection = collection
37
38
  end
38
39
 
39
40
  new_record._belongs_to(self)
40
41
 
42
+ # @private
41
43
  def new_record.save
42
44
  @belongs_to_collection << self
43
45
  super
@@ -0,0 +1,262 @@
1
+ module ActiveMocker
2
+ class MockCreator
3
+ def initialize(file:,
4
+ file_out:,
5
+ schema_scrapper:,
6
+ template_creator: nil,
7
+ class_introspector: nil,
8
+ enabled_partials: nil,
9
+ klasses_to_be_mocked:,
10
+ active_record_base_klass: ActiveRecord::Base)
11
+ @file = file
12
+ @file_out = file_out
13
+ @schema_scrapper = schema_scrapper
14
+ @template_creator = template_creator || template_creator_default(file_out)
15
+ @class_introspector = class_introspector || class_introspector_default
16
+ @enabled_partials = enabled_partials || self.class.enabled_partials_default
17
+ @klasses_to_be_mocked = klasses_to_be_mocked
18
+ @active_record_base_klass = active_record_base_klass
19
+ @errors = []
20
+ @completed = false
21
+ end
22
+
23
+ def create
24
+ verify_class
25
+ if errors.empty?
26
+ template_creator.render
27
+ file_out.close
28
+ @completed = true
29
+ end
30
+ self
31
+ end
32
+
33
+ def completed?
34
+ @completed
35
+ end
36
+
37
+ attr_reader :errors
38
+
39
+ private
40
+
41
+ attr_reader :file,
42
+ :file_out,
43
+ :schema_scrapper,
44
+ :template_creator,
45
+ :class_introspector,
46
+ :enabled_partials,
47
+ :klasses_to_be_mocked,
48
+ :active_record_base_klass
49
+
50
+ # -- Defaults -- #
51
+ private
52
+ def template_creator_default(file_out)
53
+ TemplateCreator.new(file_out: file_out,
54
+ erb_template: File.new(File.join(File.dirname(__FILE__), "mock_template.erb"), 'r'),
55
+ binding: binding)
56
+ end
57
+
58
+ def class_introspector_default
59
+ DissociatedIntrospection::Inspection.new(file: file)
60
+ end
61
+
62
+ class << self
63
+ def enabled_partials_default
64
+ [:modules_constants, :class_methods, :attributes, :scopes, :defined_methods, :associations]
65
+ end
66
+
67
+ public :enabled_partials_default
68
+ end
69
+
70
+ # -- END defaults -- #
71
+
72
+ def verify_class
73
+ v = ParentClass.new(parsed_source: class_introspector.parsed_source,
74
+ klasses_to_be_mocked: klasses_to_be_mocked,
75
+ mock_append_name: mock_append_name).call
76
+ errors << v.error if v.error
77
+ @parent_class = v.parent_mock_name
78
+ end
79
+
80
+ public
81
+
82
+ def partials
83
+ OpenStruct.new(enabled_partials.each_with_object({}) do |p, hash|
84
+ begin
85
+ file = File.new(File.join(File.dirname(__FILE__), "mock_template/_#{p}.erb"))
86
+ self.extend("ActiveMocker::MockCreator::#{p.to_s.camelize}".constantize)
87
+ hash[p] = ERB.new(file.read, nil, '-', "_sub#{p}").result(binding)
88
+ rescue => e
89
+ print "#{file.inspect}"
90
+ raise e
91
+ end
92
+ end)
93
+ end
94
+
95
+ def class_name
96
+ class_introspector.parsed_source.class_name
97
+ end
98
+
99
+ def mock_append_name
100
+ 'Mock'
101
+ end
102
+
103
+ def parent_class
104
+ @parent_class
105
+ end
106
+
107
+ def primary_key
108
+ @primary_key ||= ActiveRecordSchemaScrapper::Attribute.new(name: 'id', type: :integer)
109
+ end
110
+
111
+ module ModulesConstants
112
+ def constants
113
+ const = {}
114
+ class_introspector.get_class.constants.each { |c| const[c] = class_introspector.get_class.const_get(c) }
115
+ const = const.reject do |c, v|
116
+ v.class == Module || v.class == Class
117
+ end
118
+ const
119
+ end
120
+
121
+ def modules
122
+ @modules ||= begin
123
+ {
124
+ included: reject_local_const(class_introspector.included_modules)
125
+ .map(&:referenced_name),
126
+ extended: reject_local_const(class_introspector.extended_modules)
127
+ .map(&:referenced_name)
128
+ }
129
+ end
130
+ end
131
+
132
+ private
133
+
134
+ def reject_local_const(source)
135
+ source.reject do |n|
136
+ class_introspector.locally_defined_constants.values.include?(n)
137
+ end
138
+ end
139
+ end
140
+
141
+ module Attributes
142
+ def attributes
143
+ @attribute ||= begin
144
+ a = schema_scrapper.attributes.to_a
145
+ unless a.any? { |aa| aa.name == "id" }
146
+ a << primary_key
147
+ end
148
+ a
149
+ end
150
+ end
151
+ end
152
+
153
+ module ClassMethods
154
+ include Attributes
155
+
156
+ def attributes_with_defaults
157
+ hash = {}
158
+ attributes.each do |attr|
159
+ hash[attr.name] = Virtus::Attribute.build(attr.type).coerce(attr.default)
160
+ end
161
+ hash
162
+ end
163
+
164
+ def types_hash
165
+ types = {}
166
+ attributes.each do |attr|
167
+ types[attr.name] = "#{attr.type}"
168
+ end
169
+
170
+ type_array = types.map do |name, type|
171
+ "#{name}: #{type}"
172
+ end
173
+ '{ ' + type_array.join(', ') + ' }'
174
+ end
175
+
176
+ def associations
177
+ @associations ||= schema_scrapper.associations.to_a.each_with_object({}) do |a, h|
178
+ h[a.name] = nil
179
+ end
180
+ end
181
+
182
+ def associations_by_class
183
+ schema_scrapper.associations.to_a.each_with_object({}) do |r, hash|
184
+ hash[r.class_name.to_s] ||= {}
185
+ hash[r.class_name.to_s][r.type] ||= []
186
+ hash[r.class_name.to_s][r.type] << r.name
187
+ end
188
+ end
189
+
190
+ def attribute_names
191
+ attributes.map { |a| a.name }
192
+ end
193
+
194
+ def abstract_class
195
+ schema_scrapper.abstract_class?
196
+ end
197
+
198
+ def table_name
199
+ schema_scrapper.table_name
200
+ end
201
+ end
202
+
203
+ module Scopes
204
+ def scope_methods
205
+ class_introspector.class_macros.select { |h| h.keys.first == :scope }.map do |h|
206
+ a = h.values.first.first
207
+ OpenStruct.new(name: a[0], arguments: ReverseParameters.new(a[1]))
208
+ end
209
+ end
210
+ end
211
+
212
+ module DefinedMethods
213
+ def get_instance_methods
214
+ methods = class_introspector.get_class.public_instance_methods(false)
215
+ methods << class_introspector.get_class.superclass.public_instance_methods(false) if class_introspector.get_class.superclass != ActiveRecord::Base
216
+ methods.flatten
217
+ end
218
+
219
+ def instance_methods
220
+ get_instance_methods.map do |m|
221
+ OpenStruct.new(name: m, arguments: ReverseParameters.new(class_introspector.get_class.instance_method(m).parameters))
222
+ end
223
+ end
224
+
225
+ def get_class_methods
226
+ class_introspector.get_class.methods(false)
227
+ end
228
+
229
+ def class_methods
230
+ get_class_methods.map do |m|
231
+ OpenStruct.new(name: m, arguments: ReverseParameters.new(class_introspector.get_class.method(m).parameters))
232
+ end
233
+ end
234
+ end
235
+
236
+ module Associations
237
+ def has_many
238
+ association_collection.select { |a| a.type == :has_many }
239
+ end
240
+
241
+ def has_one
242
+ association_collection.select { |a| a.type == :has_one }
243
+ end
244
+
245
+ def belongs_to
246
+ association_collection.select { |a| a.type == :belongs_to }
247
+ end
248
+
249
+ def has_and_belongs_to_many
250
+ association_collection.select { |a| a.type == :has_and_belongs_to_many }
251
+ end
252
+
253
+ def relation_find(key, value)
254
+ association_collection.select { |r| r.send(key).to_sym == value }
255
+ end
256
+
257
+ def association_collection
258
+ @association_collection ||= schema_scrapper.associations.to_a
259
+ end
260
+ end
261
+ end
262
+ end
@@ -1,190 +1,13 @@
1
1
  require 'active_mocker/mock'
2
2
 
3
- class <%= class_name + @mock_append_name %> < <%= parent_class %>
4
- created_with('<%= ActiveMocker::VERSION %>')
5
- <% constants.each do |constant| -%>
6
- <%= constant.first %> = <%= constant.last.inspect %>
7
- <% end -%>
8
- <% modules[:included].each do |constant| -%>
9
- prepend <%= constant %>
10
- <% end -%>
11
- <% modules[:extended].each do |constant| -%>
12
- extend <%= constant %>
13
- <% end -%>
14
-
15
- class << self
16
-
17
- def attributes
18
- @attributes ||= HashWithIndifferentAccess.new(<%= attributes_with_defaults %>).merge(super)
19
- end
20
-
21
- def types
22
- @types ||= ActiveMocker::Mock::HashProcess.new(<%= types_hash %>, method(:build_type)).merge(super)
23
- end
24
-
25
- def associations
26
- @associations ||= <%= associations %>.merge(super)
27
- end
28
-
29
- def associations_by_class
30
- @associations_by_class ||= <%= associations_by_class %>.merge(super)
31
- end
32
-
33
- def mocked_class
34
- <%= class_name.inspect %>
35
- end
36
-
37
- private :mocked_class
38
-
39
- def attribute_names
40
- @attribute_names ||= <%= attribute_names %> | super
41
- end
42
-
43
- def primary_key
44
- <%= primary_key.name.inspect %>
45
- end
46
-
47
- def abstract_class?
48
- <%= abstract_class.inspect %>
49
- end
50
-
51
- def table_name
52
- <%= table_name.inspect %> || super
53
- end
54
-
55
- end
56
-
57
- ##################################
58
- # Attributes getter/setters #
59
- ##################################
60
- <% attributes.each do |meth| %>
61
- def <%= meth.name %>
62
- read_attribute(:<%= meth.name %>)
63
- end
64
-
65
- def <%= meth.name %>=(val)
66
- write_attribute(:<%= meth.name %>, val)
67
- end
68
- <% end %>
69
- ##################################
70
- # Associations #
71
- ##################################
72
-
73
- <%= '# belongs_to' unless belongs_to.empty? -%>
74
- <% belongs_to.each do |meth| %>
75
- def <%= meth.name %>
76
- <% association = relation_find(:name, meth.name).first -%>
77
- read_association(:<%= meth.name %>) || write_association(:<%= meth.name %>, classes('<%= association.class_name %>').try{ |k| k.find_by(id: <%= association.foreign_key %>)})
78
- end
79
-
80
- def <%= meth.name %>=(val)
81
- write_association(:<%= meth.name %>, val)
82
- ActiveMocker::Mock::BelongsTo.new(val, child_self: self, foreign_key: :<%= meth.foreign_key %>).item
83
- end
84
-
85
- def build_<%= meth.name %>(attributes={}, &block)
86
- <% association = relation_find(:name, meth.name).first -%>
87
- <% if association -%>
88
- association = classes('<%= association.class_name %>').try(:new, attributes, &block)
89
- write_association(:<%= meth.name %>, association) unless association.nil?
90
- <% end -%>
91
- end
3
+ class <%= class_name + mock_append_name %> < <%= parent_class %>
92
4
 
93
- def create_<%= meth.name %>(attributes={}, &block)
94
- <% association = relation_find(:name, meth.name).first -%>
95
- <% if association -%>
96
- association = classes('<%= association.class_name %>').try(:create,attributes, &block)
97
- write_association(:<%= meth.name %>, association) unless association.nil?
98
- <% end -%>
99
- end
100
- alias_method :create_<%= meth.name %>!, :create_<%= meth.name %>
101
- <% end -%>
102
- <%= '# has_one' unless has_one.empty? -%>
103
- <% has_one.each do |meth| %>
104
- def <%= meth.name %>
105
- read_association(:<%= meth.name %>)
106
- end
107
-
108
- def <%= meth.name %>=(val)
109
- write_association(:<%= meth.name %>, val)
110
- ActiveMocker::Mock::HasOne.new(val, child_self: self, foreign_key: '<%= meth.foreign_key %>').item
111
- end
112
-
113
- def build_<%= meth.name %>(attributes={}, &block)
114
- <% association = relation_find(:name, meth.name).first -%>
115
- <% if association -%>
116
- write_association(:<%= meth.name %>, classes('<%= association.class_name %>').new(attributes, &block)) if classes('<%= association.class_name %>')
117
- <% end -%>
118
- end
119
-
120
- def create_<%= meth.name %>(attributes={}, &block)
121
- <% association = relation_find(:name, meth.name).first -%>
122
- <% if association -%>
123
- write_association(:<%= meth.name %>, classes('<%= association.class_name %>').new(attributes, &block)) if classes('<%= association.class_name %>')
124
- <% end -%>
125
- end
126
- alias_method :create_<%= meth.name %>!, :create_<%= meth.name %>
127
- <% end -%>
128
-
129
- <%= '# has_many' unless has_many.empty? -%>
130
- <% has_many.each do |meth| %>
131
- def <%= meth.name %>
132
- read_association(:<%= meth.name %>, -> { ActiveMocker::Mock::HasMany.new([],foreign_key: '<%= meth.foreign_key %>', foreign_id: self.id, relation_class: classes('<%= meth.class_name %>'), source: '<%= meth.source %>') })
133
- end
134
-
135
- def <%= meth.name %>=(val)
136
- write_association(:<%= meth.name %>, ActiveMocker::Mock::HasMany.new(val, foreign_key: '<%= meth.foreign_key %>', foreign_id: self.id, relation_class: classes('<%= meth.class_name %>'), source: '<%= meth.source %>'))
137
- end
138
- <% end -%>
139
- <%= '# has_and_belongs_to_many' unless has_and_belongs_to_many.empty? -%>
140
- <% has_and_belongs_to_many.each do |meth| %>
141
- def <%= meth.name %>
142
- read_association(:<%= meth.name %>, ->{ ActiveMocker::Mock::HasAndBelongsToMany.new([]) })
143
- end
144
-
145
- def <%= meth.name %>=(val)
146
- write_association(:<%= meth.name %>, ActiveMocker::Mock::HasAndBelongsToMany.new(val))
147
- end
148
- <% end -%>
149
-
150
- module Scopes
151
- include <%= parent_class %>::Scopes
152
-
153
- <% scope_methods.each do |method| -%>
154
- def <%= method.name %><%= "(#{method.arguments})" unless method.arguments.empty? %>
155
- ActiveMocker::LoadedMocks.find('<%= class_name %>').send(:call_mock_method, method: '<%= method.name %>', caller: Kernel.caller, arguments: [<%= method.arguments.passable %>])
156
- end
157
-
158
- <% end -%>
159
- end
160
-
161
- extend Scopes
162
-
163
- class ScopeRelation < ActiveMocker::Mock::Association
164
- include <%= class_name + @mock_append_name %>::Scopes
165
- end
166
-
167
- private
168
-
169
- def self.new_relation(collection)
170
- <%= class_name + @mock_append_name %>::ScopeRelation.new(collection)
171
- end
172
-
173
- public
174
-
175
- ##################################
176
- # Model Methods #
177
- ##################################
178
-
179
- <% instance_methods.each do |method| %>
180
- def <%= method.name %><%= "(#{method.arguments})" unless method.arguments.empty? %>
181
- call_mock_method(method: __method__, caller: Kernel.caller, arguments: [<%= method.arguments.passable %>])
182
- end
183
- <% end -%>
184
- <% class_methods.each do |method| %>
185
- def self.<%= method.name %><%= "(#{method.arguments})" unless method.arguments.empty? %>
186
- call_mock_method(method: __method__, caller: Kernel.caller, arguments: [<%= method.arguments.passable %>])
187
- end
188
- <% end -%>
5
+ created_with('<%= ActiveMocker::VERSION %>')
189
6
 
190
- end
7
+ <%= partials.modules_constants %>
8
+ <%= partials.class_methods %>
9
+ <%= partials.attributes %>
10
+ <%= partials.associations %>
11
+ <%= partials.scopes %>
12
+ <%= partials.defined_methods %>
13
+ end