@@ -4,21 +4,38 @@ module Floe
44 class Workflow
55 class ChoiceRule
66 class Data < Floe ::Workflow ::ChoiceRule
7- COMPARE_KEYS = %w[ IsNull IsPresent IsNumeric IsString IsBoolean IsTimestamp String Numeric Boolean Timestamp ] . freeze
7+ OPERATIONS = { "Equals" => :== , "LessThan" => :< , "GreaterThan" => :> , "LessThanEquals" => :<= , "GreaterThanEquals" => :>= } . freeze
8+ TYPES = %w[ String Numeric Boolean Timestamp ] . freeze
9+ COMPARE_RULE = /^(Is)?(#{ TYPES . join ( "|" ) } |Null|Present)(#{ OPERATIONS . keys . join ( "|" ) } |Matches)?(Path)?$/ . freeze
810
9- attr_reader :compare_key
11+ attr_reader :compare_key , :ref , :path
1012
1113 def initialize ( *)
1214 super
13- @compare_key = payload . keys . detect { |key | key . match? ( /^(#{ COMPARE_KEYS . join ( "|" ) } )/ ) }
15+ payload . each do |key , value |
16+ is , type , operator , @path = COMPARE_RULE . match ( key ) &.captures
17+ if is
18+ # e.g.: IsTypeGreaterThan is not valid
19+ @compare_key = "#{ is } #{ type } " unless operator || path
20+ break
21+ elsif operator == "Matches"
22+ # only MatchesString is valid
23+ @compare_key = "#{ type } #{ operator } " unless type != "String" || path
24+ @ref = value
25+ break
26+ elsif operator
27+ # e.g.: NullGreaterThan not valid
28+ @compare_key = OPERATIONS [ operator ] unless %w[ Null Present ] . include? ( type )
29+ @ref = value
30+ break
31+ end
32+ end
1433
15- raise Floe ::InvalidWorkflowError , "Data-test Expression Choice Rule must have a compare key" if @ compare_key. nil?
34+ raise Floe ::InvalidWorkflowError , "Data-test Expression Choice Rule must have a valid compare key" unless compare_key
1635 end
1736
1837 def true? ( context , input )
1938 lhs = variable_value ( context , input )
20- rhs = compare_value ( context , input )
21- return false unless valid? ( lhs )
2239
2340 case compare_key
2441 when "IsNull" then is_null? ( lhs )
@@ -27,31 +44,12 @@ def true?(context, input)
2744 when "IsString" then is_string? ( lhs )
2845 when "IsBoolean" then is_boolean? ( lhs )
2946 when "IsTimestamp" then is_timestamp? ( lhs )
30- when "StringEquals" , "StringEqualsPath" ,
31- "NumericEquals" , "NumericEqualsPath" ,
32- "BooleanEquals" , "BooleanEqualsPath" ,
33- "TimestampEquals" , "TimestampEqualsPath"
34- lhs == rhs
35- when "StringLessThan" , "StringLessThanPath" ,
36- "NumericLessThan" , "NumericLessThanPath" ,
37- "TimestampLessThan" , "TimestampLessThanPath"
38- lhs < rhs
39- when "StringGreaterThan" , "StringGreaterThanPath" ,
40- "NumericGreaterThan" , "NumericGreaterThanPath" ,
41- "TimestampGreaterThan" , "TimestampGreaterThanPath"
42- lhs > rhs
43- when "StringLessThanEquals" , "StringLessThanEqualsPath" ,
44- "NumericLessThanEquals" , "NumericLessThanEqualsPath" ,
45- "TimestampLessThanEquals" , "TimestampLessThanEqualsPath"
46- lhs <= rhs
47- when "StringGreaterThanEquals" , "StringGreaterThanEqualsPath" ,
48- "NumericGreaterThanEquals" , "NumericGreaterThanEqualsPath" ,
49- "TimestampGreaterThanEquals" , "TimestampGreaterThanEqualsPath"
50- lhs >= rhs
5147 when "StringMatches"
52- lhs . match? ( Regexp . escape ( rhs ) . gsub ( '\*' , '.*?' ) )
48+ rhs = compare_value ( context , input )
49+ !lhs . nil? && lhs . match? ( Regexp . escape ( rhs ) . gsub ( '\*' , '.*?' ) )
5350 else
54- raise Floe ::InvalidWorkflowError , "Invalid choice [#{ compare_key } ]"
51+ rhs = compare_value ( context , input )
52+ !lhs . nil? && lhs . send ( compare_key , rhs )
5553 end
5654 end
5755
@@ -82,6 +80,8 @@ def is_boolean?(value) # rubocop:disable Naming/PredicateName
8280 end
8381
8482 def is_timestamp? ( value ) # rubocop:disable Naming/PredicateName
83+ return false if value . nil?
84+
8585 require "date"
8686
8787 DateTime . rfc3339 ( value )
@@ -91,7 +91,7 @@ def is_timestamp?(value) # rubocop:disable Naming/PredicateName
9191 end
9292
9393 def compare_value ( context , input )
94- compare_key . end_with? ( "Path" ) ? Path . value ( payload [ compare_key ] , context , input ) : payload [ compare_key ]
94+ path ? Path . value ( ref , context , input ) : ref
9595 end
9696 end
9797 end
0 commit comments