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