open Treeconstructor_interp open Format open Json_type let dump state ff = let rec d indent id = match (ElementMap.find id state.elements).node with | DoctypeNode (name, pubid, sysid) -> fprintf ff "| %s\n" indent name (* XXX *) | DocumentNode c -> List.iter (d indent) (List.rev c); | CommentNode s -> fprintf ff "| %s\n" indent s | TextNode s -> fprintf ff "| %s\"%s\"\n" indent s | ElementNode { name = n; attributes = a; children = c } -> fprintf ff "| %s<%s>\n" indent n; List.iter (fun (k,v) -> fprintf ff "| %s %s=\"%s\"\n" indent k v) (List.sort (fun (k1,_) (k2,_) -> String.compare k1 k2) a); List.iter (d (indent ^ " ")) (List.rev c); in d "" 0 (* ; List.iter (fprintf ff "# %s\n") (List.rev state.parseErrors) *) let begins withStr str = String.length str > String.length withStr && String.sub str 0 (String.length withStr) = withStr let char_list_of_string s = let l = ref [] in String.iter (fun c -> l := c :: !l) s; List.rev !l let jsonToString = function | String s -> s | Int i -> string_of_int i | _ -> failwith "unrecognised type in jsonToString" let runTreeTests filename = let json_obj = Json_io.load_json filename in (match json_obj with | Array tests -> List.iter (function test -> let testData = Browse.make_table (Browse.objekt test) in let input = List.flatten (List.map (function | String "ParseError" -> [ParseErrorToken] | Array [String "DOCTYPE"; String name; pubid; sysid; Bool correct] -> [DoctypeToken { doctypename = name; pubid = (match pubid with String s -> Some s | _ -> None); sysid = (match sysid with String s -> Some s | _ -> None); correct = correct }] | Array [String "StartTag"; String name; Object attrs] -> [StartTagToken { start_tag_name = name; start_tag_attributes = List.map (function (k,v) -> (k, jsonToString v)) attrs }] | Array [String "EndTag"; String name] -> [EndTagToken { end_tag_name = name }] | Array [String "Comment"; String text] -> [CommentToken text] | Array [String "Character"; String text] -> List.map (fun c -> CharacterToken c) (char_list_of_string text) | Array [String "Character"; Int text] (* broken input... *) -> List.map (fun c -> CharacterToken c) (char_list_of_string (string_of_int text)) | t -> failwith ("unhandled token " ^ Json_io.string_of_json t) ) (Browse.array (Browse.field testData "input"))) in let expected = Browse.string (Browse.field testData "output") in let errors = Browse.list Browse.string (Browse.field testData "errors") in (* print_string "Input:\n"; print_string (Json_io.string_of_json (Browse.field testData "input")); print_newline (); *) let state = interpret input in dump state str_formatter; let output = flush_str_formatter () in if output = expected && List.length errors = List.length state.parseErrors then print_string "OK\n" else ( print_string "Not OK\n"; print_string "Input:\n"; print_string (Json_io.string_of_json (Browse.field testData "input")); print_newline (); print_string "Expected:\n"; print_string expected; (*print_string "("; print_int numerrors; print_string " errors)\n";*) List.iter (fun s -> print_string s; print_newline ()) errors; print_string "Got:\n"; print_string output; (*print_string "("; print_int (List.length state.parseErrors); print_string " errors)\n";*) List.iter (fun s -> print_string s; print_newline ()) (List.rev state.parseErrors); print_newline (); ) ) tests | _ -> failwith "tests should be a JSON array") (*let traceParse str = let state = interpret str in dump state str_formatter; let output = flush_str_formatter () in print_string output; print_newline ()*) let _ = Arg.parse [ ("-tree", Arg.String runTreeTests, "run JSON test file"); (*("-trace", Arg.String traceParse, "trace parse of string");*) ] (fun _ -> ()) "foo"