Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file ppx_expect.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331open!BaseopenPpxlibopenAst_builder.DefaultopenPpx_expect_runtimeletstrict_indent=reffalsemoduleExpr=structletoption~locexpression_of_a=function|Somex->[%exprSome[%eexpression_of_a~locx]]|None->[%exprNone];;letpair~locexpression_of_aexpression_of_b(a,b)=[%expr[%eexpression_of_a~loca],[%eexpression_of_b~locb]];;letdelimiter~loc(delimiter:Delimiter.t)=[%expr([%ematchdelimiterwith|TQuote->[%exprTQuote]|T(Tagtag)->[%exprT(Tag[%eestring~loctag])]]:Ppx_expect_runtime.Delimiter.t)];;letid~locid=[%exprPpx_expect_runtime.Expectation_id.of_int_exn[%eeint~loc(Expectation_id.to_int_exnid)]];;letcompact_loc~loc({start_bol;start_pos;end_pos}:Compact_loc.t)=[%expr{start_bol=[%eeint~locstart_bol];start_pos=[%eeint~locstart_pos];end_pos=[%eeint~locend_pos]}];;letpayload~loc({contents;tag}:Payload.t)=[%expr{contents=[%eestring~loccontents];tag=[%edelimiter~loctag]}];;letid_expr_alist~localist=List.mapalist~f:(fun(expect_id,expr)->[%expr[%eid~locexpect_id],[%eexpr]])|>elist~loc;;letflexibility_of_strictness~loc=if!strict_indentthen[%exprPpx_expect_runtime.Expect_node_formatting.Flexibility.Exactly_formatted]else[%exprPpx_expect_runtime.Expect_node_formatting.Flexibility.Flexible_moduloPpx_expect_runtime.Expect_node_formatting.default];;endletcompact_loc_of_ppxlib_location{loc_start;loc_end;loc_ghost=_}:Compact_loc.t={start_bol=loc_start.pos_bol;start_pos=loc_start.pos_cnum;end_pos=loc_end.pos_cnum};;moduleExpectation_node=structtypeexpect_node_info={located_payload:(Payload.t*Compact_loc.t)option;node_loc:Compact_loc.t}typet=|Expectofexpect_node_info|Expect_exactofexpect_node_info|Expect_unreachableofCompact_loc.tletto_expr~loct=letqualify_namenode_name=pexp_ident~loc(Located.lident~loc("Ppx_expect_runtime.Test_node.Create."^node_name))inletmake_expect_nodenode_name{located_payload;node_loc}=[%expr[%equalify_namenode_name]~formatting_flexibility:[%eExpr.flexibility_of_strictness~loc]~located_payload:[%eExpr.(option~loc(pairpayloadcompact_loc))located_payload]~node_loc:[%eExpr.compact_loc~locnode_loc]]inmatchtwith|Expectexpect_node_info->make_expect_node"expect"expect_node_info|Expect_exactexpect_node_info->make_expect_node"expect_exact"expect_node_info|Expect_unreachablenode_loc->[%expr[%equalify_name"expect_unreachable"]~node_loc:[%eExpr.compact_loc~locnode_loc]];;endmodulePattern=structopenAst_patternletstring()=map(single_expr_payload(as__(pexp_constant(pconst_string______))))~f:(funfpayload_exprcontents_loctag->let(tag:Delimiter.t)=matchtagwith|None->TQuote|Sometag->T(Tagtag)inletpayload_loc=compact_loc_of_ppxlib_locationpayload_expr.pexp_locinletlocated_payload=Some(({contents;tag}:Payload.t),payload_loc)inf~located_payload);;letempty()=pstrnilletmaybe_string()=string()|||map(empty())~f:(funf->f~located_payload:None)endletmaybe_string_payload=Pattern.maybe_stringmoduleParsed_node=structtypet=|Expectation_nodeofExpectation_id.t*Expectation_node.t|Outputletexpect=Extension.Expert.declare"expect"Expression(Pattern.maybe_string())(fun~located_payloadnode_loc->Expectation_node(Expectation_id.mint(),Expect{located_payload;node_loc}));;letexpect_exact=Extension.Expert.declare"expect_exact"Expression(Pattern.maybe_string())(fun~located_payloadnode_loc->Expectation_node(Expectation_id.mint(),Expect_exact{located_payload;node_loc}));;letexpect_output=Extension.Expert.declare"@expect.output"Expression(Pattern.empty())(fun_->Output);;letexpect_unreachable=Extension.Expert.declare"@expect.unreachable"Expression(Pattern.empty())(funcompact_loc->Expectation_node(Expectation_id.mint(),Expect_unreachablecompact_loc));;letexpectations=[expect;expect_exact;expect_output;expect_unreachable]letmatch_expectatione=matche.pexp_descwith|Pexp_extensionextension->Extension.Expert.convertexpectations~loc:e.pexp_locextension|_->None;;endletis_a_ppx_expect_ext_nodee=Option.is_some(Parsed_node.match_expectatione)letreplace_and_collect_expects=objectinherit[(Expectation_id.t,expression)List.Assoc.t]Ast_traverse.fold_mapassupermethod!expression({pexp_attributes;pexp_loc=loc;_}asexpr)acc=matchParsed_node.match_expectationexprwith|None->super#expressionexpracc|Someexpect_node->letexpr,acc=matchexpect_node(compact_loc_of_ppxlib_locationloc)with|Expectation_node(id,expect_expr)->([%exprPpx_expect_test_block.run_test~test_id:[%eExpr.id~locid]],(id,Expectation_node.to_exprexpect_expr~loc)::acc)|Output->[%exprPpx_expect_test_block.read_test_output_no_backtrace_check()],accinMerlin_helpers.hide_expression{exprwithpexp_attributes},accend;;lettransform_let_expect~trailing_location~tags~expected_exn~description~locbody=letbody,expectations=replace_and_collect_expects#expressionbody[]inletfilename_rel_to_project_root=Ppx_here_expander.expand_filenameloc.loc_start.pos_fnameinlettrailing_location=compact_loc_of_ppxlib_locationtrailing_locationinletbody_loc=compact_loc_of_ppxlib_location{loc_start=loc.loc_start;loc_end=body.pexp_loc.loc_end;loc_ghost=true}inlettrailing_test_id=Expectation_id.mint()inletexn_test_id=Expectation_id.mint()in[%exprmatchPpx_inline_test_lib.testingwith|`Not_testing->()|`Testing_->letmodulePpx_expect_test_block=Ppx_expect_runtime.Make_test_block(Expect_test_config)inPpx_expect_test_block.run_suite~filename_rel_to_project_root:[%eestring~locfilename_rel_to_project_root]~line_number:[%eeint~locloc.loc_start.pos_lnum]~location:[%eExpr.compact_loc~loc(compact_loc_of_ppxlib_locationloc)]~trailing_loc:[%eExpr.compact_loc~loctrailing_location]~body_loc:[%eExpr.compact_loc~locbody_loc]~formatting_flexibility:[%eExpr.flexibility_of_strictness~loc]~expected_exn:[%eExpr.(option~loc(pairpayloadcompact_loc))expected_exn]~trailing_test_id:[%eExpr.id~loctrailing_test_id]~exn_test_id:[%eExpr.id~locexn_test_id]~description:[%eExpr.optionestring~locdescription]~tags:[%etags|>List.map~f:(estring~loc)|>elist~loc]~inline_test_config:(moduleInline_test_config)~expectations:[%eMerlin_helpers.hide_expression(Expr.id_expr_alist~locexpectations)](fun()->[%ebody])];;letlet_expect_pat=letopenAst_patterninletuncaught_exn=Attribute.declare_with_attr_loc"@expect.uncaught_exn"Attribute.Context.value_binding(Pattern.string())(fun~attr_loc~located_payload->attr_loc,located_payload)inletopt_name=map(pstring__)~f:(funfx->f~name:(Somex))|||mapppat_any~f:(funf->f~name:None)inpstr(pstr_valuenonrecursive(Attribute.patternuncaught_exn(value_binding~constraint_:drop~pat:(map(Attribute.patternPpx_inline_test.tagsopt_name)~f:(funfattributes->f~tags:(Option.value~default:[]attributes)))~expr:__)^::nil)^::nil);;letexpect_test=Extension.V3.declare_inline"expect_test"Structure_itemlet_expect_pat(fun~ctxttrailing~tags~namecode->letloc=Ppxlib.Expansion_context.Extension.extension_point_locctxtinletloc={locwithloc_ghost=true}inlettrailing_location,expected_exn=matchtrailingwith|Some(attr_loc,expected_exn)->attr_loc,expected_exn|None->{locwithloc_start=loc.loc_end},NoneinPpx_inline_test.validate_extension_point_exn~name_of_ppx_rewriter:"ppx_expect"~loc~tags;transform_let_expect~trailing_location~tags~expected_exn~description:name~loccode|>Ppx_inline_test.maybe_droploc);;let()=Driver.add_arg"-expect-test-strict-indentation"(Bool((:=)strict_indent))~doc:(Printf.sprintf"BOOL Require standardized indentation in [[%%expect]] (default: %b)"!strict_indent);;let()=Driver.register_transformation"expect_test"~rules:[Context_free.Rule.extensionexpect_test]~enclose_impl:(funsource_file_loc->matchsource_file_loc,Ppx_inline_test_libname.get()with|Someloc,Some_->(* Insert the header and footer used for "current file" tracking only if:
1. The file is nonempty and
2. The executable is being built with the [-inline-test-lib _] flag, indicating
that there is some library for which we might run expect tests. If the
[-inline-test-lib] flag was not passed, then we shouldn't insert the header and
footer, as we will not be running expect tests and the [Ppx_expect_runtime]
library might not even be in scope (as is the case in toplevel expect tests,
which are not run through [Ppx_inline_test_lib]).
*)letloc={locwithloc_ghost=true}inletfilename_rel_to_project_root=Ppx_here_expander.expand_filenameloc.loc_start.pos_fnameinletheader=letloc={locwithloc_end=loc.loc_start}inPpx_inline_test.maybe_droploc[%exprPpx_expect_runtime.Current_file.set~filename_rel_to_project_root:[%eestring~locfilename_rel_to_project_root]]andfooter=letloc={locwithloc_start=loc.loc_end}inPpx_inline_test.maybe_droploc[%exprPpx_expect_runtime.Current_file.unset()]inheader,footer|_->[],[]);;