Class: Factory
- Inherits:
-
Object
- Object
- Factory
- Defined in:
- lib/factory_girl/proxy.rb,
lib/factory_girl/syntax.rb,
lib/factory_girl/aliases.rb,
lib/factory_girl/factory.rb,
lib/factory_girl/sequence.rb,
lib/factory_girl/attribute.rb,
lib/factory_girl/proxy/stub.rb,
lib/factory_girl/proxy/build.rb,
lib/factory_girl/syntax/make.rb,
lib/factory_girl/syntax/sham.rb,
lib/factory_girl/proxy/create.rb,
lib/factory_girl/syntax/generate.rb,
lib/factory_girl/attribute/static.rb,
lib/factory_girl/syntax/blueprint.rb,
lib/factory_girl/attribute/dynamic.rb,
lib/factory_girl/attribute/callback.rb,
lib/factory_girl/proxy/attributes_for.rb,
lib/factory_girl/attribute/association.rb
Defined Under Namespace
Modules: Syntax Classes: AssociationDefinitionError, Attribute, AttributeDefinitionError, DuplicateDefinitionError, FileDefinitionError, InvalidCallbackNameError, Proxy, Sequence, SequenceAbuseError
Class Attribute Summary collapse
-
.aliases ⇒ Object
:nodoc:.
-
.definition_file_paths ⇒ Object
An Array of strings specifying locations that should be searched for factory definitions.
-
.factories ⇒ Object
:nodoc:.
-
.sequences ⇒ Object
:nodoc:.
Instance Attribute Summary collapse
-
#attributes ⇒ Object
readonly
:nodoc:.
-
#factory_name ⇒ Object
readonly
:nodoc:.
Class Method Summary collapse
-
.alias(pattern, replace) ⇒ Object
Defines a new alias for attributes.
-
.aliases_for(attribute) ⇒ Object
:nodoc:.
-
.attributes_for(name, overrides = {}) ⇒ Object
Generates and returns a Hash of attributes from this factory.
-
.build(name, overrides = {}) ⇒ Object
Generates and returns an instance from this factory.
-
.create(name, overrides = {}) ⇒ Object
Generates, saves, and returns an instance from this factory.
-
.default_strategy(name, overrides = {}) ⇒ Object
Executes the default strategy for the given factory.
-
.define(name, options = {}) {|instance| ... } ⇒ Object
Defines a new factory that can be used by the build strategies (create and build) to build new objects.
- .factory_by_name(name) ⇒ Object
-
.find_definitions ⇒ Object
:nodoc:.
-
.next(sequence) ⇒ Object
Generates and returns the next value in a sequence.
-
.sequence(name, &block) ⇒ Object
Defines a new sequence that can be used to generate unique values in a specific format.
-
.stub(name, overrides = {}) ⇒ Object
Generates and returns an object with all attributes from this factory stubbed out.
Instance Method Summary collapse
-
#add_attribute(name, value = nil, &block) ⇒ Object
Adds an attribute that should be assigned on generated instances for this factory.
- #after_build(&block) ⇒ Object
- #after_create(&block) ⇒ Object
- #after_stub(&block) ⇒ Object
-
#association(name, options = {}) ⇒ Object
Adds an attribute that builds an association.
- #associations ⇒ Object
-
#build_class ⇒ Object
:nodoc:.
- #callback(name, &block) ⇒ Object
-
#class_name ⇒ Object
:nodoc:.
-
#default_strategy ⇒ Object
:nodoc:.
- #human_name(*args, &block) ⇒ Object
-
#inherit_from(parent) ⇒ Object
:nodoc:.
-
#initialize(name, options = {}) ⇒ Factory
constructor
:nodoc:.
-
#method_missing(name, *args, &block) ⇒ Object
Calls add_attribute using the missing method name as the name of the attribute, so that:.
-
#paperclip(attr, file, *options) ⇒ Object
Add a file to a paperclip association Example Factory.define :fact do |f| f.paperclip :image, ‘path_to_image’, ‘image/jpeg’ end.
-
#run(proxy_class, overrides) ⇒ Object
:nodoc:.
-
#sequence(name, &block) ⇒ Object
Adds an attribute that will have unique values generated by a sequence with a specified format.
Constructor Details
#initialize(name, options = {}) ⇒ Factory
:nodoc:
81 82 83 84 85 86 |
# File 'lib/factory_girl/factory.rb', line 81 def initialize (name, = {}) #:nodoc: () @factory_name = factory_name_for(name) @options = @attributes = [] end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &block) ⇒ Object
147 148 149 |
# File 'lib/factory_girl/factory.rb', line 147 def method_missing (name, *args, &block) add_attribute(name, *args, &block) end |
Class Attribute Details
.aliases ⇒ Object
:nodoc:
4 5 6 |
# File 'lib/factory_girl/aliases.rb', line 4 def aliases @aliases end |
.definition_file_paths ⇒ Object
An Array of strings specifying locations that should be searched for factory definitions. By default, factory_girl will attempt to require “factories,” “test/factories,” and “spec/factories.” Only the first existing file will be loaded.
27 28 29 |
# File 'lib/factory_girl/factory.rb', line 27 def definition_file_paths @definition_file_paths end |
.factories ⇒ Object
:nodoc:
21 22 23 |
# File 'lib/factory_girl/factory.rb', line 21 def factories @factories end |
.sequences ⇒ Object
:nodoc:
24 25 26 |
# File 'lib/factory_girl/sequence.rb', line 24 def sequences @sequences end |
Instance Attribute Details
#attributes ⇒ Object (readonly)
:nodoc:
34 35 36 |
# File 'lib/factory_girl/factory.rb', line 34 def attributes @attributes end |
#factory_name ⇒ Object (readonly)
:nodoc:
33 34 35 |
# File 'lib/factory_girl/factory.rb', line 33 def factory_name @factory_name end |
Class Method Details
.alias(pattern, replace) ⇒ Object
Defines a new alias for attributes.
Arguments:
-
pattern:
Regexp
A pattern that will be matched against attributes when looking for aliases. Contents captured in the pattern can be used in the alias. -
replace:
String
The alias that results from the matched pattern. Captured strings can be substituded like with String#sub.
Example:
Factory.alias /(.*)_confirmation/, '\1'
factory_girl starts with aliases for foreign keys, so that a :user association can be overridden by a :user_id parameter:
Factory.define :post do |p|
p.association :user
end
# The user association will not be built in this example. The user_id
# will be used instead.
Factory(:post, :user_id => 1)
35 36 37 |
# File 'lib/factory_girl/aliases.rb', line 35 def self.alias (pattern, replace) self.aliases << [pattern, replace] end |
.aliases_for(attribute) ⇒ Object
:nodoc:
39 40 41 42 43 44 45 46 47 48 |
# File 'lib/factory_girl/aliases.rb', line 39 def self.aliases_for (attribute) #:nodoc: aliases.collect do |params| pattern, replace = *params if pattern.match(attribute.to_s) attribute.to_s.sub(pattern, replace).to_sym else nil end end.compact << attribute end |
.attributes_for(name, overrides = {}) ⇒ Object
Generates and returns a Hash of attributes from this factory. Attributes can be individually overridden by passing in a Hash of attribute => value pairs.
Arguments:
-
name:
Symbol
orString
The name of the factory that should be used. -
overrides:
Hash
Attributes to overwrite for this set.
Returns: Hash
A set of attributes that can be used to build an instance of the class this factory generates.
260 261 262 |
# File 'lib/factory_girl/factory.rb', line 260 def self.attributes_for (name, overrides = {}) factory_by_name(name).run(Proxy::AttributesFor, overrides) end |
.build(name, overrides = {}) ⇒ Object
Generates and returns an instance from this factory. Attributes can be individually overridden by passing in a Hash of attribute => value pairs.
Arguments:
-
name:
Symbol
orString
The name of the factory that should be used. -
overrides:
Hash
Attributes to overwrite for this instance.
Returns: Object
An instance of the class this factory generates, with generated attributes assigned.
276 277 278 |
# File 'lib/factory_girl/factory.rb', line 276 def self.build (name, overrides = {}) factory_by_name(name).run(Proxy::Build, overrides) end |
.create(name, overrides = {}) ⇒ Object
Generates, saves, and returns an instance from this factory. Attributes can be individually overridden by passing in a Hash of attribute => value pairs.
Instances are saved using the save!
method, so ActiveRecord models will raise ActiveRecord::RecordInvalid exceptions for invalid attribute sets.
Arguments:
-
name:
Symbol
orString
The name of the factory that should be used. -
overrides:
Hash
Attributes to overwrite for this instance.
Returns: Object
A saved instance of the class this factory generates, with generated attributes assigned.
296 297 298 |
# File 'lib/factory_girl/factory.rb', line 296 def self.create (name, overrides = {}) factory_by_name(name).run(Proxy::Create, overrides) end |
.default_strategy(name, overrides = {}) ⇒ Object
Executes the default strategy for the given factory. This is usually create, but it can be overridden for each factory.
Arguments:
-
name:
Symbol
orString
The name of the factory that should be used. -
overrides:
Hash
Attributes to overwrite for this instance.
Returns: Object
The result of the default strategy.
327 328 329 |
# File 'lib/factory_girl/factory.rb', line 327 def self.default_strategy (name, overrides = {}) self.send(factory_by_name(name).default_strategy, name, overrides) end |
.define(name, options = {}) {|instance| ... } ⇒ Object
Defines a new factory that can be used by the build strategies (create and build) to build new objects.
Arguments:
-
name:
Symbol
orString
A unique name used to identify this factory. -
options:
Hash
Options:
-
class:
Symbol
,Class
, orString
The class that will be used when generating instances for this factory. If not specified, the class will be guessed from the factory name. -
parent:
Symbol
The parent factory. If specified, the attributes from the parent factory will be copied to the current one with an ability to override them. -
default_strategy:
Symbol
The strategy that will be used by the Factory shortcut method. Defaults to :create.
Yields: Factory
The newly created factory.
57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/factory_girl/factory.rb', line 57 def self.define (name, = {}) instance = Factory.new(name, ) yield(instance) if parent = .delete(:parent) instance.inherit_from(Factory.factory_by_name(parent)) end if self.factories[instance.factory_name] raise DuplicateDefinitionError, "Factory already defined: #{name}" end self.factories[instance.factory_name] = instance end |
.factory_by_name(name) ⇒ Object
356 357 358 |
# File 'lib/factory_girl/factory.rb', line 356 def self.factory_by_name (name) factories[name.to_sym] or raise ArgumentError.new("No such factory: #{name.to_s}") end |
.find_definitions ⇒ Object
:nodoc:
331 332 333 334 335 336 337 338 339 340 341 |
# File 'lib/factory_girl/factory.rb', line 331 def self.find_definitions #:nodoc: definition_file_paths.each do |path| require("#{path}.rb") if File.exists?("#{path}.rb") if File.directory? path Dir[File.join(path, '*.rb')].each do |file| require file end end end end |
.next(sequence) ⇒ Object
Generates and returns the next value in a sequence.
Arguments:
name: (Symbol)
The name of the sequence that a value should be generated for.
Returns:
The next value in the sequence. (Object)
55 56 57 58 59 60 61 |
# File 'lib/factory_girl/sequence.rb', line 55 def self.next (sequence) unless self.sequences.key?(sequence) raise "No such sequence: #{sequence}" end self.sequences[sequence].next end |
.sequence(name, &block) ⇒ Object
Defines a new sequence that can be used to generate unique values in a specific format.
Arguments:
name: (Symbol)
A unique name for this sequence. This name will be referenced when
calling next to generate new values from this sequence.
block: (Proc)
The code to generate each value in the sequence. This block will be
called with a unique number each time a value in the sequence is to be
generated. The block should return the generated value for the
sequence.
Example:
Factory.sequence(:email) {|n| "somebody_#{n}@example.com" }
43 44 45 |
# File 'lib/factory_girl/sequence.rb', line 43 def self.sequence (name, &block) self.sequences[name] = Sequence.new(&block) end |
.stub(name, overrides = {}) ⇒ Object
Generates and returns an object with all attributes from this factory stubbed out. Attributes can be individually overridden by passing in a Hash of attribute => value pairs.
Arguments:
-
name:
Symbol
orString
The name of the factory that should be used. -
overrides:
Hash
Attributes to overwrite for this instance.
Returns: Object
An object with generated attributes stubbed out.
312 313 314 |
# File 'lib/factory_girl/factory.rb', line 312 def self.stub (name, overrides = {}) factory_by_name(name).run(Proxy::Stub, overrides) end |
Instance Method Details
#add_attribute(name, value = nil, &block) ⇒ Object
Adds an attribute that should be assigned on generated instances for this factory.
This method should be called with either a value or block, but not both. If called with a block, the attribute will be generated “lazily,” whenever an instance is generated. Lazy attribute blocks will not be called if that attribute is overriden for a specific instance.
When defining lazy attributes, an instance of Factory::Proxy will be yielded, allowing associations to be built using the correct build strategy.
Arguments:
-
name:
Symbol
orString
The name of this attribute. This will be assigned using :“#name=” for generated instances. -
value:
Object
If no block is given, this value will be used for this attribute.
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/factory_girl/factory.rb', line 115 def add_attribute (name, value = nil, &block) if block_given? if value raise AttributeDefinitionError, "Both value and block given" else attribute = Attribute::Dynamic.new(name, block) end else attribute = Attribute::Static.new(name, value) end if attribute_defined?(attribute.name) raise AttributeDefinitionError, "Attribute already defined: #{name}" end @attributes << attribute end |
#after_build(&block) ⇒ Object
228 229 230 |
# File 'lib/factory_girl/factory.rb', line 228 def after_build(&block) callback(:after_build, &block) end |
#after_create(&block) ⇒ Object
232 233 234 |
# File 'lib/factory_girl/factory.rb', line 232 def after_create(&block) callback(:after_create, &block) end |
#after_stub(&block) ⇒ Object
236 237 238 |
# File 'lib/factory_girl/factory.rb', line 236 def after_stub(&block) callback(:after_stub, &block) end |
#association(name, options = {}) ⇒ Object
Adds an attribute that builds an association. The associated instance will be built using the same build strategy as the parent instance.
Example:
Factory.define :user do |f|
f.name 'Joey'
end
Factory.define :post do |f|
f.association :author, :factory => :user
end
Arguments:
-
name:
Symbol
The name of this attribute. -
options:
Hash
Options:
-
factory:
Symbol
orString
The name of the factory to use when building the associated instance. If no name is given, the name of the attribute is assumed to be the name of the factory. For example, a "user" association will by default use the "user" factory.
174 175 176 177 178 179 180 |
# File 'lib/factory_girl/factory.rb', line 174 def association (name, = {}) factory_name = .delete(:factory) || name if factory_name_for(factory_name) == self.factory_name raise AssociationDefinitionError, "Self-referencing association '#{name}' in factory '#{self.factory_name}'" end @attributes << Attribute::Association.new(name, factory_name, ) end |
#associations ⇒ Object
368 369 370 |
# File 'lib/factory_girl/factory.rb', line 368 def associations attributes.select {|attribute| attribute.is_a?(Attribute::Association) } end |
#build_class ⇒ Object
:nodoc:
73 74 75 |
# File 'lib/factory_girl/factory.rb', line 73 def build_class #:nodoc: @build_class ||= class_for(class_name) end |
#callback(name, &block) ⇒ Object
240 241 242 243 244 245 |
# File 'lib/factory_girl/factory.rb', line 240 def callback(name, &block) unless [:after_build, :after_create, :after_stub].include?(name.to_sym) raise InvalidCallbackNameError, "#{name} is not a valid callback name. Valid callback names are :after_build, :after_create, and :after_stub" end @attributes << Attribute::Callback.new(name.to_sym, block) end |
#class_name ⇒ Object
:nodoc:
69 70 71 |
# File 'lib/factory_girl/factory.rb', line 69 def class_name #:nodoc: @options[:class] || factory_name end |
#default_strategy ⇒ Object
:nodoc:
77 78 79 |
# File 'lib/factory_girl/factory.rb', line 77 def default_strategy #:nodoc: @options[:default_strategy] || :create end |
#human_name(*args, &block) ⇒ Object
360 361 362 363 364 365 366 |
# File 'lib/factory_girl/factory.rb', line 360 def human_name(*args, &block) if args.size == 0 && block.nil? factory_name.to_s.gsub('_', ' ') else add_attribute(:human_name, *args, &block) end end |
#inherit_from(parent) ⇒ Object
:nodoc:
88 89 90 91 92 93 94 95 |
# File 'lib/factory_girl/factory.rb', line 88 def inherit_from(parent) #:nodoc: @options[:class] ||= parent.class_name parent.attributes.each do |attribute| unless attribute_defined?(attribute.name) @attributes << attribute.clone end end end |
#paperclip(attr, file, *options) ⇒ Object
Add a file to a paperclip association Example
Factory.define :fact do |f|
f.paperclip :image, 'path_to_image', 'image/jpeg'
end
Arguments:
-
attr:
Symbol
The name of the paperclip association. -
file:
String
A path to the file
Options:
-
content_type:
String
The content_type of the file -
binary:
Boolean+
whether it’s binary or not default is false
All options regarding to ActionController::TestUploadedFile
201 202 203 204 205 |
# File 'lib/factory_girl/factory.rb', line 201 def paperclip(attr, file, *) raise FileDefinitionError unless file file = ActionController::TestUploadedFile.new(file, *) add_attribute attr, file end |
#run(proxy_class, overrides) ⇒ Object
:nodoc:
343 344 345 346 347 348 349 350 351 352 353 354 |
# File 'lib/factory_girl/factory.rb', line 343 def run (proxy_class, overrides) #:nodoc: proxy = proxy_class.new(build_class) overrides = symbolize_keys(overrides) overrides.each {|attr, val| proxy.set(attr, val) } passed_keys = overrides.keys.collect {|k| Factory.aliases_for(k) }.flatten @attributes.each do |attribute| unless passed_keys.include?(attribute.name) attribute.add_to(proxy) end end proxy.result end |
#sequence(name, &block) ⇒ Object
Adds an attribute that will have unique values generated by a sequence with a specified format.
The result of:
Factory.define :user do |f|
f.sequence(:email) { |n| "person#{n}@example.com" }
end
Is equal to:
Factory.sequence(:email) { |n| "person#{n}@example.com" }
Factory.define :user do |f|
f.email { Factory.next(:email) }
end
Except that no globally available sequence will be defined.
223 224 225 226 |
# File 'lib/factory_girl/factory.rb', line 223 def sequence (name, &block) s = Sequence.new(&block) add_attribute(name) { s.next } end |