lib/rom/factory/dsl.rb in rom-factory-0.4.0 vs lib/rom/factory/dsl.rb in rom-factory-0.5.0
- old
+ new
@@ -1,15 +1,15 @@
require 'faker'
require 'dry/core/inflector'
require 'rom/factory/builder'
-require 'rom/factory/attributes/regular'
-require 'rom/factory/attributes/callable'
-require 'rom/factory/attributes/sequence'
+require 'rom/factory/attribute_registry'
+require 'rom/factory/attributes'
module ROM
module Factory
+ # @api private
def self.fake(type, *args)
api = Faker.const_get(Dry::Core::Inflector.classify(type.to_s))
meth, *rest = args
if meth.is_a?(Symbol)
@@ -17,78 +17,141 @@
else
api.public_send(type, *args)
end
end
+ # Factory builder DSL
+ #
+ # @api public
class DSL < BasicObject
- attr_reader :_name, :_relation, :_schema, :_factories, :_valid_names
+ define_method(:rand, ::Kernel.instance_method(:rand))
- def initialize(name, schema: {}, relation:, factories:, &block)
+ attr_reader :_name, :_relation, :_attributes, :_factories, :_valid_names
+
+ # @api private
+ def initialize(name, attributes: AttributeRegistry.new, relation:, factories:)
@_name = name
@_relation = relation
@_factories = factories
- @_schema = schema.dup
+ @_attributes = attributes.dup
@_valid_names = _relation.schema.attributes.map(&:name)
yield(self)
end
+ # @api private
def call
- ::ROM::Factory::Builder.new(_schema, _relation)
+ ::ROM::Factory::Builder.new(_attributes, _relation)
end
+ # Delegate to a builder and persist a struct
+ #
+ # @param [Symbol] The name of the registered builder
+ #
+ # @api public
def create(name, *args)
_factories[name, *args]
end
+ # Create a sequence attribute
+ #
+ # @param [Symbol] name The attribute name
+ #
+ # @api private
def sequence(meth, &block)
if _valid_names.include?(meth)
define_sequence(meth, block)
end
end
+ # Set timestamp attributes
+ #
+ # @api public
def timestamps
created_at { ::Time.now }
updated_at { ::Time.now }
end
+ # Create a fake value using Faker gem
+ #
+ # @overload fake(type)
+ # @example
+ # f.email { fake(:name) }
+ #
+ # @param [Symbol] type The value type to generate
+ #
+ # @overload fake(api, type)
+ # @example
+ # f.email { fake(:internet, :email) }
+ #
+ # @param [Symbol] api The faker API identifier ie. :internet, :product etc.
+ # @param [Symbol] type The value type to generate
+ #
+ # @overload fake(api, type, *args)
+ # @example
+ # f.email { fake(:number, :between, 10, 100) }
+ #
+ # @param [Symbol] api The faker API identifier ie. :internet, :product etc.
+ # @param [Symbol] type The value type to generate
+ # @param [Array] args Additional arguments
+ #
+ # @see https://github.com/stympy/faker/tree/master/doc
+ #
+ # @api public
def fake(*args)
::ROM::Factory.fake(*args)
end
- def association(name)
+ # Create an association attribute
+ #
+ # @example belongs-to
+ # f.association(:group)
+ #
+ # @example has-many
+ # f.association(:posts, count: 2)
+ #
+ # @param [Symbol] name The name of the configured association
+ # @param [Hash] options Additional options
+ # @option options [Integer] count Number of objects to generate (has-many only)
+ #
+ # @api public
+ def association(name, options = {})
assoc = _relation.associations[name]
- other = _relation.__registry__[assoc.target]
+ builder = -> { _factories.for_relation(assoc.target) }
- fk = _relation.foreign_key(other)
- pk = other.primary_key
-
- block = -> { create(name)[pk] }
-
- _schema[fk] = attributes::Callable.new(self, block)
+ _attributes << attributes::Association.new(assoc, builder, options)
end
private
+ # @api private
def method_missing(meth, *args, &block)
if _valid_names.include?(meth)
define_attr(meth, *args, &block)
else
super
end
end
+ # @api private
+ def respond_to_missing?(method_name, include_private = false)
+ _valid_names.include?(meth) || super
+ end
+
+ # @api private
def define_sequence(name, block)
- _schema[name] = attributes::Callable.new(self, attributes::Sequence.new(&block))
+ _attributes << attributes::Callable.new(name, self, &attributes::Sequence.new(name, &block))
end
+ # @api private
def define_attr(name, *args, &block)
if block
- _schema[name] = attributes::Callable.new(self, block)
+ _attributes << attributes::Callable.new(name, self, &block)
else
- _schema[name] = attributes::Regular.new(*args)
+ _attributes << attributes::Value.new(name, *args)
end
end
+ # @api private
def attributes
::ROM::Factory::Attributes
end
end
end