Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file expect_test_helpers_base.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462open!Baseopen!StdioincludeExpect_test_helpers_base_intfletprint_stringstring=print_stringstring;Out_channel.(flushstdout);;moduleCR=structincludeCRletmessagethere=letcrcr=String.concat["(* ";cr;" require-failed: ";here|>Source_code_position.to_string;".\n";" Do not 'X' this CR; instead make the required property true,\n";" which will make the CR disappear. For more information, see\n";" [Expect_test_helpers_base.require]. *)"]inmatchtwith|CR->cr"CR"|CR_soon->cr"CR-soon"|CR_someday->cr"CR-someday"|Comment->String.concat["(* require-failed: ";here|>Source_code_position.to_string;". *)"]|Suppress->"";;lethide_unstable_output=function|CR->false|CR_soon|CR_someday|Comment|Suppress->true;;endmoduleSexp_style=structincludeSexp_styleletdefault_pretty=Pretty(Sexp_pretty.Config.create~color:false())letsimple_pretty=Pretty{indent=1;data_alignment=Data_not_aligned;color_scheme=[||];atom_coloring=Color_none;atom_printing=Escaped;paren_coloring=false;opening_parens=Same_line;closing_parens=Same_line;comments=Drop;singleton_limit=Singleton_limit(Atom_threshold0,Character_threshold0);leading_threshold=Atom_threshold0,Character_threshold0;separator=No_separator;sticky_comments=After};;endmodulePhys_equal(M:sigtypet[@@derivingsexp_of]end)=structtypet=M.t[@@derivingsexp_of]letequal=phys_equalendlethide_temp_files_in_string=letre=lazy(Re.compile(Re.seq[Re.str".tmp.";Re.repnRe.alnum6(Some6)]))infunstring->Re.replace_string(forcere)~by:".tmp.RANDOM"string;;lethide_positions_in_string=letmoduleRe=Re.Pcreinletexpanders=lazy([(* This first pattern has an alphabetic prefix because we want to match exceptions
and their file positions without also matching timestamps. However, [Re.Pcre]
doesn't implement back-references, precluding a simple substitution. Instead,
we provide a length of matched data to copy into the output, effectively acting
like a back-reference in this special case. *)"[a-zA-z]:[0-9]+:[0-9]+",1,":LINE:COL";"line [0-9]+:",0,"line LINE:";"line [0-9]+, characters [0-9]+-[0-9]+",0,"line LINE, characters C1-C2"]|>List.map~f:(fun(pattern,prefix_len,expansion)->letrex=Re.regexppatterninfunstring->Re.substitute~rexstring~subst:(funorig->String.concat[String.prefixorigprefix_len;expansion])))infunstring->List.fold(forceexpanders)~init:string~f:(funacexpander->expanderac);;letmaybe_hide_positions_in_string?(hide_positions=false)string=ifhide_positionsthenhide_positions_in_stringstringelsestring;;letsexp_style=refSexp_style.default_prettyletsexp_to_string?hide_positionssexp=letstring=match!sexp_stylewith|To_string_mach->Sexp.to_string_machsexp^"\n"|To_string_hum->Sexp.to_string_humsexp^"\n"|Prettyconfig->Sexp_pretty.pretty_stringconfigsexpinmaybe_hide_positions_in_string?hide_positionsstring;;letreplace=String.substr_replace_allletrecreplace_s(sexp:Sexp.t)~pattern~with_:Sexp.t=matchsexpwith|Atomatom->Atom(replaceatom~pattern~with_)|Listlist->List(List.maplist~f:(replace_s~pattern~with_));;letexpect_test_outputhere=Expect_test_collector.save_and_return_output(Expect_test_common.File.Location.of_source_code_positionhere);;letwrapf=Staged.stage(fun?hide_positionsstring->f(maybe_hide_positions_in_string?hide_positionsstring));;letrecsmash_sexpsexp~f=matchfsexpwith|Sexp.Listlist->Sexp.List(List.maplist~f:(smash_sexp~f))|Sexp.Atom_asatom->atom;;letremove_backtraces=letprefixes=(* taken from [printexc.ml] in ocaml runtime *)["Raised at ";"Re-raised at ";"Raised by primitive operation at ";"Called from "]insmash_sexp~f:(function|Sexp.(List(Atomhd::_))whenList.existsprefixes~f:(funprefix->String.is_prefix~prefixhd)->Sexp.(List[Atom"ELIDED BACKTRACE"])|s->s);;letprint_endline=Staged.unstage(wrapprint_endline)letprint_string=Staged.unstage(wrapprint_string)letprint_s?hide_positionssexp=print_string(sexp_to_string?hide_positionssexp)leton_print_cr=ref(funstring->print_endlinestring)letprint_cr_with_optional_message?(cr=CR.CR)?(hide_positions=CR.hide_unstable_outputcr)hereoptional_message=matchcrwith|Suppress->()|_->letcr=CR.messagecrhere|>maybe_hide_positions_in_string~hide_positionsin!on_print_cr(matchoptional_messagewith|None->cr|Somesexp->String.concat[cr;"\n";String.rstrip(sexp_to_string~hide_positionssexp)]);;letprint_cr?cr?hide_positionsheremessage=print_cr_with_optional_message?cr?hide_positionshere(Somemessage);;letrequire?cr?hide_positions?if_false_then_print_sherebool=matchboolwith|true->()|false->print_cr_with_optional_message?cr?hide_positionshere(Option.mapif_false_then_print_s~f:force);;letrequire_equal(typea)?cr?hide_positions?if_false_then_print_s?(message="values are not equal")here(moduleM:With_equalwithtypet=a)xy=require?cr?hide_positionshere(M.equalxy)~if_false_then_print_s:(lazy[%messagemessage~_:(x:M.t)~_:(y:M.t)~_:(if_false_then_print_s:(Sexp.tLazy.toption[@sexp.option]))]);;letrequire_compare_equal(typea)?cr?hide_positions?messagehere(moduleM:With_comparewithtypet=a)xy=require_equal?cr?hide_positions?messagehere(modulestructincludeMletequal=[%compare.equal:t]end)xy;;letrequire_sets_are_equal(typeeltcmp)?cr?hide_positions?(names="first","second")here(moduleElt:With_comparatorwithtypet=eltandtypecomparator_witness=cmp)firstsecond=require?cr?hide_positionshere(Set.equalfirstsecond)~if_false_then_print_s:(lazy(letshow_diff(name1,set1)(name2,set2)=letdiff=Set.diffset1set2inifSet.is_emptydiffthen[%message]else[%message(Printf.sprintf"in %s but not in %s"name1name2)~_:(diff:Set.M(Elt).t)]inletfirst=fstnames,firstinletsecond=sndnames,secondin[%message.omit_nil"sets are not equal"~_:(show_difffirstsecond:Sexp.t)~_:(show_diffsecondfirst:Sexp.t)]));;typetry_with_result=|Did_not_raise|RaisedofSexp.tlettry_with?raise_message?(show_backtrace=false)(typea)(f:unit->a)=Backtrace.Exn.with_recordingshow_backtrace~f:(fun()->matchignore(f():a)with|()->Did_not_raise|exceptionexn->letbacktrace=ifnotshow_backtracethenNoneelseSome(Backtrace.Exn.most_recent())inRef.set_temporarilyBacktrace.elide(notshow_backtrace)~f:(fun()->Raised[%message""~_:(raise_message:(stringoption[@sexp.option]))~_:(exn:exn)(backtrace:(Backtrace.toption[@sexp.option]))]));;letrequire_does_not_raise?cr?hide_positions?show_backtraceheref=matchtry_withf?show_backtrace~raise_message:"unexpectedly raised"with|Did_not_raise->()|Raisedmessage->print_cr?cr?hide_positionsheremessage;;letrequire_does_raise?cr?hide_positions?show_backtraceheref=matchtry_withf?show_backtracewith|Raisedmessage->print_s?hide_positionsmessage|Did_not_raise->print_cr?cr?hide_positionshere[%message"did not raise"];;letrequire_first_gen(typefirstsecond)?cr?hide_positions?(print_first:(first->Sexp.t)option)~messagehere(sexp_of_second:second->Sexp.t)(either:(first,second)Either.t)=matcheitherwith|Firstfirst->(matchprint_firstwith|None->()|Somesexp_of_first->print_s[%sexp(first:first)])|Secondsecond->print_cr?cr?hide_positionshere[%messagemessage~_:(second:second)];;letrequire_first=require_first_gen~message:"unexpected [Second]"letrequire_second?cr?hide_positions?print_secondhereprint_firsteither=require_first_gen?cr?hide_positions?print_first:print_second~message:"unexpected [First]"hereprint_first(Either.swapeither);;letrequire_some?cr?hide_positions?print_somehereoption=require_first_gen?cr~message:"unexpected [None]"?hide_positions?print_first:print_somehere[%sexp_of:unit](matchoptionwith|Somesome->Firstsome|None->Second());;letrequire_none?cr?hide_positionsheresexp_of_someoption=require_first_gen?cr~message:"unexpected [Some]"?hide_positionsheresexp_of_some(matchoptionwith|None->First()|Somesome->Secondsome);;letrequire_ok_result?cr?hide_positions?print_okheresexp_of_errorresult=require_first_gen?cr~message:"unexpected [Error]"?hide_positions?print_first:print_okheresexp_of_error(matchresultwith|Okok->Firstok|Errorerror->Seconderror);;letrequire_error_result?cr?hide_positions?print_errorheresexp_of_okresult=require_first_gen?cr~message:"unexpected [Ok]"?hide_positions?print_first:print_errorheresexp_of_ok(matchresultwith|Errorerror->Firsterror|Okok->Secondok);;letrequire_ok?cr?hide_positions?print_okhereres=require_ok_result?cr?hide_positions?print_okhere[%sexp_of:Error.t]res;;letrequire_error?cr?hide_positions?(print_error=false)heresexp_of_okres=letprint_error=Option.some_ifprint_error[%sexp_of:Error.t]inrequire_error_result?cr?hide_positions?print_errorheresexp_of_okres;;letshow_raise(typea)?hide_positions?show_backtrace(f:unit->a)=print_s?hide_positions(matchtry_withf?show_backtrace~raise_message:"raised"with|Did_not_raise->[%message"did not raise"]|Raisedmessage->message);;letquickcheck_m(typea)here?config?cr?examples?hide_positions(moduleM:Base_quickcheck.Test.Swithtypet=a)~f=Base_quickcheck.Test.result?config?examples(moduleM)~f:(funelt->letcrs=Queue.create()in(* We set [on_print_cr] to accumulate CRs in [crs]; it affects both [f elt] as
well as our call to [require_does_not_raise]. *)Ref.set_temporarilyon_print_cr(Queue.enqueuecrs)~f:(fun()->require_does_not_raisehere?cr?hide_positions(fun()->felt));ifQueue.is_emptycrsthenOk()elseError(Queue.to_listcrs))|>Result.iter_error~f:(fun(input,output)->print_s[%message"quickcheck: test failed"(input:M.t)];List.iteroutput~f:print_endline);;letquickcheck(typea)here?cr?hide_positions?(seed=Base_quickcheck.Test.default_config.seed)?(sizes=Base_quickcheck.Test.default_config.sizes)?(trials=Base_quickcheck.Test.default_config.test_count)?(shrinker=Base_quickcheck.Shrinker.atomic)?(shrink_attempts=Base_quickcheck.Test.default_config.shrink_count)?examples~sexp_of~fquickcheck_generator=quickcheck_mhere~config:{seed;test_count=trials;shrink_count=shrink_attempts;sizes}?cr?examples?hide_positions(modulestructtypet=aletsexp_of_t=sexp_ofletquickcheck_generator=quickcheck_generatorletquickcheck_shrinker=shrinkerend)~f;;