factory_girl 1.3.3 → 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.
- data/README.rdoc +68 -60
- data/features/support/test.db +0 -0
- data/lib/factory_girl.rb +6 -12
- data/lib/factory_girl/aliases.rb +2 -31
- data/lib/factory_girl/attribute.rb +1 -1
- data/lib/factory_girl/attribute/association.rb +1 -1
- data/lib/factory_girl/attribute/callback.rb +1 -1
- data/lib/factory_girl/attribute/dynamic.rb +3 -3
- data/lib/factory_girl/attribute/static.rb +1 -1
- data/lib/factory_girl/definition_proxy.rb +180 -0
- data/lib/factory_girl/deprecated.rb +18 -0
- data/lib/factory_girl/factory.rb +120 -355
- data/lib/factory_girl/find_definitions.rb +25 -0
- data/lib/factory_girl/proxy.rb +4 -6
- data/lib/factory_girl/proxy/attributes_for.rb +1 -1
- data/lib/factory_girl/proxy/build.rb +7 -5
- data/lib/factory_girl/proxy/create.rb +1 -1
- data/lib/factory_girl/proxy/stub.rb +11 -5
- data/lib/factory_girl/rails2.rb +1 -1
- data/lib/factory_girl/sequence.rb +5 -40
- data/lib/factory_girl/step_definitions.rb +7 -7
- data/lib/factory_girl/syntax.rb +7 -7
- data/lib/factory_girl/syntax/blueprint.rb +5 -4
- data/lib/factory_girl/syntax/default.rb +31 -0
- data/lib/factory_girl/syntax/generate.rb +13 -8
- data/lib/factory_girl/syntax/make.rb +8 -6
- data/lib/factory_girl/syntax/sham.rb +11 -8
- data/lib/factory_girl/syntax/vintage.rb +196 -0
- data/lib/factory_girl/version.rb +4 -0
- data/spec/acceptance/acceptance_spec.rb +43 -60
- data/spec/acceptance/syntax/blueprint_spec.rb +1 -5
- data/spec/acceptance/syntax/generate_spec.rb +1 -4
- data/spec/acceptance/syntax/make_spec.rb +1 -4
- data/spec/acceptance/syntax/sham_spec.rb +9 -7
- data/spec/acceptance/syntax/vintage_spec.rb +184 -0
- data/spec/factory_girl/aliases_spec.rb +5 -5
- data/spec/factory_girl/attribute/association_spec.rb +3 -3
- data/spec/factory_girl/attribute/callback_spec.rb +3 -3
- data/spec/factory_girl/attribute/dynamic_spec.rb +20 -9
- data/spec/factory_girl/attribute/static_spec.rb +5 -5
- data/spec/factory_girl/attribute_spec.rb +5 -5
- data/spec/factory_girl/definition_proxy_spec.rb +138 -0
- data/spec/factory_girl/deprecated_spec.rb +66 -0
- data/spec/factory_girl/factory_spec.rb +283 -566
- data/spec/factory_girl/find_definitions_spec.rb +89 -0
- data/spec/factory_girl/proxy/attributes_for_spec.rb +2 -2
- data/spec/factory_girl/proxy/build_spec.rb +17 -12
- data/spec/factory_girl/proxy/create_spec.rb +17 -12
- data/spec/factory_girl/proxy/stub_spec.rb +6 -5
- data/spec/factory_girl/proxy_spec.rb +2 -2
- data/spec/factory_girl/sequence_spec.rb +15 -38
- data/spec/spec_helper.rb +4 -0
- metadata +28 -11
@@ -0,0 +1,18 @@
|
|
1
|
+
module Factory
|
2
|
+
def self.method_missing(name, *args, &block)
|
3
|
+
if FactoryGirl.respond_to?(name)
|
4
|
+
$stderr.puts "DEPRECATION WARNING: Change Factory.#{name} to FactoryGirl.#{name}"
|
5
|
+
FactoryGirl.send(name, *args, &block)
|
6
|
+
else
|
7
|
+
super(name, *args, &block)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.const_missing(name)
|
12
|
+
if FactoryGirl.const_defined?(name)
|
13
|
+
FactoryGirl.const_get(name)
|
14
|
+
else
|
15
|
+
super(name)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/factory_girl/factory.rb
CHANGED
@@ -1,412 +1,177 @@
|
|
1
|
-
|
2
|
-
undef :id if Factory.instance_methods.include?('id')
|
3
|
-
undef :type if Factory.instance_methods.include?('type')
|
4
|
-
|
5
|
-
# Raised when a factory is defined that attempts to instantiate itself.
|
6
|
-
class AssociationDefinitionError < RuntimeError
|
7
|
-
end
|
8
|
-
|
9
|
-
# Raised when a callback is defined that has an invalid name
|
10
|
-
class InvalidCallbackNameError < RuntimeError
|
11
|
-
end
|
12
|
-
|
13
|
-
# Raised when a factory is defined with the same name as a previously-defined factory.
|
14
|
-
class DuplicateDefinitionError < RuntimeError
|
15
|
-
end
|
16
|
-
|
1
|
+
module FactoryGirl
|
17
2
|
class << self
|
18
3
|
attr_accessor :factories #:nodoc:
|
19
|
-
|
20
|
-
# An Array of strings specifying locations that should be searched for
|
21
|
-
# factory definitions. By default, factory_girl will attempt to require
|
22
|
-
# "factories," "test/factories," and "spec/factories." Only the first
|
23
|
-
# existing file will be loaded.
|
24
|
-
attr_accessor :definition_file_paths
|
25
4
|
end
|
26
5
|
|
27
6
|
self.factories = {}
|
28
|
-
self.definition_file_paths = %w(factories test/factories spec/factories)
|
29
7
|
|
30
|
-
|
31
|
-
|
8
|
+
def self.factory_by_name(name)
|
9
|
+
factories[name.to_sym] or raise ArgumentError.new("No such factory: #{name.to_s}")
|
10
|
+
end
|
32
11
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
# Arguments:
|
37
|
-
# * name: +Symbol+ or +String+
|
38
|
-
# A unique name used to identify this factory.
|
39
|
-
# * options: +Hash+
|
40
|
-
#
|
41
|
-
# Options:
|
42
|
-
# * class: +Symbol+, +Class+, or +String+
|
43
|
-
# The class that will be used when generating instances for this factory. If not specified, the class will be guessed from the factory name.
|
44
|
-
# * parent: +Symbol+
|
45
|
-
# The parent factory. If specified, the attributes from the parent
|
46
|
-
# factory will be copied to the current one with an ability to override
|
47
|
-
# them.
|
48
|
-
# * default_strategy: +Symbol+
|
49
|
-
# The strategy that will be used by the Factory shortcut method.
|
50
|
-
# Defaults to :create.
|
51
|
-
#
|
52
|
-
# Yields: +Factory+
|
53
|
-
# The newly created factory.
|
54
|
-
def self.define (name, options = {})
|
55
|
-
instance = Factory.new(name, options)
|
56
|
-
yield(instance)
|
57
|
-
if parent = options.delete(:parent)
|
58
|
-
instance.inherit_from(Factory.factory_by_name(parent))
|
59
|
-
end
|
60
|
-
if self.factories[instance.factory_name]
|
12
|
+
def self.register_factory(factory, options = {})
|
13
|
+
name = options[:as] || factory.name
|
14
|
+
if self.factories[name]
|
61
15
|
raise DuplicateDefinitionError, "Factory already defined: #{name}"
|
62
16
|
end
|
63
|
-
self.factories[
|
64
|
-
end
|
65
|
-
|
66
|
-
def class_name #:nodoc:
|
67
|
-
@options[:class] || factory_name
|
17
|
+
self.factories[name] = factory
|
68
18
|
end
|
69
19
|
|
70
|
-
|
71
|
-
|
20
|
+
# Raised when a factory is defined that attempts to instantiate itself.
|
21
|
+
class AssociationDefinitionError < RuntimeError
|
72
22
|
end
|
73
23
|
|
74
|
-
|
75
|
-
|
24
|
+
# Raised when a callback is defined that has an invalid name
|
25
|
+
class InvalidCallbackNameError < RuntimeError
|
76
26
|
end
|
77
27
|
|
78
|
-
|
79
|
-
|
80
|
-
@factory_name = factory_name_for(name)
|
81
|
-
@options = options
|
82
|
-
@attributes = []
|
28
|
+
# Raised when a factory is defined with the same name as a previously-defined factory.
|
29
|
+
class DuplicateDefinitionError < RuntimeError
|
83
30
|
end
|
84
31
|
|
85
|
-
|
86
|
-
|
87
|
-
|
32
|
+
class Factory
|
33
|
+
attr_reader :name #:nodoc:
|
34
|
+
attr_reader :attributes #:nodoc:
|
88
35
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
new_attributes << attribute.clone
|
93
|
-
end
|
36
|
+
def factory_name
|
37
|
+
puts "WARNING: factory.factory_name is deprecated. Use factory.name instead."
|
38
|
+
name
|
94
39
|
end
|
95
|
-
@attributes.unshift *new_attributes
|
96
|
-
end
|
97
40
|
|
98
|
-
|
99
|
-
|
100
|
-
#
|
101
|
-
# This method should be called with either a value or block, but not both. If
|
102
|
-
# called with a block, the attribute will be generated "lazily," whenever an
|
103
|
-
# instance is generated. Lazy attribute blocks will not be called if that
|
104
|
-
# attribute is overridden for a specific instance.
|
105
|
-
#
|
106
|
-
# When defining lazy attributes, an instance of Factory::Proxy will
|
107
|
-
# be yielded, allowing associations to be built using the correct build
|
108
|
-
# strategy.
|
109
|
-
#
|
110
|
-
# Arguments:
|
111
|
-
# * name: +Symbol+ or +String+
|
112
|
-
# The name of this attribute. This will be assigned using :"#{name}=" for
|
113
|
-
# generated instances.
|
114
|
-
# * value: +Object+
|
115
|
-
# If no block is given, this value will be used for this attribute.
|
116
|
-
def add_attribute (name, value = nil, &block)
|
117
|
-
if block_given?
|
118
|
-
if value
|
119
|
-
raise AttributeDefinitionError, "Both value and block given"
|
120
|
-
else
|
121
|
-
attribute = Attribute::Dynamic.new(name, block)
|
122
|
-
end
|
123
|
-
else
|
124
|
-
attribute = Attribute::Static.new(name, value)
|
41
|
+
def class_name #:nodoc:
|
42
|
+
@options[:class] || name
|
125
43
|
end
|
126
44
|
|
127
|
-
|
128
|
-
|
45
|
+
def build_class #:nodoc:
|
46
|
+
@build_class ||= class_for(class_name)
|
129
47
|
end
|
130
48
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
# Calls add_attribute using the missing method name as the name of the
|
135
|
-
# attribute, so that:
|
136
|
-
#
|
137
|
-
# Factory.define :user do |f|
|
138
|
-
# f.name 'Billy Idol'
|
139
|
-
# end
|
140
|
-
#
|
141
|
-
# and:
|
142
|
-
#
|
143
|
-
# Factory.define :user do |f|
|
144
|
-
# f.add_attribute :name, 'Billy Idol'
|
145
|
-
# end
|
146
|
-
#
|
147
|
-
# are equivilent.
|
148
|
-
def method_missing (name, *args, &block)
|
149
|
-
add_attribute(name, *args, &block)
|
150
|
-
end
|
151
|
-
|
152
|
-
# Adds an attribute that builds an association. The associated instance will
|
153
|
-
# be built using the same build strategy as the parent instance.
|
154
|
-
#
|
155
|
-
# Example:
|
156
|
-
# Factory.define :user do |f|
|
157
|
-
# f.name 'Joey'
|
158
|
-
# end
|
159
|
-
#
|
160
|
-
# Factory.define :post do |f|
|
161
|
-
# f.association :author, :factory => :user
|
162
|
-
# end
|
163
|
-
#
|
164
|
-
# Arguments:
|
165
|
-
# * name: +Symbol+
|
166
|
-
# The name of this attribute.
|
167
|
-
# * options: +Hash+
|
168
|
-
#
|
169
|
-
# Options:
|
170
|
-
# * factory: +Symbol+ or +String+
|
171
|
-
# The name of the factory to use when building the associated instance.
|
172
|
-
# If no name is given, the name of the attribute is assumed to be the
|
173
|
-
# name of the factory. For example, a "user" association will by
|
174
|
-
# default use the "user" factory.
|
175
|
-
def association (name, options = {})
|
176
|
-
factory_name = options.delete(:factory) || name
|
177
|
-
if factory_name_for(factory_name) == self.factory_name
|
178
|
-
raise AssociationDefinitionError, "Self-referencing association '#{name}' in factory '#{self.factory_name}'"
|
49
|
+
def default_strategy #:nodoc:
|
50
|
+
@options[:default_strategy] || :create
|
179
51
|
end
|
180
|
-
@attributes << Attribute::Association.new(name, factory_name, options)
|
181
|
-
end
|
182
|
-
|
183
|
-
# Adds an attribute that will have unique values generated by a sequence with
|
184
|
-
# a specified format.
|
185
|
-
#
|
186
|
-
# The result of:
|
187
|
-
# Factory.define :user do |f|
|
188
|
-
# f.sequence(:email) { |n| "person#{n}@example.com" }
|
189
|
-
# end
|
190
|
-
#
|
191
|
-
# Is equal to:
|
192
|
-
# Factory.sequence(:email) { |n| "person#{n}@example.com" }
|
193
|
-
#
|
194
|
-
# Factory.define :user do |f|
|
195
|
-
# f.email { Factory.next(:email) }
|
196
|
-
# end
|
197
|
-
#
|
198
|
-
# Except that no globally available sequence will be defined.
|
199
|
-
def sequence (name, &block)
|
200
|
-
s = Sequence.new(&block)
|
201
|
-
add_attribute(name) { s.next }
|
202
|
-
end
|
203
|
-
|
204
|
-
def after_build(&block)
|
205
|
-
callback(:after_build, &block)
|
206
|
-
end
|
207
52
|
|
208
|
-
|
209
|
-
|
210
|
-
|
53
|
+
def initialize(name, options = {}) #:nodoc:
|
54
|
+
assert_valid_options(options)
|
55
|
+
@name = factory_name_for(name)
|
56
|
+
@options = options
|
57
|
+
@attributes = []
|
58
|
+
end
|
211
59
|
|
212
|
-
|
213
|
-
|
214
|
-
|
60
|
+
def inherit_from(parent) #:nodoc:
|
61
|
+
@options[:class] ||= parent.class_name
|
62
|
+
@options[:default_strategy] ||= parent.default_strategy
|
215
63
|
|
216
|
-
|
217
|
-
|
218
|
-
|
64
|
+
new_attributes = []
|
65
|
+
parent.attributes.each do |attribute|
|
66
|
+
unless attribute_defined?(attribute.name)
|
67
|
+
new_attributes << attribute.clone
|
68
|
+
end
|
69
|
+
end
|
70
|
+
@attributes.unshift *new_attributes
|
219
71
|
end
|
220
|
-
@attributes << Attribute::Callback.new(name.to_sym, block)
|
221
|
-
end
|
222
72
|
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
# A set of attributes that can be used to build an instance of the class
|
235
|
-
# this factory generates.
|
236
|
-
def self.attributes_for (name, overrides = {})
|
237
|
-
factory_by_name(name).run(Proxy::AttributesFor, overrides)
|
238
|
-
end
|
73
|
+
def define_attribute(attribute)
|
74
|
+
name = attribute.name
|
75
|
+
# TODO: move these checks into Attribute
|
76
|
+
if attribute_defined?(name)
|
77
|
+
raise AttributeDefinitionError, "Attribute already defined: #{name}"
|
78
|
+
end
|
79
|
+
if attribute.respond_to?(:factory) && attribute.factory == self.name
|
80
|
+
raise AssociationDefinitionError, "Self-referencing association '#{name}' in factory '#{self.name}'"
|
81
|
+
end
|
82
|
+
@attributes << attribute
|
83
|
+
end
|
239
84
|
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
# * overrides: +Hash+
|
247
|
-
# Attributes to overwrite for this instance.
|
248
|
-
#
|
249
|
-
# Returns: +Object+
|
250
|
-
# An instance of the class this factory generates, with generated attributes
|
251
|
-
# assigned.
|
252
|
-
def self.build (name, overrides = {})
|
253
|
-
factory_by_name(name).run(Proxy::Build, overrides)
|
254
|
-
end
|
85
|
+
def add_callback(name, &block)
|
86
|
+
unless [:after_build, :after_create, :after_stub].include?(name.to_sym)
|
87
|
+
raise InvalidCallbackNameError, "#{name} is not a valid callback name. Valid callback names are :after_build, :after_create, and :after_stub"
|
88
|
+
end
|
89
|
+
@attributes << Attribute::Callback.new(name.to_sym, block)
|
90
|
+
end
|
255
91
|
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
#
|
269
|
-
# Returns: +Object+
|
270
|
-
# A saved instance of the class this factory generates, with generated
|
271
|
-
# attributes assigned.
|
272
|
-
def self.create (name, overrides = {})
|
273
|
-
factory_by_name(name).run(Proxy::Create, overrides)
|
274
|
-
end
|
92
|
+
def run (proxy_class, overrides) #:nodoc:
|
93
|
+
proxy = proxy_class.new(build_class)
|
94
|
+
overrides = symbolize_keys(overrides)
|
95
|
+
overrides.each {|attr, val| proxy.set(attr, val) }
|
96
|
+
passed_keys = overrides.keys.collect {|k| FactoryGirl.aliases_for(k) }.flatten
|
97
|
+
@attributes.each do |attribute|
|
98
|
+
unless passed_keys.include?(attribute.name)
|
99
|
+
attribute.add_to(proxy)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
proxy.result
|
103
|
+
end
|
275
104
|
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
#
|
280
|
-
# Arguments:
|
281
|
-
# * name: +Symbol+ or +String+
|
282
|
-
# The name of the factory that should be used.
|
283
|
-
# * overrides: +Hash+
|
284
|
-
# Attributes to overwrite for this instance.
|
285
|
-
#
|
286
|
-
# Returns: +Object+
|
287
|
-
# An object with generated attributes stubbed out.
|
288
|
-
def self.stub (name, overrides = {})
|
289
|
-
factory_by_name(name).run(Proxy::Stub, overrides)
|
290
|
-
end
|
105
|
+
def human_name(*args, &block)
|
106
|
+
name.to_s.gsub('_', ' ')
|
107
|
+
end
|
291
108
|
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
# Arguments:
|
296
|
-
# * name: +Symbol+ or +String+
|
297
|
-
# The name of the factory that should be used.
|
298
|
-
# * overrides: +Hash+
|
299
|
-
# Attributes to overwrite for this instance.
|
300
|
-
#
|
301
|
-
# Returns: +Object+
|
302
|
-
# The result of the default strategy.
|
303
|
-
def self.default_strategy (name, overrides = {})
|
304
|
-
self.send(factory_by_name(name).default_strategy, name, overrides)
|
305
|
-
end
|
109
|
+
def associations
|
110
|
+
attributes.select {|attribute| attribute.is_a?(Attribute::Association) }
|
111
|
+
end
|
306
112
|
|
307
|
-
|
308
|
-
definition_file_paths.each do |path|
|
309
|
-
full_path = File.expand_path(path)
|
310
|
-
require("#{full_path}.rb") if File.exists?("#{full_path}.rb")
|
113
|
+
private
|
311
114
|
|
312
|
-
|
313
|
-
|
314
|
-
|
115
|
+
def class_for (class_or_to_s)
|
116
|
+
if class_or_to_s.respond_to?(:to_sym)
|
117
|
+
class_name = variable_name_to_class_name(class_or_to_s)
|
118
|
+
class_name.split('::').inject(Object) do |object, string|
|
119
|
+
object.const_get(string)
|
315
120
|
end
|
121
|
+
else
|
122
|
+
class_or_to_s
|
316
123
|
end
|
317
124
|
end
|
318
|
-
end
|
319
125
|
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
@attributes.each do |attribute|
|
326
|
-
unless passed_keys.include?(attribute.name)
|
327
|
-
attribute.add_to(proxy)
|
126
|
+
def factory_name_for(class_or_to_s)
|
127
|
+
if class_or_to_s.respond_to?(:to_sym)
|
128
|
+
class_or_to_s.to_sym
|
129
|
+
else
|
130
|
+
class_name_to_variable_name(class_or_to_s).to_sym
|
328
131
|
end
|
329
132
|
end
|
330
|
-
proxy.result
|
331
|
-
end
|
332
133
|
|
333
|
-
|
334
|
-
|
335
|
-
end
|
336
|
-
|
337
|
-
def human_name(*args, &block)
|
338
|
-
if args.size == 0 && block.nil?
|
339
|
-
factory_name.to_s.gsub('_', ' ')
|
340
|
-
else
|
341
|
-
add_attribute(:human_name, *args, &block)
|
134
|
+
def attribute_defined? (name)
|
135
|
+
!@attributes.detect {|attr| attr.name == name && !attr.is_a?(Attribute::Callback) }.nil?
|
342
136
|
end
|
343
|
-
end
|
344
|
-
|
345
|
-
def associations
|
346
|
-
attributes.select {|attribute| attribute.is_a?(Attribute::Association) }
|
347
|
-
end
|
348
137
|
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
class_name = variable_name_to_class_name(class_or_to_s)
|
354
|
-
class_name.split('::').inject(Object) do |object, string|
|
355
|
-
object.const_get(string)
|
138
|
+
def assert_valid_options(options)
|
139
|
+
invalid_keys = options.keys - [:class, :parent, :default_strategy]
|
140
|
+
unless invalid_keys == []
|
141
|
+
raise ArgumentError, "Unknown arguments: #{invalid_keys.inspect}"
|
356
142
|
end
|
357
|
-
|
358
|
-
class_or_to_s
|
143
|
+
assert_valid_strategy(options[:default_strategy]) if options[:default_strategy]
|
359
144
|
end
|
360
|
-
end
|
361
145
|
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
class_name_to_variable_name(class_or_to_s).to_sym
|
146
|
+
def assert_valid_strategy(strategy)
|
147
|
+
unless Proxy.const_defined? variable_name_to_class_name(strategy)
|
148
|
+
raise ArgumentError, "Unknown strategy: #{strategy}"
|
149
|
+
end
|
367
150
|
end
|
368
|
-
end
|
369
151
|
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
raise ArgumentError, "Unknown arguments: #{invalid_keys.inspect}"
|
152
|
+
# Based on ActiveSupport's underscore inflector
|
153
|
+
def class_name_to_variable_name(name)
|
154
|
+
name.to_s.gsub(/::/, '/').
|
155
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
156
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
157
|
+
tr("-", "_").
|
158
|
+
downcase
|
378
159
|
end
|
379
|
-
assert_valid_strategy(options[:default_strategy]) if options[:default_strategy]
|
380
|
-
end
|
381
160
|
|
382
|
-
|
383
|
-
|
384
|
-
|
161
|
+
# Based on ActiveSupport's camelize inflector
|
162
|
+
def variable_name_to_class_name(name)
|
163
|
+
name.to_s.
|
164
|
+
gsub(/\/(.?)/) { "::#{$1.upcase}" }.
|
165
|
+
gsub(/(?:^|_)(.)/) { $1.upcase }
|
385
166
|
end
|
386
|
-
end
|
387
|
-
|
388
|
-
# Based on ActiveSupport's underscore inflector
|
389
|
-
def class_name_to_variable_name(name)
|
390
|
-
name.to_s.gsub(/::/, '/').
|
391
|
-
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
392
|
-
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
393
|
-
tr("-", "_").
|
394
|
-
downcase
|
395
|
-
end
|
396
167
|
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
# From ActiveSupport
|
405
|
-
def symbolize_keys(hash)
|
406
|
-
hash.inject({}) do |options, (key, value)|
|
407
|
-
options[(key.to_sym rescue key) || key] = value
|
408
|
-
options
|
168
|
+
# From ActiveSupport
|
169
|
+
def symbolize_keys(hash)
|
170
|
+
hash.inject({}) do |options, (key, value)|
|
171
|
+
options[(key.to_sym rescue key) || key] = value
|
172
|
+
options
|
173
|
+
end
|
409
174
|
end
|
410
|
-
end
|
411
175
|
|
176
|
+
end
|
412
177
|
end
|