/
proxy.rb
132 lines (113 loc) · 3.25 KB
/
proxy.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
require "active_support/core_ext/hash/except"
require "factory_girl/proxy/build"
require "factory_girl/proxy/create"
require "factory_girl/proxy/attributes_for"
require "factory_girl/proxy/stub"
module FactoryGirl
class Proxy #:nodoc:
def initialize(klass, callbacks = [])
@callbacks = process_callbacks(callbacks)
@proxy = ObjectWrapper.new(klass, self)
end
delegate :set, :to => :@proxy
def run_callbacks(name)
if @callbacks[name]
@callbacks[name].each do |callback|
callback.run(result_instance, @proxy.anonymous_instance)
end
end
end
# Generates an association using the current build strategy.
#
# Arguments:
# name: (Symbol)
# The name of the factory that should be used to generate this
# association.
# attributes: (Hash)
# A hash of attributes that should be overridden for this association.
#
# Returns:
# The generated association for the current build strategy. Note that
# associations are not generated for the attributes_for strategy. Returns
# nil in this case.
#
# Example:
#
# factory :user do
# # ...
# end
#
# factory :post do
# # ...
# author { |post| post.association(:user, :name => 'Joe') }
# end
#
# # Builds (but doesn't save) a Post and a User
# FactoryGirl.build(:post)
#
# # Builds and saves a User, builds a Post, assigns the User to the
# # author association, and saves the Post.
# FactoryGirl.create(:post)
#
def association(name, overrides = {})
end
def result(to_create)
raise NotImplementedError, "Strategies must return a result"
end
def self.ensure_strategy_exists!(strategy)
unless Proxy.const_defined? strategy.to_s.camelize
raise ArgumentError, "Unknown strategy: #{strategy}"
end
end
private
def process_callbacks(callbacks)
callbacks.inject({}) do |result, callback|
result[callback.name] ||= []
result[callback.name] << callback
result
end
end
def result_instance
@proxy.object
end
def result_hash
@proxy.to_hash
end
class ObjectWrapper
def initialize(klass, proxy)
@klass = klass
@proxy = proxy
@assigned_attributes = []
@evaluator = AnonymousEvaluator.new
@evaluator.evaluator.send(:define_method, :association) { |*args|
proxy.association(*args)
}
end
delegate :set, :attributes, :to => :@evaluator
def to_hash
attributes.inject({}) do |result, attribute|
result[attribute] = get(attribute)
result
end
end
def object
@object ||= @klass.new
assign_object_attributes
@object
end
def anonymous_instance
@anonymous_instance ||= @evaluator.evaluator.new
end
private
def assign_object_attributes
(attributes - @assigned_attributes).each do |attribute|
@assigned_attributes << attribute
@object.send("#{attribute}=", get(attribute))
end
end
def get(attribute)
anonymous_instance.send(attribute)
end
end
end
end