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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/README.md +4 -2
- data/lib/active_mocker.rb +9 -25
- data/lib/active_mocker/config.rb +26 -46
- data/lib/active_mocker/generate.rb +115 -110
- data/lib/active_mocker/loaded_mocks.rb +76 -65
- data/lib/active_mocker/mock/base.rb +283 -287
- data/lib/active_mocker/mock/has_many.rb +2 -0
- data/lib/active_mocker/mock_creator.rb +262 -0
- data/lib/active_mocker/mock_template.erb +9 -186
- data/lib/active_mocker/mock_template/_associations.erb +82 -0
- data/lib/active_mocker/mock_template/_attributes.erb +11 -0
- data/lib/active_mocker/mock_template/_class_methods.erb +41 -0
- data/lib/active_mocker/mock_template/_defined_methods.erb +10 -0
- data/lib/active_mocker/mock_template/_modules_constants.erb +10 -0
- data/lib/active_mocker/mock_template/_scopes.erb +23 -0
- data/lib/active_mocker/null_progress.rb +9 -0
- data/lib/active_mocker/output_capture.rb +32 -0
- data/lib/active_mocker/parent_class.rb +64 -0
- data/lib/active_mocker/progress.rb +13 -0
- data/lib/active_mocker/public_methods.rb +15 -23
- data/lib/active_mocker/rspec.rb +16 -0
- data/lib/active_mocker/rspec_helper.rb +10 -8
- data/lib/active_mocker/task.rake +6 -1
- data/lib/active_mocker/template_creator.rb +22 -0
- data/lib/active_mocker/version.rb +1 -1
- metadata +43 -103
- data/lib/active_mocker/active_record.rb +0 -74
- data/lib/active_mocker/active_record/field.rb +0 -39
- data/lib/active_mocker/active_record/relationships.rb +0 -110
- data/lib/active_mocker/active_record/schema.rb +0 -81
- data/lib/active_mocker/active_record/scope.rb +0 -22
- data/lib/active_mocker/active_record/table.rb +0 -26
- data/lib/active_mocker/active_record/unknown_class_method.rb +0 -17
- data/lib/active_mocker/active_record/unknown_module.rb +0 -30
- data/lib/active_mocker/db_to_ruby_type.rb +0 -29
- data/lib/active_mocker/file_reader.rb +0 -11
- data/lib/active_mocker/model_reader.rb +0 -191
- data/lib/active_mocker/model_schema.rb +0 -285
- data/lib/active_mocker/model_schema/assemble.rb +0 -220
- data/lib/active_mocker/reparameterize.rb +0 -41
- data/lib/active_mocker/ruby_parse.rb +0 -68
- data/lib/active_mocker/schema_reader.rb +0 -30
- 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 +
|
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
|
-
|
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
|
-
|
7
|
+
<%= partials.modules_constants %>
|
8
|
+
<%= partials.class_methods %>
|
9
|
+
<%= partials.attributes %>
|
10
|
+
<%= partials.associations %>
|
11
|
+
<%= partials.scopes %>
|
12
|
+
<%= partials.defined_methods %>
|
13
|
+
end
|