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