123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378(**************************************************************************)(* The OUnit library *)(* *)(* Copyright (C) 2002-2008 Maas-Maarten Zeeman. *)(* Copyright (C) 2010 OCamlCore SARL *)(* Copyright (C) 2013 Sylvain Le Gall *)(* *)(* The package OUnit is copyright by Maas-Maarten Zeeman, OCamlCore SARL *)(* and Sylvain Le Gall. *)(* *)(* Permission is hereby granted, free of charge, to any person obtaining *)(* a copy of this document and the OUnit software ("the Software"), to *)(* deal in the Software without restriction, including without limitation *)(* the rights to use, copy, modify, merge, publish, distribute, *)(* sublicense, and/or sell copies of the Software, and to permit persons *)(* to whom the Software is furnished to do so, subject to the following *)(* conditions: *)(* *)(* The above copyright notice and this permission notice shall be *)(* included in all copies or substantial portions of the Software. *)(* *)(* The Software is provided ``as is'', without warranty of any kind, *)(* express or implied, including but not limited to the warranties of *)(* merchantability, fitness for a particular purpose and noninfringement. *)(* In no event shall Maas-Maarten Zeeman be liable for any claim, damages *)(* or other liability, whether in an action of contract, tort or *)(* otherwise, arising from, out of or in connection with the Software or *)(* the use or other dealings in the software. *)(* *)(* See LICENSE.txt for details. *)(**************************************************************************)openOUnitUtilsletget_test_context,set_test_context,reset_test_context=letcontext_opt=refNonein(* get *)(fun()->match!context_optwith|Somectxt->ctxt|None->failwith"Function need to be called from inside a test."),(functxt->context_opt:=Somectxt),(fun_->context_opt:=None)typenode=ListItemofint|Labelofstringletnode1_of_node=function|OUnitTest.ListItemi->ListItemi|OUnitTest.Labels->Labelsletnode_of_node1=function|ListItemi->OUnitTest.ListItemi|Labels->OUnitTest.Labelstypepath=nodelistletpath1_of_pathpth=List.mapnode1_of_nodepthtypetest_fun=unit->unittypetest=TestCaseoftest_fun|TestListoftestlist|TestLabelofstring*testletrectest1_of_test=function|OUnitTest.TestCase(_,f)->TestCase(fun()->f(get_test_context()))|OUnitTest.TestListlst->TestList(List.maptest1_of_testlst)|OUnitTest.TestLabel(str,tst)->TestLabel(str,test1_of_testtst)letrectest_of_test1=function|TestCasef->OUnitTest.TestCase(OUnitTest.Short,functxt->set_test_contextctxt;f();reset_test_context())|TestListlst->OUnitTest.TestList(List.maptest_of_test1lst)|TestLabel(str,tst)->OUnitTest.TestLabel(str,test_of_test1tst)letrecounit2_of_ounit1=function|TestCasef->OUnit2.test_case(functxt->set_test_contextctxt;f();reset_test_context())|TestListlst->OUnit2.test_list(List.mapounit2_of_ounit1lst)|TestLabel(lbl,test)->OUnit2.(>:)lbl(ounit2_of_ounit1test)typetest_result=RSuccessofpath|RFailureofpath*string|RErrorofpath*string|RSkipofpath*string|RTodoofpath*stringlettest_result1_of_test_resultpathrslt=letpath1=path1_of_pathpathinletrslt1=matchrsltwith|OUnitTest.RSuccess->RSuccesspath1|OUnitTest.RFailure(str,_,_)->RFailure(path1,str)|OUnitTest.RError(str,_)->RError(path1,str)|OUnitTest.RSkipstr->RSkip(path1,str)|OUnitTest.RTodostr->RTodo(path1,str)|OUnitTest.RTimeouttest_length->RError(path1,(Printf.sprintf"timeout after %.1fs."(OUnitTest.delay_of_lengthtest_length)))inrslt1typetest_event=EStartofpath|EEndofpath|EResultoftest_resulttypetest_results=test_resultlistletlist_result1_of_list_result=List.map(fun(pth,rslt,_)->test_result1_of_test_resultpthrslt)letassert_failure=OUnitAssert.assert_failureletassert_bool=OUnitAssert.assert_boollet(@?)=OUnitAssert.assert_boolletassert_string=OUnitAssert.assert_stringletassert_command?exit_code?sinput?foutput?use_stderr?env?(verbose=false)prgargs=letctxt=letctxt=get_test_context()inletconf'=Hashtbl.copyctxt.OUnitTest.confinOUnitConf.set~origin:"OUnit.assert_command"conf'"verbose"(string_of_boolverbose);{ctxtwithOUnitTest.test_logger=OUnitLogger.Test.create(OUnitLoggerStd.std_loggerconf'OUnitLogger.shard_default)ctxt.OUnitTest.path;}inOUnitAssert.assert_command?exit_code?sinput?foutput?use_stderr?env~ctxtprgargsletassert_equal?cmp?printer?pp_diff?msgab=OUnitAssert.assert_equal?cmp?printer?pp_diff?msgabletassert_raises?msgexcf=OUnitAssert.assert_raises?msgexcfletskip_if=OUnitAssert.skip_iflettodo=OUnitAssert.todoletcmp_float?epsilonf1f2=OUnitUtils.cmp_float?epsilonf1f2letbracketprefpost()=OUnitTest.section_ctxt(get_test_context())(functxt->letfixture=OUnitBracket.create(fun_->pre())(funfixture_->postfixture)ctxtinlet()=ffixturein())letbracket_tmpfile?prefix?suffix?modegen()=OUnitTest.section_ctxt(get_test_context())(functxt->letfixture=OUnitBracket.bracket_tmpfile?prefix?suffix?modectxtingenfixture)let(>:)ab=test1_of_test(OUnitTest.(>:)a(test_of_test1b))let(>::)ab=test1_of_test(OUnitTest.(>::)a(fun_->b()))let(>:::)ab=test1_of_test(OUnitTest.(>:::)a(List.maptest_of_test1b))lettest_decorategtst=test1_of_test(OUnitTest.test_decorate(funf->letf1=(fun()->f(get_test_context()))inletf1'=gf1in(functxt->set_test_contextctxt;f1'();reset_test_context()))(test_of_test1tst))lettest_filter?skiplsttest=letres=OUnitTest.test_filter?skiplst(test_of_test1test)inmatchreswith|Sometst->Some(test1_of_testtst)|None->Nonelettest_case_counttst=OUnitTest.test_case_count(test_of_test1tst)letstring_of_nodend=OUnitTest.string_of_node(node_of_node1nd)letstring_of_pathpth=OUnitTest.string_of_path(List.mapnode_of_node1pth)lettest_case_pathstst=letlst=OUnitTest.test_case_paths(test_of_test1tst)inList.map(List.mapnode1_of_node)lstletdefault_v1_conf?(verbose=false)()=OUnitConf.default~preset:["chooser","simple";"runner","sequential";"results_style_1_X","true";"verbose",(string_of_boolverbose);"output_file","none";]()letperform_testlogger1tst=letlogger=OUnitLogger.fun_logger(function|{OUnitLogger.event=OUnitLogger.GlobalEvent_;_}->()|{OUnitLogger.event=OUnitLogger.TestEvent(path,test_event);_}->beginletpath1=path1_of_pathpathinmatchtest_eventwith|OUnitLogger.EStart->logger1(EStartpath1)|OUnitLogger.EEnd->logger1(EEndpath1)|OUnitLogger.EResultrslt->logger1(EResult(test_result1_of_test_resultpathrslt))|OUnitLogger.ELog_|OUnitLogger.ELogRaw_->()end)ignoreinletconf=default_v1_conf()inlist_result1_of_list_result(OUnitCore.perform_testconflogger(snd(OUnitRunner.choiceconf))(snd(OUnitChooser.choiceconf))(test_of_test1tst))letrun_test_tt?verbosetest=letconf=default_v1_conf?verbose()inlist_result1_of_list_result(OUnitCore.run_test_ttconf(OUnitLoggerStd.createconfOUnitLogger.shard_default)(snd(OUnitRunner.choiceconf))(snd(OUnitChooser.choiceconf))(test_of_test1test))letrun_test_tt_main?(arg_specs=[])?(set_verbose=ignore)suite=letsuite=test_of_test1suiteinletonly_test=ref[]inletlist_test=reffalseinletverbose=reffalseinletspecs=["-verbose",Arg.Setverbose," Rather than displaying dots while running the test, be more verbose.";"-only-test",Arg.String(funstr->only_test:=str::!only_test),"path Run only the selected tests.";"-list-test",Arg.Setlist_test," List tests";]@arg_specsinlet()=Arg.parse(Arg.alignspecs)(funx->raise(Arg.Bad("Bad argument : "^x)))("usage: "^Sys.argv.(0)^" [options] [-only-test path]*")inletconf=default_v1_conf~verbose:!verbose()inset_verbose(OUnitLoggerStd.verboseconf);if!list_testthenbeginList.iter(funpth->print_endline(OUnitTest.string_of_pathpth))(OUnitTest.test_case_pathssuite);[]endelsebeginletnsuite=if!only_test=[]thensuiteelsebeginmatchOUnitTest.test_filter~skip:true!only_testsuitewith|Sometest->test|None->failwithf"Filtering test %s lead to no tests."(String.concat", "!only_test)endinlettest_results=OUnitCore.run_test_ttconf(OUnitLoggerStd.std_loggerconfOUnitLogger.shard_default)(snd(OUnitRunner.choiceconf))(snd(OUnitChooser.choiceconf))nsuiteinifnot(OUnitResultSummary.was_successfultest_results)thenexit1elselist_result1_of_list_resulttest_results;end