Class: Factory
- Inherits:
-
Object
- Object
- Factory
- Defined in:
- lib/factory_girl/aliases.rb,
lib/factory_girl/factory.rb,
lib/factory_girl/sequence.rb,
lib/factory_girl/attribute.rb,
lib/factory_girl/attribute_proxy.rb
Defined Under Namespace
Classes: Attribute, AttributeDefinitionError, AttributeProxy, ScopeDefinitionError, ScopeNotFoundError, Sequence
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
-
#factory_name ⇒ Object
readonly
Returns the value of attribute factory_name.
Class Method Summary collapse
-
.alias(pattern, replace) ⇒ Object
Defines a new alias for attributes.
-
.aliases_for(attribute) ⇒ Object
:nodoc:.
-
.attributes_for(name, attrs = {}) ⇒ Object
Generates and returns a Hash of attributes from this factory.
-
.build(name, attrs = {}) ⇒ Object
Generates and returns an instance from this factory.
-
.create(name, attrs = {}) ⇒ Object
Generates, saves, and returns an instance from this 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.
-
.find_definitions ⇒ Object
:nodoc:.
- .method_missing(chain, *args, &block) ⇒ Object
-
.next(sequence) ⇒ Object
Generates and returns the next value in a sequence.
-
.scope_attributes_for(name, scope, attrs = {}) ⇒ Object
:nodoc.
-
.sequence(name, &block) ⇒ Object
Defines a new sequence that can be used to generate unique values in a specific format.
Instance Method Summary collapse
-
#add_attribute(name, value = nil, &block) ⇒ Object
Adds an attribute that should be assigned on generated instances for this factory.
- #add_scope(name, attr = {}) ⇒ Object
-
#association(name, options = {}) ⇒ Object
Adds an attribute that builds an association.
-
#attributes_for(attrs = {}) ⇒ Object
:nodoc:.
-
#build(attrs = {}) ⇒ Object
:nodoc:.
-
#build_class ⇒ Object
:nodoc:.
-
#create(attrs = {}) ⇒ 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:.
-
#scope_attributes_for(scope, attrs = {}) ⇒ Object
:nodoc.
- #scope_names ⇒ Object
Constructor Details
#initialize(name, options = {}) ⇒ Factory
:nodoc:
47 48 49 50 51 52 53 |
# File 'lib/factory_girl/factory.rb', line 47 def initialize (name, = {}) #:nodoc: () @factory_name = factory_name_for(name) @options = @attributes = [] @scopes = {} end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &block) ⇒ Object
110 111 112 |
# File 'lib/factory_girl/factory.rb', line 110 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.
16 17 18 |
# File 'lib/factory_girl/factory.rb', line 16 def definition_file_paths @definition_file_paths end |
.factories ⇒ Object
:nodoc:
10 11 12 |
# File 'lib/factory_girl/factory.rb', line 10 def factories @factories end |
.sequences ⇒ Object
:nodoc:
19 20 21 |
# File 'lib/factory_girl/sequence.rb', line 19 def sequences @sequences end |
Instance Attribute Details
#factory_name ⇒ Object (readonly)
Returns the value of attribute factory_name.
22 23 24 |
# File 'lib/factory_girl/factory.rb', line 22 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 insert like String#sub.
Example:
Factory.alias /(.*)_confirmation/, '\1'
24 25 26 |
# File 'lib/factory_girl/aliases.rb', line 24 def self.alias (pattern, replace) self.aliases << [pattern, replace] end |
.aliases_for(attribute) ⇒ Object
:nodoc:
28 29 30 31 32 33 34 35 36 37 |
# File 'lib/factory_girl/aliases.rb', line 28 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, attrs = {}) ⇒ 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:
attrs: (Hash)
Attributes to overwrite for this set.
Returns:
A set of attributes that can be used to build an instance of the class
this factory generates. (Hash)
204 205 206 |
# File 'lib/factory_girl/factory.rb', line 204 def attributes_for (name, attrs = {}) factory_by_name(name).attributes_for(attrs) end |
.build(name, attrs = {}) ⇒ Object
Generates and returns an instance from this factory. Attributes can be individually overridden by passing in a Hash of attribute => value pairs.
Arguments:
attrs: (Hash)
See attributes_for
Returns:
An instance of the class this factory generates, with generated
attributes assigned.
222 223 224 |
# File 'lib/factory_girl/factory.rb', line 222 def build (name, attrs = {}) factory_by_name(name).build(attrs) end |
.create(name, attrs = {}) ⇒ Object
Generates, saves, and returns an instance from this factory. Attributes can be individually overridden by passing in a Hash of attribute => value pairs.
If the instance is not valid, an ActiveRecord::Invalid exception will be raised.
Arguments:
attrs: (Hash)
See attributes_for
Returns:
A saved instance of the class this factory generates, with generated
attributes assigned.
240 241 242 |
# File 'lib/factory_girl/factory.rb', line 240 def create (name, attrs = {}) factory_by_name(name).create(attrs) 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)
A unique name used to identify this factory.
options: (Hash)
class: the class that will be used when generating instances for this
factory. If not specified, the class will be guessed from the
factory name.
Yields:
The newly created factory (Factory)
37 38 39 40 41 |
# File 'lib/factory_girl/factory.rb', line 37 def self.define (name, = {}) instance = Factory.new(name, ) yield(instance) self.factories[instance.factory_name] = instance end |
.find_definitions ⇒ Object
:nodoc:
244 245 246 247 248 249 250 251 252 253 254 |
# File 'lib/factory_girl/factory.rb', line 244 def 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 |
.method_missing(chain, *args, &block) ⇒ Object
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/factory_girl/factory.rb', line 114 def self.method_missing(chain, *args, &block) name = args[0] chain = chain.to_s = args. factory = Factory.factories[name.to_sym] super(*args, &block) unless factory names = factory.scope_names.map(&:to_s) super(*args, &block) if names.empty? rs = true assigned = {} while rs rs = names.any? do |n| if chain.start_with?(n) assigned.merge!(factory.scope_attributes_for(n.to_sym)) chain.gsub!(/^#{n}_?/, "") !chain.empty? end end end raise ScopeNotFoundError, "Can't found scope with name '#{chain}'" unless chain.empty? Factory(name.to_sym, assigned.merge()) 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)
50 51 52 53 54 55 56 |
# File 'lib/factory_girl/sequence.rb', line 50 def self.next (sequence) unless self.sequences.key?(sequence) raise "No such sequence: #{sequence}" end self.sequences[sequence].next end |
.scope_attributes_for(name, scope, attrs = {}) ⇒ Object
:nodoc
208 209 210 |
# File 'lib/factory_girl/factory.rb', line 208 def scope_attributes_for(name, scope, attrs = {}) #:nodoc factory_by_name(name).scope_attributes_for(scope, attrs) 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" }
38 39 40 |
# File 'lib/factory_girl/sequence.rb', line 38 def self.sequence (name, &block) self.sequences[name] = Sequence.new(&block) 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::AttributeProxy will be yielded, allowing associations to be built using the correct build strategy.
Arguments:
name: (Symbol)
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.
73 74 75 76 77 78 79 80 81 |
# File 'lib/factory_girl/factory.rb', line 73 def add_attribute (name, value = nil, &block) attribute = Attribute.new(name, value, block) if attribute_defined?(attribute.name) raise AttributeDefinitionError, "Attribute already defined: #{name}" end @attributes << attribute end |
#add_scope(name, attr = {}) ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/factory_girl/factory.rb', line 83 def add_scope(name, attr = {}) if @scopes.has_key?(name.to_sym) raise ScopeDefinitionError, "Scope already defined: #{name}" end attrs = [] attr.each_pair do |k,v| attrs << Attribute.new(k, v, nil) end @scopes[name.to_sym] = attrs 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)
factory: (Symbol)
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.
161 162 163 164 165 166 167 |
# File 'lib/factory_girl/factory.rb', line 161 def association (name, = {}) name = name.to_sym = symbolize_keys() association_factory = [:factory] || name add_attribute(name) {|a| a.association(association_factory) } end |
#attributes_for(attrs = {}) ⇒ Object
:nodoc:
169 170 171 |
# File 'lib/factory_girl/factory.rb', line 169 def attributes_for (attrs = {}) #:nodoc: build_attributes_hash(attrs, :attributes_for) end |
#build(attrs = {}) ⇒ Object
:nodoc:
181 182 183 |
# File 'lib/factory_girl/factory.rb', line 181 def build (attrs = {}) #:nodoc: build_instance(attrs, :build) end |
#build_class ⇒ Object
:nodoc:
43 44 45 |
# File 'lib/factory_girl/factory.rb', line 43 def build_class #:nodoc: @build_class ||= class_for(@options[:class] || factory_name) end |
#create(attrs = {}) ⇒ Object
:nodoc:
185 186 187 188 189 |
# File 'lib/factory_girl/factory.rb', line 185 def create (attrs = {}) #:nodoc: instance = build_instance(attrs, :create) instance.save! instance end |
#scope_attributes_for(scope, attrs = {}) ⇒ Object
:nodoc
173 174 175 |
# File 'lib/factory_girl/factory.rb', line 173 def scope_attributes_for(scope, attrs = {}) #:nodoc build_attributes_hash(attrs, :attributes_for, @scopes[scope]) end |
#scope_names ⇒ Object
177 178 179 |
# File 'lib/factory_girl/factory.rb', line 177 def scope_names @scopes.keys end |