diff --git a/lib/tests/dune.inc b/lib/tests/dune.inc index e219fc10e..b16a266b6 100644 --- a/lib/tests/dune.inc +++ b/lib/tests/dune.inc @@ -32,13 +32,23 @@ (library ;; lib/tests/test_fun_call.ml (name test_fun_call_75) - (enabled_if (<> %{profile} using-effects)) + (enabled_if (and (<> %{profile} using-effects) (<> %{profile} wasm) (<> %{profile} wasm-effects))) (modules test_fun_call) (libraries js_of_ocaml unix) (inline_tests (modes js)) (preprocess (pps ppx_js_internal ppx_expect))) +(library + ;; lib/tests/test_fun_call_2.ml + (name test_fun_call_2_75) + (enabled_if true) + (modules test_fun_call_2) + (libraries js_of_ocaml unix) + (inline_tests (modes js)) + (preprocess + (pps ppx_js_internal ppx_expect))) + (library ;; lib/tests/test_json.ml (name test_json_75) @@ -62,13 +72,23 @@ (library ;; lib/tests/test_poly_compare.ml (name test_poly_compare_75) - (enabled_if true) + (enabled_if (and (<> %{profile} wasm) (<> %{profile} wasm-effects))) (modules test_poly_compare) (libraries js_of_ocaml unix) (inline_tests (modes js)) (preprocess (pps ppx_js_internal ppx_expect))) +(library + ;; lib/tests/test_poly_equal.ml + (name test_poly_equal_75) + (enabled_if true) + (modules test_poly_equal) + (libraries js_of_ocaml unix) + (inline_tests (modes js)) + (preprocess + (pps ppx_js_internal ppx_expect))) + (library ;; lib/tests/test_regexp.ml (name test_regexp_75) diff --git a/lib/tests/gen-rules/gen.ml b/lib/tests/gen-rules/gen.ml index cc42105ce..eda5eea71 100644 --- a/lib/tests/gen-rules/gen.ml +++ b/lib/tests/gen-rules/gen.ml @@ -47,14 +47,14 @@ let prefix : string = type enabled_if = | GE5 - | No_effects | Not_wasm + | No_effects_not_wasm | Any let enabled_if = function | "test_sys" -> GE5 - | "test_fun_call" -> No_effects - | "test_json" -> Not_wasm + | "test_fun_call" -> No_effects_not_wasm + | "test_json" | "test_poly_compare" -> Not_wasm | _ -> Any let () = @@ -85,6 +85,8 @@ let () = (* ZZZ /static not yet implemented *) "(and (>= %{ocaml_version} 5) (<> %{profile} wasm) (<> %{profile} \ wasm-effects))" - | No_effects -> "(<> %{profile} using-effects)" - | Not_wasm -> "(and (<> %{profile} wasm) (<> %{profile} wasm-effects))") + | Not_wasm -> "(and (<> %{profile} wasm) (<> %{profile} wasm-effects))" + | No_effects_not_wasm -> + "(and (<> %{profile} using-effects) (<> %{profile} wasm) (<> %{profile} \ + wasm-effects))") basename) diff --git a/lib/tests/test_fun_call.ml b/lib/tests/test_fun_call.ml index f36b0b871..888246dd2 100644 --- a/lib/tests/test_fun_call.ml +++ b/lib/tests/test_fun_call.ml @@ -29,8 +29,9 @@ let s x = return "undefined" if(typeof x === "function") return "function#" + x.length + "#" + x.l - if (x.toString) return x.toString(); - return "other" + if(x.toString() == "[object Arguments]") + return "(Arguments: " + Array.prototype.slice.call(x).toString() + ")"; + return x.toString() }) |} in @@ -146,7 +147,7 @@ let%expect_test "wrap_callback_strict" = (Js.Unsafe.callback_with_arity 2 cb3) {| (function(f){ return f(1,2,3) }) |}; [%expect {| - Result: other |}]; + Result: function#1#1 |}]; call_and_log (Js.Unsafe.callback_with_arity 2 cb3) ~cont:(fun g -> g 4) @@ -163,7 +164,7 @@ let%expect_test "wrap_callback_strict" = Result: 0 |}]; call_and_log (Js.Unsafe.callback_with_arity 2 cb3) {| (function(f){ return f(1,2) }) |}; [%expect {| - Result: other |}] + Result: function#1#1 |}] let%expect_test "wrap_callback_strict" = call_and_log @@ -290,7 +291,7 @@ let%expect_test "wrap_meth_callback_strict" = (Js.Unsafe.meth_callback_with_arity 2 cb4) {| (function(f){ return f.apply("this",[1,2,3]) }) |}; [%expect {| - Result: other |}]; + Result: function#1#1 |}]; call_and_log (Js.Unsafe.meth_callback_with_arity 2 cb4) ~cont:(fun g -> g 4) @@ -308,7 +309,7 @@ let%expect_test "wrap_meth_callback_strict" = call_and_log (Js.Unsafe.meth_callback_with_arity 2 cb4) {| (function(f){ return f.apply("this",[1,2]) }) |}; - [%expect {| Result: other |}] + [%expect {| Result: function#1#1 |}] let%expect_test "wrap_meth_callback_strict" = call_and_log @@ -353,15 +354,13 @@ let%expect_test "partial application, extra arguments set to undefined" = let%expect_test _ = call_and_log cb3 ~cont:(fun g -> g 1) {| (function(f){ return f }) |}; [%expect {| - Result: other |}] + Result: function#2#2 |}] -(* let%expect_test _ = call_and_log cb3 ~cont:(fun g -> g 1 2 3 4) {| (function(f){ return f }) |}; [%expect {| got 1, 2, 3, done Result: 0 |}] -*) let%expect_test _ = let f cb = @@ -370,17 +369,15 @@ let%expect_test _ = | _ -> Printf.printf "Error: unknown" in f cb5; - [%expect {| Result: other |}]; + [%expect {| Result: function#1#1 |}]; f cb4; [%expect {| got 1, 1, 2, 3, done Result: 0 |}]; - () -(* f cb3; - [%expect {| - got 1, 1, 2, done - Result: 0 |}] -*) + f cb3; + [%expect {| + got 1, 1, 2, done + Result: 0 |}] let%expect_test _ = let f cb = @@ -388,7 +385,6 @@ let%expect_test _ = | Invalid_argument s | Failure s -> Printf.printf "Error: %s" s | _ -> Printf.printf "Error: unknown" in - (* f (Obj.magic cb1); [%expect {| got 1, done @@ -397,21 +393,20 @@ let%expect_test _ = [%expect {| got 1, 2, done Result: 0 |}]; -*) f (Obj.magic cb3); [%expect {| got 1, 2, 3, done Result: 0 |}]; f (Obj.magic cb4); [%expect {| - Result: other |}]; + Result: function#1#1 |}]; f (Obj.magic cb5); [%expect {| - Result: other |}] + Result: function#2#2 |}] let%expect_test _ = let open Js_of_ocaml in - let f = Js.wrap_callback (fun s -> print_endline (Js.to_string s)) in + let f = Js.wrap_callback (fun s -> print_endline s) in Js.export "f" f; let () = Js.Unsafe.fun_call diff --git a/lib/tests/test_fun_call_2.ml b/lib/tests/test_fun_call_2.ml new file mode 100644 index 000000000..1a8dd0071 --- /dev/null +++ b/lib/tests/test_fun_call_2.ml @@ -0,0 +1,420 @@ +(* Js_of_ocaml tests + * http://www.ocsigen.org/js_of_ocaml/ + * Copyright (C) 2020 Hugo Heuzard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, with linking exception; + * either version 2.1 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *) +open Js_of_ocaml + +let s x = + let to_string = + Js.Unsafe.eval_string + {| +(function(x){ + if(x === null) + return "null" + if(x === undefined) + return "undefined" + if (!(typeof x == 'function') && x.toString) return x.toString(); + return "other" +}) +|} + in + Js.to_string (Js.Unsafe.fun_call to_string [| Js.Unsafe.inject x |]) + +let call_and_log f ?(cont = (Obj.magic Fun.id : _ -> _)) str = + let call = Js.Unsafe.eval_string str in + let r = Js.Unsafe.fun_call call [| Js.Unsafe.inject f |] in + Printf.printf "Result: %s" (s (cont r)) + +let cb1 a = Printf.printf "got %s, done\n" (s a) + +let cb2 a b = Printf.printf "got %s, %s, done\n" (s a) (s b) + +let cb3 a b c = Printf.printf "got %s, %s, %s, done\n" (s a) (s b) (s c) + +let cb4 a b c d = Printf.printf "got %s, %s, %s, %s, done\n" (s a) (s b) (s c) (s d) + +let cb5 a b c d e = + Printf.printf "got %s, %s, %s, %s, %s, done\n" (s a) (s b) (s c) (s d) (s e) + +(* Wrap callback *) + +let%expect_test "over application, extra arguments are dropped" = + call_and_log (Js.wrap_callback cb3) {| (function(f){ return f(1,2,3,4) }) |}; + [%expect {| + got 1, 2, 3, done + Result: 0 |}] + +let%expect_test "over application, extra arguments are dropped" = + call_and_log (Js.wrap_callback cb3) {| (function(f){ return f(1,2)(3,4) }) |}; + [%expect {| + got 1, 2, 3, done + Result: 0 |}] + +let%expect_test "partial application 1 + 2" = + call_and_log (Js.wrap_callback cb3) {| (function(f){ return f(1)(2,3) }) |}; + [%expect {| + got 1, 2, 3, done + Result: 0 |}] + +let%expect_test "partial application 2 + 1" = + call_and_log (Js.wrap_callback cb3) {| (function(f){ return f(1,2)(3) }) |}; + [%expect {| + got 1, 2, 3, done + Result: 0 |}] + +let%expect_test "partial application, callback is called when all arguments are available" + = + call_and_log (Js.wrap_callback cb5) {| (function(f){ return f(1)(2)(3)(4)(5) }) |}; + [%expect {| + got 1, 2, 3, 4, 5, done + Result: 0 |}] + +let%expect_test "partial application, 0 argument call is treated like 1 argument \ + (undefined)" = + call_and_log (Js.wrap_callback cb5) {| (function(f){ return f(1)()(3)()(5) }) |}; + [%expect {| + got 1, undefined, 3, undefined, 5, done + Result: 0 |}] + +let%expect_test _ = + let plus = Js.wrap_callback (fun a b -> a + b) in + call_and_log plus {| (function(f){ return f(1) }) |}; + [%expect {| Result: other |}]; + call_and_log plus {| (function(f){ return f(1)(2) }) |}; + [%expect {| Result: 3 |}]; + call_and_log plus {| (function(f){ return f(1,2) }) |}; + [%expect {| Result: 3 |}]; + call_and_log plus {| (function(f){ return f(1,2,3) }) |}; + [%expect {| Result: 3 |}] + +(* Wrap callback with argument *) + +let%expect_test "wrap_callback_arguments" = + call_and_log + (Js.Unsafe.callback_with_arguments (Obj.magic cb1)) + {| (function(f){ return f(1,2,3,4,5) }) |}; + [%expect {| + got 1,2,3,4,5, done + Result: 0 |}] + +let%expect_test "wrap_callback_arguments" = + call_and_log + (Js.Unsafe.callback_with_arguments (Obj.magic cb1)) + {| (function(f){ return f() }) |}; + [%expect {| + got , done + Result: 0 |}] + +(* Wrap with arity *) + +let%expect_test "wrap_callback_strict" = + call_and_log + (Js.Unsafe.callback_with_arity 3 cb3) + {| (function(f){ return f(1,2,3) }) |}; + [%expect {| + got 1, 2, 3, done + Result: 0 |}]; + call_and_log + (Js.Unsafe.callback_with_arity 3 cb3) + {| (function(f){ return f(1,2,3,4) }) |}; + [%expect {| + got 1, 2, 3, done + Result: 0 |}]; + call_and_log (Js.Unsafe.callback_with_arity 3 cb3) {| (function(f){ return f(1,2) }) |}; + [%expect {| + got 1, 2, undefined, done + Result: 0 |}] + +let%expect_test "wrap_callback_strict" = + call_and_log + (Js.Unsafe.callback_with_arity 2 cb3) + {| (function(f){ return f(1,2,3) }) |}; + [%expect {| + Result: other |}]; + call_and_log + (Js.Unsafe.callback_with_arity 2 cb3) + ~cont:(fun g -> g 4) + {| (function(f){ return f(1,2,3) }) |}; + [%expect {| + got 1, 2, 4, done + Result: 0 |}]; + call_and_log + (Js.Unsafe.callback_with_arity 2 cb3) + ~cont:(fun g -> g 3) + {| (function(f){ return f(1,2) }) |}; + [%expect {| + got 1, 2, 3, done + Result: 0 |}]; + call_and_log (Js.Unsafe.callback_with_arity 2 cb3) {| (function(f){ return f(1,2) }) |}; + [%expect {| + Result: other |}] + +let%expect_test "wrap_callback_strict" = + call_and_log + (Js.Unsafe.callback_with_arity 4 cb3) + {| (function(f){ return f(1,2,3) }) |}; + [%expect {| + got 1, 2, 3, done + Result: 0 |}]; + call_and_log + (Js.Unsafe.callback_with_arity 4 cb3) + {| (function(f){ return f(1,2,3,4) }) |}; + [%expect {| + got 1, 2, 3, done + Result: 0 |}]; + call_and_log (Js.Unsafe.callback_with_arity 4 cb3) {| (function(f){ return f(1,2) }) |}; + [%expect {| + got 1, 2, undefined, done + Result: 0 |}] + +(* Wrap meth callback *) + +let%expect_test "over application, extra arguments are dropped" = + call_and_log + (Js.wrap_meth_callback cb4) + {| (function(f){ return f.apply("this",[1,2,3,4]) }) |}; + [%expect {| + got this, 1, 2, 3, done + Result: 0 |}] + +let%expect_test "over application, extra arguments are dropped" = + call_and_log + (Js.wrap_meth_callback cb4) + {| (function(f){ return f.apply("this",[1,2])(3,4) }) |}; + [%expect {| + got this, 1, 2, 3, done + Result: 0 |}] + +let%expect_test "partial application 1 + 2" = + call_and_log + (Js.wrap_meth_callback cb4) + {| (function(f){ return f.apply("this", [1])(2,3) }) |}; + [%expect {| + got this, 1, 2, 3, done + Result: 0 |}] + +let%expect_test "partial application 2 + 1" = + call_and_log + (Js.wrap_meth_callback cb4) + {| (function(f){ return f.apply("this",[1,2])(3) }) |}; + [%expect {| + got this, 1, 2, 3, done + Result: 0 |}] + +let%expect_test "partial application, callback is called when all arguments are available" + = + call_and_log + (Js.wrap_meth_callback cb5) + {| (function(f){ return f.apply("this",[])(1)(2)(3)(4) }) |}; + [%expect {| + got this, 1, 2, 3, 4, done + Result: 0 |}] + +let%expect_test "partial application, 0 argument call is treated 1 argument (undefined)" = + call_and_log + (Js.wrap_meth_callback cb5) + {| (function(f){ return f.apply("this",[])(1)()(3)() }) |}; + [%expect {| + got this, 1, undefined, 3, undefined, done + Result: 0 |}] + +let%expect_test _ = + let plus = Js.wrap_meth_callback (fun _ a b -> a + b) in + call_and_log plus {| (function(f){ return f(1) }) |}; + [%expect {| Result: other |}]; + call_and_log plus {| (function(f){ return f(1)(2) }) |}; + [%expect {| Result: 3 |}]; + call_and_log plus {| (function(f){ return f(1,2) }) |}; + [%expect {| Result: 3 |}]; + call_and_log plus {| (function(f){ return f(1,2,3) }) |}; + [%expect {| Result: 3 |}] + +(* Wrap callback with argument *) + +let%expect_test "wrap_meth_callback_arguments" = + call_and_log + (Js.Unsafe.meth_callback_with_arguments (Obj.magic cb2)) + {| (function(f){ return f.apply("this",[1,2,3,4,5]) }) |}; + [%expect {| + got this, 1,2,3,4,5, done + Result: 0 |}] + +let%expect_test "wrap_meth_callback_arguments" = + call_and_log + (Js.Unsafe.meth_callback_with_arguments (Obj.magic cb2)) + {| (function(f){ return f.apply("this", []) }) |}; + [%expect {| + got this, , done + Result: 0 |}] + +(* Wrap with arity *) + +let%expect_test "wrap_meth_callback_strict" = + call_and_log + (Js.Unsafe.meth_callback_with_arity 3 cb4) + {| (function(f){ return f.apply("this",[1,2,3]) }) |}; + [%expect {| + got this, 1, 2, 3, done + Result: 0 |}]; + call_and_log + (Js.Unsafe.meth_callback_with_arity 3 cb4) + {| (function(f){ return f.apply("this",[1,2,3,4]) }) |}; + [%expect {| + got this, 1, 2, 3, done + Result: 0 |}]; + call_and_log + (Js.Unsafe.meth_callback_with_arity 3 cb4) + {| (function(f){ return f.apply("this",[1,2]) }) |}; + [%expect {| + got this, 1, 2, undefined, done + Result: 0 |}] + +let%expect_test "wrap_meth_callback_strict" = + call_and_log + (Js.Unsafe.meth_callback_with_arity 2 cb4) + {| (function(f){ return f.apply("this",[1,2,3]) }) |}; + [%expect {| + Result: other |}]; + call_and_log + (Js.Unsafe.meth_callback_with_arity 2 cb4) + ~cont:(fun g -> g 4) + {| (function(f){ return f.apply("this",[1,2,3]) }) |}; + [%expect {| + got this, 1, 2, 4, done + Result: 0 |}]; + call_and_log + (Js.Unsafe.meth_callback_with_arity 2 cb4) + ~cont:(fun g -> g 3) + {| (function(f){ return f.apply("this",[1,2]) }) |}; + [%expect {| + got this, 1, 2, 3, done + Result: 0 |}]; + call_and_log + (Js.Unsafe.meth_callback_with_arity 2 cb4) + {| (function(f){ return f.apply("this",[1,2]) }) |}; + [%expect {| Result: other |}] + +let%expect_test "wrap_meth_callback_strict" = + call_and_log + (Js.Unsafe.meth_callback_with_arity 4 cb4) + {| (function(f){ return f.apply("this",[1,2,3]) }) |}; + [%expect {| + got this, 1, 2, 3, done + Result: 0 |}]; + call_and_log + (Js.Unsafe.meth_callback_with_arity 4 cb4) + {| (function(f){ return f.apply("this",[1,2,3,4]) }) |}; + (* Should not return a function *) + [%expect {| + got this, 1, 2, 3, done + Result: 0 |}]; + call_and_log + (Js.Unsafe.meth_callback_with_arity 4 cb4) + {| (function(f){ return f.apply("this",[1,2]) }) |}; + [%expect {| + got this, 1, 2, undefined, done + Result: 0 |}] + +(* Wrap meth callback unsafe *) +let%expect_test "over application, extra arguments are dropped" = + call_and_log + (Js.Unsafe.meth_callback cb4) + {| (function(f){ return f.apply("this",[1,2,3,4]) }) |}; + [%expect {| + got this, 1, 2, 3, done + Result: 0 |}] + +let%expect_test "partial application, extra arguments set to undefined" = + call_and_log + (Js.Unsafe.meth_callback cb4) + {| (function(f){ return f.apply("this",[1,2]) }) |}; + [%expect {| + got this, 1, 2, undefined, done + Result: 0 |}] + +(* caml_call_gen *) + +let%expect_test _ = + call_and_log cb3 ~cont:(fun g -> g 1) {| (function(f){ return f }) |}; + [%expect {| + Result: other |}] + +(* +let%expect_test _ = + call_and_log cb3 ~cont:(fun g -> g 1 2 3 4) {| (function(f){ return f }) |}; + [%expect {| + got 1, 2, 3, done + Result: 0 |}] +*) + +let%expect_test _ = + let f cb = + try call_and_log (cb 1) ~cont:(fun g -> g 1 2 3) {| (function(f){ return f }) |} with + | Invalid_argument s | Failure s -> Printf.printf "Error: %s" s + | _ -> Printf.printf "Error: unknown" + in + f cb5; + [%expect {| Result: other |}]; + f cb4; + [%expect {| + got 1, 1, 2, 3, done + Result: 0 |}]; + () +(* f cb3; + [%expect {| + got 1, 1, 2, done + Result: 0 |}] +*) + +let%expect_test _ = + let f cb = + try call_and_log (cb 1 2 3) {| (function(f){ return f }) |} with + | Invalid_argument s | Failure s -> Printf.printf "Error: %s" s + | _ -> Printf.printf "Error: unknown" + in + (* + f (Obj.magic cb1); + [%expect {| + got 1, done + Result: 0 |}]; + f (Obj.magic cb2); + [%expect {| + got 1, 2, done + Result: 0 |}]; +*) + f (Obj.magic cb3); + [%expect {| + got 1, 2, 3, done + Result: 0 |}]; + f (Obj.magic cb4); + [%expect {| + Result: other |}]; + f (Obj.magic cb5); + [%expect {| + Result: other |}] + +let%expect_test _ = + let open Js_of_ocaml in + let f = Js.wrap_callback (fun s -> print_endline (Js.to_string s)) in + Js.export "f" f; + let () = + Js.Unsafe.fun_call + (Js.Unsafe.pure_js_expr "jsoo_exports")##.f + [| Js.Unsafe.coerce (Js.string "hello") |] + in + (); + [%expect {| hello |}] diff --git a/lib/tests/test_poly_compare.ml b/lib/tests/test_poly_compare.ml index b9799cc8d..62c47b46b 100644 --- a/lib/tests/test_poly_compare.ml +++ b/lib/tests/test_poly_compare.ml @@ -25,7 +25,6 @@ let%expect_test "poly equal" = assert (List.mem obj1 [ obj2; obj1 ]); assert (not (List.mem obj1 [ obj2 ])); () -[@@expect.uncaught_exn {| (Invalid_argument "compare: abstract value") |}] let%expect_test "poly equal neg" = let obj1 = Js.Unsafe.obj [||] in @@ -50,8 +49,7 @@ let%expect_test "poly compare" = then print_endline "preserve" else print_endline "not preserve" | _ -> assert false); - [%expect.unreachable] -[@@expect.uncaught_exn {| (Invalid_argument "compare: abstract value") |}] + [%expect {| not preserve |}] type pack = Pack : 'a -> pack @@ -65,7 +63,6 @@ let%expect_test "number comparison" = assert ( Pack (Js.Unsafe.js_expr "new Number(2.1)") = Pack (Js.Unsafe.js_expr "new Number(2.1)")) -[@@expect.uncaught_exn {| "Assert_failure lib/tests/test_poly_compare.ml:59:2" |}] let js_string_enabled = Js.typeof (Obj.magic "") == Js.string "string" @@ -82,7 +79,6 @@ let%expect_test "string comparison" = assert ( Pack (Js.Unsafe.js_expr "new String('abcd')") = Pack (Js.Unsafe.js_expr "new String('abcd')")) -[@@expect.uncaught_exn {| "Assert_failure lib/tests/test_poly_compare.ml:82:2" |}] let%expect_test "symbol comparison" = let s1 = Pack (Js.Unsafe.js_expr "Symbol('2')") in @@ -92,7 +88,6 @@ let%expect_test "symbol comparison" = assert (compare s1 s1 = 0); assert (compare s1 s2 = 1); assert (compare s2 s1 = 1) -[@@expect.uncaught_exn {| (Invalid_argument "compare: abstract value") |}] let%expect_test "object comparison" = let s1 = Pack (Js.Unsafe.js_expr "{}") in @@ -102,7 +97,6 @@ let%expect_test "object comparison" = assert (compare s1 s1 = 0); assert (compare s1 s2 = 1); assert (compare s2 s1 = 1) -[@@expect.uncaught_exn {| (Invalid_argument "compare: abstract value") |}] let%expect_test "poly compare" = let l = @@ -120,13 +114,36 @@ let%expect_test "poly compare" = let l' = List.sort (fun (_, a) (_, b) -> compare a b) l in List.iter (fun (i, _) -> Printf.printf "%d\n" i) l'; print_endline ""; - [%expect.unreachable]; + [%expect {| + 1 + 3 + 2 + 0 + 6 + 7 + 5 + 4 |}]; let l' = List.sort (fun (_, a) (_, b) -> compare a b) (List.rev l) in let l'' = List.sort (fun (_, a) (_, b) -> compare a b) (List.rev l') in List.iter (fun (i, _) -> Printf.printf "%d\n" i) l'; print_endline ""; - [%expect.unreachable]; + [%expect {| + 3 + 1 + 2 + 0 + 4 + 5 + 7 + 6 |}]; List.iter (fun (i, _) -> Printf.printf "%d\n" i) l''; print_endline ""; - [%expect.unreachable] -[@@expect.uncaught_exn {| (Invalid_argument "compare: abstract value") |}] + [%expect {| + 1 + 3 + 2 + 0 + 4 + 5 + 6 + 7 |}] diff --git a/lib/tests/test_poly_equal.ml b/lib/tests/test_poly_equal.ml new file mode 100644 index 000000000..0f6cf095e --- /dev/null +++ b/lib/tests/test_poly_equal.ml @@ -0,0 +1,66 @@ +(* Js_of_ocaml tests + * http://www.ocsigen.org/js_of_ocaml/ + * Copyright (C) 2019 Hugo Heuzard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *) +open Js_of_ocaml + +let%expect_test "poly equal" = + let obj1 = Js.Unsafe.obj [||] in + let obj2 = Js.Unsafe.obj [||] in + assert (obj1 = obj2); + assert (not (obj1 = obj2)); + () +[@@expect.uncaught_exn {| "Assert_failure lib/tests/test_poly_equal.ml:24:2" |}] + +let%expect_test "poly equal neg" = + let obj1 = Js.Unsafe.obj [||] in + let obj2 = Js.Unsafe.obj [||] in + assert (obj1 <> obj2); + assert (not (obj1 <> obj1)); + () + +type pack = Pack : 'a -> pack + +let%expect_test "number comparison" = + assert (Pack 2 = Pack 2); + assert (Pack 2 <> Pack 2.1); + assert (Pack (Js.float 2.1) = Pack (Js.float 2.1)); + assert (Pack (Js.Unsafe.js_expr "Number(2.1)") <> Pack 2.); + assert (Pack (Js.Unsafe.js_expr "new Number(2.1)") <> Pack 2.); + assert (Pack (Js.Unsafe.js_expr "Number(2.1)") = Pack (Js.Unsafe.js_expr "Number(2.1)")) + +let%expect_test "string comparison" = + assert (Pack (Js.Unsafe.js_expr "String(2)") = Pack (Js.string "2")); + assert (Pack (Js.Unsafe.js_expr "String('abc')") = Pack (Js.string "abc")); + assert (Pack (Js.Unsafe.js_expr "new String('abcሴ')") = Pack (Js.string "abcሴ")); + assert (Pack (Js.Unsafe.js_expr "String(1)") <> Pack (Js.string "2")); + assert (Pack (Js.Unsafe.js_expr "String('abcd')") <> Pack (Js.string "abc")); + assert (Pack (Js.Unsafe.js_expr "new String('abcd')") <> Pack (Js.string "abc")); + assert ( + Pack (Js.Unsafe.js_expr "String('abcd')") = Pack (Js.Unsafe.js_expr "String('abcd')")) + +let%expect_test "symbol comparison" = + let s1 = Pack (Js.Unsafe.js_expr "Symbol('2')") in + let s2 = Pack (Js.Unsafe.js_expr "Symbol('2')") in + assert (s1 <> s2); + assert (s1 = s1) + +let%expect_test "object comparison" = + let s1 = Pack (Js.Unsafe.js_expr "{}") in + let s2 = Pack (Js.Unsafe.js_expr "{}") in + assert (s1 <> s2); + assert (s1 = s1)