active_mocker 1.8.4 → 2.0.0.beta1

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.
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