open OUnit2 module T = ImportExpression.T module Expr = Expression_builder module M = Expr.Make (ImportExpression.Query.Query) let eval = M.eval ~path_repr:(fun formatter n -> Format.fprintf formatter "%s" n) let printer = Fun.id let test_expr ?(nested = ImportExpression.Query.QueryParameter.Literal) expr = let buffer = Buffer.create 16 in let formatter = Format.formatter_of_buffer buffer in let () = ImportExpression.Query.Query.observe expr formatter ~nested in Format.pp_print_flush formatter (); Buffer.contents buffer let empty = "empty" >:: fun _ -> let expr = eval Expr.empty in let content = test_expr expr and expected = "''" in assert_equal ~printer expected content let litteral = "literal" >:: fun _ -> let expr = eval Expr.literal_test in let content = test_expr expr and expected = "'test'" in assert_equal ~printer expected content let litteral_quoted = "literal_quoted" >:: fun _ -> let expr = eval Expr.literal_quoted in let content = test_expr expr and expected = "'\''" in assert_equal ~printer expected content let litteral_raw = "literal_raw" >:: fun _ -> let expr = eval Expr.literal_test in let nested = ImportExpression.Query.QueryParameter.(Raw Literal) in let content = test_expr expr ~nested and expected = "test" in assert_equal ~printer expected content let path = "path" >:: fun _ -> (* In the path, the given function do all the job *) let expr = eval @@ Expr.path "test" in let content = test_expr expr and expected = "test" in assert_equal ~printer expected content let concat = "concat" >:: fun _ -> let expr = eval Expr.concat in let content = test_expr expr and expected = "'' || 'test'" in assert_equal ~printer expected content let nvl = "nvl" >:: fun _ -> let expr = eval @@ Expr.nvl Expr.empty Expr.literal_test in let content = test_expr expr and expected = "COALESCE('', 'test')" in assert_equal ~printer expected content let upper = "upper" >:: fun _ -> let expr = eval @@ Expr.function' T.Upper [ Expr.literal_test ] in let content = test_expr expr and expected = "UPPER('test')" in assert_equal ~printer expected content let join = "join" >:: fun _ -> let expr = ImportExpression.Query.Query.( join "," [ eval Expr.empty; eval Expr.literal_test ]) in let content = test_expr expr and expected = "CONCAT(',', '', 'test')" in assert_equal ~printer expected content let boperator_eq = "boperator_eq" >:: fun _ -> let expr = eval @@ Expr.equal Expr.empty Expr.literal_test in let content = test_expr expr and expected = "''='test'" in assert_equal ~printer expected content let boperator_div = "boperator_div" >:: fun _ -> let expr = eval @@ Expr.divide Expr.integer_one Expr.integer_zero in let content = test_expr expr and expected = "CAST(1 AS REAL)/0" in assert_equal ~printer expected content let boperator_neq = "boperator_neq" >:: fun _ -> let expr = eval @@ Expr.different Expr.empty Expr.literal_test in let content = test_expr expr and expected = "''<>'test'" in assert_equal ~printer expected content let expr = "expr" >:: fun _ -> let expr = eval Expr.expr in let content = test_expr expr and expected = "(test NOT NULL)" in assert_equal ~printer expected content let unify_int = "unify_int" >:: fun _ -> let expr = eval @@ Expr.equal (Expr.path "external") Expr.integer_zero in let content = test_expr expr and expected = "COALESCE(external,0)=0" in assert_equal ~printer expected content let unify_string = "unify_string" >:: fun _ -> let expr = eval @@ Expr.equal (Expr.path "external") Expr.literal_zero in let content = test_expr expr and expected = "COALESCE(external,'')='0'" in assert_equal ~printer expected content let in_string = "in_string" >:: fun _ -> let expr = eval @@ Expr.in_ (Expr.path "external") [ Expr.literal_zero ] in let content = test_expr expr and expected = "COALESCE(external,'') IN('0')" in assert_equal ~printer expected content let not_in_string = "in_string" >:: fun _ -> let expr = eval @@ Expr.not_in (Expr.path "external") [ Expr.literal_zero ] in let content = test_expr expr and expected = "COALESCE(external,'') NOT IN('0')" in assert_equal ~printer expected content (* Evaluate the max function *) let max = "max" >:: fun _ -> let expr = eval @@ Expr.(max (path ":C") [ path ":A" ] [ path ":A"; path ":B" ]) in let content = test_expr expr and expected = "LAST_VALUE(:C) OVER (PARTITION BY :A ORDER BY :A, :B RANGE BETWEEN \ UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)" in assert_equal ~printer expected content let in_int = "in_int" >:: fun _ -> let expr = eval @@ Expr.in_ (Expr.path "external") [ Expr.integer_zero; Expr.integer_one ] in let content = test_expr expr and expected = "COALESCE(external,0) IN(0, 1)" in assert_equal ~printer expected content let counter_no_order = "counter_no_order" >:: fun _ -> let expr = eval @@ Expr.(counter [ path ":A" ] []) in let content = test_expr expr and expected = "COUNT() OVER (PARTITION BY :A)" in assert_equal ~printer expected content let counter_order = "counter_no_order" >:: fun _ -> let expr = eval @@ Expr.(counter [ path ":A" ] [ path ":B" ]) in let content = test_expr expr and expected = "ROW_NUMBER() OVER (PARTITION BY :A ORDER BY :B)" in assert_equal ~printer expected content let test_suit = [ empty; litteral; litteral_quoted; litteral_raw; path; concat; nvl; upper; join; boperator_eq; boperator_neq; boperator_div; expr; unify_int; unify_string; in_string; not_in_string; in_int; max; counter_no_order; counter_order; ] let tests = "expression_query" >::: test_suit