Module Mack::Data::Factory::ClassMethods
In: lib/mack-data_factory/data_factory.rb

Methods

association   create   field   scope_for  

Public Instance methods

Define an association rule for this field.

Example:

  class ItemFactory
    include Mack::Data::Factory
    ...
    association :owner_id, {:user => 'id'}, :random
  end

The above example states that for each item generated, its owner_id will come from user‘s id field. But which user? since the association rule is set to random, then the generator will pick random user.

Supported association rules:

  :first:: If there are 10 users, then the item will get associated with user #0.
  :last:: If there are 10 users, then the item will get associated with user #10.
  :random:: If there are 10 users, then the item will get associated with user #rand(10)
  :spread:: If there are 3 users, then the items' association will be spread out (i.e. 6 items will have id, sequentially, [0, 1, 2, 0, 1, 2])

Parameters:

  model_attrib_sym: the name of the field
  assoc_map: the association map

[Source]

     # File lib/mack-data_factory/data_factory.rb, line 194
194:         def association(model_attrib_sym, assoc_map, assoc_rule = :spread)
195:           field(model_attrib_sym, {:default => {:df_assoc_map => assoc_map}, :assoc => assoc_rule})
196:         end

Run the factory to produce n number of objects.

Example:

  class CarFactory
    include Mack::Data::Factory
    field(:name, :default => "honda") do |def_value, rules, index|
      "#{def_value} #{['civic', 'accord', 'pilot'].randomize[0]}"
    end
  end

  CarFactory.create(100) #=> will produce 100 cars whose name is "honda xxx" where xxx is a random item from ['civic', 'accord', 'pilot']

Scoping:

In some instances, you may want different settings in the factory for different test scope. You can achieve this by doing the following:

    class UserFactory
        include Mack::Data::Factory

        field :username, :default => "planters", :length => 25, :content => :alpha
        field :password, :default => "roastedPeanuts", :immutable => true

        scope_for(:long_username) do
            field :username, :default => "planters", :length => 128, :content => :alpha
        end
    end

The above example defined a scoping for "long_username", which you can use by calling:

  UserFactory.create(100, :long_username)

When a scope is defined and called, the field defined in the block will overwrite the default field listing in that class. Scopes in the factory is independent to each other, so one scope cannot affect the others.

Parameters:

  num:  how many objects to produce
  scope:  run the factory in a named scope.  By default the factory will be run in _default_ scope

[Source]

     # File lib/mack-data_factory/data_factory.rb, line 75
 75:         def create(num, scope = :default)
 76:           factory_name = self.name.underscore
 77:           
 78:           # retrieve the model name from the factory class. 
 79:           model_name = factory_name.gsub('_factory', '')
 80:           
 81:           # if user is running custom scope, then merge the fields 
 82:           # defined for that scope with the default one, before we run the factory
 83:           scoped_fields = field_manager.scopes[scope]
 84:           fields = field_manager.scopes[:default].merge(scoped_fields)
 85:           
 86:           ret_arr = []
 87:           
 88:           Mack::Data::RegistryMap.reset!
 89:           num.times do |i|
 90:             #puts "Creating #{model_name} ##{i+1}"
 91:             obj = model_name.camelcase.constantize.new
 92:             
 93:             fields.each_pair do |k, v|
 94:               field_name = k.to_s
 95:               field_value = v.get_value(i)
 96:               assert_method(obj, "#{field_name}=", "#{model_name.camelcase} doesn't have #{field_name}= method!") do
 97:                 obj.send("#{field_name}=", field_value)
 98:               end
 99:             end
100:             
101:             assert_method(obj, "save", "#{model_name.camelcase} doesn't have save method.  Data will not be saved!") do
102:               obj.save
103:             end
104:             
105:             ret_arr << obj
106:           end
107:           Mack::Data::RegistryMap.reset!
108:           
109:           return ret_arr[0] if ret_arr.size == 1
110:           return ret_arr
111:         end

Define a field for the factory class, and set the name of the field, any options for the field, and optionally specify a block that serves as the custom content generator.

The options can be categorized into the following:

  • default value (e.g. :default_value => "foo")
  • whether it‘s immutable or not (e.g. :immutable => true, and by default it‘s false)
  • the field‘s content type (e.g. :content => :alpha)
  • and the rules on how to generate the content (rules are contextually dependent on the content type).

Example:

  class UserFactory
    include Mack::Data::Factory
    field :full_name, :content => :name
    field :created_at, :content => :time, :start_time => 2.days.ago, :end_time => 1.day.from_now
  end

The following are all the supported content types and its rules:

Strings and Numbers

  • :alpha —> alphabets. rules: [:length, :min_length, :max_length]
  • :alphanumeric —> alphabets and number. rules: same as :alpha
  • :numeric —> numbers [optional, because if the field‘s default value is number, its content type will automatically set to numeric)

Time and Money

  • :time —> generate random time object. rules: [:start_time, :end_time]. It will generate random time between the given start and end time if available, otherwise it‘ll generate random time between ‘now’ and 1 day from ‘now‘
  • :money —> generate random amount of money. rules: [:min, :max]. It will generate random money amount (of BigDecimal type) between the given min and max amount.

Internet related content

  • :email —> generate random email address
  • :username —> generate random username
  • :domain —> generate random domain name

Name related info

  • :firstname —> generate first name
  • :lastname —> generate last name
  • :name —> generate full name

Address related info

  • :city —> generate city name
  • :streetname —> generate street name
  • :state —> generate state. rules: [:country —> :us or :uk, :abbr —> true if you want a abbreviated state name (us only)]
  • :zipcode —> generate zipcode. rules: [:country —> :us or :uk]
  • :phone —> generate phone number

Company info

  • :company —> generate company name. rules: [:include_bs —> include sales tag line] example: field, :content => :company, :include_bs => true could generate something like:
        Fadel-Larkin
        monetize cross-media experiences
    

Parameters:

 model_attrib_sym: the name of the field
 options: the options for the field.
 block: the optional custom content generator

[Source]

     # File lib/mack-data_factory/data_factory.rb, line 166
166:         def field(model_attrib_sym, options = {}, &block)
167:           field_manager.add(scope, model_attrib_sym, options, &block)
168:         end

Define a scope in the factory. Any field defined in a scope will overwrite its sibling in the default scope.

Parameters:

  tag: name of the scope

[Source]

     # File lib/mack-data_factory/data_factory.rb, line 205
205:         def scope_for(tag)
206:           set_scope(tag)
207:           yield
208:           set_scope(:default)
209:         end

[Validate]