module Blueprints
# A helper module that should be included in test framework. Adds methods build and demolish
module Helper
# Builds one or more blueprints by their names. You can pass names as symbols or strings. You can also pass additional
# options hash which will be available by calling options in blueprint block. Returns result of last blueprint block.
# @example build :apple and :orange blueprints.
# build :apple, :orange
# @example build :apple blueprint with additional options.
# build :apple => {:color => 'red'}
# @example passing options to several blueprints.
# build :pear, :apple => {:color => 'red'}, :orange => {:color => 'orange'}
# @param [Array] names Names of blueprints/namespaces to build. Pass Hash if you want to pass additional options.
# @return Return value of last blueprint
def build(*names)
Namespace.root.build(names, self, true)
end
# Same as #build except that you can use it to build same blueprint several times.
# @overload build!(*names)
# @param [Array] names Names of blueprints/namespaces to build. Pass Hash if you want to pass additional options.
# @return Return value of last blueprint
# @overload build!(count, *names)
# @param [Integer] count Times to build passed blueprint
# @param [Array] names Names of blueprints/namespaces to build. Pass Hash if you want to pass additional options.
# @return [Array] Array of return values of last blueprint, which is same size as count that you pass
def build!(*names)
if names.first.is_a?(Integer)
(0...names.shift).collect { build! *names }
else
Namespace.root.build(names, self, false)
end
end
# Returns attributes that are used to build blueprint.
# @example Setting and retrieving attributes.
# # In blueprint.rb file
# attributes(:name => 'apple').blueprint :apple do
# Fruit.build attributes
# end
#
# # In spec/test file
# build_attributes :apple #=> {:name => 'apple'}
# @param [Symbol, String] name Name of blueprint/namespace.
# @return [Hash] Normalized attributes of blueprint/namespace
def build_attributes(name)
blueprint = Namespace.root[name]
blueprint.build_parents(Namespace.root.eval_context)
Namespace.root.eval_context.normalize_hash(blueprint.attributes).tap { Namespace.root.eval_context.copy_instance_variables(self) }
end
# Returns Blueprint::Dependency object that can be used to define dependencies on other blueprints.
# @example Building :post blueprint with different user.
# build :post => {:user => d(:admin)}
# @example Building :post blueprint by first building :user_profile with :name => 'John', then taking value of @profile and calling +user+ on it.
# build :post => {:user => d(:user_profile, :profile, :name => 'John').user}
# @see Blueprints::Dependency#initialize Blueprints::Dependency for accepted arguments.
# @return [Blueprints::Dependency] Dependency object that can be passed as option when building blueprint/namespace.
def d(*args)
Dependency.new(*args)
end
# Demolishes built blueprints (by default simply calls destroy method on result of blueprint, but can be customized).
# @example Demolish :apple and :pear blueprints
# demolish :apple, :pear
# @param [Array] names Names of blueprints/namespaces to demolish.
def demolish(*names)
names.each { |name| Namespace.root[name].demolish(Namespace.root.eval_context) }
end
alias :build_blueprint :build
alias :build_blueprint! :build!
alias :blueprint_dependency :d
alias :blueprint_demolish :demolish
end
end