2 * Copyright (c) 2014, Facebook, Inc.
5 * This source code is licensed under the MIT license found in the
6 * LICENSE file in the "hack" directory of this source tree.
11 module DP
= Docblock_parse
17 exception Test_failure
of string
19 let test_at_parse () =
22 "My_klass", T.ATclass
"My_klass";
23 "string|Klass", T.ATcomposite
[T.ATstring
; T.ATclass
"Klass"];
24 "*int[]", T.ATvariadic
(T.ATarray
(T.ATint
));
25 "int|string[]", T.ATcomposite
[T.ATint
; T.ATarray
T.ATstring
];
26 "(int|string)[]", T.ATarray
(T.ATcomposite
[T.ATint
; T.ATstring
]);
27 "(int|string)|bool", T.ATcomposite
[T.ATint
; T.ATstring
; T.ATbool
];
29 let check (input
, output
) =
30 if (At_parse.parse input
) <> output
then
31 raise
(Test_failure input
)
36 type test_convert_ty_case
=
43 let test_convert_ty () =
47 strict
= Common.Left
H.Hstring
;
48 loose
= Common.Left
H.Hstring
;
52 strict
= Common.Right
"";
53 loose
= Common.Left
H.Hmixed
;
55 {name
= "nullable class";
56 input
= T.ATcomposite
[T.ATclass
"foo"; T.ATnull
];
57 strict
= Common.Left
(H.Hnullable
(H.Hclass
"foo"));
58 loose
= Common.Left
(H.Hnullable
(H.Hclass
"foo"));
60 {name
= "nullable mixed 1";
61 input
= T.ATcomposite
[T.ATmixed
; T.ATnull
];
62 strict
= Common.Left
H.Hmixed
;
63 loose
= Common.Left
H.Hmixed
;
65 {name
= "nullable mixed 2";
66 input
= T.ATcomposite
[T.ATmixed
]; (* Not sure how meaningful this is. *)
67 strict
= Common.Right
"";
68 loose
= Common.Left
H.Hmixed
;
70 {name
= "loose composite";
71 input
= T.ATcomposite
[T.ATuint
; T.ATfloat
];
72 strict
= Common.Right
"";
73 loose
= Common.Left
H.Hnum
;
75 {name
= "multiple reduce";
76 input
= T.ATcomposite
[T.ATint
; T.ATnull
; T.ATfloat
];
77 strict
= Common.Left
(H.Hnullable
H.Hnum
);
78 loose
= Common.Left
(H.Hnullable
H.Hnum
);
81 let check_single name output expected
= match output
, expected
with
82 | Common.Left e1
, Common.Left e2
when e1
= e2
-> ()
83 | Common.Right _
, Common.Right _
-> ()
84 | _
-> raise
(Test_failure name
) in
85 let check {name
; input
; strict
; loose
} =
86 check_single (name ^
" (strict)") (C.convert
C.Strict input
) strict
;
87 check_single (name ^
" (loose)") (C.convert
C.Loose input
) loose
;
92 let test_docblock_parse () =
96 * This is a cool docblock!\n\
97 * @param int|Fun_class $first_arg\n\
98 * @param string $second_arg\n\
101 let m = DP.parse
input in
102 let check var expected
=
103 let actual = match Smap.find var
m with
104 | None
-> raise
(Test_failure var
)
106 if actual <> expected
then raise
(Test_failure var
) else () in
107 check "$first_arg" (T.ATcomposite
[T.ATint
; T.ATclass
"Fun_class"]);
108 check "$second_arg" T.ATstring
;
109 check DP.ret_key
T.ATbool
;
112 let test_integration () =
113 let testdir = Sys.argv
.(1) in
114 let testfiles = PC2.glob
(testdir ^
"/*.php") in
115 List.iter
begin fun testfile
->
116 let (dir
, base
, _
) = PC2.dbe_of_filename testfile
in
117 let outfile = PC2.filename_of_dbe
(dir
, base
, "out") in
118 let errfile = PC2.filename_of_dbe
(dir
, base
, "err") in
120 let outopt, errl
= Convert.convert
C.Loose testfile
in
121 let out = match outopt with
124 let err = (String.concat
"\n" errl
) ^
"\n" in
126 let outtmpfile = PC.new_temp_file
"augtytest" "php" in
127 PC.write_file ~file
:outtmpfile out;
128 let errtmpfile = PC.new_temp_file
"augtytest" "err" in
129 PC.write_file ~file
:errtmpfile err;
131 let outdiff = PC2.unix_diff
outtmpfile outfile in
132 if List.length
outdiff > 1 then begin
133 List.iter prerr_endline
outdiff;
134 raise
(Test_failure
"output differs")
137 let errdiff = PC2.unix_diff
errtmpfile errfile in
138 if List.length
errdiff > 1 then begin
139 List.iter prerr_endline
errdiff;
140 raise
(Test_failure
"err differs")
149 test_docblock_parse ();
151 print_endline
"Success!"