open StdLabels open OUnit2 module Expression = ImportExpression.T module Path = ImportDataTypes.Path open Path let printer = function | Ok e -> ImportExpression.Repr.repr ImportConf.Path.repr e | Error msg -> msg let parse_dquoted = "parse_dquoted" >:: fun _ -> let expr = "match(\"\\(..\\)\", :B)" in let result = ImportConf.expression_from_string expr in assert_equal ~printer (Ok (Function ("match", [ Literal "\\(..\\)"; Path { alias = None; column = 2 } ]))) result let parse_quoted = "parse_quoted" >:: fun _ -> let expr = "match('\\(..\\)', :B)" in let result = ImportConf.expression_from_string expr in assert_equal ~printer (Ok (Function ("match", [ Literal "\\(..\\)"; Path { alias = None; column = 2 } ]))) result let concat = "concat" >:: fun _ -> let expr = ":A ^ :B" in let result = ImportConf.expression_from_string expr in assert_equal ~printer (Ok (Concat [ Path { alias = None; column = 1 }; Path { alias = None; column = 2 }; ])) result let concat2 = "concat2" >:: fun _ -> let expr = "'A' ^ '_' ^ 'B'" in let result = ImportConf.expression_from_string expr in assert_equal ~printer (Ok (Concat [ Literal "A"; Literal "_"; Literal "B" ])) result let litteral = "litteral" >:: fun _ -> (* The text is quoted in shall not be considered as a path *) let expr = "':A'" in let result = ImportConf.expression_from_string expr in assert_equal ~printer (Ok (Literal ":A")) result let empty = "empty" >:: fun _ -> let expr = "" in let result = ImportConf.expression_from_string expr in assert_equal ~printer (Ok Empty) result let upper_nvl = "upper_nvl" >:: fun _ -> let expr = "NVL('','')" in let result = ImportConf.expression_from_string expr in assert_equal ~printer (Ok (Nvl [ Empty; Empty ])) result let lower_nvl = "lower_nvl" >:: fun _ -> let expr = "nvl('','')" in let result = ImportConf.expression_from_string expr in assert_equal ~printer (Ok (Nvl [ Empty; Empty ])) result let numeric = "numeric" >:: fun _ -> let expr = "123" in let result = ImportConf.expression_from_string expr in assert_equal ~printer (Ok (Integer "123")) result let numeric_neg = "numeric_neg" >:: fun _ -> let expr = "-123" in let result = ImportConf.expression_from_string expr in assert_equal ~printer (Ok (Integer "-123")) result let op_priority = "operator_priority" >:: fun _ -> let expr = "1 + 2 > 2" in let result = ImportConf.expression_from_string expr and expected = ImportExpression.T.( BOperator (GT, BOperator (Add, Integer "1", Integer "2"), Integer "2")) in assert_equal ~printer (Ok expected) result let op_priority2 = "operator_priority" >:: fun _ -> let expr = "1 ^ 2 = 2" in let result = ImportConf.expression_from_string expr and expected = ImportExpression.T.( BOperator (Equal, Concat [ Integer "1"; Integer "2" ], Integer "2")) in assert_equal ~printer (Ok expected) result let join = "join" >:: fun _ -> let expr = "join('sep', :A, :B)" in let result = ImportConf.expression_from_string expr in assert_equal ~printer (Ok (Join ( "sep", [ Path { alias = None; column = 1 }; Path { alias = None; column = 2 }; ] ))) result let join_empty = "join" >:: fun _ -> let expr = "join('', :A, :B)" in let result = ImportConf.expression_from_string expr in assert_equal ~printer (Ok (Join ( "", [ Path { alias = None; column = 1 }; Path { alias = None; column = 2 }; ] ))) result let upper = "upper" >:: fun _ -> let expr = "upper('')" in let result = ImportConf.expression_from_string expr in assert_equal ~printer (Ok (Function' (Upper, [ Empty ]))) result let trim = "trim" >:: fun _ -> let expr = "trim('')" in let result = ImportConf.expression_from_string expr in assert_equal ~printer (Ok (Function' (Trim, [ Empty ]))) result (** Extract the columns from a window function *) let fold_values = "fold_values" >:: fun _ -> (* The expression we want to test *) let expr = Expression.Window ( Previous (Path { alias = None; column = 1 }), [ Path { alias = None; column = 2 } ], [ Path { alias = None; column = 3 } ] ) in (* Extract the columns from the expression. The result is sorted because the order is not preserved during the extraction. *) let result = Expression.fold_values ~init:[] ~f:(fun acc v -> v :: acc) expr |> List.sort ~cmp:Path.compare in let expected = [ { alias = None; column = 1 }; { alias = None; column = 2 }; { alias = None; column = 3 }; ] in assert_equal expected result let bad_quote = "bad_quote" >:: fun _ -> let expr = "':source.A" in let result = ImportConf.expression_from_string expr in assert_equal ~printer (Error "Unclosed quote at line 1 : \"':source.A\"") result let nested_expression = "nested_expression" >:: fun _ -> let expr = "1 = (1 = 0)" in let result = ImportConf.expression_from_string expr in assert_equal ~printer (Ok (BOperator ( Equal, Integer "1", Expr (BOperator (Equal, Integer "1", Integer "0")) ))) result let priority_equality = "priority_equality" >:: fun _ -> let expr = "1 = 1 = 0" in let result = ImportConf.expression_from_string expr in assert_equal ~printer (Ok (BOperator (Equal, Integer "1", BOperator (Equal, Integer "1", Integer "0")))) result let priority_operator_and = "priority_equality" >:: fun _ -> let expr = "1 and 1 = 0" in let result = ImportConf.expression_from_string expr in assert_equal ~printer (Ok (BOperator (And, Integer "1", BOperator (Equal, Integer "1", Integer "0")))) result let priority_operator_or = "priority_equality" >:: fun _ -> let expr = "1 <> 1 or 0" in let result = ImportConf.expression_from_string expr in assert_equal ~printer (Ok (BOperator (Or, BOperator (Different, Integer "1", Integer "1"), Integer "0"))) result let test_suit = [ parse_dquoted; parse_quoted; concat; concat2; litteral; empty; upper_nvl; lower_nvl; numeric; numeric_neg; op_priority; op_priority2; join; upper; trim; join_empty; fold_values; bad_quote; nested_expression; priority_equality; priority_operator_and; priority_operator_or; ] let tests = "configuration_expression" >::: test_suit