123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228open!BaseopenImportopenExpect_test_commonopenSexplib0.Sexp_convmoduleResult=struct(* Either match with an explicit success, or (lazily) produce a correction. *)type'at=|Match|Correctionof'a[@@deriving_inlinesexp_of,compare]let_=fun(_:'at)->()letsexp_of_t:'a.('a->Sexplib0.Sexp.t)->'at->Sexplib0.Sexp.t=fun(typea__004_):((a__004_->Sexplib0.Sexp.t)->a__004_t->Sexplib0.Sexp.t)->fun_of_a__001_->function|Match->Sexplib0.Sexp.Atom"Match"|Correctionarg0__002_->letres0__003_=_of_a__001_arg0__002_inSexplib0.Sexp.List[Sexplib0.Sexp.Atom"Correction";res0__003_];;let_=sexp_of_tletcompare:'a.('a->'a->int)->'at->'at->int=fun_cmp__aa__005_b__006_->ifPpx_compare_lib.phys_equala__005_b__006_then0else(matcha__005_,b__006_with|Match,Match->0|Match,_->-1|_,Match->1|Correction_a__007_,Correction_b__008_->_cmp__a_a__007__b__008_);;let_=compare[@@@end]letmapt~f=matchtwith|Match->Match|Correctionx->Correction(fx);;letvaluet~success=matchtwith|Match->success|Correctionf->f;;endletmatches_regexp~(pat:Re.t)s=Re.execp(Re.compile(Re.whole_stringpat))s;;letglob=Re.Glob.glob~anchored:true~pathname:false~expand_braces:trueletline_matches~(expect:Fmt.t)~actual=matchexpectwith|Literalexpect->expect=actual|Globexpect->matches_regexp~pat:(globexpect)actual|Regexpexpect->matches_regexp~pat:(Re.Emacs.reexpect)actual;;letliteral_line~allow_output_patternsactual:Fmt.tCst.Line.t=matchactualwith|""->Blank""|_->letline_matches_itself=(notallow_output_patterns)||line_matches~expect:(Lexer.parse_pretty_lineactual~allow_output_patterns)~actualinNot_blank{data=Literalactual;orig=(ifline_matches_itselfthenactualelseactual^" (literal)");trailing_blanks=""};;letreconcile_line~(expect:Fmt.t)~actual~allow_output_patterns:Fmt.tCst.Line.tResult.t=assert(not(String.containsactual'\n'));ifline_matches~expect~actualthenMatchelseCorrection(literal_lineactual~allow_output_patterns);;letreclines_match~(expect_lines:Fmt.tCst.Line.tlist)~(actual_lines:stringlist)~allow_output_patterns:bool=matchexpect_lines,actual_lineswith|[],[]->true|[],_->false|_,[]->false|expect::expect_lines,actual::actual_lines->letformat=Cst.Line.dataexpect~blank:(Literal"")~conflict_marker:(funmarker->Literalmarker)inletline=reconcile_line~expect:format~actual~allow_output_patternsin(matchlinewith|Match->lines_match~expect_lines~actual_lines~allow_output_patterns|Correction_->false);;letreccorrected_revacc~(expect_lines:Fmt.tCst.Line.tlist)~(actual_lines:stringlist)~allow_output_patterns:Fmt.tCst.Line.tlist=matchexpect_lines,actual_lineswith|[],[]->acc|[],actual_lines->List.foldactual_lines~init:acc~f:(funaccx->literal_linex~allow_output_patterns::acc)|_,[]->acc|expect::expect_lines,actual::actual_lines->letformat=Cst.Line.dataexpect~blank:(Literal"")~conflict_marker:(funmarker->Literalmarker)inletline=reconcile_line~expect:format~actual~allow_output_patterns|>Result.value~success:expectincorrected_rev~expect_lines~actual_lines(line::acc)~allow_output_patterns;;letreconcile_lines~expect_lines~actual_lines~allow_output_patterns:Fmt.tCst.Line.tlistResult.t=iflines_match~expect_lines~actual_lines~allow_output_patternsthenMatchelseCorrection(List.rev(corrected_rev[]~expect_lines~actual_lines~allow_output_patterns));;letexpectation_body_internal~(expect:Fmt.tCst.tExpectation.Body.t)~actual~default_indent~pad_single_line~allow_output_patterns:Fmt.tCst.tExpectation.Body.tResult.t=matchexpectwith|Exactexpect->ifexpect=actualthenMatchelseCorrection(Exactactual)|Output->Match|Prettyexpect->letactual_lines=Lexer.strip_surrounding_whitespacesactual|>Cst.stripped_original_linesinletexpect_lines=Cst.to_linesexpectin(matchreconcile_lines~expect_lines~actual_lines~allow_output_patternswith|Match->Match|Correctionreconciled_lines->letreconciled=Cst.reconcileexpect~lines:reconciled_lines~default_indentation:default_indent~pad_single_lineinCorrection(Prettyreconciled))|Unreachable->letactual_lines=Lexer.strip_surrounding_whitespacesactual|>Cst.stripped_original_linesin(matchreconcile_lines~expect_lines:[]~actual_lines~allow_output_patternswith|Match->Correction(Pretty(Empty""))|Correctionreconciled_lines->letreconciled=Cst.reconcile(Empty"")~lines:reconciled_lines~default_indentation:default_indent~pad_single_lineinCorrection(Prettyreconciled));;letexpectation_body~(expect:Fmt.tCst.tExpectation.Body.t)~actual~default_indent~pad_single_line~allow_output_patterns:Fmt.tCst.tExpectation.Body.tResult.t=letres=expectation_body_internal~expect~actual~default_indent~pad_single_line~allow_output_patternsinmatchreswith|Match->Match|Correctionc->(matchexpectation_body_internal~expect:c~actual~default_indent~pad_single_line~allow_output_patternswith|Match->res|Correction_->assertfalse);;modulePrivate=structletline_matches=line_matchesletreconcile_line=reconcile_lineend