diff options
Diffstat (limited to 'lib/xmerl/test/test_xmerl.erl')
-rw-r--r-- | lib/xmerl/test/test_xmerl.erl | 329 |
1 files changed, 329 insertions, 0 deletions
diff --git a/lib/xmerl/test/test_xmerl.erl b/lib/xmerl/test/test_xmerl.erl new file mode 100644 index 0000000000..d2c5d35a85 --- /dev/null +++ b/lib/xmerl/test/test_xmerl.erl @@ -0,0 +1,329 @@ +%%%------------------------------------------------------------------- +%%% File : test_xmerl.erl +%%% Author : Bertil Karlsson <bertil@finrod> +%%% Description : +%%% +%%% Created : 2 Dec 2003 by Bertil Karlsson <bertil@finrod> +%%%------------------------------------------------------------------- +-module(test_xmerl). + +-compile(export_all). + +-define(xmerl_test_root,"/ldisk/xml/xml-test-suite/xmlconf"). +-define(jclark_subdir,"/ldisk/xml/xml-test-suite/xmlconf/xmltest"). +-define(sun_subdir,"/ldisk/xml/xml-test-suite/xmlconf/sun"). +-define(xerox_subdir,"/ldisk/xml/xml-test-suite/xmlconf/japanese"). +-define(oasis_subdir,"/ldisk/xml/xml-test-suite/xmlconf/oasis"). +-define(ibm_subdir,"/ldisk/xml/xml-test-suite/xmlconf/ibm"). + + +get_xmlconf() -> + FileName = filename:join(?xmerl_test_root,"xmlconf.xml"), + {ok,L} = read_file(FileName), + L. + +read_file(FileName) -> + case file:read_file(FileName) of + {ok,Binary} -> + {ok,binary_to_list(Binary)}; + Err -> + exit({error,Err}) + end. + +get_file(F="sun"++_Rest) -> + get_sun_xml(F); +get_file(F="jclark-xmltest") -> + get_jclark_xml(F); +get_file(F="xerox-japanese") -> + get_xerox_xml(F); +get_file(F="nist-oasis") -> + get_oasis_xml(F); +get_file("ibm-"++Rest) -> + get_ibm_xml(Rest). + + +get_sun_xml(F) -> + FileName = filename:join([?sun_subdir,F++".xml"]), + {ok,L} = read_file(FileName), + L. +get_jclark_xml(_F) -> + FileName = filename:join([?jclark_subdir,"xmltest.xml"]), + {ok,L} = read_file(FileName), + L. +get_xerox_xml(_F) -> + FileName = filename:join([?xerox_subdir,"japanese.xml"]), + {ok,L} = read_file(FileName), + L. +get_oasis_xml(_F) -> + FileName = filename:join([?oasis_subdir,"oasis.xml"]), + {ok,L} = read_file(FileName), + L. +get_ibm_xml(F) -> + FileName = filename:join([?ibm_subdir,"ibm_oasis_"++F++".xml"]), + {ok,L} = read_file(FileName), + L. + +%% The generated xml file must have a unique name: concatenate the +%% sub directory name and the ID of the TEST tag. +%% In each file the start of xmlconf.xml is included. Then a TEST +%% follows. It must be properly finished with end tags. +extract_TESTSUITEs() -> + TestSuites = ["sun-valid","sun-invalid","sun-not-wf","sun-error", + "jclark-xmltest","xerox-japanese","nist-oasis", + "ibm-invalid","ibm-not-wf","ibm-valid"], + Pid=spawn_link(?MODULE,ticker,[]), + lists:foreach(fun extract_TESTCASES/1,TestSuites), + generate_testfuncs(), + xmerl_ticker ! finished. + +extract_TESTCASES(Suite) -> +% io:format("extract_TESTCASES:1~n",[]), + L = get_file(Suite), % fetch xml file in sub directory +% io:format("Reading Suite: ~p~n",[Suite]), + Prol = xmlconf_prolog(), +% io:format("Reading xmlconf.xml~n",[]), + xmerl_ticker ! {suite,Suite}, + extract_TESTs(Suite,L,Prol,[]). + +extract_TESTs(Suite,TCfile,Prol,TCAcc) -> + case find_start_tag(Suite,TCfile,[],TCAcc) of + {[],_,_,_} -> ok; +%% print_filenames(); + {T,Rest,TC,ID} -> + generate_TEST(Suite,ID,Prol,TC,T), + extract_TESTs(Suite,Rest,Prol,TC) +% file_output("out.xml",L1) + end. + +generate_TEST(Suite,ID,Prolog,TC,T) -> +% GenDir = filename:join(["test",sub_dir(Suite)]), + GenDir = sub_dir(Suite), + Extension = extension(Suite), +% Filename = filename:join([GenDir,ID ++ Extension]), + Filename = mk_filename(Suite,GenDir,ID ++ Extension), + save_filename(Suite,ID), + {ok,IOF}=file:open(Filename,[write]), + TSEnding = testsuite_end(), + TCEnding = testcases_end(length(TC)), + file:write(IOF,Prolog ++ "\n\n" ++ TC ++ "\n\n" ++ T ++ "\n\n" ++ + TCEnding++ "\n\n" ++ TSEnding), + file:close(IOF). + +save_filename("xerox-japanese",Name) -> + NewName = "japanese-"++Name, + save_filename1(NewName); +save_filename(_,Name) -> + save_filename1(Name). + +save_filename1(Name) -> + Saves = case get(filenames) of + undefined -> + []; + L -> L + end, + put(filenames,[Name|Saves]). + +generate_testfuncs() -> + Filenames = get(filenames), + Res = (catch generate_testfuncs(lists:reverse(Filenames))), + io:format("~p~n",[Res]). +generate_testfuncs(Filenames) -> + file:delete(testfuncs.erl), + {ok,IOF} = file:open(testfuncs.erl,[append]), + lists:foreach(fun(X) -> + RN = filename:rootname(X), + TestDirPath = "filename:join([?config(data_dir,Config),"++xmerl_SUITE:testcase_dir(list_to_atom(RN)), + file:write(IOF,"'"++RN++"'(suite) -> [];\n'"++RN++ + "'(Config) ->\n"++ + " ?line file:set_cwd(?config(data_dir,Config)),\n"++ + " ?line {A,_} = xmerl_scan:file("++ + TestDirPath++",\""++RN++".xml\"])"++ + ",[]),\n"++ + " ?line C = xmerl:export([A],xmerl_test)."++ + "\n\n") end,Filenames), + file:close(IOF), + io:format("~ngenerated ~w testcases.erl.~n",[length(Filenames)]). + +print_filenames() -> + Filenames = get(filenames), + io:format("~n,~w files generated.~n[",[length(Filenames)]), + lists:foreach(fun(X) -> + io:format("~p,",[list_to_atom(X)]) end, + Filenames), + io:format("]~n"), + put(filenames,[]). + + +mk_filename("xerox-japanese",GenDir,Name) -> + filename:join([GenDir,"japanese-"++Name]); +mk_filename(_,GenDir,Name) -> + filename:join([GenDir,Name]). + +file_output(Filename,Content) -> + {ok,IOF}=file:open(Filename,[write]), + C1 = xmlconf_prolog(), + C2 = xmlconf_end(), + file:write(IOF,C1 ++ "\n\n" ++ Content ++ "\n\n" ++ C2), + file:close(IOF). + + +find_start_tag(Suite,"<TESTCASES"++Rest,TAcc,TCAcc) -> + {L,Rest2}=parse_until_end_TCs_skip_base(Rest,[]), + find_start_tag(Suite,Rest2,TAcc,["<TESTCASES"++L|TCAcc]); +find_start_tag(Suite,"</TESTCASES>"++Rest,TAcc,[H|T]) -> + find_start_tag(Suite,Rest,TAcc,T); +find_start_tag(Suite,"<TEST"++Rest,TAcc,TCAcc) -> + Id = extract_ID(Rest), + {L,Rest2} = parse_until_end_T(Suite,Rest,[]), + {"<TEST" ++ L,Rest2,TCAcc,Id}; +find_start_tag(Suite,[H|T],TAcc,TCAcc) -> + find_start_tag(Suite,T,TAcc,TCAcc); +find_start_tag(_,[],TAcc,TCAcc) -> % no more tests + {TAcc,[],TCAcc,[]}. + +parse_until_end_T(Suite,"URI"++Rest,Acc) -> + {Up2URI,Rest2}=parse_upto_URI_val(Suite,Rest,["URI"]), + parse_until_end_T(Suite,Rest2,[Up2URI|Acc]); +% parse_until_end_T(Suite,"</TEST>"++Rest,Acc) -> +% {lists:flatten(lists:reverse(["</TEST>"|Acc])),Rest}; +parse_until_end_T(Suite,"OUTPUT"++Rest,Acc) -> + {Up2OUTPUT,Rest2}=parse_upto_URI_val(Suite,Rest,["OUTPUT"]), + parse_until_end_T(Suite,Rest2,[Up2OUTPUT|Acc]); +parse_until_end_T(_Suite,"</TEST>"++Rest,Acc) -> + {lists:flatten(lists:reverse(["</TEST>"|Acc])),Rest}; +parse_until_end_T(Suite,[H|T],Acc) -> + parse_until_end_T(Suite,T,[H|Acc]); +parse_until_end_T(_,[],Acc) -> + exit({error,{"unexpected end",lists:reverse(Acc)}}). + +parse_upto_URI_val(Suite,[H|Rest],Acc) when H==$\t;H==$\n;H==$\s -> + parse_upto_URI_val(Suite,Rest,[H|Acc]); +parse_upto_URI_val(Suite,[H|Rest],Acc) when H/="=" -> + {lists:flatten(lists:reverse([H|Acc])),Rest}; +parse_upto_URI_val(Suite,[H|Rest],Acc) -> + parse_upto_URI_val2(Suite,Rest,[H|Acc]). + +parse_upto_URI_val2(Suite,[H|Rest],Acc) when H==$"; H==$' -> + SubDir = sub_dir(Suite), + {lists:flatten(lists:reverse([$/,SubDir,H|Acc])),Rest}; +parse_upto_URI_val2(Suite,[H|T],Acc) -> + parse_upto_URI_val2(Suite,T,[H|Acc]). + +parse_until_end_TCs_skip_base(">"++Rest,Acc) -> + {lists:flatten(lists:reverse(["\n",">"|Acc])),Rest}; +parse_until_end_TCs_skip_base("xml:base="++Rest,Acc) -> + Rest2=skip_base_def(Rest), + parse_until_end_TCs_skip_base(Rest2,Acc) -> +parse_until_end_TCs_skip_base([H|T],Acc) -> + parse_until_end_TCs_skip_base(T,[H|Acc]). + +skip_base_def([Del|R]) -> + skip_base_def(R,Del). +skip_base_def([Del|R],Del) -> + R; +skip_base_def([_H|R],Del) -> + skip_base_def(R,Del). + +% parse_end_T("</TEST>"++Rest,Acc) -> +% {lists:flatten(lists:reverse(["</TEST>"|Acc])),Rest}; +% parse_end_T([H|T],Acc) -> +% parse_end_T(T,[H|Acc]). + + +xmlconf_prolog() -> + FC = get_xmlconf(), + parse_xmlconf_prolog(FC,[]). + + +%% +extract_ID("ID"++Rest) -> + extract_ID2(Rest); +extract_ID([H|T]) -> + extract_ID(T). + +extract_ID2([H|Rest]) when H==$";H==$' -> + extract_IDval(Rest,[]); +extract_ID2([H|T]) -> %skip '=' and white space + extract_ID2(T). + +extract_IDval([H|Rest],Acc) when H==$";H==$' -> + lists:flatten(lists:reverse(Acc)); +extract_IDval([H|T],Acc) -> + extract_IDval(T,[H|Acc]). + + +testsuite_end() -> + "</TESTSUITE>". + +testcases_end(0) -> + ""; +testcases_end(N) -> + "</TESTCASES>" ++ "\n" ++testcases_end(N-1). + +xmlconf_end() -> + "</TESTSUITE>". + + +parse_xmlconf_prolog("href=\"xmlconformance.xsl\""++Rest,Acc) -> + HRef = lists:reverse("href=\"../../xmlconformance.xsl\""), + parse_xmlconf_prolog(Rest,HRef++Acc); +parse_xmlconf_prolog("<!DOCTYPE TESTSUITE SYSTEM \"testcases.dtd\""++Rest,Acc) -> + Rest2 = skip_entity_defs(Rest), + DocType = lists:reverse("<!DOCTYPE TESTSUITE SYSTEM \"../../testcases.dtd\">"), + parse_xmlconf_prolog(Rest2,DocType++Acc); +parse_xmlconf_prolog("<TESTSUITE"++Rest,Acc) -> + Acc2 = parse_until_TESTSUITE_tag(Rest,[]), + lists:flatten(lists:reverse([Acc2,"<TESTSUITE"|Acc])); +parse_xmlconf_prolog([H|T],Acc) -> + parse_xmlconf_prolog(T,[H|Acc]); +parse_xmlconf_prolog([],Acc) -> + exit({error,{"unexpected end",lists:reverse(Acc)}}). + +parse_until_TESTSUITE_tag(">"++_Rest,Acc) -> + lists:flatten(lists:reverse([">"|Acc])); +parse_until_TESTSUITE_tag([H|T],Acc) -> + parse_until_TESTSUITE_tag(T,[H|Acc]); +parse_until_TESTSUITE_tag([],Acc) -> + exit({error,{"unexpected end",lists:reverse(Acc)}}). + +skip_entity_defs("]>"++Rest) -> + Rest; +skip_entity_defs([H|T]) -> + skip_entity_defs(T). + +sub_dir("jclark-xmltest") -> + "xmerl_SUITE_data/xmltest"; +sub_dir("xerox-japanese") -> + "xmerl_SUITE_data/japanese"; +sub_dir("sun"++_Rest) -> + "xmerl_SUITE_data/sun"; +sub_dir("nist-oasis") -> + "xmerl_SUITE_data/oasis"; +sub_dir("ibm"++_Rest) -> + "xmerl_SUITE_data/ibm". + +extension("ibm"++_R) -> + ""; +extension(_) -> + ".xml". + +%***************************** +ticker() -> + register(xmerl_ticker,self()), + receive + {suite,Name} -> + io:format("~nGenerating suite ~p",[Name]) + end, + ticker_loop(). + +ticker_loop() -> + receive + {suite,Name} -> + io:format("~nGenerating suite ~p",[Name]), + ticker_loop(); + finished -> + ok + after 400 -> +% io:format(".",[]), + ticker_loop() + end. |