Skip to content

Commit

Permalink
introduce binary choice rules
Browse files Browse the repository at this point in the history
only access payload in initialize
  • Loading branch information
kbrock committed May 31, 2024
1 parent 604fc35 commit 856fce4
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 39 deletions.
53 changes: 15 additions & 38 deletions lib/floe/workflow/choice_rule/data.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,59 +4,36 @@ module Floe
class Workflow
class ChoiceRule
class Data < Floe::Workflow::ChoiceRule
COMPARE_KEYS = %w[IsNull IsPresent IsNumeric IsString IsBoolean IsTimestamp String Numeric Boolean Timestamp].freeze
COMPARE_RULE = /^(String|Numeric|Boolean|Timestamp)(Equals|GreaterThan|LessThan|GreaterThanEquals|LessThanEquals|Matches)(Path)?$/.freeze
OPERATIONS = {"Equals" => :==, "LessThan" => :<, "GreaterThan" => :>, "LessThanEquals" => :<=, "GreaterThanEquals" => :>=, "Matches" => "match?"}.freeze

attr_reader :compare_key
attr_reader :operation, :ref, :path

def initialize(*)
super
@compare_key = payload.keys.detect { |key| key.match?(/^(#{COMPARE_KEYS.join("|")})/) }
payload.each.detect do |key, value|
_type, operator, @path = COMPARE_RULE.match(key)&.captures
@operation = OPERATIONS[operator]
@ref = value
operator # detect aborts once an operator is found
end

raise Floe::InvalidWorkflowError, "Data-test Expression Choice Rule must have a compare key" if @compare_key.nil?
raise Floe::InvalidWorkflowError, "Data-test Expression Choice Rule must have a valid compare key" unless operation
end

def true?(context, input)
lhs = variable_value(context, input)
rhs = compare_value(context, input)
return false unless valid?(lhs)
return false if lhs.nil?

case compare_key
when "StringEquals", "StringEqualsPath",
"NumericEquals", "NumericEqualsPath",
"BooleanEquals", "BooleanEqualsPath",
"TimestampEquals", "TimestampEqualsPath"
lhs == rhs
when "StringLessThan", "StringLessThanPath",
"NumericLessThan", "NumericLessThanPath",
"TimestampLessThan", "TimestampLessThanPath"
lhs < rhs
when "StringGreaterThan", "StringGreaterThanPath",
"NumericGreaterThan", "NumericGreaterThanPath",
"TimestampGreaterThan", "TimestampGreaterThanPath"
lhs > rhs
when "StringLessThanEquals", "StringLessThanEqualsPath",
"NumericLessThanEquals", "NumericLessThanEqualsPath",
"TimestampLessThanEquals", "TimestampLessThanEqualsPath"
lhs <= rhs
when "StringGreaterThanEquals", "StringGreaterThanEqualsPath",
"NumericGreaterThanEquals", "NumericGreaterThanEqualsPath",
"TimestampGreaterThanEquals", "TimestampGreaterThanEqualsPath"
lhs >= rhs
when "StringMatches"
lhs.match?(Regexp.escape(rhs).gsub('\*', '.*?'))
else
raise Floe::InvalidWorkflowError, "Invalid choice [#{compare_key}]"
end
rhs = compare_value(context, input)
rhs = Regexp.escape(rhs).gsub('\*', '.*?') if operation == "match?"
lhs.send(operation, rhs)
end

private

def valid?(value)
!value.nil?
end

def compare_value(context, input)
compare_key.end_with?("Path") ? Path.value(payload[compare_key], context, input) : payload[compare_key]
path ? Path.value(ref, context, input) : ref
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion spec/workflow/choice_rule_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
let(:input) { {"foo" => "bar"} }

it "raises an exception" do
expect { subject }.to raise_exception(Floe::InvalidWorkflowError, "Data-test Expression Choice Rule must have a compare key")
expect { subject }.to raise_exception(Floe::InvalidWorkflowError, "Data-test Expression Choice Rule must have a valid compare key")
end
end

Expand Down

0 comments on commit 856fce4

Please sign in to comment.