open OUnit2 module T = ImportExpression.T module Types = ImportDataTypes.Types module Expr = Expression_builder module M = Expr.Make (ImportExpression.Type_of) let eval = M.eval ~path_repr:(fun _ -> ()) let printer = Types.string_of_t let test_expr expr = ImportExpression.Type_of.observe expr let empty = "empty" >:: fun _ -> let expr = eval Expr.empty in let content = test_expr expr and expected = Types.None in assert_equal ~printer expected content (** Control an if statement with a predicate which is not a boolean *) let invalid_if = "invalid_if" >:: fun _ -> (* The expression we want to test *) let raw_expr = Expr.if_ Expr.literal_test Expr.integer_zero Expr.integer_one in let exn = ImportErrors.TypeError { expected = Types.Bool; actual = Types.String; expression = ImportExpression.Repr.repr Fun.id raw_expr; subset = "the predicate"; } in assert_raises exn (fun () -> let expr = eval raw_expr in test_expr expr) (** The application should infer that the expression is a string *) let valid_if = "valid_if" >:: fun _ -> let expr = eval @@ Expr.if_ (Expr.equal Expr.integer_one Expr.integer_zero) Expr.literal_test Expr.literal_test in let content = test_expr expr and expected = Types.String 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 = Types.String in assert_equal ~printer expected content let in_int = "in_int" >:: fun _ -> let expr = eval @@ Expr.in_ (Expr.path "external") [ Expr.integer_one ] in let content = test_expr expr and expected = Types.Bool in assert_equal ~printer expected content let tests = "expression_type_of" >::: [ empty; invalid_if; valid_if; in_int ; upper ]