123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174open!Coreopen!ImportopenBonsai_testopenBonsai.For_openopenBonsai.Let_syntaxmodulePath=Bonsai.Private.Pathlet%expect_test"path"=letcomponent=let%sub()=opaque_const()inlet%subpath=Bonsai.Private.pathinreturn(Value.mappath~f:Path.to_unique_identifier_string)inlethandle=Handle.create(Result_spec.string(moduleString))componentinHandle.showhandle;(* The first of these "Subst_from" is actually a component that is
added by the testing helpers. *)[%expect{| bonsai_path |}];;let%expect_test"path constant folding"=letcomponent=let%sub()=Bonsai.const()inlet%subpath=Bonsai.Private.pathinreturn(Value.mappath~f:Path.to_unique_identifier_string)inlethandle=Handle.create(Result_spec.string(moduleString))componentinHandle.showhandle;(* The first of these "Subst_from" is actually a component that is
added by the testing helpers. *)[%expect{| bonsai_path |}];;letassert_path_unique_id_is_alphapath=letunique_id=Path.to_unique_identifier_stringpathinassert(String.for_allunique_id~f:(function|'a'..'z'|'_'->true|_->false));;let%test_unit"all the values are alpha"=letstring_id=Type_equal.Id.create~name:"string"[%sexp_of:string]inletkeyed=Path.Elem.keyed~compare:String.comparestring_id|>unstageinQuickcheck.testString.quickcheck_generator~sexp_of:[%sexp_of:string]~f:(funstring->letpath=Path.appendPath.empty(Path.Elem.Assoc(keyedstring))inassert_path_unique_id_is_alphapath);;let%test_unit"larger groupings of paths behave"=letstring_id=Type_equal.Id.create~name:"string"[%sexp_of:string]inletkeyed=Path.Elem.keyed~compare:String.comparestring_id|>unstageinletmoduleP=struct(* Make a dumb version of this module so that we can derive quickcheck for it. *)typet=|From|Into|Assocofstring|Switchofint[@@derivingquickcheck,sexp]letto_path_element=function|From->Path.Elem.Subst_from|Into->Path.Elem.Subst_into|Assocs->Path.Elem.Assoc(keyeds)|Switchi->Path.Elem.Switchi;;endinQuickcheck.test[%quickcheck.generator:P.tlist]~sexp_of:[%sexp_of:P.tlist]~f:(funpath->letpath=path|>List.map~f:P.to_path_element|>List.fold~init:Path.empty~f:Path.appendinassert_path_unique_id_is_alphapath);;typesimple_path=[`Subst_into|`Subst_from|`AssocofInt.t|`SwitchofInt.t]list[@@derivingsexp,quickcheck]letiterations=ref0letcompare_true=ref0letcompare_false=ref0letcompare_true_empty_list=ref0letcompare_false_empty_list=ref0let%quick_test("Bisimulating run length encoding path id comparison and slow but \
simpler comparison"[@remember_failures])=fun((a,b):simple_path*simple_path)->incriterations;letint_id=Type_equal.Id.create~name:"int"[%sexp_of:int]inletpath_a,path_b=Tuple2.map(a,b)~f:(funelements->List.foldelements~init:Bonsai.Private.Path.empty~f:(funpathelement->letelement=matchelementwith|`Subst_from->Bonsai.Private.Path.Elem.Subst_from|`Subst_into->Subst_into|`Associ->Assoc(T{key=i;id=int_id;compare=[%compare:int]})|`Switchi->SwitchiinBonsai.Private.Path.appendpathelement))inletcorrect_result=Bonsai.Private.Path.For_testing.slow_but_correct_compare_for_bisimulationpath_apath_binletfast_result=Bonsai.Private.Path.comparepath_apath_binifcorrect_result=0then(incrcompare_true;matcha,bwith|[],[]->incrcompare_true_empty_list|_->())else(incrcompare_false;matcha,bwith|[],_|_,[]->incrcompare_false_empty_list|_->());assert(correct_result=fast_result);;let%expect_test("distribution of quick_test samples"[@tags"no-js"])=print_s[%message""~total:(!iterations:int)~the_same:(!compare_true-!compare_true_empty_list:int)~not_the_same:(!compare_false-!compare_false_empty_list:int)~includes_the_empty_list:(!compare_true_empty_list+!compare_false_empty_list:int)];[%expect{|
((total 10000)
(the_same 62)
(not_the_same 6095)
(includes_the_empty_list 3843))
|}];;let%quick_test("Bisimulating run length encoding path id comparison and slow but same \
list"[@remember_failures])=fun(path:simple_path)->letint_id=Type_equal.Id.create~name:"int"[%sexp_of:int]inletpath_a,path_b=Tuple2.map(path,path)~f:(funpath->(* Constructing the same path twice is silly, but it's so that the phys_equal
doesn't accidentally prevent the functions we want to compare from running... *)List.foldpath~init:Bonsai.Private.Path.empty~f:(funpathelement->letelement=matchelementwith|`Subst_from->Bonsai.Private.Path.Elem.Subst_from|`Subst_into->Subst_into|`Associ->Assoc(T{key=i;id=int_id;compare=[%compare:int]})|`Switchi->SwitchiinBonsai.Private.Path.appendpathelement))inletcorrect_result=Bonsai.Private.Path.For_testing.slow_but_correct_compare_for_bisimulationpath_apath_binletfast_result=Bonsai.Private.Path.comparepath_apath_binassert(correct_result=fast_result);;