lib/floe/workflow/choice_rule.rb in floe-0.13.0 vs lib/floe/workflow/choice_rule.rb in floe-0.13.1

- old
+ new

@@ -1,10 +1,12 @@ # frozen_string_literal: true module Floe class Workflow class ChoiceRule + include ValidationMixin + class << self def build(workflow, name, payload) if (sub_payloads = payload["Not"]) name += ["Not"] Floe::Workflow::ChoiceRule::Not.new(workflow, name, payload, build_children(workflow, name, [sub_payloads])) @@ -23,28 +25,51 @@ def build_children(workflow, name, sub_payloads) sub_payloads.map.with_index { |payload, i| build(workflow, name + [i.to_s], payload) } end end - attr_reader :next, :payload, :variable, :children, :name + attr_reader :next, :payload, :children, :name - def initialize(_workflow, name, payload, children = nil) + def initialize(workflow, name, payload, children = nil) @name = name @payload = payload @children = children + @next = payload["Next"] - @next = payload["Next"] - @variable = payload["Variable"] + validate_next!(workflow) end def true?(*) raise NotImplementedError, "Must be implemented in a subclass" end private - def variable_value(context, input) - Path.value(variable, context, input) + def validate_next!(workflow) + if is_child? + # non-top level nodes don't allow a next + invalid_field_error!("Next", @next, "not allowed in a child rule") if @next + elsif !@next + # top level nodes require a next + missing_field_error!("Next") + elsif !workflow_state?(@next, workflow) + # top level nodes require a next field that is found + invalid_field_error!("Next", @next, "is not found in \"States\"") + end + end + + # returns true if this is a child rule underneath an And/Or/Not + # { + # "Or": [ + # {"Variable": "$.foo", "IsString": true}, + # {"Variable": "$.foo", "IsBoolean": true} + # ], "Next": "Finished" + # } + # + # The Or node, has no conjunction parent, so it is not a child (requires a Next) + # The 2 Data nodes have a conjunction parent, so each one is a child (do not allow a Next) + def is_child? # rubocop:disable Naming/PredicateName + !(%w[And Or Not] & name[0..-2]).empty? end end end end