Class: FakerMaker::Factory

Inherits:
Object
  • Object
show all
Includes:
Auditable
Defined in:
lib/faker_maker/factory.rb

Overview

Factories construct instances of a fake

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Auditable

#audit

Constructor Details

#initialize(name, options = {}) ⇒ Factory

Create a new Factory object.

This method does not automatically register the factory,see FakerMaker#register_factory

Options:

  • :class_name - override the default class name that FakerMaker will generate. This is useful in the case of collisions with existing classes or keywords.

  • :parent - the parent factory from which this factory inherits attributes. Instances built by this factory will have a class which inherits from the parent’s class.

  • :naming - one of:

    • nil (default) - use field names as the method name and in JSON conversion

    • :json - use field names as the method name but convert when rendering JSON, e.g. hello_world becomes helloWorld

    • :json_capitalised (or :json_capitalized) - as :json but with the first letter captialised, e.g. hello_world becomes HelloWorld



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/faker_maker/factory.rb', line 28

def initialize( name, options = {} )
  assert_valid_options options
  @name = name.respond_to?(:to_sym) ? name.to_sym : name.to_s.underscore.to_sym
  @class_name = (options[:class] || @name).to_s.camelcase
  @naming_strategy = case options[:naming]
                     when :json
                       FakerMaker::Naming::JSON
                     when :json_capitalized, :json_capitalised
                       FakerMaker::Naming::JSONCapitalized
                     when nil
                       nil
                     else
                       raise FakerMaker::NoSuchAttributeNamingStrategy, options[:naming]
                     end
  @attributes = []
  @klass = nil
  @parent = options[:parent]
end

Instance Attribute Details

#chaos_selected_attributesObject (readonly)

Returns the value of attribute chaos_selected_attributes.



9
10
11
# File 'lib/faker_maker/factory.rb', line 9

def chaos_selected_attributes
  @chaos_selected_attributes
end

#class_nameObject (readonly)

Returns the value of attribute class_name.



9
10
11
# File 'lib/faker_maker/factory.rb', line 9

def class_name
  @class_name
end

#nameObject (readonly)

Returns the value of attribute name.



9
10
11
# File 'lib/faker_maker/factory.rb', line 9

def name
  @name
end

#parentObject (readonly)

Returns the value of attribute parent.



9
10
11
# File 'lib/faker_maker/factory.rb', line 9

def parent
  @parent
end

Instance Method Details

#as_json(*_args) ⇒ Object Also known as: to_h



104
105
106
# File 'lib/faker_maker/factory.rb', line 104

def as_json(*_args)
  build.as_json
end

#assembleObject

Construct a Class object which will become the parent type of objects built by this factory.

The Class object will be created and the attributes added to it. The returned value is a Ruby Class which can be instantiated.



90
91
92
93
94
95
96
97
98
# File 'lib/faker_maker/factory.rb', line 90

def assemble
  if @klass.nil?
    @klass = Class.new parent_class
    FakerMaker::Factory.const_set @class_name, @klass
    attach_attributes_to_class
    attach_json_overrides_to_class
  end
  @klass
end

#attach_attribute(attribute) ⇒ Object

Attach a FakerMaker::Attribute to this Factory



57
58
59
# File 'lib/faker_maker/factory.rb', line 57

def attach_attribute( attribute )
  @attributes << attribute
end

#attribute_namesArray

Returns a transformed list of attribute names from the ‘attributes` array. For each item in the array:

  • If the item is a Hash, recursively transforms its keys and values, replacing keys with their ‘name` and applying the same transformation to values.

  • Otherwise, replaces the item with its ‘name`.

Returns:

  • (Array)

    An array (possibly nested) of attribute names, with hashes’ keys replaced by their ‘name`.



139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/faker_maker/factory.rb', line 139

def attribute_names
  transform = lambda do |arr|
    arr.map do |item|
      if item.is_a?(Hash)
        item.transform_keys(&:name).transform_values { |v| transform.call(v) }
      else
        item.name
      end
    end
  end
  transform.call(attributes)
end

#attributes(collection = [], include_embeddings: true) ⇒ Array

