active_mocker 2.1.3 → 2.2.0
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/CHANGELOG.md +13 -0
- data/README.md +5 -0
- data/lib/active_mocker.rb +7 -6
- data/lib/active_mocker/config.rb +6 -8
- data/lib/active_mocker/deprecated_components/mock_abilities.rb +6 -10
- data/lib/active_mocker/deprecated_components/rspec.rb +2 -1
- data/lib/active_mocker/display_errors.rb +3 -2
- data/lib/active_mocker/error_object.rb +13 -13
- data/lib/active_mocker/file_path_to_ruby_class.rb +2 -3
- data/lib/active_mocker/file_writer.rb +125 -0
- data/lib/active_mocker/generate.rb +56 -71
- data/lib/active_mocker/hash_new_style.rb +2 -1
- data/lib/active_mocker/loaded_mocks.rb +9 -11
- data/lib/active_mocker/mock.rb +28 -26
- data/lib/active_mocker/mock/alias_attribute.rb +19 -0
- data/lib/active_mocker/mock/association.rb +2 -1
- data/lib/active_mocker/mock/base.rb +22 -20
- data/lib/active_mocker/mock/belongs_to.rb +1 -1
- data/lib/active_mocker/mock/collection.rb +6 -6
- data/lib/active_mocker/mock/do_nothing_active_record_methods.rb +4 -7
- data/lib/active_mocker/mock/exceptions.rb +1 -4
- data/lib/active_mocker/mock/has_and_belongs_to_many.rb +2 -1
- data/lib/active_mocker/mock/has_many.rb +6 -7
- data/lib/active_mocker/mock/has_one.rb +2 -2
- data/lib/active_mocker/mock/hash_process.rb +2 -2
- data/lib/active_mocker/mock/mock_relation.rb +1 -0
- data/lib/active_mocker/mock/object_inspect.rb +2 -2
- data/lib/active_mocker/mock/queries.rb +12 -16
- data/lib/active_mocker/mock/records.rb +3 -3
- data/lib/active_mocker/mock/relation.rb +5 -5
- data/lib/active_mocker/mock/single_relation.rb +2 -4
- data/lib/active_mocker/mock/template_methods.rb +3 -5
- data/lib/active_mocker/mock_creator.rb +78 -22
- data/lib/active_mocker/mock_template.erb +1 -0
- data/lib/active_mocker/mock_template/_recreate_class_method_calls.erb +12 -0
- data/lib/active_mocker/null_progress.rb +2 -2
- data/lib/active_mocker/parent_class.rb +4 -2
- data/lib/active_mocker/progress.rb +6 -8
- data/lib/active_mocker/public_methods.rb +3 -2
- data/lib/active_mocker/railtie.rb +3 -3
- data/lib/active_mocker/rspec.rb +2 -1
- data/lib/active_mocker/rspec_helper.rb +4 -3
- data/lib/active_mocker/task.rake +9 -10
- data/lib/active_mocker/template_creator.rb +5 -5
- data/lib/active_mocker/version.rb +2 -1
- metadata +25 -8
@@ -1,11 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module ActiveMocker
|
2
3
|
class HasOne < SingleRelation
|
3
4
|
attr_reader :item
|
4
5
|
|
5
6
|
def initialize(item, child_self:, foreign_key:)
|
6
|
-
item.send(:write_attribute, foreign_key, item.try(:id))
|
7
|
+
item.send(:write_attribute, foreign_key, item.try(:id)) unless item.try(:id).nil?
|
7
8
|
super
|
8
9
|
end
|
9
|
-
|
10
10
|
end
|
11
11
|
end
|
@@ -1,13 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module ActiveMocker
|
2
3
|
module Queries
|
3
|
-
|
4
4
|
class Find
|
5
|
-
|
6
5
|
def initialize(record)
|
7
6
|
@record = record
|
8
7
|
end
|
9
8
|
|
10
|
-
def is_of(conditions={})
|
9
|
+
def is_of(conditions = {})
|
11
10
|
conditions.all? do |col, match|
|
12
11
|
if match.is_a? Enumerable
|
13
12
|
any_match(col, match)
|
@@ -26,17 +25,15 @@ module ActiveMocker
|
|
26
25
|
def compare(col, match)
|
27
26
|
@record.send(col) == match
|
28
27
|
end
|
29
|
-
|
30
28
|
end
|
31
29
|
|
32
30
|
class WhereNotChain
|
33
|
-
|
34
31
|
def initialize(collection, parent_class)
|
35
32
|
@collection = collection
|
36
33
|
@parent_class = parent_class
|
37
34
|
end
|
38
35
|
|
39
|
-
def not(conditions={})
|
36
|
+
def not(conditions = {})
|
40
37
|
@parent_class.call(@collection.reject do |record|
|
41
38
|
Find.new(record).is_of(conditions)
|
42
39
|
end)
|
@@ -60,16 +57,16 @@ module ActiveMocker
|
|
60
57
|
#
|
61
58
|
# Post.limit(100).delete_all
|
62
59
|
# # => ActiveMocker::Error: delete_all doesn't support limit scope
|
63
|
-
def delete_all(conditions=nil)
|
60
|
+
def delete_all(conditions = nil)
|
64
61
|
raise ActiveMocker::Error.new("delete_all doesn't support limit scope") if from_limit?
|
65
62
|
if conditions.nil?
|
66
63
|
to_a.map(&:delete)
|
67
64
|
return to_a.clear
|
68
65
|
end
|
69
|
-
where(conditions).map
|
66
|
+
where(conditions).map(&:delete).count
|
70
67
|
end
|
71
68
|
|
72
|
-
|
69
|
+
alias destroy_all delete_all
|
73
70
|
|
74
71
|
# Returns a new relation, which is the result of filtering the current relation
|
75
72
|
# according to the conditions in the arguments.
|
@@ -113,7 +110,7 @@ module ActiveMocker
|
|
113
110
|
# User.where.not(name: "Jon")
|
114
111
|
#
|
115
112
|
# See WhereChain for more details on #not.
|
116
|
-
def where(conditions=nil)
|
113
|
+
def where(conditions = nil)
|
117
114
|
return WhereNotChain.new(all, method(:__new_relation__)) if conditions.nil?
|
118
115
|
__new_relation__(to_a.select do |record|
|
119
116
|
Find.new(record).is_of(conditions)
|
@@ -131,7 +128,7 @@ module ActiveMocker
|
|
131
128
|
#
|
132
129
|
# <tt>ActiveMocker::RecordNotFound</tt> will be raised if one or more ids are not found.
|
133
130
|
def find(ids)
|
134
|
-
raise RecordNotFound.new("Couldn't find #{
|
131
|
+
raise RecordNotFound.new("Couldn't find #{name} without an ID") if ids.nil?
|
135
132
|
results = [*ids].map do |id|
|
136
133
|
find_by!(id: id.to_i)
|
137
134
|
end
|
@@ -200,10 +197,10 @@ module ActiveMocker
|
|
200
197
|
|
201
198
|
# Like <tt>find_by</tt>, except that if no record is found, raises
|
202
199
|
# an <tt>ActiveMocker::RecordNotFound</tt> error.
|
203
|
-
def find_by!(conditions={})
|
200
|
+
def find_by!(conditions = {})
|
204
201
|
result = find_by(conditions)
|
205
202
|
if result.nil?
|
206
|
-
raise RecordNotFound.new("Couldn't find #{
|
203
|
+
raise RecordNotFound.new("Couldn't find #{name} with '#{conditions.keys.first}'=#{conditions.values.first}")
|
207
204
|
end
|
208
205
|
result
|
209
206
|
end
|
@@ -234,7 +231,7 @@ module ActiveMocker
|
|
234
231
|
find_by(attributes) || create(attributes, &block)
|
235
232
|
end
|
236
233
|
|
237
|
-
|
234
|
+
alias find_or_create_by! find_or_create_by
|
238
235
|
|
239
236
|
# Like <tt>find_or_create_by</tt>, but calls <tt>new</tt> instead of <tt>create</tt>.
|
240
237
|
def find_or_initialize_by(attributes, &block)
|
@@ -354,10 +351,9 @@ module ActiveMocker
|
|
354
351
|
end
|
355
352
|
|
356
353
|
def __new_relation__(collection)
|
357
|
-
duped =
|
354
|
+
duped = dup
|
358
355
|
duped.collection = collection
|
359
356
|
duped
|
360
357
|
end
|
361
|
-
|
362
358
|
end
|
363
359
|
end
|
@@ -1,6 +1,6 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module ActiveMocker
|
2
3
|
class Records
|
3
|
-
|
4
4
|
extend Forwardable
|
5
5
|
def_delegators :records, :<<, :count, :length, :to_a
|
6
6
|
|
@@ -16,7 +16,7 @@ module ActiveMocker
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def delete(record)
|
19
|
-
raise RecordNotFound,
|
19
|
+
raise RecordNotFound, "Record has not been created." unless records.delete(record)
|
20
20
|
end
|
21
21
|
|
22
22
|
def exists?(record)
|
@@ -61,4 +61,4 @@ module ActiveMocker
|
|
61
61
|
record
|
62
62
|
end
|
63
63
|
end
|
64
|
-
end
|
64
|
+
end
|
@@ -1,16 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module ActiveMocker
|
2
3
|
class Relation < Collection
|
3
4
|
include Queries
|
4
5
|
|
5
|
-
def initialize(collection=[])
|
6
|
+
def initialize(collection = [])
|
6
7
|
super
|
7
8
|
@from_limit = false
|
8
9
|
end
|
9
10
|
|
10
11
|
def inspect
|
11
12
|
entries = to_a.take(11).map!(&:inspect)
|
12
|
-
entries[10] =
|
13
|
-
"#<#{self.class.name} [#{entries.join(
|
13
|
+
entries[10] = "..." if entries.size == 11
|
14
|
+
"#<#{self.class.name} [#{entries.join(", ")}]>"
|
14
15
|
end
|
15
16
|
|
16
17
|
def from_limit?
|
@@ -22,6 +23,5 @@ module ActiveMocker
|
|
22
23
|
def set_from_limit
|
23
24
|
@from_limit = true
|
24
25
|
end
|
25
|
-
|
26
26
|
end
|
27
|
-
end
|
27
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module ActiveMocker
|
2
3
|
class SingleRelation
|
3
|
-
|
4
4
|
attr_reader :item
|
5
5
|
|
6
6
|
def initialize(item, child_self:, foreign_key:)
|
@@ -9,7 +9,7 @@ module ActiveMocker
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def assign_associations(child_self, item)
|
12
|
-
[*item.class._find_associations_by_class(child_self.class.send(
|
12
|
+
[*item.class._find_associations_by_class(child_self.class.send("mocked_class"))].each do |_type, relations|
|
13
13
|
relations.each do |relation|
|
14
14
|
if item.send(relation).class <= Collection
|
15
15
|
item.send(relation) << child_self
|
@@ -19,7 +19,5 @@ module ActiveMocker
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
22
|
-
|
23
22
|
end
|
24
23
|
end
|
25
|
-
|
@@ -1,12 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module ActiveMocker
|
2
3
|
module TemplateMethods
|
3
|
-
|
4
4
|
def self.included(base)
|
5
5
|
base.extend(ClassMethods)
|
6
6
|
end
|
7
7
|
|
8
8
|
module ClassMethods
|
9
|
-
|
10
9
|
def attributes
|
11
10
|
HashWithIndifferentAccess.new({})
|
12
11
|
end
|
@@ -24,7 +23,7 @@ module ActiveMocker
|
|
24
23
|
end
|
25
24
|
|
26
25
|
def mocked_class
|
27
|
-
|
26
|
+
""
|
28
27
|
end
|
29
28
|
|
30
29
|
def attribute_names
|
@@ -32,9 +31,8 @@ module ActiveMocker
|
|
32
31
|
end
|
33
32
|
|
34
33
|
def primary_key
|
35
|
-
|
34
|
+
""
|
36
35
|
end
|
37
|
-
|
38
36
|
end
|
39
37
|
end
|
40
38
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module ActiveMocker
|
2
3
|
class MockCreator
|
3
4
|
def initialize(file:,
|
@@ -8,6 +9,7 @@ module ActiveMocker
|
|
8
9
|
enabled_partials: nil,
|
9
10
|
klasses_to_be_mocked:,
|
10
11
|
mock_append_name:,
|
12
|
+
active_record_model:,
|
11
13
|
active_record_base_klass: ActiveRecord::Base)
|
12
14
|
@file = file
|
13
15
|
@file_out = file_out
|
@@ -18,6 +20,7 @@ module ActiveMocker
|
|
18
20
|
@klasses_to_be_mocked = klasses_to_be_mocked
|
19
21
|
@active_record_base_klass = active_record_base_klass
|
20
22
|
@mock_append_name = mock_append_name
|
23
|
+
@active_record_model = active_record_model
|
21
24
|
@errors = []
|
22
25
|
@completed = false
|
23
26
|
end
|
@@ -61,14 +64,15 @@ module ActiveMocker
|
|
61
64
|
# -- Defaults -- #
|
62
65
|
def template_creator_default(file_out)
|
63
66
|
TemplateCreator.new(file_out: file_out,
|
64
|
-
erb_template: File.new(File.join(File.dirname(__FILE__), "mock_template.erb"),
|
67
|
+
erb_template: File.new(File.join(File.dirname(__FILE__), "mock_template.erb"), "r"),
|
65
68
|
binding: binding,
|
66
|
-
post_process:
|
67
|
-
ruby_code = DissociatedIntrospection::RubyCode.build_from_source(str,
|
69
|
+
post_process: lambda do |str|
|
70
|
+
ruby_code = DissociatedIntrospection::RubyCode.build_from_source(str,
|
71
|
+
parse_with_comments: true)
|
68
72
|
DissociatedIntrospection::WrapInModules.new(ruby_code: ruby_code)
|
69
73
|
.call(modules: nested_modules)
|
70
74
|
.source_from_ast.gsub(/end\n/, "end\n\n")
|
71
|
-
|
75
|
+
end)
|
72
76
|
end
|
73
77
|
|
74
78
|
def class_introspector_default
|
@@ -77,7 +81,15 @@ module ActiveMocker
|
|
77
81
|
|
78
82
|
class << self
|
79
83
|
def enabled_partials_default
|
80
|
-
[
|
84
|
+
[
|
85
|
+
:modules_constants,
|
86
|
+
:class_methods,
|
87
|
+
:attributes,
|
88
|
+
:scopes,
|
89
|
+
:recreate_class_method_calls,
|
90
|
+
:defined_methods,
|
91
|
+
:associations,
|
92
|
+
]
|
81
93
|
end
|
82
94
|
|
83
95
|
public :enabled_partials_default
|
@@ -99,11 +111,18 @@ module ActiveMocker
|
|
99
111
|
OpenStruct.new(enabled_partials.each_with_object({}) do |p, hash|
|
100
112
|
begin
|
101
113
|
file = File.new(File.join(File.dirname(__FILE__), "mock_template/_#{p}.erb"))
|
102
|
-
|
103
|
-
hash[p] = ERB.new(file.read, nil,
|
114
|
+
extend("ActiveMocker::MockCreator::#{p.to_s.camelize}".constantize)
|
115
|
+
hash[p] = ERB.new(file.read, nil, "-", "_sub#{p}").result(binding)
|
104
116
|
rescue => e
|
105
|
-
errors << ErrorObject.new(class_name:
|
106
|
-
|
117
|
+
errors << ErrorObject.new(class_name: class_name,
|
118
|
+
original_error: e, type: :generation,
|
119
|
+
level: :error,
|
120
|
+
message: e.message)
|
121
|
+
errors << ErrorObject.new(class_name: class_name,
|
122
|
+
original_error: e,
|
123
|
+
type: :erb,
|
124
|
+
level: :debug,
|
125
|
+
message: "Erb template: #{p} failed.\n#{file.path}")
|
107
126
|
raise e
|
108
127
|
end
|
109
128
|
end)
|
@@ -119,12 +138,10 @@ module ActiveMocker
|
|
119
138
|
end
|
120
139
|
end
|
121
140
|
|
122
|
-
|
123
|
-
@parent_class
|
124
|
-
end
|
141
|
+
attr_reader :parent_class, :active_record_model
|
125
142
|
|
126
143
|
def primary_key
|
127
|
-
@primary_key ||= ActiveRecordSchemaScrapper::Attribute.new(name:
|
144
|
+
@primary_key ||= ActiveRecordSchemaScrapper::Attribute.new(name: "id", type: :integer)
|
128
145
|
end
|
129
146
|
|
130
147
|
module ModulesConstants
|
@@ -139,7 +156,7 @@ module ActiveMocker
|
|
139
156
|
@modules ||= begin
|
140
157
|
{
|
141
158
|
included: get_module_by_reference(:included_modules),
|
142
|
-
extended: get_module_by_reference(:extended_modules)
|
159
|
+
extended: get_module_by_reference(:extended_modules),
|
143
160
|
}
|
144
161
|
end
|
145
162
|
end
|
@@ -147,7 +164,28 @@ module ActiveMocker
|
|
147
164
|
private
|
148
165
|
|
149
166
|
def get_module_by_reference(type)
|
150
|
-
reject_local_const(class_introspector.public_send(type)).map(&:referenced_name)
|
167
|
+
isolated_module_names = reject_local_const(class_introspector.public_send(type)).map(&:referenced_name)
|
168
|
+
real_module_names = get_real_module(type).map(&:name).compact
|
169
|
+
isolated_module_names.map do |isolated_name|
|
170
|
+
real_name = real_module_names.detect do |rmn|
|
171
|
+
real_parts = rmn.split("::")
|
172
|
+
total_parts_count = active_record_model.name.split("::").count + isolated_name.split("::").count
|
173
|
+
[
|
174
|
+
real_parts.include?(active_record_model.name),
|
175
|
+
real_parts.include?(isolated_name),
|
176
|
+
(total_parts_count == real_parts.count)
|
177
|
+
].all?
|
178
|
+
end
|
179
|
+
real_name ? real_name : isolated_name
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def get_real_module(type)
|
184
|
+
if type == :extended_modules
|
185
|
+
active_record_model.singleton_class.included_modules
|
186
|
+
else
|
187
|
+
active_record_model.included_modules
|
188
|
+
end
|
151
189
|
end
|
152
190
|
|
153
191
|
def reject_local_const(source)
|
@@ -161,9 +199,7 @@ module ActiveMocker
|
|
161
199
|
def attributes
|
162
200
|
@attribute ||= begin
|
163
201
|
a = schema_scrapper.attributes.to_a
|
164
|
-
unless a.any? { |aa| aa.name == "id" }
|
165
|
-
a << primary_key
|
166
|
-
end
|
202
|
+
a << primary_key unless a.any? { |aa| aa.name == "id" }
|
167
203
|
a
|
168
204
|
end
|
169
205
|
end
|
@@ -180,7 +216,7 @@ module ActiveMocker
|
|
180
216
|
|
181
217
|
def types_hash
|
182
218
|
attributes.each_with_object(HashNewStyle.new) do |attr, types|
|
183
|
-
types[attr.name] =
|
219
|
+
types[attr.name] = attr.type.to_s
|
184
220
|
end.inspect
|
185
221
|
end
|
186
222
|
|
@@ -199,7 +235,7 @@ module ActiveMocker
|
|
199
235
|
end
|
200
236
|
|
201
237
|
def attribute_names
|
202
|
-
attributes.map
|
238
|
+
attributes.map(&:name)
|
203
239
|
end
|
204
240
|
|
205
241
|
def abstract_class
|
@@ -226,8 +262,26 @@ module ActiveMocker
|
|
226
262
|
end
|
227
263
|
end
|
228
264
|
|
229
|
-
|
265
|
+
AliasAttributeMethod = Struct.new(:new_name, :old_name)
|
266
|
+
module RecreateClassMethodCalls
|
267
|
+
def class_method_calls
|
268
|
+
@class_method_calls ||= class_introspector
|
269
|
+
.class_macros
|
270
|
+
.select { |h| h.keys.first == :alias_attribute }
|
271
|
+
.map do |h|
|
272
|
+
a = h.values.first.first
|
273
|
+
AliasAttributeMethod.new(a[0].to_s, a[1].to_s)
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
def attribute_aliases
|
278
|
+
class_method_calls.each_with_object({}) do |alias_attr, hash|
|
279
|
+
hash[alias_attr.new_name] = alias_attr.old_name
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
230
283
|
|
284
|
+
module DefinedMethods
|
231
285
|
def instance_methods
|
232
286
|
class_introspector
|
233
287
|
.get_class
|
@@ -247,7 +301,9 @@ module ActiveMocker
|
|
247
301
|
private
|
248
302
|
|
249
303
|
def create_method(m, type)
|
250
|
-
Method.new(m,
|
304
|
+
Method.new(m,
|
305
|
+
ReverseParameters.new(class_introspector.get_class.send(type, m).parameters,
|
306
|
+
blocks_as_values: true))
|
251
307
|
end
|
252
308
|
end
|
253
309
|
|