factory_girl 1.3.3 → 2.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|