Returns a collection of attributes for the factory, optionally including embedded factory attributes.

If the factory has a parent, its attributes are merged in. Attributes without embedded factories are added directly. If ‘include_embeddings` is true, attributes with embedded factories are added as hashes mapping the attribute to the flattened attributes of its embedded factories. If false, only the attribute itself is added.

Parameters:

  • collection (Array) (defaults to: [])

    an optional array of attributes to start with (default: empty array)

  • include_embeddings (Boolean) (defaults to: true)

    whether to include attributes from embedded factories (default: true)

Returns:

  • (Array)

    the collection of attributes, possibly including embedded factory attributes as hashes



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/faker_maker/factory.rb', line 162

def attributes( collection = [], include_embeddings: true )
  collection |= FakerMaker[parent].attributes( collection ) if parent?
  collection |= @attributes.reject { |attr| attr.embedded_factories.any? }

  # if there is an embedded factory(-ies) and we are including the embedded factory's
  # fields, we are going to return a hash
  if include_embeddings
    @attributes.select { |attr| attr.embedded_factories.any? }.each do |attr|
      collection << { attr => attr.embedded_factories.flat_map(&:attributes) }
    end
  # if there is an embedded factory(-ies) and we are not including the embedded factory's
  # fields, just add the attribute into the set of returned fields
  else
    collection |= @attributes.select { |attr| attr.embedded_factories.any? }
  end

  collection
end

#build(attributes: {}, chaos: false) {|instance| ... } ⇒ Object

Yields:



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/faker_maker/factory.rb', line 65

def build( attributes: {}, chaos: false )
  @instance = nil
  before_build if respond_to? :before_build

  # TODO: make this cleverer to handle nested attributes
  assert_only_known_attributes_for_override( attributes )

  assert_chaos_options chaos if chaos

  optional_attributes
  required_attributes

  populate_instance(instance, attributes, chaos:)
  yield instance if block_given?

  after_build if respond_to? :after_build
  audit(@instance) if FakerMaker.configuration.audit?
  instance
end

#find_attribute(name = '') ⇒ Object?

Finds and returns the first attribute matching the given name.

This method searches through the attributes (excluding embeddings) and returns the first attribute whose name, translation, or the result of applying the naming strategy to its name matches the provided ‘name`.

Parameters:

  • name (String) (defaults to: '')

    The name to search for among the attributes. Defaults to an empty string.

Returns:

  • (Object, nil)

    The first matching attribute object, or nil if no match is found.



188
189
190
191
192
# File 'lib/faker_maker/factory.rb', line 188

def find_attribute( name = '' )
  attributes(include_embeddings: false).filter do |a|
    [a.name, a.translation, @naming_strategy&.name(a.name)].include? name
  end.first
end

#instanceObject



61
62
63
# File 'lib/faker_maker/factory.rb', line 61

def instance
  @instance ||= instantiate
end

#json_key_mapObject



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/faker_maker/factory.rb', line 113

def json_key_map
  unless @json_key_map
    @json_key_map = {}.with_indifferent_access
    @json_key_map.merge!( FakerMaker[parent].json_key_map ) if parent?
    attributes(include_embeddings: false).each_with_object( @json_key_map ) do |attr, map|
      key = if attr.translation?
              attr.translation
            elsif @naming_strategy
              @naming_strategy.name(attr.name)
            else
              attr.name
            end

      map[attr.name] = key
    end
  end
  @json_key_map
end

#parent?Boolean

Returns:

  • (Boolean)


109
110
111
# File 'lib/faker_maker/factory.rb', line 109

def parent?
  !@parent.nil?
end

#parent_classObject

Get the Class of the parent for this factory



48
49
50
51
52
53
54
# File 'lib/faker_maker/factory.rb', line 48

def parent_class
  if @parent
    FakerMaker::Factory.const_get( FakerMaker[@parent].class_name )
  else
    Object
  end
end

#to_json(*_args) ⇒ Object



100
101
102
# File 'lib/faker_maker/factory.rb', line 100

def to_json(*_args)
  build.to_json
end