Class: Factrey::DSL
- Inherits:
-
Object
- Object
- Factrey::DSL
- Includes:
- Ref::ShorthandMethods
- Defined in:
- lib/factrey/dsl.rb
Overview
Blueprint DSL implementation.
Constant Summary collapse
- RESERVED_METHODS =
Methods reserved for DSL.
%i[ ref ext object_node computed_node let on args __send__ __method__ __id__ nil? is_a? to_s inspect object_id class instance_eval instance_variables initialize block_given? enum_for raise ].to_set.freeze
Instance Attribute Summary collapse
-
#ext ⇒ Object
readonly
The external object passed to blueprint.
Class Method Summary collapse
-
.add_type(type) ⇒ Object
Add a new type that will be available in this DSL.
-
.types ⇒ Hash{Symbol => Type}
The types defined in this DSL.
Instance Method Summary collapse
-
#args(*args, **kwargs) {|@ancestors.last.to_ref| ... } ⇒ Object
Add arguments to the current node.
-
#computed_node(name, value) ⇒ Object
Add a computed node to the blueprint.
-
#initialize(blueprint:, ext:) ⇒ DSL
constructor
A new instance of DSL.
-
#let(setter_name = nil, *args, **kwargs, &block) ⇒ Ref, Proxy
Define a computed node with name.
-
#object_node(name, type) {|ref| ... } ⇒ Ref
Add an object node to the blueprint.
-
#on(node_name = nil) ⇒ Ref, Proxy
Enter the node to configure arguments and child nodes.
Methods included from Ref::ShorthandMethods
Constructor Details
#initialize(blueprint:, ext:) ⇒ DSL
Returns a new instance of DSL.
21 22 23 24 25 |
# File 'lib/factrey/dsl.rb', line 21 def initialize(blueprint:, ext:) @blueprint = blueprint @ext = ext @ancestors = [] end |
Instance Attribute Details
#ext ⇒ Object (readonly)
Returns the external object passed to Factrey.blueprint.
30 31 32 |
# File 'lib/factrey/dsl.rb', line 30 def ext @ext end |
Class Method Details
.add_type(type) ⇒ Object
Add a new type that will be available in this DSL. This method defines a helper method with the same name as the type name. For example, if you have added the foo
type, you can declare an object node with #foo
.
add_type is called automatically when you use factory_bot-blueprint
gem.
151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/factrey/dsl.rb', line 151 def add_type(type) if RESERVED_METHODS.member? type.name raise ArgumentError, "Cannot use reserved method name '#{type.name}' for type name" end if types.member? type.name raise ArgumentError, "duplicate type definition: #{type.name}" if types[type.name] != type return end types[type.name] = type define_method(type.name) { |*args, **kwargs, &block| object_node(nil, type, *args, **kwargs, &block) } end |
.types ⇒ Hash{Symbol => Type}
Returns the types defined in this DSL.
130 131 132 |
# File 'lib/factrey/dsl.rb', line 130 def types @types ||= {} end |
Instance Method Details
#args(*args, **kwargs) {|@ancestors.last.to_ref| ... } ⇒ Object
Add arguments to the current node.
118 119 120 121 122 123 124 125 126 |
# File 'lib/factrey/dsl.rb', line 118 def args(*args, **kwargs) raise NameError, "cannot use args at toplevel" if @ancestors.empty? raise NameError, "cannot use args to computed nodes" if @ancestors.last.type == Blueprint::Type::COMPUTED @ancestors.last.args.concat(args) @ancestors.last.kwargs.update(kwargs) yield @ancestors.last.to_ref if block_given? @ancestors.last.to_ref end |
#computed_node(name, value) ⇒ Object
Add a computed node to the blueprint.
This method is usually not called directly. Use #let instead.
49 50 51 52 |
# File 'lib/factrey/dsl.rb', line 49 def computed_node(name, value) node = @blueprint.add_node(Blueprint::Node.computed(name, value, ancestors: @ancestors)) node.to_ref end |
#let(setter_name = nil, *args, **kwargs, &block) ⇒ Ref, Proxy
Define a computed node with name.
66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/factrey/dsl.rb', line 66 def let(setter_name = nil, *args, **kwargs, &block) return Proxy.new(self, __method__) unless setter_name if setter_name.end_with? "=" raise ArgumentError, "Wrong setter use" if args.size != 1 || !kwargs.empty? || block computed_node(setter_name[0..-2].to_sym, args[0]) else # `let.node_name(...)` is a shorthand for `let.node_name = node_name(...)` let(:"#{setter_name}=", __send__(setter_name, *args, **kwargs, &block)) end end |
#object_node(name, type) {|ref| ... } ⇒ Ref
Add an object node to the blueprint.
This method is usually not called directly. Use the shorthand method defined by add_type instead.
39 40 41 42 |
# File 'lib/factrey/dsl.rb', line 39 def object_node(name, type, ...) node = @blueprint.add_node(Blueprint::Node.new(name, type, ancestors: @ancestors)) on(node.name, ...) end |
#on(node_name = nil) ⇒ Ref, Proxy
Enter the node to configure arguments and child nodes.
94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/factrey/dsl.rb', line 94 def on(node_name = nil, ...) return Proxy.new(self, __method__) unless node_name node = @blueprint.resolve_node(node_name) raise ArgumentError, "unknown node: #{node_name}" unless node stashed_ancestors = @ancestors @ancestors = node.ancestors + [node] begin args(...) ensure @ancestors = stashed_ancestors end end |