doctest.h 302 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816
  1. // ====================================================================== lgtm [cpp/missing-header-guard]
  2. // == DO NOT MODIFY THIS FILE BY HAND - IT IS AUTO GENERATED BY CMAKE! ==
  3. // ======================================================================
  4. //
  5. // doctest.h - the lightest feature-rich C++ single-header testing framework for unit tests and TDD
  6. //
  7. // Copyright (c) 2016-2021 Viktor Kirilov
  8. //
  9. // Distributed under the MIT Software License
  10. // See accompanying file LICENSE.txt or copy at
  11. // https://opensource.org/licenses/MIT
  12. //
  13. // The documentation can be found at the library's page:
  14. // https://github.com/doctest/doctest/blob/master/doc/markdown/readme.md
  15. //
  16. // =================================================================================================
  17. // =================================================================================================
  18. // =================================================================================================
  19. //
  20. // The library is heavily influenced by Catch - https://github.com/catchorg/Catch2
  21. // which uses the Boost Software License - Version 1.0
  22. // see here - https://github.com/catchorg/Catch2/blob/master/LICENSE.txt
  23. //
  24. // The concept of subcases (sections in Catch) and expression decomposition are from there.
  25. // Some parts of the code are taken directly:
  26. // - stringification - the detection of "ostream& operator<<(ostream&, const T&)" and StringMaker<>
  27. // - the Approx() helper class for floating point comparison
  28. // - colors in the console
  29. // - breaking into a debugger
  30. // - signal / SEH handling
  31. // - timer
  32. // - XmlWriter class - thanks to Phil Nash for allowing the direct reuse (AKA copy/paste)
  33. //
  34. // The expression decomposing templates are taken from lest - https://github.com/martinmoene/lest
  35. // which uses the Boost Software License - Version 1.0
  36. // see here - https://github.com/martinmoene/lest/blob/master/LICENSE.txt
  37. //
  38. // =================================================================================================
  39. // =================================================================================================
  40. // =================================================================================================
  41. #ifndef DOCTEST_LIBRARY_INCLUDED
  42. #define DOCTEST_LIBRARY_INCLUDED
  43. // =================================================================================================
  44. // == VERSION ======================================================================================
  45. // =================================================================================================
  46. #define DOCTEST_VERSION_MAJOR 2
  47. #define DOCTEST_VERSION_MINOR 4
  48. #define DOCTEST_VERSION_PATCH 8
  49. // util we need here
  50. #define DOCTEST_TOSTR_IMPL(x) #x
  51. #define DOCTEST_TOSTR(x) DOCTEST_TOSTR_IMPL(x)
  52. #define DOCTEST_VERSION_STR \
  53. DOCTEST_TOSTR(DOCTEST_VERSION_MAJOR) "." \
  54. DOCTEST_TOSTR(DOCTEST_VERSION_MINOR) "." \
  55. DOCTEST_TOSTR(DOCTEST_VERSION_PATCH)
  56. #define DOCTEST_VERSION \
  57. (DOCTEST_VERSION_MAJOR * 10000 + DOCTEST_VERSION_MINOR * 100 + DOCTEST_VERSION_PATCH)
  58. // =================================================================================================
  59. // == COMPILER VERSION =============================================================================
  60. // =================================================================================================
  61. // ideas for the version stuff are taken from here: https://github.com/cxxstuff/cxx_detect
  62. #define DOCTEST_COMPILER(MAJOR, MINOR, PATCH) ((MAJOR)*10000000 + (MINOR)*100000 + (PATCH))
  63. // GCC/Clang and GCC/MSVC are mutually exclusive, but Clang/MSVC are not because of clang-cl...
  64. #if defined(_MSC_VER) && defined(_MSC_FULL_VER)
  65. #if _MSC_VER == _MSC_FULL_VER / 10000
  66. #define DOCTEST_MSVC DOCTEST_COMPILER(_MSC_VER / 100, _MSC_VER % 100, _MSC_FULL_VER % 10000)
  67. #else // MSVC
  68. #define DOCTEST_MSVC \
  69. DOCTEST_COMPILER(_MSC_VER / 100, (_MSC_FULL_VER / 100000) % 100, _MSC_FULL_VER % 100000)
  70. #endif // MSVC
  71. #endif // MSVC
  72. #if defined(__clang__) && defined(__clang_minor__)
  73. #define DOCTEST_CLANG DOCTEST_COMPILER(__clang_major__, __clang_minor__, __clang_patchlevel__)
  74. #elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) && \
  75. !defined(__INTEL_COMPILER)
  76. #define DOCTEST_GCC DOCTEST_COMPILER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
  77. #endif // GCC
  78. #ifndef DOCTEST_MSVC
  79. #define DOCTEST_MSVC 0
  80. #endif // DOCTEST_MSVC
  81. #ifndef DOCTEST_CLANG
  82. #define DOCTEST_CLANG 0
  83. #endif // DOCTEST_CLANG
  84. #ifndef DOCTEST_GCC
  85. #define DOCTEST_GCC 0
  86. #endif // DOCTEST_GCC
  87. // =================================================================================================
  88. // == COMPILER WARNINGS HELPERS ====================================================================
  89. // =================================================================================================
  90. #if DOCTEST_CLANG
  91. #define DOCTEST_PRAGMA_TO_STR(x) _Pragma(#x)
  92. #define DOCTEST_CLANG_SUPPRESS_WARNING_PUSH _Pragma("clang diagnostic push")
  93. #define DOCTEST_CLANG_SUPPRESS_WARNING(w) DOCTEST_PRAGMA_TO_STR(clang diagnostic ignored w)
  94. #define DOCTEST_CLANG_SUPPRESS_WARNING_POP _Pragma("clang diagnostic pop")
  95. #define DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(w) \
  96. DOCTEST_CLANG_SUPPRESS_WARNING_PUSH DOCTEST_CLANG_SUPPRESS_WARNING(w)
  97. #else // DOCTEST_CLANG
  98. #define DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
  99. #define DOCTEST_CLANG_SUPPRESS_WARNING(w)
  100. #define DOCTEST_CLANG_SUPPRESS_WARNING_POP
  101. #define DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(w)
  102. #endif // DOCTEST_CLANG
  103. #if DOCTEST_GCC
  104. #define DOCTEST_PRAGMA_TO_STR(x) _Pragma(#x)
  105. #define DOCTEST_GCC_SUPPRESS_WARNING_PUSH _Pragma("GCC diagnostic push")
  106. #define DOCTEST_GCC_SUPPRESS_WARNING(w) DOCTEST_PRAGMA_TO_STR(GCC diagnostic ignored w)
  107. #define DOCTEST_GCC_SUPPRESS_WARNING_POP _Pragma("GCC diagnostic pop")
  108. #define DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH(w) \
  109. DOCTEST_GCC_SUPPRESS_WARNING_PUSH DOCTEST_GCC_SUPPRESS_WARNING(w)
  110. #else // DOCTEST_GCC
  111. #define DOCTEST_GCC_SUPPRESS_WARNING_PUSH
  112. #define DOCTEST_GCC_SUPPRESS_WARNING(w)
  113. #define DOCTEST_GCC_SUPPRESS_WARNING_POP
  114. #define DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH(w)
  115. #endif // DOCTEST_GCC
  116. #if DOCTEST_MSVC
  117. #define DOCTEST_MSVC_SUPPRESS_WARNING_PUSH __pragma(warning(push))
  118. #define DOCTEST_MSVC_SUPPRESS_WARNING(w) __pragma(warning(disable : w))
  119. #define DOCTEST_MSVC_SUPPRESS_WARNING_POP __pragma(warning(pop))
  120. #define DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(w) \
  121. DOCTEST_MSVC_SUPPRESS_WARNING_PUSH DOCTEST_MSVC_SUPPRESS_WARNING(w)
  122. #else // DOCTEST_MSVC
  123. #define DOCTEST_MSVC_SUPPRESS_WARNING_PUSH
  124. #define DOCTEST_MSVC_SUPPRESS_WARNING(w)
  125. #define DOCTEST_MSVC_SUPPRESS_WARNING_POP
  126. #define DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(w)
  127. #endif // DOCTEST_MSVC
  128. // =================================================================================================
  129. // == COMPILER WARNINGS ============================================================================
  130. // =================================================================================================
  131. // both the header and the implementation suppress all of these,
  132. // so it only makes sense to aggregrate them like so
  133. #define DOCTEST_SUPPRESS_COMMON_WARNINGS_PUSH \
  134. DOCTEST_CLANG_SUPPRESS_WARNING_PUSH \
  135. DOCTEST_CLANG_SUPPRESS_WARNING("-Wunknown-pragmas") \
  136. DOCTEST_CLANG_SUPPRESS_WARNING("-Wweak-vtables") \
  137. DOCTEST_CLANG_SUPPRESS_WARNING("-Wpadded") \
  138. DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-prototypes") \
  139. DOCTEST_CLANG_SUPPRESS_WARNING("-Wunused-local-typedef") \
  140. DOCTEST_CLANG_SUPPRESS_WARNING("-Wc++98-compat") \
  141. DOCTEST_CLANG_SUPPRESS_WARNING("-Wc++98-compat-pedantic") \
  142. \
  143. DOCTEST_GCC_SUPPRESS_WARNING_PUSH \
  144. DOCTEST_GCC_SUPPRESS_WARNING("-Wunknown-pragmas") \
  145. DOCTEST_GCC_SUPPRESS_WARNING("-Wpragmas") \
  146. DOCTEST_GCC_SUPPRESS_WARNING("-Weffc++") \
  147. DOCTEST_GCC_SUPPRESS_WARNING("-Wstrict-overflow") \
  148. DOCTEST_GCC_SUPPRESS_WARNING("-Wstrict-aliasing") \
  149. DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-declarations") \
  150. DOCTEST_GCC_SUPPRESS_WARNING("-Wunused-local-typedefs") \
  151. DOCTEST_GCC_SUPPRESS_WARNING("-Wuseless-cast") \
  152. DOCTEST_GCC_SUPPRESS_WARNING("-Wnoexcept") \
  153. \
  154. DOCTEST_MSVC_SUPPRESS_WARNING_PUSH \
  155. /* these 4 also disabled globally via cmake: */ \
  156. DOCTEST_MSVC_SUPPRESS_WARNING(4514) /* unreferenced inline function has been removed */ \
  157. DOCTEST_MSVC_SUPPRESS_WARNING(4571) /* SEH related */ \
  158. DOCTEST_MSVC_SUPPRESS_WARNING(4710) /* function not inlined */ \
  159. DOCTEST_MSVC_SUPPRESS_WARNING(4711) /* function selected for inline expansion*/ \
  160. /* */ \
  161. DOCTEST_MSVC_SUPPRESS_WARNING(4616) /* invalid compiler warning */ \
  162. DOCTEST_MSVC_SUPPRESS_WARNING(4619) /* invalid compiler warning */ \
  163. DOCTEST_MSVC_SUPPRESS_WARNING(4996) /* The compiler encountered a deprecated declaration */ \
  164. DOCTEST_MSVC_SUPPRESS_WARNING(4706) /* assignment within conditional expression */ \
  165. DOCTEST_MSVC_SUPPRESS_WARNING(4512) /* 'class' : assignment operator could not be generated */ \
  166. DOCTEST_MSVC_SUPPRESS_WARNING(4127) /* conditional expression is constant */ \
  167. DOCTEST_MSVC_SUPPRESS_WARNING(4820) /* padding */ \
  168. DOCTEST_MSVC_SUPPRESS_WARNING(4625) /* copy constructor was implicitly deleted */ \
  169. DOCTEST_MSVC_SUPPRESS_WARNING(4626) /* assignment operator was implicitly deleted */ \
  170. DOCTEST_MSVC_SUPPRESS_WARNING(5027) /* move assignment operator implicitly deleted */ \
  171. DOCTEST_MSVC_SUPPRESS_WARNING(5026) /* move constructor was implicitly deleted */ \
  172. DOCTEST_MSVC_SUPPRESS_WARNING(4640) /* construction of local static object not thread-safe */ \
  173. DOCTEST_MSVC_SUPPRESS_WARNING(5045) /* Spectre mitigation for memory load */ \
  174. /* static analysis */ \
  175. DOCTEST_MSVC_SUPPRESS_WARNING(26439) /* Function may not throw. Declare it 'noexcept' */ \
  176. DOCTEST_MSVC_SUPPRESS_WARNING(26495) /* Always initialize a member variable */ \
  177. DOCTEST_MSVC_SUPPRESS_WARNING(26451) /* Arithmetic overflow ... */ \
  178. DOCTEST_MSVC_SUPPRESS_WARNING(26444) /* Avoid unnamed objects with custom ctor and dtor... */ \
  179. DOCTEST_MSVC_SUPPRESS_WARNING(26812) /* Prefer 'enum class' over 'enum' */
  180. #define DOCTEST_SUPPRESS_COMMON_WARNINGS_POP \
  181. DOCTEST_CLANG_SUPPRESS_WARNING_POP \
  182. DOCTEST_GCC_SUPPRESS_WARNING_POP \
  183. DOCTEST_MSVC_SUPPRESS_WARNING_POP
  184. DOCTEST_SUPPRESS_COMMON_WARNINGS_PUSH
  185. DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
  186. DOCTEST_CLANG_SUPPRESS_WARNING("-Wnon-virtual-dtor")
  187. DOCTEST_CLANG_SUPPRESS_WARNING("-Wdeprecated")
  188. DOCTEST_GCC_SUPPRESS_WARNING_PUSH
  189. DOCTEST_GCC_SUPPRESS_WARNING("-Wctor-dtor-privacy")
  190. DOCTEST_GCC_SUPPRESS_WARNING("-Wnon-virtual-dtor")
  191. DOCTEST_GCC_SUPPRESS_WARNING("-Wsign-promo")
  192. DOCTEST_MSVC_SUPPRESS_WARNING_PUSH
  193. DOCTEST_MSVC_SUPPRESS_WARNING(4623) // default constructor was implicitly defined as deleted
  194. #define DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN \
  195. DOCTEST_MSVC_SUPPRESS_WARNING_PUSH \
  196. DOCTEST_MSVC_SUPPRESS_WARNING(4548) /* before comma no effect; expected side - effect */ \
  197. DOCTEST_MSVC_SUPPRESS_WARNING(4265) /* virtual functions, but destructor is not virtual */ \
  198. DOCTEST_MSVC_SUPPRESS_WARNING(4986) /* exception specification does not match previous */ \
  199. DOCTEST_MSVC_SUPPRESS_WARNING(4350) /* 'member1' called instead of 'member2' */ \
  200. DOCTEST_MSVC_SUPPRESS_WARNING(4668) /* not defined as a preprocessor macro */ \
  201. DOCTEST_MSVC_SUPPRESS_WARNING(4365) /* signed/unsigned mismatch */ \
  202. DOCTEST_MSVC_SUPPRESS_WARNING(4774) /* format string not a string literal */ \
  203. DOCTEST_MSVC_SUPPRESS_WARNING(4820) /* padding */ \
  204. DOCTEST_MSVC_SUPPRESS_WARNING(4625) /* copy constructor was implicitly deleted */ \
  205. DOCTEST_MSVC_SUPPRESS_WARNING(4626) /* assignment operator was implicitly deleted */ \
  206. DOCTEST_MSVC_SUPPRESS_WARNING(5027) /* move assignment operator implicitly deleted */ \
  207. DOCTEST_MSVC_SUPPRESS_WARNING(5026) /* move constructor was implicitly deleted */ \
  208. DOCTEST_MSVC_SUPPRESS_WARNING(4623) /* default constructor was implicitly deleted */ \
  209. DOCTEST_MSVC_SUPPRESS_WARNING(5039) /* pointer to pot. throwing function passed to extern C */ \
  210. DOCTEST_MSVC_SUPPRESS_WARNING(5045) /* Spectre mitigation for memory load */ \
  211. DOCTEST_MSVC_SUPPRESS_WARNING(5105) /* macro producing 'defined' has undefined behavior */
  212. #define DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END DOCTEST_MSVC_SUPPRESS_WARNING_POP
  213. // =================================================================================================
  214. // == FEATURE DETECTION ============================================================================
  215. // =================================================================================================
  216. // general compiler feature support table: https://en.cppreference.com/w/cpp/compiler_support
  217. // MSVC C++11 feature support table: https://msdn.microsoft.com/en-us/library/hh567368.aspx
  218. // GCC C++11 feature support table: https://gcc.gnu.org/projects/cxx-status.html
  219. // MSVC version table:
  220. // https://en.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B#Internal_version_numbering
  221. // MSVC++ 14.3 (17) _MSC_VER == 1930 (Visual Studio 2022)
  222. // MSVC++ 14.2 (16) _MSC_VER == 1920 (Visual Studio 2019)
  223. // MSVC++ 14.1 (15) _MSC_VER == 1910 (Visual Studio 2017)
  224. // MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015)
  225. // MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013)
  226. // MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012)
  227. // MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010)
  228. // MSVC++ 9.0 _MSC_VER == 1500 (Visual Studio 2008)
  229. // MSVC++ 8.0 _MSC_VER == 1400 (Visual Studio 2005)
  230. // Universal Windows Platform support
  231. #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
  232. #define DOCTEST_CONFIG_NO_WINDOWS_SEH
  233. #endif // WINAPI_FAMILY
  234. #if DOCTEST_MSVC && !defined(DOCTEST_CONFIG_WINDOWS_SEH)
  235. #define DOCTEST_CONFIG_WINDOWS_SEH
  236. #endif // MSVC
  237. #if defined(DOCTEST_CONFIG_NO_WINDOWS_SEH) && defined(DOCTEST_CONFIG_WINDOWS_SEH)
  238. #undef DOCTEST_CONFIG_WINDOWS_SEH
  239. #endif // DOCTEST_CONFIG_NO_WINDOWS_SEH
  240. #if !defined(_WIN32) && !defined(__QNX__) && !defined(DOCTEST_CONFIG_POSIX_SIGNALS) && \
  241. !defined(__EMSCRIPTEN__)
  242. #define DOCTEST_CONFIG_POSIX_SIGNALS
  243. #endif // _WIN32
  244. #if defined(DOCTEST_CONFIG_NO_POSIX_SIGNALS) && defined(DOCTEST_CONFIG_POSIX_SIGNALS)
  245. #undef DOCTEST_CONFIG_POSIX_SIGNALS
  246. #endif // DOCTEST_CONFIG_NO_POSIX_SIGNALS
  247. #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
  248. #if !defined(__cpp_exceptions) && !defined(__EXCEPTIONS) && !defined(_CPPUNWIND)
  249. #define DOCTEST_CONFIG_NO_EXCEPTIONS
  250. #endif // no exceptions
  251. #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
  252. #ifdef DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS
  253. #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
  254. #define DOCTEST_CONFIG_NO_EXCEPTIONS
  255. #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
  256. #endif // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS
  257. #if defined(DOCTEST_CONFIG_NO_EXCEPTIONS) && !defined(DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS)
  258. #define DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS
  259. #endif // DOCTEST_CONFIG_NO_EXCEPTIONS && !DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS
  260. #if defined(DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN) && !defined(DOCTEST_CONFIG_IMPLEMENT)
  261. #define DOCTEST_CONFIG_IMPLEMENT
  262. #endif // DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
  263. #if defined(_WIN32) || defined(__CYGWIN__)
  264. #if DOCTEST_MSVC
  265. #define DOCTEST_SYMBOL_EXPORT __declspec(dllexport)
  266. #define DOCTEST_SYMBOL_IMPORT __declspec(dllimport)
  267. #else // MSVC
  268. #define DOCTEST_SYMBOL_EXPORT __attribute__((dllexport))
  269. #define DOCTEST_SYMBOL_IMPORT __attribute__((dllimport))
  270. #endif // MSVC
  271. #else // _WIN32
  272. #define DOCTEST_SYMBOL_EXPORT __attribute__((visibility("default")))
  273. #define DOCTEST_SYMBOL_IMPORT
  274. #endif // _WIN32
  275. #ifdef DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL
  276. #ifdef DOCTEST_CONFIG_IMPLEMENT
  277. #define DOCTEST_INTERFACE DOCTEST_SYMBOL_EXPORT
  278. #else // DOCTEST_CONFIG_IMPLEMENT
  279. #define DOCTEST_INTERFACE DOCTEST_SYMBOL_IMPORT
  280. #endif // DOCTEST_CONFIG_IMPLEMENT
  281. #else // DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL
  282. #define DOCTEST_INTERFACE
  283. #endif // DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL
  284. #define DOCTEST_EMPTY
  285. #if DOCTEST_MSVC
  286. #define DOCTEST_NOINLINE __declspec(noinline)
  287. #define DOCTEST_UNUSED
  288. #define DOCTEST_ALIGNMENT(x)
  289. #elif DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 5, 0)
  290. #define DOCTEST_NOINLINE
  291. #define DOCTEST_UNUSED
  292. #define DOCTEST_ALIGNMENT(x)
  293. #else
  294. #define DOCTEST_NOINLINE __attribute__((noinline))
  295. #define DOCTEST_UNUSED __attribute__((unused))
  296. #define DOCTEST_ALIGNMENT(x) __attribute__((aligned(x)))
  297. #endif
  298. #ifndef DOCTEST_NORETURN
  299. #if DOCTEST_MSVC && (DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0))
  300. #define DOCTEST_NORETURN
  301. #else // DOCTEST_MSVC
  302. #define DOCTEST_NORETURN [[noreturn]]
  303. #endif // DOCTEST_MSVC
  304. #endif // DOCTEST_NORETURN
  305. #ifndef DOCTEST_NOEXCEPT
  306. #if DOCTEST_MSVC && (DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0))
  307. #define DOCTEST_NOEXCEPT
  308. #else // DOCTEST_MSVC
  309. #define DOCTEST_NOEXCEPT noexcept
  310. #endif // DOCTEST_MSVC
  311. #endif // DOCTEST_NOEXCEPT
  312. #ifndef DOCTEST_CONSTEXPR
  313. #if DOCTEST_MSVC && (DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0))
  314. #define DOCTEST_CONSTEXPR const
  315. #else // DOCTEST_MSVC
  316. #define DOCTEST_CONSTEXPR constexpr
  317. #endif // DOCTEST_MSVC
  318. #endif // DOCTEST_CONSTEXPR
  319. // =================================================================================================
  320. // == FEATURE DETECTION END ========================================================================
  321. // =================================================================================================
  322. // internal macros for string concatenation and anonymous variable name generation
  323. #define DOCTEST_CAT_IMPL(s1, s2) s1##s2
  324. #define DOCTEST_CAT(s1, s2) DOCTEST_CAT_IMPL(s1, s2)
  325. #ifdef __COUNTER__ // not standard and may be missing for some compilers
  326. #define DOCTEST_ANONYMOUS(x) DOCTEST_CAT(x, __COUNTER__)
  327. #else // __COUNTER__
  328. #define DOCTEST_ANONYMOUS(x) DOCTEST_CAT(x, __LINE__)
  329. #endif // __COUNTER__
  330. #ifndef DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE
  331. #define DOCTEST_REF_WRAP(x) x&
  332. #else // DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE
  333. #define DOCTEST_REF_WRAP(x) x
  334. #endif // DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE
  335. // not using __APPLE__ because... this is how Catch does it
  336. #ifdef __MAC_OS_X_VERSION_MIN_REQUIRED
  337. #define DOCTEST_PLATFORM_MAC
  338. #elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
  339. #define DOCTEST_PLATFORM_IPHONE
  340. #elif defined(_WIN32)
  341. #define DOCTEST_PLATFORM_WINDOWS
  342. #else // DOCTEST_PLATFORM
  343. #define DOCTEST_PLATFORM_LINUX
  344. #endif // DOCTEST_PLATFORM
  345. namespace doctest { namespace detail {
  346. static DOCTEST_CONSTEXPR int consume(const int*, int) { return 0; }
  347. }}
  348. #define DOCTEST_GLOBAL_NO_WARNINGS(var, ...) \
  349. DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wglobal-constructors") \
  350. static const int var = doctest::detail::consume(&var, __VA_ARGS__); \
  351. DOCTEST_CLANG_SUPPRESS_WARNING_POP
  352. #ifndef DOCTEST_BREAK_INTO_DEBUGGER
  353. // should probably take a look at https://github.com/scottt/debugbreak
  354. #ifdef DOCTEST_PLATFORM_LINUX
  355. #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
  356. // Break at the location of the failing check if possible
  357. #define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :) // NOLINT (hicpp-no-assembler)
  358. #else
  359. #include <signal.h>
  360. #define DOCTEST_BREAK_INTO_DEBUGGER() raise(SIGTRAP)
  361. #endif
  362. #elif defined(DOCTEST_PLATFORM_MAC)
  363. #if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || defined(__i386)
  364. #define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :) // NOLINT (hicpp-no-assembler)
  365. #else
  366. #define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("brk #0"); // NOLINT (hicpp-no-assembler)
  367. #endif
  368. #elif DOCTEST_MSVC
  369. #define DOCTEST_BREAK_INTO_DEBUGGER() __debugbreak()
  370. #elif defined(__MINGW32__)
  371. DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wredundant-decls")
  372. extern "C" __declspec(dllimport) void __stdcall DebugBreak();
  373. DOCTEST_GCC_SUPPRESS_WARNING_POP
  374. #define DOCTEST_BREAK_INTO_DEBUGGER() ::DebugBreak()
  375. #else // linux
  376. #define DOCTEST_BREAK_INTO_DEBUGGER() (static_cast<void>(0))
  377. #endif // linux
  378. #endif // DOCTEST_BREAK_INTO_DEBUGGER
  379. // this is kept here for backwards compatibility since the config option was changed
  380. #ifdef DOCTEST_CONFIG_USE_IOSFWD
  381. #define DOCTEST_CONFIG_USE_STD_HEADERS
  382. #endif // DOCTEST_CONFIG_USE_IOSFWD
  383. // for clang - always include ciso646 (which drags some std stuff) because
  384. // we want to check if we are using libc++ with the _LIBCPP_VERSION macro in
  385. // which case we don't want to forward declare stuff from std - for reference:
  386. // https://github.com/doctest/doctest/issues/126
  387. // https://github.com/doctest/doctest/issues/356
  388. #if DOCTEST_CLANG
  389. #include <ciso646>
  390. #ifdef _LIBCPP_VERSION
  391. #define DOCTEST_CONFIG_USE_STD_HEADERS
  392. #endif // _LIBCPP_VERSION
  393. #endif // clang
  394. #ifdef DOCTEST_CONFIG_USE_STD_HEADERS
  395. #ifndef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
  396. #define DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
  397. #endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
  398. #include <cstddef>
  399. #include <ostream>
  400. #include <istream>
  401. #else // DOCTEST_CONFIG_USE_STD_HEADERS
  402. // Forward declaring 'X' in namespace std is not permitted by the C++ Standard.
  403. DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4643)
  404. namespace std { // NOLINT (cert-dcl58-cpp)
  405. typedef decltype(nullptr) nullptr_t;
  406. template <class charT>
  407. struct char_traits;
  408. template <>
  409. struct char_traits<char>;
  410. template <class charT, class traits>
  411. class basic_ostream;
  412. typedef basic_ostream<char, char_traits<char>> ostream;
  413. template <class charT, class traits>
  414. class basic_istream;
  415. typedef basic_istream<char, char_traits<char>> istream;
  416. template <class... Types>
  417. class tuple;
  418. #if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0)
  419. // see this issue on why this is needed: https://github.com/doctest/doctest/issues/183
  420. template <class Ty>
  421. class allocator;
  422. template <class Elem, class Traits, class Alloc>
  423. class basic_string;
  424. using string = basic_string<char, char_traits<char>, allocator<char>>;
  425. #endif // VS 2019
  426. } // namespace std
  427. DOCTEST_MSVC_SUPPRESS_WARNING_POP
  428. #endif // DOCTEST_CONFIG_USE_STD_HEADERS
  429. #ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
  430. #include <type_traits>
  431. #endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
  432. namespace doctest {
  433. DOCTEST_INTERFACE extern bool is_running_in_test;
  434. // A 24 byte string class (can be as small as 17 for x64 and 13 for x86) that can hold strings with length
  435. // of up to 23 chars on the stack before going on the heap - the last byte of the buffer is used for:
  436. // - "is small" bit - the highest bit - if "0" then it is small - otherwise its "1" (128)
  437. // - if small - capacity left before going on the heap - using the lowest 5 bits
  438. // - if small - 2 bits are left unused - the second and third highest ones
  439. // - if small - acts as a null terminator if strlen() is 23 (24 including the null terminator)
  440. // and the "is small" bit remains "0" ("as well as the capacity left") so its OK
  441. // Idea taken from this lecture about the string implementation of facebook/folly - fbstring
  442. // https://www.youtube.com/watch?v=kPR8h4-qZdk
  443. // TODO:
  444. // - optimizations - like not deleting memory unnecessarily in operator= and etc.
  445. // - resize/reserve/clear
  446. // - substr
  447. // - replace
  448. // - back/front
  449. // - iterator stuff
  450. // - find & friends
  451. // - push_back/pop_back
  452. // - assign/insert/erase
  453. // - relational operators as free functions - taking const char* as one of the params
  454. class DOCTEST_INTERFACE String
  455. {
  456. static const unsigned len = 24; //!OCLINT avoid private static members
  457. static const unsigned last = len - 1; //!OCLINT avoid private static members
  458. struct view // len should be more than sizeof(view) - because of the final byte for flags
  459. {
  460. char* ptr;
  461. unsigned size;
  462. unsigned capacity;
  463. };
  464. union
  465. {
  466. char buf[len];
  467. view data;
  468. };
  469. char* allocate(unsigned sz);
  470. bool isOnStack() const { return (buf[last] & 128) == 0; }
  471. void setOnHeap();
  472. void setLast(unsigned in = last);
  473. void copy(const String& other);
  474. public:
  475. String();
  476. ~String();
  477. // cppcheck-suppress noExplicitConstructor
  478. String(const char* in);
  479. String(const char* in, unsigned in_size);
  480. String(std::istream& in, unsigned in_size);
  481. String(const String& other);
  482. String& operator=(const String& other);
  483. String& operator+=(const String& other);
  484. String(String&& other);
  485. String& operator=(String&& other);
  486. char operator[](unsigned i) const;
  487. char& operator[](unsigned i);
  488. // the only functions I'm willing to leave in the interface - available for inlining
  489. const char* c_str() const { return const_cast<String*>(this)->c_str(); } // NOLINT
  490. char* c_str() {
  491. if(isOnStack())
  492. return reinterpret_cast<char*>(buf);
  493. return data.ptr;
  494. }
  495. unsigned size() const;
  496. unsigned capacity() const;
  497. int compare(const char* other, bool no_case = false) const;
  498. int compare(const String& other, bool no_case = false) const;
  499. };
  500. DOCTEST_INTERFACE String operator+(const String& lhs, const String& rhs);
  501. DOCTEST_INTERFACE bool operator==(const String& lhs, const String& rhs);
  502. DOCTEST_INTERFACE bool operator!=(const String& lhs, const String& rhs);
  503. DOCTEST_INTERFACE bool operator<(const String& lhs, const String& rhs);
  504. DOCTEST_INTERFACE bool operator>(const String& lhs, const String& rhs);
  505. DOCTEST_INTERFACE bool operator<=(const String& lhs, const String& rhs);
  506. DOCTEST_INTERFACE bool operator>=(const String& lhs, const String& rhs);
  507. DOCTEST_INTERFACE std::ostream& operator<<(std::ostream& s, const String& in);
  508. namespace Color {
  509. enum Enum
  510. {
  511. None = 0,
  512. White,
  513. Red,
  514. Green,
  515. Blue,
  516. Cyan,
  517. Yellow,
  518. Grey,
  519. Bright = 0x10,
  520. BrightRed = Bright | Red,
  521. BrightGreen = Bright | Green,
  522. LightGrey = Bright | Grey,
  523. BrightWhite = Bright | White
  524. };
  525. DOCTEST_INTERFACE std::ostream& operator<<(std::ostream& s, Color::Enum code);
  526. } // namespace Color
  527. namespace assertType {
  528. enum Enum
  529. {
  530. // macro traits
  531. is_warn = 1,
  532. is_check = 2 * is_warn,
  533. is_require = 2 * is_check,
  534. is_normal = 2 * is_require,
  535. is_throws = 2 * is_normal,
  536. is_throws_as = 2 * is_throws,
  537. is_throws_with = 2 * is_throws_as,
  538. is_nothrow = 2 * is_throws_with,
  539. is_false = 2 * is_nothrow,
  540. is_unary = 2 * is_false, // not checked anywhere - used just to distinguish the types
  541. is_eq = 2 * is_unary,
  542. is_ne = 2 * is_eq,
  543. is_lt = 2 * is_ne,
  544. is_gt = 2 * is_lt,
  545. is_ge = 2 * is_gt,
  546. is_le = 2 * is_ge,
  547. // macro types
  548. DT_WARN = is_normal | is_warn,
  549. DT_CHECK = is_normal | is_check,
  550. DT_REQUIRE = is_normal | is_require,
  551. DT_WARN_FALSE = is_normal | is_false | is_warn,
  552. DT_CHECK_FALSE = is_normal | is_false | is_check,
  553. DT_REQUIRE_FALSE = is_normal | is_false | is_require,
  554. DT_WARN_THROWS = is_throws | is_warn,
  555. DT_CHECK_THROWS = is_throws | is_check,
  556. DT_REQUIRE_THROWS = is_throws | is_require,
  557. DT_WARN_THROWS_AS = is_throws_as | is_warn,
  558. DT_CHECK_THROWS_AS = is_throws_as | is_check,
  559. DT_REQUIRE_THROWS_AS = is_throws_as | is_require,
  560. DT_WARN_THROWS_WITH = is_throws_with | is_warn,
  561. DT_CHECK_THROWS_WITH = is_throws_with | is_check,
  562. DT_REQUIRE_THROWS_WITH = is_throws_with | is_require,
  563. DT_WARN_THROWS_WITH_AS = is_throws_with | is_throws_as | is_warn,
  564. DT_CHECK_THROWS_WITH_AS = is_throws_with | is_throws_as | is_check,
  565. DT_REQUIRE_THROWS_WITH_AS = is_throws_with | is_throws_as | is_require,
  566. DT_WARN_NOTHROW = is_nothrow | is_warn,
  567. DT_CHECK_NOTHROW = is_nothrow | is_check,
  568. DT_REQUIRE_NOTHROW = is_nothrow | is_require,
  569. DT_WARN_EQ = is_normal | is_eq | is_warn,
  570. DT_CHECK_EQ = is_normal | is_eq | is_check,
  571. DT_REQUIRE_EQ = is_normal | is_eq | is_require,
  572. DT_WARN_NE = is_normal | is_ne | is_warn,
  573. DT_CHECK_NE = is_normal | is_ne | is_check,
  574. DT_REQUIRE_NE = is_normal | is_ne | is_require,
  575. DT_WARN_GT = is_normal | is_gt | is_warn,
  576. DT_CHECK_GT = is_normal | is_gt | is_check,
  577. DT_REQUIRE_GT = is_normal | is_gt | is_require,
  578. DT_WARN_LT = is_normal | is_lt | is_warn,
  579. DT_CHECK_LT = is_normal | is_lt | is_check,
  580. DT_REQUIRE_LT = is_normal | is_lt | is_require,
  581. DT_WARN_GE = is_normal | is_ge | is_warn,
  582. DT_CHECK_GE = is_normal | is_ge | is_check,
  583. DT_REQUIRE_GE = is_normal | is_ge | is_require,
  584. DT_WARN_LE = is_normal | is_le | is_warn,
  585. DT_CHECK_LE = is_normal | is_le | is_check,
  586. DT_REQUIRE_LE = is_normal | is_le | is_require,
  587. DT_WARN_UNARY = is_normal | is_unary | is_warn,
  588. DT_CHECK_UNARY = is_normal | is_unary | is_check,
  589. DT_REQUIRE_UNARY = is_normal | is_unary | is_require,
  590. DT_WARN_UNARY_FALSE = is_normal | is_false | is_unary | is_warn,
  591. DT_CHECK_UNARY_FALSE = is_normal | is_false | is_unary | is_check,
  592. DT_REQUIRE_UNARY_FALSE = is_normal | is_false | is_unary | is_require,
  593. };
  594. } // namespace assertType
  595. DOCTEST_INTERFACE const char* assertString(assertType::Enum at);
  596. DOCTEST_INTERFACE const char* failureString(assertType::Enum at);
  597. DOCTEST_INTERFACE const char* skipPathFromFilename(const char* file);
  598. struct DOCTEST_INTERFACE TestCaseData
  599. {
  600. String m_file; // the file in which the test was registered (using String - see #350)
  601. unsigned m_line; // the line where the test was registered
  602. const char* m_name; // name of the test case
  603. const char* m_test_suite; // the test suite in which the test was added
  604. const char* m_description;
  605. bool m_skip;
  606. bool m_no_breaks;
  607. bool m_no_output;
  608. bool m_may_fail;
  609. bool m_should_fail;
  610. int m_expected_failures;
  611. double m_timeout;
  612. };
  613. struct DOCTEST_INTERFACE AssertData
  614. {
  615. // common - for all asserts
  616. const TestCaseData* m_test_case;
  617. assertType::Enum m_at;
  618. const char* m_file;
  619. int m_line;
  620. const char* m_expr;
  621. bool m_failed;
  622. // exception-related - for all asserts
  623. bool m_threw;
  624. String m_exception;
  625. // for normal asserts
  626. String m_decomp;
  627. // for specific exception-related asserts
  628. bool m_threw_as;
  629. const char* m_exception_type;
  630. const char* m_exception_string;
  631. };
  632. struct DOCTEST_INTERFACE MessageData
  633. {
  634. String m_string;
  635. const char* m_file;
  636. int m_line;
  637. assertType::Enum m_severity;
  638. };
  639. struct DOCTEST_INTERFACE SubcaseSignature
  640. {
  641. String m_name;
  642. const char* m_file;
  643. int m_line;
  644. bool operator<(const SubcaseSignature& other) const;
  645. };
  646. struct DOCTEST_INTERFACE IContextScope
  647. {
  648. IContextScope();
  649. virtual ~IContextScope();
  650. virtual void stringify(std::ostream*) const = 0;
  651. };
  652. namespace detail {
  653. struct DOCTEST_INTERFACE TestCase;
  654. } // namespace detail
  655. struct ContextOptions //!OCLINT too many fields
  656. {
  657. std::ostream* cout = nullptr; // stdout stream
  658. String binary_name; // the test binary name
  659. const detail::TestCase* currentTest = nullptr;
  660. // == parameters from the command line
  661. String out; // output filename
  662. String order_by; // how tests should be ordered
  663. unsigned rand_seed; // the seed for rand ordering
  664. unsigned first; // the first (matching) test to be executed
  665. unsigned last; // the last (matching) test to be executed
  666. int abort_after; // stop tests after this many failed assertions
  667. int subcase_filter_levels; // apply the subcase filters for the first N levels
  668. bool success; // include successful assertions in output
  669. bool case_sensitive; // if filtering should be case sensitive
  670. bool exit; // if the program should be exited after the tests are ran/whatever
  671. bool duration; // print the time duration of each test case
  672. bool minimal; // minimal console output (only test failures)
  673. bool quiet; // no console output
  674. bool no_throw; // to skip exceptions-related assertion macros
  675. bool no_exitcode; // if the framework should return 0 as the exitcode
  676. bool no_run; // to not run the tests at all (can be done with an "*" exclude)
  677. bool no_intro; // to not print the intro of the framework
  678. bool no_version; // to not print the version of the framework
  679. bool no_colors; // if output to the console should be colorized
  680. bool force_colors; // forces the use of colors even when a tty cannot be detected
  681. bool no_breaks; // to not break into the debugger
  682. bool no_skip; // don't skip test cases which are marked to be skipped
  683. bool gnu_file_line; // if line numbers should be surrounded with :x: and not (x):
  684. bool no_path_in_filenames; // if the path to files should be removed from the output
  685. bool no_line_numbers; // if source code line numbers should be omitted from the output
  686. bool no_debug_output; // no output in the debug console when a debugger is attached
  687. bool no_skipped_summary; // don't print "skipped" in the summary !!! UNDOCUMENTED !!!
  688. bool no_time_in_output; // omit any time/timestamps from output !!! UNDOCUMENTED !!!
  689. bool help; // to print the help
  690. bool version; // to print the version
  691. bool count; // if only the count of matching tests is to be retrieved
  692. bool list_test_cases; // to list all tests matching the filters
  693. bool list_test_suites; // to list all suites matching the filters
  694. bool list_reporters; // lists all registered reporters
  695. };
  696. namespace detail {
  697. template <bool CONDITION, typename TYPE = void>
  698. struct enable_if
  699. {};
  700. template <typename TYPE>
  701. struct enable_if<true, TYPE>
  702. { typedef TYPE type; };
  703. // clang-format off
  704. template<class T> struct remove_reference { typedef T type; };
  705. template<class T> struct remove_reference<T&> { typedef T type; };
  706. template<class T> struct remove_reference<T&&> { typedef T type; };
  707. template<typename T, typename U = T&&> U declval(int);
  708. template<typename T> T declval(long);
  709. template<typename T> auto declval() DOCTEST_NOEXCEPT -> decltype(declval<T>(0)) ;
  710. template<class T> struct is_lvalue_reference { const static bool value=false; };
  711. template<class T> struct is_lvalue_reference<T&> { const static bool value=true; };
  712. template<class T> struct is_rvalue_reference { const static bool value=false; };
  713. template<class T> struct is_rvalue_reference<T&&> { const static bool value=true; };
  714. template <class T>
  715. inline T&& forward(typename remove_reference<T>::type& t) DOCTEST_NOEXCEPT
  716. {
  717. return static_cast<T&&>(t);
  718. }
  719. template <class T>
  720. inline T&& forward(typename remove_reference<T>::type&& t) DOCTEST_NOEXCEPT
  721. {
  722. static_assert(!is_lvalue_reference<T>::value,
  723. "Can not forward an rvalue as an lvalue.");
  724. return static_cast<T&&>(t);
  725. }
  726. template<class T> struct remove_const { typedef T type; };
  727. template<class T> struct remove_const<const T> { typedef T type; };
  728. #ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
  729. template<class T> struct is_enum : public std::is_enum<T> {};
  730. template<class T> struct underlying_type : public std::underlying_type<T> {};
  731. #else
  732. // Use compiler intrinsics
  733. template<class T> struct is_enum { DOCTEST_CONSTEXPR static bool value = __is_enum(T); };
  734. template<class T> struct underlying_type { typedef __underlying_type(T) type; };
  735. #endif
  736. // clang-format on
  737. template <typename T>
  738. struct deferred_false
  739. // cppcheck-suppress unusedStructMember
  740. { static const bool value = false; };
  741. namespace has_insertion_operator_impl {
  742. std::ostream &os();
  743. template<class T>
  744. DOCTEST_REF_WRAP(T) val();
  745. template<class, class = void>
  746. struct check {
  747. static DOCTEST_CONSTEXPR bool value = false;
  748. };
  749. template<class T>
  750. struct check<T, decltype(os() << val<T>(), void())> {
  751. static DOCTEST_CONSTEXPR bool value = true;
  752. };
  753. } // namespace has_insertion_operator_impl
  754. template<class T>
  755. using has_insertion_operator = has_insertion_operator_impl::check<const T>;
  756. DOCTEST_INTERFACE std::ostream* tlssPush();
  757. DOCTEST_INTERFACE String tlssPop();
  758. template <bool C>
  759. struct StringMakerBase
  760. {
  761. template <typename T>
  762. static String convert(const DOCTEST_REF_WRAP(T)) {
  763. return "{?}";
  764. }
  765. };
  766. // Vector<int> and various type other than pointer or array.
  767. template<typename T>
  768. struct filldata
  769. {
  770. static void fill(std::ostream* stream, const T &in) {
  771. *stream << in;
  772. }
  773. };
  774. template<typename T,unsigned long N>
  775. struct filldata<T[N]>
  776. {
  777. static void fill(std::ostream* stream, const T (&in)[N]) {
  778. for (unsigned long i = 0; i < N; i++) {
  779. *stream << in[i];
  780. }
  781. }
  782. };
  783. // Specialized since we don't want the terminating null byte!
  784. template<unsigned long N>
  785. struct filldata<const char[N]>
  786. {
  787. static void fill(std::ostream* stream, const char(&in)[N]) {
  788. *stream << in;
  789. }
  790. };
  791. template<typename T>
  792. void filloss(std::ostream* stream, const T& in) {
  793. filldata<T>::fill(stream, in);
  794. }
  795. template<typename T,unsigned long N>
  796. void filloss(std::ostream* stream, const T (&in)[N]) {
  797. // T[N], T(&)[N], T(&&)[N] have same behaviour.
  798. // Hence remove reference.
  799. filldata<typename remove_reference<decltype(in)>::type>::fill(stream, in);
  800. }
  801. template <>
  802. struct StringMakerBase<true>
  803. {
  804. template <typename T>
  805. static String convert(const DOCTEST_REF_WRAP(T) in) {
  806. /* When parameter "in" is a null terminated const char* it works.
  807. * When parameter "in" is a T arr[N] without '\0' we can fill the
  808. * stringstream with N objects (T=char).If in is char pointer *
  809. * without '\0' , it would cause segfault
  810. * stepping over unaccessible memory.
  811. */
  812. std::ostream* stream = tlssPush();
  813. filloss(stream, in);
  814. return tlssPop();
  815. }
  816. };
  817. DOCTEST_INTERFACE String rawMemoryToString(const void* object, unsigned size);
  818. template <typename T>
  819. String rawMemoryToString(const DOCTEST_REF_WRAP(T) object) {
  820. return rawMemoryToString(&object, sizeof(object));
  821. }
  822. template <typename T>
  823. const char* type_to_string() {
  824. return "<>";
  825. }
  826. } // namespace detail
  827. template <typename T>
  828. struct StringMaker : public detail::StringMakerBase<detail::has_insertion_operator<T>::value>
  829. {};
  830. template <typename T>
  831. struct StringMaker<T*>
  832. {
  833. template <typename U>
  834. static String convert(U* p) {
  835. if(p)
  836. return detail::rawMemoryToString(p);
  837. return "NULL";
  838. }
  839. };
  840. template <typename R, typename C>
  841. struct StringMaker<R C::*>
  842. {
  843. static String convert(R C::*p) {
  844. if(p)
  845. return detail::rawMemoryToString(p);
  846. return "NULL";
  847. }
  848. };
  849. template <typename T, typename detail::enable_if<!detail::is_enum<T>::value, bool>::type = true>
  850. String toString(const DOCTEST_REF_WRAP(T) value) {
  851. return StringMaker<T>::convert(value);
  852. }
  853. #ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
  854. DOCTEST_INTERFACE String toString(char* in);
  855. DOCTEST_INTERFACE String toString(const char* in);
  856. #endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
  857. DOCTEST_INTERFACE String toString(bool in);
  858. DOCTEST_INTERFACE String toString(float in);
  859. DOCTEST_INTERFACE String toString(double in);
  860. DOCTEST_INTERFACE String toString(double long in);
  861. DOCTEST_INTERFACE String toString(char in);
  862. DOCTEST_INTERFACE String toString(char signed in);
  863. DOCTEST_INTERFACE String toString(char unsigned in);
  864. DOCTEST_INTERFACE String toString(int short in);
  865. DOCTEST_INTERFACE String toString(int short unsigned in);
  866. DOCTEST_INTERFACE String toString(int in);
  867. DOCTEST_INTERFACE String toString(int unsigned in);
  868. DOCTEST_INTERFACE String toString(int long in);
  869. DOCTEST_INTERFACE String toString(int long unsigned in);
  870. DOCTEST_INTERFACE String toString(int long long in);
  871. DOCTEST_INTERFACE String toString(int long long unsigned in);
  872. DOCTEST_INTERFACE String toString(std::nullptr_t in);
  873. template <typename T, typename detail::enable_if<detail::is_enum<T>::value, bool>::type = true>
  874. String toString(const DOCTEST_REF_WRAP(T) value) {
  875. typedef typename detail::underlying_type<T>::type UT;
  876. return toString(static_cast<UT>(value));
  877. }
  878. #if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0)
  879. // see this issue on why this is needed: https://github.com/doctest/doctest/issues/183
  880. DOCTEST_INTERFACE String toString(const std::string& in);
  881. #endif // VS 2019
  882. class DOCTEST_INTERFACE Approx
  883. {
  884. public:
  885. explicit Approx(double value);
  886. Approx operator()(double value) const;
  887. #ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
  888. template <typename T>
  889. explicit Approx(const T& value,
  890. typename detail::enable_if<std::is_constructible<double, T>::value>::type* =
  891. static_cast<T*>(nullptr)) {
  892. *this = Approx(static_cast<double>(value));
  893. }
  894. #endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
  895. Approx& epsilon(double newEpsilon);
  896. #ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
  897. template <typename T>
  898. typename detail::enable_if<std::is_constructible<double, T>::value, Approx&>::type epsilon(
  899. const T& newEpsilon) {
  900. m_epsilon = static_cast<double>(newEpsilon);
  901. return *this;
  902. }
  903. #endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
  904. Approx& scale(double newScale);
  905. #ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
  906. template <typename T>
  907. typename detail::enable_if<std::is_constructible<double, T>::value, Approx&>::type scale(
  908. const T& newScale) {
  909. m_scale = static_cast<double>(newScale);
  910. return *this;
  911. }
  912. #endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
  913. // clang-format off
  914. DOCTEST_INTERFACE friend bool operator==(double lhs, const Approx & rhs);
  915. DOCTEST_INTERFACE friend bool operator==(const Approx & lhs, double rhs);
  916. DOCTEST_INTERFACE friend bool operator!=(double lhs, const Approx & rhs);
  917. DOCTEST_INTERFACE friend bool operator!=(const Approx & lhs, double rhs);
  918. DOCTEST_INTERFACE friend bool operator<=(double lhs, const Approx & rhs);
  919. DOCTEST_INTERFACE friend bool operator<=(const Approx & lhs, double rhs);
  920. DOCTEST_INTERFACE friend bool operator>=(double lhs, const Approx & rhs);
  921. DOCTEST_INTERFACE friend bool operator>=(const Approx & lhs, double rhs);
  922. DOCTEST_INTERFACE friend bool operator< (double lhs, const Approx & rhs);
  923. DOCTEST_INTERFACE friend bool operator< (const Approx & lhs, double rhs);
  924. DOCTEST_INTERFACE friend bool operator> (double lhs, const Approx & rhs);
  925. DOCTEST_INTERFACE friend bool operator> (const Approx & lhs, double rhs);
  926. DOCTEST_INTERFACE friend String toString(const Approx& in);
  927. #ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
  928. #define DOCTEST_APPROX_PREFIX \
  929. template <typename T> friend typename detail::enable_if<std::is_constructible<double, T>::value, bool>::type
  930. DOCTEST_APPROX_PREFIX operator==(const T& lhs, const Approx& rhs) { return operator==(double(lhs), rhs); }
  931. DOCTEST_APPROX_PREFIX operator==(const Approx& lhs, const T& rhs) { return operator==(rhs, lhs); }
  932. DOCTEST_APPROX_PREFIX operator!=(const T& lhs, const Approx& rhs) { return !operator==(lhs, rhs); }
  933. DOCTEST_APPROX_PREFIX operator!=(const Approx& lhs, const T& rhs) { return !operator==(rhs, lhs); }
  934. DOCTEST_APPROX_PREFIX operator<=(const T& lhs, const Approx& rhs) { return double(lhs) < rhs.m_value || lhs == rhs; }
  935. DOCTEST_APPROX_PREFIX operator<=(const Approx& lhs, const T& rhs) { return lhs.m_value < double(rhs) || lhs == rhs; }
  936. DOCTEST_APPROX_PREFIX operator>=(const T& lhs, const Approx& rhs) { return double(lhs) > rhs.m_value || lhs == rhs; }
  937. DOCTEST_APPROX_PREFIX operator>=(const Approx& lhs, const T& rhs) { return lhs.m_value > double(rhs) || lhs == rhs; }
  938. DOCTEST_APPROX_PREFIX operator< (const T& lhs, const Approx& rhs) { return double(lhs) < rhs.m_value && lhs != rhs; }
  939. DOCTEST_APPROX_PREFIX operator< (const Approx& lhs, const T& rhs) { return lhs.m_value < double(rhs) && lhs != rhs; }
  940. DOCTEST_APPROX_PREFIX operator> (const T& lhs, const Approx& rhs) { return double(lhs) > rhs.m_value && lhs != rhs; }
  941. DOCTEST_APPROX_PREFIX operator> (const Approx& lhs, const T& rhs) { return lhs.m_value > double(rhs) && lhs != rhs; }
  942. #undef DOCTEST_APPROX_PREFIX
  943. #endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
  944. // clang-format on
  945. private:
  946. double m_epsilon;
  947. double m_scale;
  948. double m_value;
  949. };
  950. DOCTEST_INTERFACE String toString(const Approx& in);
  951. DOCTEST_INTERFACE const ContextOptions* getContextOptions();
  952. #if !defined(DOCTEST_CONFIG_DISABLE)
  953. namespace detail {
  954. // clang-format off
  955. #ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
  956. template<class T> struct decay_array { typedef T type; };
  957. template<class T, unsigned N> struct decay_array<T[N]> { typedef T* type; };
  958. template<class T> struct decay_array<T[]> { typedef T* type; };
  959. template<class T> struct not_char_pointer { enum { value = 1 }; };
  960. template<> struct not_char_pointer<char*> { enum { value = 0 }; };
  961. template<> struct not_char_pointer<const char*> { enum { value = 0 }; };
  962. template<class T> struct can_use_op : public not_char_pointer<typename decay_array<T>::type> {};
  963. #endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
  964. // clang-format on
  965. struct DOCTEST_INTERFACE TestFailureException
  966. {
  967. };
  968. DOCTEST_INTERFACE bool checkIfShouldThrow(assertType::Enum at);
  969. #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
  970. DOCTEST_NORETURN
  971. #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
  972. DOCTEST_INTERFACE void throwException();
  973. struct DOCTEST_INTERFACE Subcase
  974. {
  975. SubcaseSignature m_signature;
  976. bool m_entered = false;
  977. Subcase(const String& name, const char* file, int line);
  978. ~Subcase();
  979. operator bool() const;
  980. };
  981. template <typename L, typename R>
  982. String stringifyBinaryExpr(const DOCTEST_REF_WRAP(L) lhs, const char* op,
  983. const DOCTEST_REF_WRAP(R) rhs) {
  984. // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
  985. return toString(lhs) + op + toString(rhs);
  986. }
  987. #if DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 6, 0)
  988. DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wunused-comparison")
  989. #endif
  990. // This will check if there is any way it could find a operator like member or friend and uses it.
  991. // If not it doesn't find the operator or if the operator at global scope is defined after
  992. // this template, the template won't be instantiated due to SFINAE. Once the template is not
  993. // instantiated it can look for global operator using normal conversions.
  994. #define SFINAE_OP(ret,op) decltype((void)(doctest::detail::declval<L>() op doctest::detail::declval<R>()),ret{})
  995. #define DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(op, op_str, op_macro) \
  996. template <typename R> \
  997. DOCTEST_NOINLINE SFINAE_OP(Result,op) operator op(const R&& rhs) { \
  998. bool res = op_macro(doctest::detail::forward<const L>(lhs), doctest::detail::forward<const R>(rhs)); \
  999. if(m_at & assertType::is_false) \
  1000. res = !res; \
  1001. if(!res || doctest::getContextOptions()->success) \
  1002. return Result(res, stringifyBinaryExpr(lhs, op_str, rhs)); \
  1003. return Result(res); \
  1004. } \
  1005. template <typename R ,typename enable_if<!doctest::detail::is_rvalue_reference<R>::value, void >::type* = nullptr> \
  1006. DOCTEST_NOINLINE SFINAE_OP(Result,op) operator op(const R& rhs) { \
  1007. bool res = op_macro(doctest::detail::forward<const L>(lhs), rhs); \
  1008. if(m_at & assertType::is_false) \
  1009. res = !res; \
  1010. if(!res || doctest::getContextOptions()->success) \
  1011. return Result(res, stringifyBinaryExpr(lhs, op_str, rhs)); \
  1012. return Result(res); \
  1013. }
  1014. // more checks could be added - like in Catch:
  1015. // https://github.com/catchorg/Catch2/pull/1480/files
  1016. // https://github.com/catchorg/Catch2/pull/1481/files
  1017. #define DOCTEST_FORBIT_EXPRESSION(rt, op) \
  1018. template <typename R> \
  1019. rt& operator op(const R&) { \
  1020. static_assert(deferred_false<R>::value, \
  1021. "Expression Too Complex Please Rewrite As Binary Comparison!"); \
  1022. return *this; \
  1023. }
  1024. struct DOCTEST_INTERFACE Result
  1025. {
  1026. bool m_passed;
  1027. String m_decomp;
  1028. Result() = default;
  1029. Result(bool passed, const String& decomposition = String());
  1030. // forbidding some expressions based on this table: https://en.cppreference.com/w/cpp/language/operator_precedence
  1031. DOCTEST_FORBIT_EXPRESSION(Result, &)
  1032. DOCTEST_FORBIT_EXPRESSION(Result, ^)
  1033. DOCTEST_FORBIT_EXPRESSION(Result, |)
  1034. DOCTEST_FORBIT_EXPRESSION(Result, &&)
  1035. DOCTEST_FORBIT_EXPRESSION(Result, ||)
  1036. DOCTEST_FORBIT_EXPRESSION(Result, ==)
  1037. DOCTEST_FORBIT_EXPRESSION(Result, !=)
  1038. DOCTEST_FORBIT_EXPRESSION(Result, <)
  1039. DOCTEST_FORBIT_EXPRESSION(Result, >)
  1040. DOCTEST_FORBIT_EXPRESSION(Result, <=)
  1041. DOCTEST_FORBIT_EXPRESSION(Result, >=)
  1042. DOCTEST_FORBIT_EXPRESSION(Result, =)
  1043. DOCTEST_FORBIT_EXPRESSION(Result, +=)
  1044. DOCTEST_FORBIT_EXPRESSION(Result, -=)
  1045. DOCTEST_FORBIT_EXPRESSION(Result, *=)
  1046. DOCTEST_FORBIT_EXPRESSION(Result, /=)
  1047. DOCTEST_FORBIT_EXPRESSION(Result, %=)
  1048. DOCTEST_FORBIT_EXPRESSION(Result, <<=)
  1049. DOCTEST_FORBIT_EXPRESSION(Result, >>=)
  1050. DOCTEST_FORBIT_EXPRESSION(Result, &=)
  1051. DOCTEST_FORBIT_EXPRESSION(Result, ^=)
  1052. DOCTEST_FORBIT_EXPRESSION(Result, |=)
  1053. };
  1054. #ifndef DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION
  1055. DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
  1056. DOCTEST_CLANG_SUPPRESS_WARNING("-Wsign-conversion")
  1057. DOCTEST_CLANG_SUPPRESS_WARNING("-Wsign-compare")
  1058. //DOCTEST_CLANG_SUPPRESS_WARNING("-Wdouble-promotion")
  1059. //DOCTEST_CLANG_SUPPRESS_WARNING("-Wconversion")
  1060. //DOCTEST_CLANG_SUPPRESS_WARNING("-Wfloat-equal")
  1061. DOCTEST_GCC_SUPPRESS_WARNING_PUSH
  1062. DOCTEST_GCC_SUPPRESS_WARNING("-Wsign-conversion")
  1063. DOCTEST_GCC_SUPPRESS_WARNING("-Wsign-compare")
  1064. //DOCTEST_GCC_SUPPRESS_WARNING("-Wdouble-promotion")
  1065. //DOCTEST_GCC_SUPPRESS_WARNING("-Wconversion")
  1066. //DOCTEST_GCC_SUPPRESS_WARNING("-Wfloat-equal")
  1067. DOCTEST_MSVC_SUPPRESS_WARNING_PUSH
  1068. // https://stackoverflow.com/questions/39479163 what's the difference between 4018 and 4389
  1069. DOCTEST_MSVC_SUPPRESS_WARNING(4388) // signed/unsigned mismatch
  1070. DOCTEST_MSVC_SUPPRESS_WARNING(4389) // 'operator' : signed/unsigned mismatch
  1071. DOCTEST_MSVC_SUPPRESS_WARNING(4018) // 'expression' : signed/unsigned mismatch
  1072. //DOCTEST_MSVC_SUPPRESS_WARNING(4805) // 'operation' : unsafe mix of type 'type' and type 'type' in operation
  1073. #endif // DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION
  1074. // clang-format off
  1075. #ifndef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
  1076. #define DOCTEST_COMPARISON_RETURN_TYPE bool
  1077. #else // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
  1078. #define DOCTEST_COMPARISON_RETURN_TYPE typename enable_if<can_use_op<L>::value || can_use_op<R>::value, bool>::type
  1079. // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
  1080. inline bool eq(const char* lhs, const char* rhs) { return String(lhs) == String(rhs); }
  1081. inline bool ne(const char* lhs, const char* rhs) { return String(lhs) != String(rhs); }
  1082. inline bool lt(const char* lhs, const char* rhs) { return String(lhs) < String(rhs); }
  1083. inline bool gt(const char* lhs, const char* rhs) { return String(lhs) > String(rhs); }
  1084. inline bool le(const char* lhs, const char* rhs) { return String(lhs) <= String(rhs); }
  1085. inline bool ge(const char* lhs, const char* rhs) { return String(lhs) >= String(rhs); }
  1086. #endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
  1087. // clang-format on
  1088. #define DOCTEST_RELATIONAL_OP(name, op) \
  1089. template <typename L, typename R> \
  1090. DOCTEST_COMPARISON_RETURN_TYPE name(const DOCTEST_REF_WRAP(L) lhs, \
  1091. const DOCTEST_REF_WRAP(R) rhs) { \
  1092. return lhs op rhs; \
  1093. }
  1094. DOCTEST_RELATIONAL_OP(eq, ==)
  1095. DOCTEST_RELATIONAL_OP(ne, !=)
  1096. DOCTEST_RELATIONAL_OP(lt, <)
  1097. DOCTEST_RELATIONAL_OP(gt, >)
  1098. DOCTEST_RELATIONAL_OP(le, <=)
  1099. DOCTEST_RELATIONAL_OP(ge, >=)
  1100. #ifndef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
  1101. #define DOCTEST_CMP_EQ(l, r) l == r
  1102. #define DOCTEST_CMP_NE(l, r) l != r
  1103. #define DOCTEST_CMP_GT(l, r) l > r
  1104. #define DOCTEST_CMP_LT(l, r) l < r
  1105. #define DOCTEST_CMP_GE(l, r) l >= r
  1106. #define DOCTEST_CMP_LE(l, r) l <= r
  1107. #else // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
  1108. #define DOCTEST_CMP_EQ(l, r) eq(l, r)
  1109. #define DOCTEST_CMP_NE(l, r) ne(l, r)
  1110. #define DOCTEST_CMP_GT(l, r) gt(l, r)
  1111. #define DOCTEST_CMP_LT(l, r) lt(l, r)
  1112. #define DOCTEST_CMP_GE(l, r) ge(l, r)
  1113. #define DOCTEST_CMP_LE(l, r) le(l, r)
  1114. #endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
  1115. template <typename L>
  1116. // cppcheck-suppress copyCtorAndEqOperator
  1117. struct Expression_lhs
  1118. {
  1119. L lhs;
  1120. assertType::Enum m_at;
  1121. explicit Expression_lhs(L&& in, assertType::Enum at)
  1122. : lhs(doctest::detail::forward<L>(in))
  1123. , m_at(at) {}
  1124. DOCTEST_NOINLINE operator Result() {
  1125. // this is needed only for MSVC 2015
  1126. DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4800) // 'int': forcing value to bool
  1127. bool res = static_cast<bool>(lhs);
  1128. DOCTEST_MSVC_SUPPRESS_WARNING_POP
  1129. if(m_at & assertType::is_false) //!OCLINT bitwise operator in conditional
  1130. res = !res;
  1131. if(!res || getContextOptions()->success)
  1132. return Result(res, toString(lhs));
  1133. return Result(res);
  1134. }
  1135. /* This is required for user-defined conversions from Expression_lhs to L */
  1136. operator L() const { return lhs; }
  1137. // clang-format off
  1138. DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(==, " == ", DOCTEST_CMP_EQ) //!OCLINT bitwise operator in conditional
  1139. DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(!=, " != ", DOCTEST_CMP_NE) //!OCLINT bitwise operator in conditional
  1140. DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(>, " > ", DOCTEST_CMP_GT) //!OCLINT bitwise operator in conditional
  1141. DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(<, " < ", DOCTEST_CMP_LT) //!OCLINT bitwise operator in conditional
  1142. DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(>=, " >= ", DOCTEST_CMP_GE) //!OCLINT bitwise operator in conditional
  1143. DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(<=, " <= ", DOCTEST_CMP_LE) //!OCLINT bitwise operator in conditional
  1144. // clang-format on
  1145. // forbidding some expressions based on this table: https://en.cppreference.com/w/cpp/language/operator_precedence
  1146. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, &)
  1147. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, ^)
  1148. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, |)
  1149. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, &&)
  1150. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, ||)
  1151. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, =)
  1152. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, +=)
  1153. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, -=)
  1154. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, *=)
  1155. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, /=)
  1156. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, %=)
  1157. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, <<=)
  1158. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, >>=)
  1159. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, &=)
  1160. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, ^=)
  1161. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, |=)
  1162. // these 2 are unfortunate because they should be allowed - they have higher precedence over the comparisons, but the
  1163. // ExpressionDecomposer class uses the left shift operator to capture the left operand of the binary expression...
  1164. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, <<)
  1165. DOCTEST_FORBIT_EXPRESSION(Expression_lhs, >>)
  1166. };
  1167. #ifndef DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION
  1168. DOCTEST_CLANG_SUPPRESS_WARNING_POP
  1169. DOCTEST_MSVC_SUPPRESS_WARNING_POP
  1170. DOCTEST_GCC_SUPPRESS_WARNING_POP
  1171. #endif // DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION
  1172. #if DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 6, 0)
  1173. DOCTEST_CLANG_SUPPRESS_WARNING_POP
  1174. #endif
  1175. struct DOCTEST_INTERFACE ExpressionDecomposer
  1176. {
  1177. assertType::Enum m_at;
  1178. ExpressionDecomposer(assertType::Enum at);
  1179. // The right operator for capturing expressions is "<=" instead of "<<" (based on the operator precedence table)
  1180. // but then there will be warnings from GCC about "-Wparentheses" and since "_Pragma()" is problematic this will stay for now...
  1181. // https://github.com/catchorg/Catch2/issues/870
  1182. // https://github.com/catchorg/Catch2/issues/565
  1183. template <typename L>
  1184. Expression_lhs<const L> operator<<(const L &&operand) {
  1185. return Expression_lhs<const L>(doctest::detail::forward<const L>(operand), m_at);
  1186. }
  1187. template <typename L,typename enable_if<!doctest::detail::is_rvalue_reference<L>::value,void >::type* = nullptr>
  1188. Expression_lhs<const L&> operator<<(const L &operand) {
  1189. return Expression_lhs<const L&>(operand, m_at);
  1190. }
  1191. };
  1192. struct DOCTEST_INTERFACE TestSuite
  1193. {
  1194. const char* m_test_suite = nullptr;
  1195. const char* m_description = nullptr;
  1196. bool m_skip = false;
  1197. bool m_no_breaks = false;
  1198. bool m_no_output = false;
  1199. bool m_may_fail = false;
  1200. bool m_should_fail = false;
  1201. int m_expected_failures = 0;
  1202. double m_timeout = 0;
  1203. TestSuite& operator*(const char* in);
  1204. template <typename T>
  1205. TestSuite& operator*(const T& in) {
  1206. in.fill(*this);
  1207. return *this;
  1208. }
  1209. };
  1210. typedef void (*funcType)();
  1211. struct DOCTEST_INTERFACE TestCase : public TestCaseData
  1212. {
  1213. funcType m_test; // a function pointer to the test case
  1214. const char* m_type; // for templated test cases - gets appended to the real name
  1215. int m_template_id; // an ID used to distinguish between the different versions of a templated test case
  1216. String m_full_name; // contains the name (only for templated test cases!) + the template type
  1217. TestCase(funcType test, const char* file, unsigned line, const TestSuite& test_suite,
  1218. const char* type = "", int template_id = -1);
  1219. TestCase(const TestCase& other);
  1220. DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(26434) // hides a non-virtual function
  1221. TestCase& operator=(const TestCase& other);
  1222. DOCTEST_MSVC_SUPPRESS_WARNING_POP
  1223. TestCase& operator*(const char* in);
  1224. template <typename T>
  1225. TestCase& operator*(const T& in) {
  1226. in.fill(*this);
  1227. return *this;
  1228. }
  1229. bool operator<(const TestCase& other) const;
  1230. };
  1231. // forward declarations of functions used by the macros
  1232. DOCTEST_INTERFACE int regTest(const TestCase& tc);
  1233. DOCTEST_INTERFACE int setTestSuite(const TestSuite& ts);
  1234. DOCTEST_INTERFACE bool isDebuggerActive();
  1235. template<typename T>
  1236. int instantiationHelper(const T&) { return 0; }
  1237. namespace binaryAssertComparison {
  1238. enum Enum
  1239. {
  1240. eq = 0,
  1241. ne,
  1242. gt,
  1243. lt,
  1244. ge,
  1245. le
  1246. };
  1247. } // namespace binaryAssertComparison
  1248. // clang-format off
  1249. template <int, class L, class R> struct RelationalComparator { bool operator()(const DOCTEST_REF_WRAP(L), const DOCTEST_REF_WRAP(R) ) const { return false; } };
  1250. #define DOCTEST_BINARY_RELATIONAL_OP(n, op) \
  1251. template <class L, class R> struct RelationalComparator<n, L, R> { bool operator()(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) const { return op(lhs, rhs); } };
  1252. // clang-format on
  1253. DOCTEST_BINARY_RELATIONAL_OP(0, doctest::detail::eq)
  1254. DOCTEST_BINARY_RELATIONAL_OP(1, doctest::detail::ne)
  1255. DOCTEST_BINARY_RELATIONAL_OP(2, doctest::detail::gt)
  1256. DOCTEST_BINARY_RELATIONAL_OP(3, doctest::detail::lt)
  1257. DOCTEST_BINARY_RELATIONAL_OP(4, doctest::detail::ge)
  1258. DOCTEST_BINARY_RELATIONAL_OP(5, doctest::detail::le)
  1259. struct DOCTEST_INTERFACE ResultBuilder : public AssertData
  1260. {
  1261. ResultBuilder(assertType::Enum at, const char* file, int line, const char* expr,
  1262. const char* exception_type = "", const char* exception_string = "");
  1263. void setResult(const Result& res);
  1264. template <int comparison, typename L, typename R>
  1265. DOCTEST_NOINLINE bool binary_assert(const DOCTEST_REF_WRAP(L) lhs,
  1266. const DOCTEST_REF_WRAP(R) rhs) {
  1267. m_failed = !RelationalComparator<comparison, L, R>()(lhs, rhs);
  1268. if(m_failed || getContextOptions()->success)
  1269. m_decomp = stringifyBinaryExpr(lhs, ", ", rhs);
  1270. return !m_failed;
  1271. }
  1272. template <typename L>
  1273. DOCTEST_NOINLINE bool unary_assert(const DOCTEST_REF_WRAP(L) val) {
  1274. m_failed = !val;
  1275. if(m_at & assertType::is_false) //!OCLINT bitwise operator in conditional
  1276. m_failed = !m_failed;
  1277. if(m_failed || getContextOptions()->success)
  1278. m_decomp = toString(val);
  1279. return !m_failed;
  1280. }
  1281. void translateException();
  1282. bool log();
  1283. void react() const;
  1284. };
  1285. namespace assertAction {
  1286. enum Enum
  1287. {
  1288. nothing = 0,
  1289. dbgbreak = 1,
  1290. shouldthrow = 2
  1291. };
  1292. } // namespace assertAction
  1293. DOCTEST_INTERFACE void failed_out_of_a_testing_context(const AssertData& ad);
  1294. DOCTEST_INTERFACE bool decomp_assert(assertType::Enum at, const char* file, int line,
  1295. const char* expr, Result result);
  1296. #define DOCTEST_ASSERT_OUT_OF_TESTS(decomp) \
  1297. do { \
  1298. if(!is_running_in_test) { \
  1299. if(failed) { \
  1300. ResultBuilder rb(at, file, line, expr); \
  1301. rb.m_failed = failed; \
  1302. rb.m_decomp = decomp; \
  1303. failed_out_of_a_testing_context(rb); \
  1304. if(isDebuggerActive() && !getContextOptions()->no_breaks) \
  1305. DOCTEST_BREAK_INTO_DEBUGGER(); \
  1306. if(checkIfShouldThrow(at)) \
  1307. throwException(); \
  1308. } \
  1309. return !failed; \
  1310. } \
  1311. } while(false)
  1312. #define DOCTEST_ASSERT_IN_TESTS(decomp) \
  1313. ResultBuilder rb(at, file, line, expr); \
  1314. rb.m_failed = failed; \
  1315. if(rb.m_failed || getContextOptions()->success) \
  1316. rb.m_decomp = decomp; \
  1317. if(rb.log()) \
  1318. DOCTEST_BREAK_INTO_DEBUGGER(); \
  1319. if(rb.m_failed && checkIfShouldThrow(at)) \
  1320. throwException()
  1321. template <int comparison, typename L, typename R>
  1322. DOCTEST_NOINLINE bool binary_assert(assertType::Enum at, const char* file, int line,
  1323. const char* expr, const DOCTEST_REF_WRAP(L) lhs,
  1324. const DOCTEST_REF_WRAP(R) rhs) {
  1325. bool failed = !RelationalComparator<comparison, L, R>()(lhs, rhs);
  1326. // ###################################################################################
  1327. // IF THE DEBUGGER BREAKS HERE - GO 1 LEVEL UP IN THE CALLSTACK FOR THE FAILING ASSERT
  1328. // THIS IS THE EFFECT OF HAVING 'DOCTEST_CONFIG_SUPER_FAST_ASSERTS' DEFINED
  1329. // ###################################################################################
  1330. DOCTEST_ASSERT_OUT_OF_TESTS(stringifyBinaryExpr(lhs, ", ", rhs));
  1331. DOCTEST_ASSERT_IN_TESTS(stringifyBinaryExpr(lhs, ", ", rhs));
  1332. return !failed;
  1333. }
  1334. template <typename L>
  1335. DOCTEST_NOINLINE bool unary_assert(assertType::Enum at, const char* file, int line,
  1336. const char* expr, const DOCTEST_REF_WRAP(L) val) {
  1337. bool failed = !val;
  1338. if(at & assertType::is_false) //!OCLINT bitwise operator in conditional
  1339. failed = !failed;
  1340. // ###################################################################################
  1341. // IF THE DEBUGGER BREAKS HERE - GO 1 LEVEL UP IN THE CALLSTACK FOR THE FAILING ASSERT
  1342. // THIS IS THE EFFECT OF HAVING 'DOCTEST_CONFIG_SUPER_FAST_ASSERTS' DEFINED
  1343. // ###################################################################################
  1344. DOCTEST_ASSERT_OUT_OF_TESTS(toString(val));
  1345. DOCTEST_ASSERT_IN_TESTS(toString(val));
  1346. return !failed;
  1347. }
  1348. struct DOCTEST_INTERFACE IExceptionTranslator
  1349. {
  1350. IExceptionTranslator();
  1351. virtual ~IExceptionTranslator();
  1352. virtual bool translate(String&) const = 0;
  1353. };
  1354. template <typename T>
  1355. class ExceptionTranslator : public IExceptionTranslator //!OCLINT destructor of virtual class
  1356. {
  1357. public:
  1358. explicit ExceptionTranslator(String (*translateFunction)(T))
  1359. : m_translateFunction(translateFunction) {}
  1360. bool translate(String& res) const override {
  1361. #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
  1362. try {
  1363. throw; // lgtm [cpp/rethrow-no-exception]
  1364. // cppcheck-suppress catchExceptionByValue
  1365. } catch(T ex) { // NOLINT
  1366. res = m_translateFunction(ex); //!OCLINT parameter reassignment
  1367. return true;
  1368. } catch(...) {} //!OCLINT - empty catch statement
  1369. #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
  1370. static_cast<void>(res); // to silence -Wunused-parameter
  1371. return false;
  1372. }
  1373. private:
  1374. String (*m_translateFunction)(T);
  1375. };
  1376. DOCTEST_INTERFACE void registerExceptionTranslatorImpl(const IExceptionTranslator* et);
  1377. template <bool C>
  1378. struct StringStreamBase
  1379. {
  1380. template <typename T>
  1381. static void convert(std::ostream* s, const T& in) {
  1382. *s << toString(in);
  1383. }
  1384. // always treat char* as a string in this context - no matter
  1385. // if DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING is defined
  1386. static void convert(std::ostream* s, const char* in) { *s << String(in); }
  1387. };
  1388. template <>
  1389. struct StringStreamBase<true>
  1390. {
  1391. template <typename T>
  1392. static void convert(std::ostream* s, const T& in) {
  1393. *s << in;
  1394. }
  1395. };
  1396. template <typename T>
  1397. struct StringStream : public StringStreamBase<has_insertion_operator<T>::value>
  1398. {};
  1399. template <typename T>
  1400. void toStream(std::ostream* s, const T& value) {
  1401. StringStream<T>::convert(s, value);
  1402. }
  1403. #ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
  1404. DOCTEST_INTERFACE void toStream(std::ostream* s, char* in);
  1405. DOCTEST_INTERFACE void toStream(std::ostream* s, const char* in);
  1406. #endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
  1407. DOCTEST_INTERFACE void toStream(std::ostream* s, bool in);
  1408. DOCTEST_INTERFACE void toStream(std::ostream* s, float in);
  1409. DOCTEST_INTERFACE void toStream(std::ostream* s, double in);
  1410. DOCTEST_INTERFACE void toStream(std::ostream* s, double long in);
  1411. DOCTEST_INTERFACE void toStream(std::ostream* s, char in);
  1412. DOCTEST_INTERFACE void toStream(std::ostream* s, char signed in);
  1413. DOCTEST_INTERFACE void toStream(std::ostream* s, char unsigned in);
  1414. DOCTEST_INTERFACE void toStream(std::ostream* s, int short in);
  1415. DOCTEST_INTERFACE void toStream(std::ostream* s, int short unsigned in);
  1416. DOCTEST_INTERFACE void toStream(std::ostream* s, int in);
  1417. DOCTEST_INTERFACE void toStream(std::ostream* s, int unsigned in);
  1418. DOCTEST_INTERFACE void toStream(std::ostream* s, int long in);
  1419. DOCTEST_INTERFACE void toStream(std::ostream* s, int long unsigned in);
  1420. DOCTEST_INTERFACE void toStream(std::ostream* s, int long long in);
  1421. DOCTEST_INTERFACE void toStream(std::ostream* s, int long long unsigned in);
  1422. // ContextScope base class used to allow implementing methods of ContextScope
  1423. // that don't depend on the template parameter in doctest.cpp.
  1424. class DOCTEST_INTERFACE ContextScopeBase : public IContextScope {
  1425. protected:
  1426. ContextScopeBase();
  1427. ContextScopeBase(ContextScopeBase&& other);
  1428. void destroy();
  1429. bool need_to_destroy{true};
  1430. };
  1431. template <typename L> class ContextScope : public ContextScopeBase
  1432. {
  1433. const L lambda_;
  1434. public:
  1435. explicit ContextScope(const L &lambda) : lambda_(lambda) {}
  1436. ContextScope(ContextScope &&other) : ContextScopeBase(static_cast<ContextScopeBase&&>(other)), lambda_(other.lambda_) {}
  1437. void stringify(std::ostream* s) const override { lambda_(s); }
  1438. ~ContextScope() override {
  1439. if (need_to_destroy) {
  1440. destroy();
  1441. }
  1442. }
  1443. };
  1444. struct DOCTEST_INTERFACE MessageBuilder : public MessageData
  1445. {
  1446. std::ostream* m_stream;
  1447. bool logged = false;
  1448. MessageBuilder(const char* file, int line, assertType::Enum severity);
  1449. MessageBuilder() = delete;
  1450. ~MessageBuilder();
  1451. // the preferred way of chaining parameters for stringification
  1452. template <typename T>
  1453. MessageBuilder& operator,(const T& in) {
  1454. toStream(m_stream, in);
  1455. return *this;
  1456. }
  1457. // kept here just for backwards-compatibility - the comma operator should be preferred now
  1458. template <typename T>
  1459. MessageBuilder& operator<<(const T& in) { return this->operator,(in); }
  1460. // the `,` operator has the lowest operator precedence - if `<<` is used by the user then
  1461. // the `,` operator will be called last which is not what we want and thus the `*` operator
  1462. // is used first (has higher operator precedence compared to `<<`) so that we guarantee that
  1463. // an operator of the MessageBuilder class is called first before the rest of the parameters
  1464. template <typename T>
  1465. MessageBuilder& operator*(const T& in) { return this->operator,(in); }
  1466. bool log();
  1467. void react();
  1468. };
  1469. template <typename L>
  1470. ContextScope<L> MakeContextScope(const L &lambda) {
  1471. return ContextScope<L>(lambda);
  1472. }
  1473. } // namespace detail
  1474. #define DOCTEST_DEFINE_DECORATOR(name, type, def) \
  1475. struct name \
  1476. { \
  1477. type data; \
  1478. name(type in = def) \
  1479. : data(in) {} \
  1480. void fill(detail::TestCase& state) const { state.DOCTEST_CAT(m_, name) = data; } \
  1481. void fill(detail::TestSuite& state) const { state.DOCTEST_CAT(m_, name) = data; } \
  1482. }
  1483. DOCTEST_DEFINE_DECORATOR(test_suite, const char*, "");
  1484. DOCTEST_DEFINE_DECORATOR(description, const char*, "");
  1485. DOCTEST_DEFINE_DECORATOR(skip, bool, true);
  1486. DOCTEST_DEFINE_DECORATOR(no_breaks, bool, true);
  1487. DOCTEST_DEFINE_DECORATOR(no_output, bool, true);
  1488. DOCTEST_DEFINE_DECORATOR(timeout, double, 0);
  1489. DOCTEST_DEFINE_DECORATOR(may_fail, bool, true);
  1490. DOCTEST_DEFINE_DECORATOR(should_fail, bool, true);
  1491. DOCTEST_DEFINE_DECORATOR(expected_failures, int, 0);
  1492. template <typename T>
  1493. int registerExceptionTranslator(String (*translateFunction)(T)) {
  1494. DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wexit-time-destructors")
  1495. static detail::ExceptionTranslator<T> exceptionTranslator(translateFunction);
  1496. DOCTEST_CLANG_SUPPRESS_WARNING_POP
  1497. detail::registerExceptionTranslatorImpl(&exceptionTranslator);
  1498. return 0;
  1499. }
  1500. } // namespace doctest
  1501. // in a separate namespace outside of doctest because the DOCTEST_TEST_SUITE macro
  1502. // introduces an anonymous namespace in which getCurrentTestSuite gets overridden
  1503. namespace doctest_detail_test_suite_ns {
  1504. DOCTEST_INTERFACE doctest::detail::TestSuite& getCurrentTestSuite();
  1505. } // namespace doctest_detail_test_suite_ns
  1506. namespace doctest {
  1507. #else // DOCTEST_CONFIG_DISABLE
  1508. template <typename T>
  1509. int registerExceptionTranslator(String (*)(T)) {
  1510. return 0;
  1511. }
  1512. #endif // DOCTEST_CONFIG_DISABLE
  1513. namespace detail {
  1514. typedef void (*assert_handler)(const AssertData&);
  1515. struct ContextState;
  1516. } // namespace detail
  1517. class DOCTEST_INTERFACE Context
  1518. {
  1519. detail::ContextState* p;
  1520. void parseArgs(int argc, const char* const* argv, bool withDefaults = false);
  1521. public:
  1522. explicit Context(int argc = 0, const char* const* argv = nullptr);
  1523. ~Context();
  1524. void applyCommandLine(int argc, const char* const* argv);
  1525. void addFilter(const char* filter, const char* value);
  1526. void clearFilters();
  1527. void setOption(const char* option, bool value);
  1528. void setOption(const char* option, int value);
  1529. void setOption(const char* option, const char* value);
  1530. bool shouldExit();
  1531. void setAsDefaultForAssertsOutOfTestCases();
  1532. void setAssertHandler(detail::assert_handler ah);
  1533. void setCout(std::ostream* out);
  1534. int run();
  1535. };
  1536. namespace TestCaseFailureReason {
  1537. enum Enum
  1538. {
  1539. None = 0,
  1540. AssertFailure = 1, // an assertion has failed in the test case
  1541. Exception = 2, // test case threw an exception
  1542. Crash = 4, // a crash...
  1543. TooManyFailedAsserts = 8, // the abort-after option
  1544. Timeout = 16, // see the timeout decorator
  1545. ShouldHaveFailedButDidnt = 32, // see the should_fail decorator
  1546. ShouldHaveFailedAndDid = 64, // see the should_fail decorator
  1547. DidntFailExactlyNumTimes = 128, // see the expected_failures decorator
  1548. FailedExactlyNumTimes = 256, // see the expected_failures decorator
  1549. CouldHaveFailedAndDid = 512 // see the may_fail decorator
  1550. };
  1551. } // namespace TestCaseFailureReason
  1552. struct DOCTEST_INTERFACE CurrentTestCaseStats
  1553. {
  1554. int numAssertsCurrentTest;
  1555. int numAssertsFailedCurrentTest;
  1556. double seconds;
  1557. int failure_flags; // use TestCaseFailureReason::Enum
  1558. bool testCaseSuccess;
  1559. };
  1560. struct DOCTEST_INTERFACE TestCaseException
  1561. {
  1562. String error_string;
  1563. bool is_crash;
  1564. };
  1565. struct DOCTEST_INTERFACE TestRunStats
  1566. {
  1567. unsigned numTestCases;
  1568. unsigned numTestCasesPassingFilters;
  1569. unsigned numTestSuitesPassingFilters;
  1570. unsigned numTestCasesFailed;
  1571. int numAsserts;
  1572. int numAssertsFailed;
  1573. };
  1574. struct QueryData
  1575. {
  1576. const TestRunStats* run_stats = nullptr;
  1577. const TestCaseData** data = nullptr;
  1578. unsigned num_data = 0;
  1579. };
  1580. struct DOCTEST_INTERFACE IReporter
  1581. {
  1582. // The constructor has to accept "const ContextOptions&" as a single argument
  1583. // which has most of the options for the run + a pointer to the stdout stream
  1584. // Reporter(const ContextOptions& in)
  1585. // called when a query should be reported (listing test cases, printing the version, etc.)
  1586. virtual void report_query(const QueryData&) = 0;
  1587. // called when the whole test run starts
  1588. virtual void test_run_start() = 0;
  1589. // called when the whole test run ends (caching a pointer to the input doesn't make sense here)
  1590. virtual void test_run_end(const TestRunStats&) = 0;
  1591. // called when a test case is started (safe to cache a pointer to the input)
  1592. virtual void test_case_start(const TestCaseData&) = 0;
  1593. // called when a test case is reentered because of unfinished subcases (safe to cache a pointer to the input)
  1594. virtual void test_case_reenter(const TestCaseData&) = 0;
  1595. // called when a test case has ended
  1596. virtual void test_case_end(const CurrentTestCaseStats&) = 0;
  1597. // called when an exception is thrown from the test case (or it crashes)
  1598. virtual void test_case_exception(const TestCaseException&) = 0;
  1599. // called whenever a subcase is entered (don't cache pointers to the input)
  1600. virtual void subcase_start(const SubcaseSignature&) = 0;
  1601. // called whenever a subcase is exited (don't cache pointers to the input)
  1602. virtual void subcase_end() = 0;
  1603. // called for each assert (don't cache pointers to the input)
  1604. virtual void log_assert(const AssertData&) = 0;
  1605. // called for each message (don't cache pointers to the input)
  1606. virtual void log_message(const MessageData&) = 0;
  1607. // called when a test case is skipped either because it doesn't pass the filters, has a skip decorator
  1608. // or isn't in the execution range (between first and last) (safe to cache a pointer to the input)
  1609. virtual void test_case_skipped(const TestCaseData&) = 0;
  1610. // doctest will not be managing the lifetimes of reporters given to it but this would still be nice to have
  1611. virtual ~IReporter();
  1612. // can obtain all currently active contexts and stringify them if one wishes to do so
  1613. static int get_num_active_contexts();
  1614. static const IContextScope* const* get_active_contexts();
  1615. // can iterate through contexts which have been stringified automatically in their destructors when an exception has been thrown
  1616. static int get_num_stringified_contexts();
  1617. static const String* get_stringified_contexts();
  1618. };
  1619. namespace detail {
  1620. typedef IReporter* (*reporterCreatorFunc)(const ContextOptions&);
  1621. DOCTEST_INTERFACE void registerReporterImpl(const char* name, int prio, reporterCreatorFunc c, bool isReporter);
  1622. template <typename Reporter>
  1623. IReporter* reporterCreator(const ContextOptions& o) {
  1624. return new Reporter(o);
  1625. }
  1626. } // namespace detail
  1627. template <typename Reporter>
  1628. int registerReporter(const char* name, int priority, bool isReporter) {
  1629. detail::registerReporterImpl(name, priority, detail::reporterCreator<Reporter>, isReporter);
  1630. return 0;
  1631. }
  1632. } // namespace doctest
  1633. // if registering is not disabled
  1634. #if !defined(DOCTEST_CONFIG_DISABLE)
  1635. // common code in asserts - for convenience
  1636. #define DOCTEST_ASSERT_LOG_REACT_RETURN(b) \
  1637. if(b.log()) \
  1638. DOCTEST_BREAK_INTO_DEBUGGER(); \
  1639. b.react(); \
  1640. return !b.m_failed
  1641. #ifdef DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS
  1642. #define DOCTEST_WRAP_IN_TRY(x) x;
  1643. #else // DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS
  1644. #define DOCTEST_WRAP_IN_TRY(x) \
  1645. try { \
  1646. x; \
  1647. } catch(...) { DOCTEST_RB.translateException(); }
  1648. #endif // DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS
  1649. #ifdef DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS
  1650. #define DOCTEST_CAST_TO_VOID(...) \
  1651. DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wuseless-cast") \
  1652. static_cast<void>(__VA_ARGS__); \
  1653. DOCTEST_GCC_SUPPRESS_WARNING_POP
  1654. #else // DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS
  1655. #define DOCTEST_CAST_TO_VOID(...) __VA_ARGS__;
  1656. #endif // DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS
  1657. // registers the test by initializing a dummy var with a function
  1658. #define DOCTEST_REGISTER_FUNCTION(global_prefix, f, decorators) \
  1659. global_prefix DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_VAR_), \
  1660. doctest::detail::regTest( \
  1661. doctest::detail::TestCase( \
  1662. f, __FILE__, __LINE__, \
  1663. doctest_detail_test_suite_ns::getCurrentTestSuite()) * \
  1664. decorators))
  1665. #define DOCTEST_IMPLEMENT_FIXTURE(der, base, func, decorators) \
  1666. namespace { \
  1667. struct der : public base \
  1668. { \
  1669. void f(); \
  1670. }; \
  1671. static void func() { \
  1672. der v; \
  1673. v.f(); \
  1674. } \
  1675. DOCTEST_REGISTER_FUNCTION(DOCTEST_EMPTY, func, decorators) \
  1676. } \
  1677. inline DOCTEST_NOINLINE void der::f()
  1678. #define DOCTEST_CREATE_AND_REGISTER_FUNCTION(f, decorators) \
  1679. static void f(); \
  1680. DOCTEST_REGISTER_FUNCTION(DOCTEST_EMPTY, f, decorators) \
  1681. static void f()
  1682. #define DOCTEST_CREATE_AND_REGISTER_FUNCTION_IN_CLASS(f, proxy, decorators) \
  1683. static doctest::detail::funcType proxy() { return f; } \
  1684. DOCTEST_REGISTER_FUNCTION(inline, proxy(), decorators) \
  1685. static void f()
  1686. // for registering tests
  1687. #define DOCTEST_TEST_CASE(decorators) \
  1688. DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), decorators)
  1689. // for registering tests in classes - requires C++17 for inline variables!
  1690. #if __cplusplus >= 201703L || (DOCTEST_MSVC >= DOCTEST_COMPILER(19, 12, 0) && _MSVC_LANG >= 201703L)
  1691. #define DOCTEST_TEST_CASE_CLASS(decorators) \
  1692. DOCTEST_CREATE_AND_REGISTER_FUNCTION_IN_CLASS(DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), \
  1693. DOCTEST_ANONYMOUS(DOCTEST_ANON_PROXY_), \
  1694. decorators)
  1695. #else // DOCTEST_TEST_CASE_CLASS
  1696. #define DOCTEST_TEST_CASE_CLASS(...) \
  1697. TEST_CASES_CAN_BE_REGISTERED_IN_CLASSES_ONLY_IN_CPP17_MODE_OR_WITH_VS_2017_OR_NEWER
  1698. #endif // DOCTEST_TEST_CASE_CLASS
  1699. // for registering tests with a fixture
  1700. #define DOCTEST_TEST_CASE_FIXTURE(c, decorators) \
  1701. DOCTEST_IMPLEMENT_FIXTURE(DOCTEST_ANONYMOUS(DOCTEST_ANON_CLASS_), c, \
  1702. DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), decorators)
  1703. // for converting types to strings without the <typeinfo> header and demangling
  1704. #define DOCTEST_TYPE_TO_STRING_IMPL(...) \
  1705. template <> \
  1706. inline const char* type_to_string<__VA_ARGS__>() { \
  1707. return "<" #__VA_ARGS__ ">"; \
  1708. }
  1709. #define DOCTEST_TYPE_TO_STRING(...) \
  1710. namespace doctest { namespace detail { \
  1711. DOCTEST_TYPE_TO_STRING_IMPL(__VA_ARGS__) \
  1712. } \
  1713. } \
  1714. static_assert(true, "")
  1715. #define DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, iter, func) \
  1716. template <typename T> \
  1717. static void func(); \
  1718. namespace { \
  1719. template <typename Tuple> \
  1720. struct iter; \
  1721. template <typename Type, typename... Rest> \
  1722. struct iter<std::tuple<Type, Rest...>> \
  1723. { \
  1724. iter(const char* file, unsigned line, int index) { \
  1725. doctest::detail::regTest(doctest::detail::TestCase(func<Type>, file, line, \
  1726. doctest_detail_test_suite_ns::getCurrentTestSuite(), \
  1727. doctest::detail::type_to_string<Type>(), \
  1728. int(line) * 1000 + index) \
  1729. * dec); \
  1730. iter<std::tuple<Rest...>>(file, line, index + 1); \
  1731. } \
  1732. }; \
  1733. template <> \
  1734. struct iter<std::tuple<>> \
  1735. { \
  1736. iter(const char*, unsigned, int) {} \
  1737. }; \
  1738. } \
  1739. template <typename T> \
  1740. static void func()
  1741. #define DOCTEST_TEST_CASE_TEMPLATE_DEFINE(dec, T, id) \
  1742. DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, DOCTEST_CAT(id, ITERATOR), \
  1743. DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_))
  1744. #define DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, anon, ...) \
  1745. DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_CAT(anon, DUMMY), \
  1746. doctest::detail::instantiationHelper( \
  1747. DOCTEST_CAT(id, ITERATOR)<__VA_ARGS__>(__FILE__, __LINE__, 0)))
  1748. #define DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, ...) \
  1749. DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_), std::tuple<__VA_ARGS__>) \
  1750. static_assert(true, "")
  1751. #define DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, ...) \
  1752. DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_), __VA_ARGS__) \
  1753. static_assert(true, "")
  1754. #define DOCTEST_TEST_CASE_TEMPLATE_IMPL(dec, T, anon, ...) \
  1755. DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, DOCTEST_CAT(anon, ITERATOR), anon); \
  1756. DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(anon, anon, std::tuple<__VA_ARGS__>) \
  1757. template <typename T> \
  1758. static void anon()
  1759. #define DOCTEST_TEST_CASE_TEMPLATE(dec, T, ...) \
  1760. DOCTEST_TEST_CASE_TEMPLATE_IMPL(dec, T, DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_), __VA_ARGS__)
  1761. // for subcases
  1762. #define DOCTEST_SUBCASE(name) \
  1763. if(const doctest::detail::Subcase & DOCTEST_ANONYMOUS(DOCTEST_ANON_SUBCASE_) DOCTEST_UNUSED = \
  1764. doctest::detail::Subcase(name, __FILE__, __LINE__))
  1765. // for grouping tests in test suites by using code blocks
  1766. #define DOCTEST_TEST_SUITE_IMPL(decorators, ns_name) \
  1767. namespace ns_name { namespace doctest_detail_test_suite_ns { \
  1768. static DOCTEST_NOINLINE doctest::detail::TestSuite& getCurrentTestSuite() { \
  1769. DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4640) \
  1770. DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wexit-time-destructors") \
  1771. DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wmissing-field-initializers") \
  1772. static doctest::detail::TestSuite data{}; \
  1773. static bool inited = false; \
  1774. DOCTEST_MSVC_SUPPRESS_WARNING_POP \
  1775. DOCTEST_CLANG_SUPPRESS_WARNING_POP \
  1776. DOCTEST_GCC_SUPPRESS_WARNING_POP \
  1777. if(!inited) { \
  1778. data* decorators; \
  1779. inited = true; \
  1780. } \
  1781. return data; \
  1782. } \
  1783. } \
  1784. } \
  1785. namespace ns_name
  1786. #define DOCTEST_TEST_SUITE(decorators) \
  1787. DOCTEST_TEST_SUITE_IMPL(decorators, DOCTEST_ANONYMOUS(DOCTEST_ANON_SUITE_))
  1788. // for starting a testsuite block
  1789. #define DOCTEST_TEST_SUITE_BEGIN(decorators) \
  1790. DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_VAR_), \
  1791. doctest::detail::setTestSuite(doctest::detail::TestSuite() * decorators)) \
  1792. static_assert(true, "")
  1793. // for ending a testsuite block
  1794. #define DOCTEST_TEST_SUITE_END \
  1795. DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_VAR_), \
  1796. doctest::detail::setTestSuite(doctest::detail::TestSuite() * "")) \
  1797. typedef int DOCTEST_ANONYMOUS(DOCTEST_ANON_FOR_SEMICOLON_)
  1798. // for registering exception translators
  1799. #define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR_IMPL(translatorName, signature) \
  1800. inline doctest::String translatorName(signature); \
  1801. DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_TRANSLATOR_), \
  1802. doctest::registerExceptionTranslator(translatorName)) \
  1803. doctest::String translatorName(signature)
  1804. #define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature) \
  1805. DOCTEST_REGISTER_EXCEPTION_TRANSLATOR_IMPL(DOCTEST_ANONYMOUS(DOCTEST_ANON_TRANSLATOR_), \
  1806. signature)
  1807. // for registering reporters
  1808. #define DOCTEST_REGISTER_REPORTER(name, priority, reporter) \
  1809. DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_REPORTER_), \
  1810. doctest::registerReporter<reporter>(name, priority, true)) \
  1811. static_assert(true, "")
  1812. // for registering listeners
  1813. #define DOCTEST_REGISTER_LISTENER(name, priority, reporter) \
  1814. DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_REPORTER_), \
  1815. doctest::registerReporter<reporter>(name, priority, false)) \
  1816. static_assert(true, "")
  1817. // clang-format off
  1818. // for logging - disabling formatting because it's important to have these on 2 separate lines - see PR #557
  1819. #define DOCTEST_INFO(...) \
  1820. DOCTEST_INFO_IMPL(DOCTEST_ANONYMOUS(DOCTEST_CAPTURE_), \
  1821. DOCTEST_ANONYMOUS(DOCTEST_CAPTURE_OTHER_), \
  1822. __VA_ARGS__)
  1823. // clang-format on
  1824. #define DOCTEST_INFO_IMPL(mb_name, s_name, ...) \
  1825. auto DOCTEST_ANONYMOUS(DOCTEST_CAPTURE_) = doctest::detail::MakeContextScope( \
  1826. [&](std::ostream* s_name) { \
  1827. doctest::detail::MessageBuilder mb_name(__FILE__, __LINE__, doctest::assertType::is_warn); \
  1828. mb_name.m_stream = s_name; \
  1829. mb_name * __VA_ARGS__; \
  1830. })
  1831. #define DOCTEST_CAPTURE(x) DOCTEST_INFO(#x " := ", x)
  1832. #define DOCTEST_ADD_AT_IMPL(type, file, line, mb, ...) \
  1833. [&] { \
  1834. doctest::detail::MessageBuilder mb(file, line, doctest::assertType::type); \
  1835. mb * __VA_ARGS__; \
  1836. if(mb.log()) \
  1837. DOCTEST_BREAK_INTO_DEBUGGER(); \
  1838. mb.react(); \
  1839. }()
  1840. // clang-format off
  1841. #define DOCTEST_ADD_MESSAGE_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_warn, file, line, DOCTEST_ANONYMOUS(DOCTEST_MESSAGE_), __VA_ARGS__)
  1842. #define DOCTEST_ADD_FAIL_CHECK_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_check, file, line, DOCTEST_ANONYMOUS(DOCTEST_MESSAGE_), __VA_ARGS__)
  1843. #define DOCTEST_ADD_FAIL_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_require, file, line, DOCTEST_ANONYMOUS(DOCTEST_MESSAGE_), __VA_ARGS__)
  1844. // clang-format on
  1845. #define DOCTEST_MESSAGE(...) DOCTEST_ADD_MESSAGE_AT(__FILE__, __LINE__, __VA_ARGS__)
  1846. #define DOCTEST_FAIL_CHECK(...) DOCTEST_ADD_FAIL_CHECK_AT(__FILE__, __LINE__, __VA_ARGS__)
  1847. #define DOCTEST_FAIL(...) DOCTEST_ADD_FAIL_AT(__FILE__, __LINE__, __VA_ARGS__)
  1848. #define DOCTEST_TO_LVALUE(...) __VA_ARGS__ // Not removed to keep backwards compatibility.
  1849. #ifndef DOCTEST_CONFIG_SUPER_FAST_ASSERTS
  1850. #define DOCTEST_ASSERT_IMPLEMENT_2(assert_type, ...) \
  1851. DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Woverloaded-shift-op-parentheses") \
  1852. doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
  1853. __LINE__, #__VA_ARGS__); \
  1854. DOCTEST_WRAP_IN_TRY(DOCTEST_RB.setResult( \
  1855. doctest::detail::ExpressionDecomposer(doctest::assertType::assert_type) \
  1856. << __VA_ARGS__)) \
  1857. DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB) \
  1858. DOCTEST_CLANG_SUPPRESS_WARNING_POP
  1859. #define DOCTEST_ASSERT_IMPLEMENT_1(assert_type, ...) \
  1860. [&] { \
  1861. DOCTEST_ASSERT_IMPLEMENT_2(assert_type, __VA_ARGS__); \
  1862. }()
  1863. #else // DOCTEST_CONFIG_SUPER_FAST_ASSERTS
  1864. // necessary for <ASSERT>_MESSAGE
  1865. #define DOCTEST_ASSERT_IMPLEMENT_2 DOCTEST_ASSERT_IMPLEMENT_1
  1866. #define DOCTEST_ASSERT_IMPLEMENT_1(assert_type, ...) \
  1867. DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Woverloaded-shift-op-parentheses") \
  1868. doctest::detail::decomp_assert( \
  1869. doctest::assertType::assert_type, __FILE__, __LINE__, #__VA_ARGS__, \
  1870. doctest::detail::ExpressionDecomposer(doctest::assertType::assert_type) \
  1871. << __VA_ARGS__) DOCTEST_CLANG_SUPPRESS_WARNING_POP
  1872. #endif // DOCTEST_CONFIG_SUPER_FAST_ASSERTS
  1873. #define DOCTEST_WARN(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_WARN, __VA_ARGS__)
  1874. #define DOCTEST_CHECK(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_CHECK, __VA_ARGS__)
  1875. #define DOCTEST_REQUIRE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_REQUIRE, __VA_ARGS__)
  1876. #define DOCTEST_WARN_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_WARN_FALSE, __VA_ARGS__)
  1877. #define DOCTEST_CHECK_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_CHECK_FALSE, __VA_ARGS__)
  1878. #define DOCTEST_REQUIRE_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_REQUIRE_FALSE, __VA_ARGS__)
  1879. // clang-format off
  1880. #define DOCTEST_WARN_MESSAGE(cond, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN, cond); }()
  1881. #define DOCTEST_CHECK_MESSAGE(cond, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK, cond); }()
  1882. #define DOCTEST_REQUIRE_MESSAGE(cond, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE, cond); }()
  1883. #define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN_FALSE, cond); }()
  1884. #define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK_FALSE, cond); }()
  1885. #define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE_FALSE, cond); }()
  1886. // clang-format on
  1887. #define DOCTEST_ASSERT_THROWS_AS(expr, assert_type, message, ...) \
  1888. [&] { \
  1889. if(!doctest::getContextOptions()->no_throw) { \
  1890. doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
  1891. __LINE__, #expr, #__VA_ARGS__, message); \
  1892. try { \
  1893. DOCTEST_CAST_TO_VOID(expr) \
  1894. } catch(const typename doctest::detail::remove_const< \
  1895. typename doctest::detail::remove_reference<__VA_ARGS__>::type>::type&) { \
  1896. DOCTEST_RB.translateException(); \
  1897. DOCTEST_RB.m_threw_as = true; \
  1898. } catch(...) { DOCTEST_RB.translateException(); } \
  1899. DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB); \
  1900. } else { \
  1901. return false; \
  1902. } \
  1903. }()
  1904. #define DOCTEST_ASSERT_THROWS_WITH(expr, expr_str, assert_type, ...) \
  1905. [&] { \
  1906. if(!doctest::getContextOptions()->no_throw) { \
  1907. doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
  1908. __LINE__, expr_str, "", __VA_ARGS__); \
  1909. try { \
  1910. DOCTEST_CAST_TO_VOID(expr) \
  1911. } catch(...) { DOCTEST_RB.translateException(); } \
  1912. DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB); \
  1913. } else { \
  1914. return false; \
  1915. } \
  1916. }()
  1917. #define DOCTEST_ASSERT_NOTHROW(assert_type, ...) \
  1918. [&] { \
  1919. doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
  1920. __LINE__, #__VA_ARGS__); \
  1921. try { \
  1922. DOCTEST_CAST_TO_VOID(__VA_ARGS__) \
  1923. } catch(...) { DOCTEST_RB.translateException(); } \
  1924. DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB); \
  1925. }()
  1926. // clang-format off
  1927. #define DOCTEST_WARN_THROWS(...) DOCTEST_ASSERT_THROWS_WITH((__VA_ARGS__), #__VA_ARGS__, DT_WARN_THROWS, "")
  1928. #define DOCTEST_CHECK_THROWS(...) DOCTEST_ASSERT_THROWS_WITH((__VA_ARGS__), #__VA_ARGS__, DT_CHECK_THROWS, "")
  1929. #define DOCTEST_REQUIRE_THROWS(...) DOCTEST_ASSERT_THROWS_WITH((__VA_ARGS__), #__VA_ARGS__, DT_REQUIRE_THROWS, "")
  1930. #define DOCTEST_WARN_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_WARN_THROWS_AS, "", __VA_ARGS__)
  1931. #define DOCTEST_CHECK_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_CHECK_THROWS_AS, "", __VA_ARGS__)
  1932. #define DOCTEST_REQUIRE_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_REQUIRE_THROWS_AS, "", __VA_ARGS__)
  1933. #define DOCTEST_WARN_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, #expr, DT_WARN_THROWS_WITH, __VA_ARGS__)
  1934. #define DOCTEST_CHECK_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, #expr, DT_CHECK_THROWS_WITH, __VA_ARGS__)
  1935. #define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, #expr, DT_REQUIRE_THROWS_WITH, __VA_ARGS__)
  1936. #define DOCTEST_WARN_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_WARN_THROWS_WITH_AS, message, __VA_ARGS__)
  1937. #define DOCTEST_CHECK_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_CHECK_THROWS_WITH_AS, message, __VA_ARGS__)
  1938. #define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_REQUIRE_THROWS_WITH_AS, message, __VA_ARGS__)
  1939. #define DOCTEST_WARN_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_WARN_NOTHROW, __VA_ARGS__)
  1940. #define DOCTEST_CHECK_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_CHECK_NOTHROW, __VA_ARGS__)
  1941. #define DOCTEST_REQUIRE_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_REQUIRE_NOTHROW, __VA_ARGS__)
  1942. #define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS(expr); }()
  1943. #define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS(expr); }()
  1944. #define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS(expr); }()
  1945. #define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_AS(expr, ex); }()
  1946. #define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_AS(expr, ex); }()
  1947. #define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_AS(expr, ex); }()
  1948. #define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_WITH(expr, with); }()
  1949. #define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_WITH(expr, with); }()
  1950. #define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_WITH(expr, with); }()
  1951. #define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_WITH_AS(expr, with, ex); }()
  1952. #define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ex); }()
  1953. #define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ex); }()
  1954. #define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_NOTHROW(expr); }()
  1955. #define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_NOTHROW(expr); }()
  1956. #define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_NOTHROW(expr); }()
  1957. // clang-format on
  1958. #ifndef DOCTEST_CONFIG_SUPER_FAST_ASSERTS
  1959. #define DOCTEST_BINARY_ASSERT(assert_type, comp, ...) \
  1960. [&] { \
  1961. doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
  1962. __LINE__, #__VA_ARGS__); \
  1963. DOCTEST_WRAP_IN_TRY( \
  1964. DOCTEST_RB.binary_assert<doctest::detail::binaryAssertComparison::comp>( \
  1965. __VA_ARGS__)) \
  1966. DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB); \
  1967. }()
  1968. #define DOCTEST_UNARY_ASSERT(assert_type, ...) \
  1969. [&] { \
  1970. doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \
  1971. __LINE__, #__VA_ARGS__); \
  1972. DOCTEST_WRAP_IN_TRY(DOCTEST_RB.unary_assert(__VA_ARGS__)) \
  1973. DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB); \
  1974. }()
  1975. #else // DOCTEST_CONFIG_SUPER_FAST_ASSERTS
  1976. #define DOCTEST_BINARY_ASSERT(assert_type, comparison, ...) \
  1977. doctest::detail::binary_assert<doctest::detail::binaryAssertComparison::comparison>( \
  1978. doctest::assertType::assert_type, __FILE__, __LINE__, #__VA_ARGS__, __VA_ARGS__)
  1979. #define DOCTEST_UNARY_ASSERT(assert_type, ...) \
  1980. doctest::detail::unary_assert(doctest::assertType::assert_type, __FILE__, __LINE__, \
  1981. #__VA_ARGS__, __VA_ARGS__)
  1982. #endif // DOCTEST_CONFIG_SUPER_FAST_ASSERTS
  1983. #define DOCTEST_WARN_EQ(...) DOCTEST_BINARY_ASSERT(DT_WARN_EQ, eq, __VA_ARGS__)
  1984. #define DOCTEST_CHECK_EQ(...) DOCTEST_BINARY_ASSERT(DT_CHECK_EQ, eq, __VA_ARGS__)
  1985. #define DOCTEST_REQUIRE_EQ(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_EQ, eq, __VA_ARGS__)
  1986. #define DOCTEST_WARN_NE(...) DOCTEST_BINARY_ASSERT(DT_WARN_NE, ne, __VA_ARGS__)
  1987. #define DOCTEST_CHECK_NE(...) DOCTEST_BINARY_ASSERT(DT_CHECK_NE, ne, __VA_ARGS__)
  1988. #define DOCTEST_REQUIRE_NE(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_NE, ne, __VA_ARGS__)
  1989. #define DOCTEST_WARN_GT(...) DOCTEST_BINARY_ASSERT(DT_WARN_GT, gt, __VA_ARGS__)
  1990. #define DOCTEST_CHECK_GT(...) DOCTEST_BINARY_ASSERT(DT_CHECK_GT, gt, __VA_ARGS__)
  1991. #define DOCTEST_REQUIRE_GT(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_GT, gt, __VA_ARGS__)
  1992. #define DOCTEST_WARN_LT(...) DOCTEST_BINARY_ASSERT(DT_WARN_LT, lt, __VA_ARGS__)
  1993. #define DOCTEST_CHECK_LT(...) DOCTEST_BINARY_ASSERT(DT_CHECK_LT, lt, __VA_ARGS__)
  1994. #define DOCTEST_REQUIRE_LT(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_LT, lt, __VA_ARGS__)
  1995. #define DOCTEST_WARN_GE(...) DOCTEST_BINARY_ASSERT(DT_WARN_GE, ge, __VA_ARGS__)
  1996. #define DOCTEST_CHECK_GE(...) DOCTEST_BINARY_ASSERT(DT_CHECK_GE, ge, __VA_ARGS__)
  1997. #define DOCTEST_REQUIRE_GE(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_GE, ge, __VA_ARGS__)
  1998. #define DOCTEST_WARN_LE(...) DOCTEST_BINARY_ASSERT(DT_WARN_LE, le, __VA_ARGS__)
  1999. #define DOCTEST_CHECK_LE(...) DOCTEST_BINARY_ASSERT(DT_CHECK_LE, le, __VA_ARGS__)
  2000. #define DOCTEST_REQUIRE_LE(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_LE, le, __VA_ARGS__)
  2001. #define DOCTEST_WARN_UNARY(...) DOCTEST_UNARY_ASSERT(DT_WARN_UNARY, __VA_ARGS__)
  2002. #define DOCTEST_CHECK_UNARY(...) DOCTEST_UNARY_ASSERT(DT_CHECK_UNARY, __VA_ARGS__)
  2003. #define DOCTEST_REQUIRE_UNARY(...) DOCTEST_UNARY_ASSERT(DT_REQUIRE_UNARY, __VA_ARGS__)
  2004. #define DOCTEST_WARN_UNARY_FALSE(...) DOCTEST_UNARY_ASSERT(DT_WARN_UNARY_FALSE, __VA_ARGS__)
  2005. #define DOCTEST_CHECK_UNARY_FALSE(...) DOCTEST_UNARY_ASSERT(DT_CHECK_UNARY_FALSE, __VA_ARGS__)
  2006. #define DOCTEST_REQUIRE_UNARY_FALSE(...) DOCTEST_UNARY_ASSERT(DT_REQUIRE_UNARY_FALSE, __VA_ARGS__)
  2007. #ifdef DOCTEST_CONFIG_NO_EXCEPTIONS
  2008. #undef DOCTEST_WARN_THROWS
  2009. #undef DOCTEST_CHECK_THROWS
  2010. #undef DOCTEST_REQUIRE_THROWS
  2011. #undef DOCTEST_WARN_THROWS_AS
  2012. #undef DOCTEST_CHECK_THROWS_AS
  2013. #undef DOCTEST_REQUIRE_THROWS_AS
  2014. #undef DOCTEST_WARN_THROWS_WITH
  2015. #undef DOCTEST_CHECK_THROWS_WITH
  2016. #undef DOCTEST_REQUIRE_THROWS_WITH
  2017. #undef DOCTEST_WARN_THROWS_WITH_AS
  2018. #undef DOCTEST_CHECK_THROWS_WITH_AS
  2019. #undef DOCTEST_REQUIRE_THROWS_WITH_AS
  2020. #undef DOCTEST_WARN_NOTHROW
  2021. #undef DOCTEST_CHECK_NOTHROW
  2022. #undef DOCTEST_REQUIRE_NOTHROW
  2023. #undef DOCTEST_WARN_THROWS_MESSAGE
  2024. #undef DOCTEST_CHECK_THROWS_MESSAGE
  2025. #undef DOCTEST_REQUIRE_THROWS_MESSAGE
  2026. #undef DOCTEST_WARN_THROWS_AS_MESSAGE
  2027. #undef DOCTEST_CHECK_THROWS_AS_MESSAGE
  2028. #undef DOCTEST_REQUIRE_THROWS_AS_MESSAGE
  2029. #undef DOCTEST_WARN_THROWS_WITH_MESSAGE
  2030. #undef DOCTEST_CHECK_THROWS_WITH_MESSAGE
  2031. #undef DOCTEST_REQUIRE_THROWS_WITH_MESSAGE
  2032. #undef DOCTEST_WARN_THROWS_WITH_AS_MESSAGE
  2033. #undef DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE
  2034. #undef DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE
  2035. #undef DOCTEST_WARN_NOTHROW_MESSAGE
  2036. #undef DOCTEST_CHECK_NOTHROW_MESSAGE
  2037. #undef DOCTEST_REQUIRE_NOTHROW_MESSAGE
  2038. #ifdef DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS
  2039. #define DOCTEST_WARN_THROWS(...) ([] { return false; })
  2040. #define DOCTEST_CHECK_THROWS(...) ([] { return false; })
  2041. #define DOCTEST_REQUIRE_THROWS(...) ([] { return false; })
  2042. #define DOCTEST_WARN_THROWS_AS(expr, ...) ([] { return false; })
  2043. #define DOCTEST_CHECK_THROWS_AS(expr, ...) ([] { return false; })
  2044. #define DOCTEST_REQUIRE_THROWS_AS(expr, ...) ([] { return false; })
  2045. #define DOCTEST_WARN_THROWS_WITH(expr, ...) ([] { return false; })
  2046. #define DOCTEST_CHECK_THROWS_WITH(expr, ...) ([] { return false; })
  2047. #define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) ([] { return false; })
  2048. #define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ...) ([] { return false; })
  2049. #define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ...) ([] { return false; })
  2050. #define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ...) ([] { return false; })
  2051. #define DOCTEST_WARN_NOTHROW(...) ([] { return false; })
  2052. #define DOCTEST_CHECK_NOTHROW(...) ([] { return false; })
  2053. #define DOCTEST_REQUIRE_NOTHROW(...) ([] { return false; })
  2054. #define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) ([] { return false; })
  2055. #define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) ([] { return false; })
  2056. #define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) ([] { return false; })
  2057. #define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) ([] { return false; })
  2058. #define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) ([] { return false; })
  2059. #define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) ([] { return false; })
  2060. #define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) ([] { return false; })
  2061. #define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) ([] { return false; })
  2062. #define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) ([] { return false; })
  2063. #define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) ([] { return false; })
  2064. #define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) ([] { return false; })
  2065. #define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) ([] { return false; })
  2066. #define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) ([] { return false; })
  2067. #define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) ([] { return false; })
  2068. #define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) ([] { return false; })
  2069. #else // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS
  2070. #undef DOCTEST_REQUIRE
  2071. #undef DOCTEST_REQUIRE_FALSE
  2072. #undef DOCTEST_REQUIRE_MESSAGE
  2073. #undef DOCTEST_REQUIRE_FALSE_MESSAGE
  2074. #undef DOCTEST_REQUIRE_EQ
  2075. #undef DOCTEST_REQUIRE_NE
  2076. #undef DOCTEST_REQUIRE_GT
  2077. #undef DOCTEST_REQUIRE_LT
  2078. #undef DOCTEST_REQUIRE_GE
  2079. #undef DOCTEST_REQUIRE_LE
  2080. #undef DOCTEST_REQUIRE_UNARY
  2081. #undef DOCTEST_REQUIRE_UNARY_FALSE
  2082. #endif // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS
  2083. #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
  2084. // =================================================================================================
  2085. // == WHAT FOLLOWS IS VERSIONS OF THE MACROS THAT DO NOT DO ANY REGISTERING! ==
  2086. // == THIS CAN BE ENABLED BY DEFINING DOCTEST_CONFIG_DISABLE GLOBALLY! ==
  2087. // =================================================================================================
  2088. #else // DOCTEST_CONFIG_DISABLE
  2089. #define DOCTEST_IMPLEMENT_FIXTURE(der, base, func, name) \
  2090. namespace { \
  2091. template <typename DOCTEST_UNUSED_TEMPLATE_TYPE> \
  2092. struct der : public base \
  2093. { void f(); }; \
  2094. } \
  2095. template <typename DOCTEST_UNUSED_TEMPLATE_TYPE> \
  2096. inline void der<DOCTEST_UNUSED_TEMPLATE_TYPE>::f()
  2097. #define DOCTEST_CREATE_AND_REGISTER_FUNCTION(f, name) \
  2098. template <typename DOCTEST_UNUSED_TEMPLATE_TYPE> \
  2099. static inline void f()
  2100. // for registering tests
  2101. #define DOCTEST_TEST_CASE(name) \
  2102. DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), name)
  2103. // for registering tests in classes
  2104. #define DOCTEST_TEST_CASE_CLASS(name) \
  2105. DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), name)
  2106. // for registering tests with a fixture
  2107. #define DOCTEST_TEST_CASE_FIXTURE(x, name) \
  2108. DOCTEST_IMPLEMENT_FIXTURE(DOCTEST_ANONYMOUS(DOCTEST_ANON_CLASS_), x, \
  2109. DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), name)
  2110. // for converting types to strings without the <typeinfo> header and demangling
  2111. #define DOCTEST_TYPE_TO_STRING(...) static_assert(true, "")
  2112. #define DOCTEST_TYPE_TO_STRING_IMPL(...)
  2113. // for typed tests
  2114. #define DOCTEST_TEST_CASE_TEMPLATE(name, type, ...) \
  2115. template <typename type> \
  2116. inline void DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_)()
  2117. #define DOCTEST_TEST_CASE_TEMPLATE_DEFINE(name, type, id) \
  2118. template <typename type> \
  2119. inline void DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_)()
  2120. #define DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, ...) static_assert(true, "")
  2121. #define DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, ...) static_assert(true, "")
  2122. // for subcases
  2123. #define DOCTEST_SUBCASE(name)
  2124. // for a testsuite block
  2125. #define DOCTEST_TEST_SUITE(name) namespace
  2126. // for starting a testsuite block
  2127. #define DOCTEST_TEST_SUITE_BEGIN(name) static_assert(true, "")
  2128. // for ending a testsuite block
  2129. #define DOCTEST_TEST_SUITE_END typedef int DOCTEST_ANONYMOUS(DOCTEST_ANON_FOR_SEMICOLON_)
  2130. #define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature) \
  2131. template <typename DOCTEST_UNUSED_TEMPLATE_TYPE> \
  2132. static inline doctest::String DOCTEST_ANONYMOUS(DOCTEST_ANON_TRANSLATOR_)(signature)
  2133. #define DOCTEST_REGISTER_REPORTER(name, priority, reporter)
  2134. #define DOCTEST_REGISTER_LISTENER(name, priority, reporter)
  2135. #define DOCTEST_INFO(...) (static_cast<void>(0))
  2136. #define DOCTEST_CAPTURE(x) (static_cast<void>(0))
  2137. #define DOCTEST_ADD_MESSAGE_AT(file, line, ...) (static_cast<void>(0))
  2138. #define DOCTEST_ADD_FAIL_CHECK_AT(file, line, ...) (static_cast<void>(0))
  2139. #define DOCTEST_ADD_FAIL_AT(file, line, ...) (static_cast<void>(0))
  2140. #define DOCTEST_MESSAGE(...) (static_cast<void>(0))
  2141. #define DOCTEST_FAIL_CHECK(...) (static_cast<void>(0))
  2142. #define DOCTEST_FAIL(...) (static_cast<void>(0))
  2143. #ifdef DOCTEST_CONFIG_EVALUATE_ASSERTS_EVEN_WHEN_DISABLED
  2144. #define DOCTEST_WARN(...) [&] { return __VA_ARGS__; }()
  2145. #define DOCTEST_CHECK(...) [&] { return __VA_ARGS__; }()
  2146. #define DOCTEST_REQUIRE(...) [&] { return __VA_ARGS__; }()
  2147. #define DOCTEST_WARN_FALSE(...) [&] { return !(__VA_ARGS__); }()
  2148. #define DOCTEST_CHECK_FALSE(...) [&] { return !(__VA_ARGS__); }()
  2149. #define DOCTEST_REQUIRE_FALSE(...) [&] { return !(__VA_ARGS__); }()
  2150. #define DOCTEST_WARN_MESSAGE(cond, ...) [&] { return cond; }()
  2151. #define DOCTEST_CHECK_MESSAGE(cond, ...) [&] { return cond; }()
  2152. #define DOCTEST_REQUIRE_MESSAGE(cond, ...) [&] { return cond; }()
  2153. #define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) [&] { return !(cond); }()
  2154. #define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) [&] { return !(cond); }()
  2155. #define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) [&] { return !(cond); }()
  2156. namespace doctest {
  2157. namespace detail {
  2158. #define DOCTEST_RELATIONAL_OP(name, op) \
  2159. template <typename L, typename R> \
  2160. bool name(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) { return lhs op rhs; }
  2161. DOCTEST_RELATIONAL_OP(eq, ==)
  2162. DOCTEST_RELATIONAL_OP(ne, !=)
  2163. DOCTEST_RELATIONAL_OP(lt, <)
  2164. DOCTEST_RELATIONAL_OP(gt, >)
  2165. DOCTEST_RELATIONAL_OP(le, <=)
  2166. DOCTEST_RELATIONAL_OP(ge, >=)
  2167. } // namespace detail
  2168. } // namespace doctest
  2169. #define DOCTEST_WARN_EQ(...) [&] { return doctest::detail::eq(__VA_ARGS__); }()
  2170. #define DOCTEST_CHECK_EQ(...) [&] { return doctest::detail::eq(__VA_ARGS__); }()
  2171. #define DOCTEST_REQUIRE_EQ(...) [&] { return doctest::detail::eq(__VA_ARGS__); }()
  2172. #define DOCTEST_WARN_NE(...) [&] { return doctest::detail::ne(__VA_ARGS__); }()
  2173. #define DOCTEST_CHECK_NE(...) [&] { return doctest::detail::ne(__VA_ARGS__); }()
  2174. #define DOCTEST_REQUIRE_NE(...) [&] { return doctest::detail::ne(__VA_ARGS__); }()
  2175. #define DOCTEST_WARN_LT(...) [&] { return doctest::detail::lt(__VA_ARGS__); }()
  2176. #define DOCTEST_CHECK_LT(...) [&] { return doctest::detail::lt(__VA_ARGS__); }()
  2177. #define DOCTEST_REQUIRE_LT(...) [&] { return doctest::detail::lt(__VA_ARGS__); }()
  2178. #define DOCTEST_WARN_GT(...) [&] { return doctest::detail::gt(__VA_ARGS__); }()
  2179. #define DOCTEST_CHECK_GT(...) [&] { return doctest::detail::gt(__VA_ARGS__); }()
  2180. #define DOCTEST_REQUIRE_GT(...) [&] { return doctest::detail::gt(__VA_ARGS__); }()
  2181. #define DOCTEST_WARN_LE(...) [&] { return doctest::detail::le(__VA_ARGS__); }()
  2182. #define DOCTEST_CHECK_LE(...) [&] { return doctest::detail::le(__VA_ARGS__); }()
  2183. #define DOCTEST_REQUIRE_LE(...) [&] { return doctest::detail::le(__VA_ARGS__); }()
  2184. #define DOCTEST_WARN_GE(...) [&] { return doctest::detail::ge(__VA_ARGS__); }()
  2185. #define DOCTEST_CHECK_GE(...) [&] { return doctest::detail::ge(__VA_ARGS__); }()
  2186. #define DOCTEST_REQUIRE_GE(...) [&] { return doctest::detail::ge(__VA_ARGS__); }()
  2187. #define DOCTEST_WARN_UNARY(...) [&] { return __VA_ARGS__; }()
  2188. #define DOCTEST_CHECK_UNARY(...) [&] { return __VA_ARGS__; }()
  2189. #define DOCTEST_REQUIRE_UNARY(...) [&] { return __VA_ARGS__; }()
  2190. #define DOCTEST_WARN_UNARY_FALSE(...) [&] { return !(__VA_ARGS__); }()
  2191. #define DOCTEST_CHECK_UNARY_FALSE(...) [&] { return !(__VA_ARGS__); }()
  2192. #define DOCTEST_REQUIRE_UNARY_FALSE(...) [&] { return !(__VA_ARGS__); }()
  2193. #else // DOCTEST_CONFIG_EVALUATE_ASSERTS_EVEN_WHEN_DISABLED
  2194. #define DOCTEST_WARN(...) ([] { return false; })
  2195. #define DOCTEST_CHECK(...) ([] { return false; })
  2196. #define DOCTEST_REQUIRE(...) ([] { return false; })
  2197. #define DOCTEST_WARN_FALSE(...) ([] { return false; })
  2198. #define DOCTEST_CHECK_FALSE(...) ([] { return false; })
  2199. #define DOCTEST_REQUIRE_FALSE(...) ([] { return false; })
  2200. #define DOCTEST_WARN_MESSAGE(cond, ...) ([] { return false; })
  2201. #define DOCTEST_CHECK_MESSAGE(cond, ...) ([] { return false; })
  2202. #define DOCTEST_REQUIRE_MESSAGE(cond, ...) ([] { return false; })
  2203. #define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) ([] { return false; })
  2204. #define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) ([] { return false; })
  2205. #define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) ([] { return false; })
  2206. #define DOCTEST_WARN_EQ(...) ([] { return false; })
  2207. #define DOCTEST_CHECK_EQ(...) ([] { return false; })
  2208. #define DOCTEST_REQUIRE_EQ(...) ([] { return false; })
  2209. #define DOCTEST_WARN_NE(...) ([] { return false; })
  2210. #define DOCTEST_CHECK_NE(...) ([] { return false; })
  2211. #define DOCTEST_REQUIRE_NE(...) ([] { return false; })
  2212. #define DOCTEST_WARN_GT(...) ([] { return false; })
  2213. #define DOCTEST_CHECK_GT(...) ([] { return false; })
  2214. #define DOCTEST_REQUIRE_GT(...) ([] { return false; })
  2215. #define DOCTEST_WARN_LT(...) ([] { return false; })
  2216. #define DOCTEST_CHECK_LT(...) ([] { return false; })
  2217. #define DOCTEST_REQUIRE_LT(...) ([] { return false; })
  2218. #define DOCTEST_WARN_GE(...) ([] { return false; })
  2219. #define DOCTEST_CHECK_GE(...) ([] { return false; })
  2220. #define DOCTEST_REQUIRE_GE(...) ([] { return false; })
  2221. #define DOCTEST_WARN_LE(...) ([] { return false; })
  2222. #define DOCTEST_CHECK_LE(...) ([] { return false; })
  2223. #define DOCTEST_REQUIRE_LE(...) ([] { return false; })
  2224. #define DOCTEST_WARN_UNARY(...) ([] { return false; })
  2225. #define DOCTEST_CHECK_UNARY(...) ([] { return false; })
  2226. #define DOCTEST_REQUIRE_UNARY(...) ([] { return false; })
  2227. #define DOCTEST_WARN_UNARY_FALSE(...) ([] { return false; })
  2228. #define DOCTEST_CHECK_UNARY_FALSE(...) ([] { return false; })
  2229. #define DOCTEST_REQUIRE_UNARY_FALSE(...) ([] { return false; })
  2230. #endif // DOCTEST_CONFIG_EVALUATE_ASSERTS_EVEN_WHEN_DISABLED
  2231. // TODO: think about if these also need to work properly even when doctest is disabled
  2232. #define DOCTEST_WARN_THROWS(...) ([] { return false; })
  2233. #define DOCTEST_CHECK_THROWS(...) ([] { return false; })
  2234. #define DOCTEST_REQUIRE_THROWS(...) ([] { return false; })
  2235. #define DOCTEST_WARN_THROWS_AS(expr, ...) ([] { return false; })
  2236. #define DOCTEST_CHECK_THROWS_AS(expr, ...) ([] { return false; })
  2237. #define DOCTEST_REQUIRE_THROWS_AS(expr, ...) ([] { return false; })
  2238. #define DOCTEST_WARN_THROWS_WITH(expr, ...) ([] { return false; })
  2239. #define DOCTEST_CHECK_THROWS_WITH(expr, ...) ([] { return false; })
  2240. #define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) ([] { return false; })
  2241. #define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ...) ([] { return false; })
  2242. #define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ...) ([] { return false; })
  2243. #define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ...) ([] { return false; })
  2244. #define DOCTEST_WARN_NOTHROW(...) ([] { return false; })
  2245. #define DOCTEST_CHECK_NOTHROW(...) ([] { return false; })
  2246. #define DOCTEST_REQUIRE_NOTHROW(...) ([] { return false; })
  2247. #define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) ([] { return false; })
  2248. #define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) ([] { return false; })
  2249. #define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) ([] { return false; })
  2250. #define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) ([] { return false; })
  2251. #define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) ([] { return false; })
  2252. #define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) ([] { return false; })
  2253. #define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) ([] { return false; })
  2254. #define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) ([] { return false; })
  2255. #define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) ([] { return false; })
  2256. #define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) ([] { return false; })
  2257. #define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) ([] { return false; })
  2258. #define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) ([] { return false; })
  2259. #define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) ([] { return false; })
  2260. #define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) ([] { return false; })
  2261. #define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) ([] { return false; })
  2262. #endif // DOCTEST_CONFIG_DISABLE
  2263. // clang-format off
  2264. // KEPT FOR BACKWARDS COMPATIBILITY - FORWARDING TO THE RIGHT MACROS
  2265. #define DOCTEST_FAST_WARN_EQ DOCTEST_WARN_EQ
  2266. #define DOCTEST_FAST_CHECK_EQ DOCTEST_CHECK_EQ
  2267. #define DOCTEST_FAST_REQUIRE_EQ DOCTEST_REQUIRE_EQ
  2268. #define DOCTEST_FAST_WARN_NE DOCTEST_WARN_NE
  2269. #define DOCTEST_FAST_CHECK_NE DOCTEST_CHECK_NE
  2270. #define DOCTEST_FAST_REQUIRE_NE DOCTEST_REQUIRE_NE
  2271. #define DOCTEST_FAST_WARN_GT DOCTEST_WARN_GT
  2272. #define DOCTEST_FAST_CHECK_GT DOCTEST_CHECK_GT
  2273. #define DOCTEST_FAST_REQUIRE_GT DOCTEST_REQUIRE_GT
  2274. #define DOCTEST_FAST_WARN_LT DOCTEST_WARN_LT
  2275. #define DOCTEST_FAST_CHECK_LT DOCTEST_CHECK_LT
  2276. #define DOCTEST_FAST_REQUIRE_LT DOCTEST_REQUIRE_LT
  2277. #define DOCTEST_FAST_WARN_GE DOCTEST_WARN_GE
  2278. #define DOCTEST_FAST_CHECK_GE DOCTEST_CHECK_GE
  2279. #define DOCTEST_FAST_REQUIRE_GE DOCTEST_REQUIRE_GE
  2280. #define DOCTEST_FAST_WARN_LE DOCTEST_WARN_LE
  2281. #define DOCTEST_FAST_CHECK_LE DOCTEST_CHECK_LE
  2282. #define DOCTEST_FAST_REQUIRE_LE DOCTEST_REQUIRE_LE
  2283. #define DOCTEST_FAST_WARN_UNARY DOCTEST_WARN_UNARY
  2284. #define DOCTEST_FAST_CHECK_UNARY DOCTEST_CHECK_UNARY
  2285. #define DOCTEST_FAST_REQUIRE_UNARY DOCTEST_REQUIRE_UNARY
  2286. #define DOCTEST_FAST_WARN_UNARY_FALSE DOCTEST_WARN_UNARY_FALSE
  2287. #define DOCTEST_FAST_CHECK_UNARY_FALSE DOCTEST_CHECK_UNARY_FALSE
  2288. #define DOCTEST_FAST_REQUIRE_UNARY_FALSE DOCTEST_REQUIRE_UNARY_FALSE
  2289. #define DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id,__VA_ARGS__)
  2290. // clang-format on
  2291. // BDD style macros
  2292. // clang-format off
  2293. #define DOCTEST_SCENARIO(name) DOCTEST_TEST_CASE(" Scenario: " name)
  2294. #define DOCTEST_SCENARIO_CLASS(name) DOCTEST_TEST_CASE_CLASS(" Scenario: " name)
  2295. #define DOCTEST_SCENARIO_TEMPLATE(name, T, ...) DOCTEST_TEST_CASE_TEMPLATE(" Scenario: " name, T, __VA_ARGS__)
  2296. #define DOCTEST_SCENARIO_TEMPLATE_DEFINE(name, T, id) DOCTEST_TEST_CASE_TEMPLATE_DEFINE(" Scenario: " name, T, id)
  2297. #define DOCTEST_GIVEN(name) DOCTEST_SUBCASE(" Given: " name)
  2298. #define DOCTEST_WHEN(name) DOCTEST_SUBCASE(" When: " name)
  2299. #define DOCTEST_AND_WHEN(name) DOCTEST_SUBCASE("And when: " name)
  2300. #define DOCTEST_THEN(name) DOCTEST_SUBCASE(" Then: " name)
  2301. #define DOCTEST_AND_THEN(name) DOCTEST_SUBCASE(" And: " name)
  2302. // clang-format on
  2303. // == SHORT VERSIONS OF THE MACROS
  2304. #if !defined(DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES)
  2305. #define TEST_CASE(name) DOCTEST_TEST_CASE(name)
  2306. #define TEST_CASE_CLASS(name) DOCTEST_TEST_CASE_CLASS(name)
  2307. #define TEST_CASE_FIXTURE(x, name) DOCTEST_TEST_CASE_FIXTURE(x, name)
  2308. #define TYPE_TO_STRING(...) DOCTEST_TYPE_TO_STRING(__VA_ARGS__)
  2309. #define TEST_CASE_TEMPLATE(name, T, ...) DOCTEST_TEST_CASE_TEMPLATE(name, T, __VA_ARGS__)
  2310. #define TEST_CASE_TEMPLATE_DEFINE(name, T, id) DOCTEST_TEST_CASE_TEMPLATE_DEFINE(name, T, id)
  2311. #define TEST_CASE_TEMPLATE_INVOKE(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, __VA_ARGS__)
  2312. #define TEST_CASE_TEMPLATE_APPLY(id, ...) DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, __VA_ARGS__)
  2313. #define SUBCASE(name) DOCTEST_SUBCASE(name)
  2314. #define TEST_SUITE(decorators) DOCTEST_TEST_SUITE(decorators)
  2315. #define TEST_SUITE_BEGIN(name) DOCTEST_TEST_SUITE_BEGIN(name)
  2316. #define TEST_SUITE_END DOCTEST_TEST_SUITE_END
  2317. #define REGISTER_EXCEPTION_TRANSLATOR(signature) DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature)
  2318. #define REGISTER_REPORTER(name, priority, reporter) DOCTEST_REGISTER_REPORTER(name, priority, reporter)
  2319. #define REGISTER_LISTENER(name, priority, reporter) DOCTEST_REGISTER_LISTENER(name, priority, reporter)
  2320. #define INFO(...) DOCTEST_INFO(__VA_ARGS__)
  2321. #define CAPTURE(x) DOCTEST_CAPTURE(x)
  2322. #define ADD_MESSAGE_AT(file, line, ...) DOCTEST_ADD_MESSAGE_AT(file, line, __VA_ARGS__)
  2323. #define ADD_FAIL_CHECK_AT(file, line, ...) DOCTEST_ADD_FAIL_CHECK_AT(file, line, __VA_ARGS__)
  2324. #define ADD_FAIL_AT(file, line, ...) DOCTEST_ADD_FAIL_AT(file, line, __VA_ARGS__)
  2325. #define MESSAGE(...) DOCTEST_MESSAGE(__VA_ARGS__)
  2326. #define FAIL_CHECK(...) DOCTEST_FAIL_CHECK(__VA_ARGS__)
  2327. #define FAIL(...) DOCTEST_FAIL(__VA_ARGS__)
  2328. #define TO_LVALUE(...) DOCTEST_TO_LVALUE(__VA_ARGS__)
  2329. #define WARN(...) DOCTEST_WARN(__VA_ARGS__)
  2330. #define WARN_FALSE(...) DOCTEST_WARN_FALSE(__VA_ARGS__)
  2331. #define WARN_THROWS(...) DOCTEST_WARN_THROWS(__VA_ARGS__)
  2332. #define WARN_THROWS_AS(expr, ...) DOCTEST_WARN_THROWS_AS(expr, __VA_ARGS__)
  2333. #define WARN_THROWS_WITH(expr, ...) DOCTEST_WARN_THROWS_WITH(expr, __VA_ARGS__)
  2334. #define WARN_THROWS_WITH_AS(expr, with, ...) DOCTEST_WARN_THROWS_WITH_AS(expr, with, __VA_ARGS__)
  2335. #define WARN_NOTHROW(...) DOCTEST_WARN_NOTHROW(__VA_ARGS__)
  2336. #define CHECK(...) DOCTEST_CHECK(__VA_ARGS__)
  2337. #define CHECK_FALSE(...) DOCTEST_CHECK_FALSE(__VA_ARGS__)
  2338. #define CHECK_THROWS(...) DOCTEST_CHECK_THROWS(__VA_ARGS__)
  2339. #define CHECK_THROWS_AS(expr, ...) DOCTEST_CHECK_THROWS_AS(expr, __VA_ARGS__)
  2340. #define CHECK_THROWS_WITH(expr, ...) DOCTEST_CHECK_THROWS_WITH(expr, __VA_ARGS__)
  2341. #define CHECK_THROWS_WITH_AS(expr, with, ...) DOCTEST_CHECK_THROWS_WITH_AS(expr, with, __VA_ARGS__)
  2342. #define CHECK_NOTHROW(...) DOCTEST_CHECK_NOTHROW(__VA_ARGS__)
  2343. #define REQUIRE(...) DOCTEST_REQUIRE(__VA_ARGS__)
  2344. #define REQUIRE_FALSE(...) DOCTEST_REQUIRE_FALSE(__VA_ARGS__)
  2345. #define REQUIRE_THROWS(...) DOCTEST_REQUIRE_THROWS(__VA_ARGS__)
  2346. #define REQUIRE_THROWS_AS(expr, ...) DOCTEST_REQUIRE_THROWS_AS(expr, __VA_ARGS__)
  2347. #define REQUIRE_THROWS_WITH(expr, ...) DOCTEST_REQUIRE_THROWS_WITH(expr, __VA_ARGS__)
  2348. #define REQUIRE_THROWS_WITH_AS(expr, with, ...) DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, __VA_ARGS__)
  2349. #define REQUIRE_NOTHROW(...) DOCTEST_REQUIRE_NOTHROW(__VA_ARGS__)
  2350. #define WARN_MESSAGE(cond, ...) DOCTEST_WARN_MESSAGE(cond, __VA_ARGS__)
  2351. #define WARN_FALSE_MESSAGE(cond, ...) DOCTEST_WARN_FALSE_MESSAGE(cond, __VA_ARGS__)
  2352. #define WARN_THROWS_MESSAGE(expr, ...) DOCTEST_WARN_THROWS_MESSAGE(expr, __VA_ARGS__)
  2353. #define WARN_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__)
  2354. #define WARN_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__)
  2355. #define WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__)
  2356. #define WARN_NOTHROW_MESSAGE(expr, ...) DOCTEST_WARN_NOTHROW_MESSAGE(expr, __VA_ARGS__)
  2357. #define CHECK_MESSAGE(cond, ...) DOCTEST_CHECK_MESSAGE(cond, __VA_ARGS__)
  2358. #define CHECK_FALSE_MESSAGE(cond, ...) DOCTEST_CHECK_FALSE_MESSAGE(cond, __VA_ARGS__)
  2359. #define CHECK_THROWS_MESSAGE(expr, ...) DOCTEST_CHECK_THROWS_MESSAGE(expr, __VA_ARGS__)
  2360. #define CHECK_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__)
  2361. #define CHECK_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__)
  2362. #define CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__)
  2363. #define CHECK_NOTHROW_MESSAGE(expr, ...) DOCTEST_CHECK_NOTHROW_MESSAGE(expr, __VA_ARGS__)
  2364. #define REQUIRE_MESSAGE(cond, ...) DOCTEST_REQUIRE_MESSAGE(cond, __VA_ARGS__)
  2365. #define REQUIRE_FALSE_MESSAGE(cond, ...) DOCTEST_REQUIRE_FALSE_MESSAGE(cond, __VA_ARGS__)
  2366. #define REQUIRE_THROWS_MESSAGE(expr, ...) DOCTEST_REQUIRE_THROWS_MESSAGE(expr, __VA_ARGS__)
  2367. #define REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__)
  2368. #define REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__)
  2369. #define REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__)
  2370. #define REQUIRE_NOTHROW_MESSAGE(expr, ...) DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, __VA_ARGS__)
  2371. #define SCENARIO(name) DOCTEST_SCENARIO(name)
  2372. #define SCENARIO_CLASS(name) DOCTEST_SCENARIO_CLASS(name)
  2373. #define SCENARIO_TEMPLATE(name, T, ...) DOCTEST_SCENARIO_TEMPLATE(name, T, __VA_ARGS__)
  2374. #define SCENARIO_TEMPLATE_DEFINE(name, T, id) DOCTEST_SCENARIO_TEMPLATE_DEFINE(name, T, id)
  2375. #define GIVEN(name) DOCTEST_GIVEN(name)
  2376. #define WHEN(name) DOCTEST_WHEN(name)
  2377. #define AND_WHEN(name) DOCTEST_AND_WHEN(name)
  2378. #define THEN(name) DOCTEST_THEN(name)
  2379. #define AND_THEN(name) DOCTEST_AND_THEN(name)
  2380. #define WARN_EQ(...) DOCTEST_WARN_EQ(__VA_ARGS__)
  2381. #define CHECK_EQ(...) DOCTEST_CHECK_EQ(__VA_ARGS__)
  2382. #define REQUIRE_EQ(...) DOCTEST_REQUIRE_EQ(__VA_ARGS__)
  2383. #define WARN_NE(...) DOCTEST_WARN_NE(__VA_ARGS__)
  2384. #define CHECK_NE(...) DOCTEST_CHECK_NE(__VA_ARGS__)
  2385. #define REQUIRE_NE(...) DOCTEST_REQUIRE_NE(__VA_ARGS__)
  2386. #define WARN_GT(...) DOCTEST_WARN_GT(__VA_ARGS__)
  2387. #define CHECK_GT(...) DOCTEST_CHECK_GT(__VA_ARGS__)
  2388. #define REQUIRE_GT(...) DOCTEST_REQUIRE_GT(__VA_ARGS__)
  2389. #define WARN_LT(...) DOCTEST_WARN_LT(__VA_ARGS__)
  2390. #define CHECK_LT(...) DOCTEST_CHECK_LT(__VA_ARGS__)
  2391. #define REQUIRE_LT(...) DOCTEST_REQUIRE_LT(__VA_ARGS__)
  2392. #define WARN_GE(...) DOCTEST_WARN_GE(__VA_ARGS__)
  2393. #define CHECK_GE(...) DOCTEST_CHECK_GE(__VA_ARGS__)
  2394. #define REQUIRE_GE(...) DOCTEST_REQUIRE_GE(__VA_ARGS__)
  2395. #define WARN_LE(...) DOCTEST_WARN_LE(__VA_ARGS__)
  2396. #define CHECK_LE(...) DOCTEST_CHECK_LE(__VA_ARGS__)
  2397. #define REQUIRE_LE(...) DOCTEST_REQUIRE_LE(__VA_ARGS__)
  2398. #define WARN_UNARY(...) DOCTEST_WARN_UNARY(__VA_ARGS__)
  2399. #define CHECK_UNARY(...) DOCTEST_CHECK_UNARY(__VA_ARGS__)
  2400. #define REQUIRE_UNARY(...) DOCTEST_REQUIRE_UNARY(__VA_ARGS__)
  2401. #define WARN_UNARY_FALSE(...) DOCTEST_WARN_UNARY_FALSE(__VA_ARGS__)
  2402. #define CHECK_UNARY_FALSE(...) DOCTEST_CHECK_UNARY_FALSE(__VA_ARGS__)
  2403. #define REQUIRE_UNARY_FALSE(...) DOCTEST_REQUIRE_UNARY_FALSE(__VA_ARGS__)
  2404. // KEPT FOR BACKWARDS COMPATIBILITY
  2405. #define FAST_WARN_EQ(...) DOCTEST_FAST_WARN_EQ(__VA_ARGS__)
  2406. #define FAST_CHECK_EQ(...) DOCTEST_FAST_CHECK_EQ(__VA_ARGS__)
  2407. #define FAST_REQUIRE_EQ(...) DOCTEST_FAST_REQUIRE_EQ(__VA_ARGS__)
  2408. #define FAST_WARN_NE(...) DOCTEST_FAST_WARN_NE(__VA_ARGS__)
  2409. #define FAST_CHECK_NE(...) DOCTEST_FAST_CHECK_NE(__VA_ARGS__)
  2410. #define FAST_REQUIRE_NE(...) DOCTEST_FAST_REQUIRE_NE(__VA_ARGS__)
  2411. #define FAST_WARN_GT(...) DOCTEST_FAST_WARN_GT(__VA_ARGS__)
  2412. #define FAST_CHECK_GT(...) DOCTEST_FAST_CHECK_GT(__VA_ARGS__)
  2413. #define FAST_REQUIRE_GT(...) DOCTEST_FAST_REQUIRE_GT(__VA_ARGS__)
  2414. #define FAST_WARN_LT(...) DOCTEST_FAST_WARN_LT(__VA_ARGS__)
  2415. #define FAST_CHECK_LT(...) DOCTEST_FAST_CHECK_LT(__VA_ARGS__)
  2416. #define FAST_REQUIRE_LT(...) DOCTEST_FAST_REQUIRE_LT(__VA_ARGS__)
  2417. #define FAST_WARN_GE(...) DOCTEST_FAST_WARN_GE(__VA_ARGS__)
  2418. #define FAST_CHECK_GE(...) DOCTEST_FAST_CHECK_GE(__VA_ARGS__)
  2419. #define FAST_REQUIRE_GE(...) DOCTEST_FAST_REQUIRE_GE(__VA_ARGS__)
  2420. #define FAST_WARN_LE(...) DOCTEST_FAST_WARN_LE(__VA_ARGS__)
  2421. #define FAST_CHECK_LE(...) DOCTEST_FAST_CHECK_LE(__VA_ARGS__)
  2422. #define FAST_REQUIRE_LE(...) DOCTEST_FAST_REQUIRE_LE(__VA_ARGS__)
  2423. #define FAST_WARN_UNARY(...) DOCTEST_FAST_WARN_UNARY(__VA_ARGS__)
  2424. #define FAST_CHECK_UNARY(...) DOCTEST_FAST_CHECK_UNARY(__VA_ARGS__)
  2425. #define FAST_REQUIRE_UNARY(...) DOCTEST_FAST_REQUIRE_UNARY(__VA_ARGS__)
  2426. #define FAST_WARN_UNARY_FALSE(...) DOCTEST_FAST_WARN_UNARY_FALSE(__VA_ARGS__)
  2427. #define FAST_CHECK_UNARY_FALSE(...) DOCTEST_FAST_CHECK_UNARY_FALSE(__VA_ARGS__)
  2428. #define FAST_REQUIRE_UNARY_FALSE(...) DOCTEST_FAST_REQUIRE_UNARY_FALSE(__VA_ARGS__)
  2429. #define TEST_CASE_TEMPLATE_INSTANTIATE(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE(id, __VA_ARGS__)
  2430. #endif // DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES
  2431. #if !defined(DOCTEST_CONFIG_DISABLE)
  2432. // this is here to clear the 'current test suite' for the current translation unit - at the top
  2433. DOCTEST_TEST_SUITE_END();
  2434. // add stringification for primitive/fundamental types
  2435. namespace doctest { namespace detail {
  2436. DOCTEST_TYPE_TO_STRING_IMPL(bool)
  2437. DOCTEST_TYPE_TO_STRING_IMPL(float)
  2438. DOCTEST_TYPE_TO_STRING_IMPL(double)
  2439. DOCTEST_TYPE_TO_STRING_IMPL(long double)
  2440. DOCTEST_TYPE_TO_STRING_IMPL(char)
  2441. DOCTEST_TYPE_TO_STRING_IMPL(signed char)
  2442. DOCTEST_TYPE_TO_STRING_IMPL(unsigned char)
  2443. #if !DOCTEST_MSVC || defined(_NATIVE_WCHAR_T_DEFINED)
  2444. DOCTEST_TYPE_TO_STRING_IMPL(wchar_t)
  2445. #endif // not MSVC or wchar_t support enabled
  2446. DOCTEST_TYPE_TO_STRING_IMPL(short int)
  2447. DOCTEST_TYPE_TO_STRING_IMPL(unsigned short int)
  2448. DOCTEST_TYPE_TO_STRING_IMPL(int)
  2449. DOCTEST_TYPE_TO_STRING_IMPL(unsigned int)
  2450. DOCTEST_TYPE_TO_STRING_IMPL(long int)
  2451. DOCTEST_TYPE_TO_STRING_IMPL(unsigned long int)
  2452. DOCTEST_TYPE_TO_STRING_IMPL(long long int)
  2453. DOCTEST_TYPE_TO_STRING_IMPL(unsigned long long int)
  2454. }} // namespace doctest::detail
  2455. #endif // DOCTEST_CONFIG_DISABLE
  2456. DOCTEST_CLANG_SUPPRESS_WARNING_POP
  2457. DOCTEST_MSVC_SUPPRESS_WARNING_POP
  2458. DOCTEST_GCC_SUPPRESS_WARNING_POP
  2459. DOCTEST_SUPPRESS_COMMON_WARNINGS_POP
  2460. #endif // DOCTEST_LIBRARY_INCLUDED
  2461. #ifndef DOCTEST_SINGLE_HEADER
  2462. #define DOCTEST_SINGLE_HEADER
  2463. #endif // DOCTEST_SINGLE_HEADER
  2464. #if defined(DOCTEST_CONFIG_IMPLEMENT) || !defined(DOCTEST_SINGLE_HEADER)
  2465. #ifndef DOCTEST_SINGLE_HEADER
  2466. #include "doctest_fwd.h"
  2467. #endif // DOCTEST_SINGLE_HEADER
  2468. DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wunused-macros")
  2469. #ifndef DOCTEST_LIBRARY_IMPLEMENTATION
  2470. #define DOCTEST_LIBRARY_IMPLEMENTATION
  2471. DOCTEST_CLANG_SUPPRESS_WARNING_POP
  2472. DOCTEST_SUPPRESS_COMMON_WARNINGS_PUSH
  2473. DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
  2474. DOCTEST_CLANG_SUPPRESS_WARNING("-Wglobal-constructors")
  2475. DOCTEST_CLANG_SUPPRESS_WARNING("-Wexit-time-destructors")
  2476. DOCTEST_CLANG_SUPPRESS_WARNING("-Wsign-conversion")
  2477. DOCTEST_CLANG_SUPPRESS_WARNING("-Wshorten-64-to-32")
  2478. DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-variable-declarations")
  2479. DOCTEST_CLANG_SUPPRESS_WARNING("-Wswitch")
  2480. DOCTEST_CLANG_SUPPRESS_WARNING("-Wswitch-enum")
  2481. DOCTEST_CLANG_SUPPRESS_WARNING("-Wcovered-switch-default")
  2482. DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-noreturn")
  2483. DOCTEST_CLANG_SUPPRESS_WARNING("-Wdisabled-macro-expansion")
  2484. DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-braces")
  2485. DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-field-initializers")
  2486. DOCTEST_CLANG_SUPPRESS_WARNING("-Wunused-member-function")
  2487. DOCTEST_CLANG_SUPPRESS_WARNING("-Wnonportable-system-include-path")
  2488. DOCTEST_GCC_SUPPRESS_WARNING_PUSH
  2489. DOCTEST_GCC_SUPPRESS_WARNING("-Wconversion")
  2490. DOCTEST_GCC_SUPPRESS_WARNING("-Wsign-conversion")
  2491. DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-field-initializers")
  2492. DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-braces")
  2493. DOCTEST_GCC_SUPPRESS_WARNING("-Wswitch")
  2494. DOCTEST_GCC_SUPPRESS_WARNING("-Wswitch-enum")
  2495. DOCTEST_GCC_SUPPRESS_WARNING("-Wswitch-default")
  2496. DOCTEST_GCC_SUPPRESS_WARNING("-Wunsafe-loop-optimizations")
  2497. DOCTEST_GCC_SUPPRESS_WARNING("-Wold-style-cast")
  2498. DOCTEST_GCC_SUPPRESS_WARNING("-Wunused-function")
  2499. DOCTEST_GCC_SUPPRESS_WARNING("-Wmultiple-inheritance")
  2500. DOCTEST_GCC_SUPPRESS_WARNING("-Wsuggest-attribute")
  2501. DOCTEST_MSVC_SUPPRESS_WARNING_PUSH
  2502. DOCTEST_MSVC_SUPPRESS_WARNING(4267) // 'var' : conversion from 'x' to 'y', possible loss of data
  2503. DOCTEST_MSVC_SUPPRESS_WARNING(4530) // C++ exception handler used, but unwind semantics not enabled
  2504. DOCTEST_MSVC_SUPPRESS_WARNING(4577) // 'noexcept' used with no exception handling mode specified
  2505. DOCTEST_MSVC_SUPPRESS_WARNING(4774) // format string expected in argument is not a string literal
  2506. DOCTEST_MSVC_SUPPRESS_WARNING(4365) // conversion from 'int' to 'unsigned', signed/unsigned mismatch
  2507. DOCTEST_MSVC_SUPPRESS_WARNING(5039) // pointer to potentially throwing function passed to extern C
  2508. DOCTEST_MSVC_SUPPRESS_WARNING(4800) // forcing value to bool 'true' or 'false' (performance warning)
  2509. DOCTEST_MSVC_SUPPRESS_WARNING(5245) // unreferenced function with internal linkage has been removed
  2510. DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN
  2511. // required includes - will go only in one translation unit!
  2512. #include <ctime>
  2513. #include <cmath>
  2514. #include <climits>
  2515. // borland (Embarcadero) compiler requires math.h and not cmath - https://github.com/doctest/doctest/pull/37
  2516. #ifdef __BORLANDC__
  2517. #include <math.h>
  2518. #endif // __BORLANDC__
  2519. #include <new>
  2520. #include <cstdio>
  2521. #include <cstdlib>
  2522. #include <cstring>
  2523. #include <limits>
  2524. #include <utility>
  2525. #include <fstream>
  2526. #include <sstream>
  2527. #include <iostream>
  2528. #include <algorithm>
  2529. #include <iomanip>
  2530. #include <vector>
  2531. #include <atomic>
  2532. #include <mutex>
  2533. #include <set>
  2534. #include <map>
  2535. #include <exception>
  2536. #include <stdexcept>
  2537. #include <csignal>
  2538. #include <cfloat>
  2539. #include <cctype>
  2540. #include <cstdint>
  2541. #ifdef DOCTEST_PLATFORM_MAC
  2542. #include <sys/types.h>
  2543. #include <unistd.h>
  2544. #include <sys/sysctl.h>
  2545. #endif // DOCTEST_PLATFORM_MAC
  2546. #ifdef DOCTEST_PLATFORM_WINDOWS
  2547. // defines for a leaner windows.h
  2548. #ifndef WIN32_LEAN_AND_MEAN
  2549. #define WIN32_LEAN_AND_MEAN
  2550. #endif // WIN32_LEAN_AND_MEAN
  2551. #ifndef NOMINMAX
  2552. #define NOMINMAX
  2553. #endif // NOMINMAX
  2554. // not sure what AfxWin.h is for - here I do what Catch does
  2555. #ifdef __AFXDLL
  2556. #include <AfxWin.h>
  2557. #else
  2558. #include <windows.h>
  2559. #endif
  2560. #include <io.h>
  2561. #else // DOCTEST_PLATFORM_WINDOWS
  2562. #include <sys/time.h>
  2563. #include <unistd.h>
  2564. #endif // DOCTEST_PLATFORM_WINDOWS
  2565. // this is a fix for https://github.com/doctest/doctest/issues/348
  2566. // https://mail.gnome.org/archives/xml/2012-January/msg00000.html
  2567. #if !defined(HAVE_UNISTD_H) && !defined(STDOUT_FILENO)
  2568. #define STDOUT_FILENO fileno(stdout)
  2569. #endif // HAVE_UNISTD_H
  2570. DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END
  2571. // counts the number of elements in a C array
  2572. #define DOCTEST_COUNTOF(x) (sizeof(x) / sizeof(x[0]))
  2573. #ifdef DOCTEST_CONFIG_DISABLE
  2574. #define DOCTEST_BRANCH_ON_DISABLED(if_disabled, if_not_disabled) if_disabled
  2575. #else // DOCTEST_CONFIG_DISABLE
  2576. #define DOCTEST_BRANCH_ON_DISABLED(if_disabled, if_not_disabled) if_not_disabled
  2577. #endif // DOCTEST_CONFIG_DISABLE
  2578. #ifndef DOCTEST_CONFIG_OPTIONS_PREFIX
  2579. #define DOCTEST_CONFIG_OPTIONS_PREFIX "dt-"
  2580. #endif
  2581. #ifndef DOCTEST_THREAD_LOCAL
  2582. #if DOCTEST_MSVC && (DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0))
  2583. #define DOCTEST_THREAD_LOCAL
  2584. #else // DOCTEST_MSVC
  2585. #define DOCTEST_THREAD_LOCAL thread_local
  2586. #endif // DOCTEST_MSVC
  2587. #endif // DOCTEST_THREAD_LOCAL
  2588. #ifndef DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES
  2589. #define DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES 32
  2590. #endif
  2591. #ifndef DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE
  2592. #define DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE 64
  2593. #endif
  2594. #ifdef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
  2595. #define DOCTEST_OPTIONS_PREFIX_DISPLAY DOCTEST_CONFIG_OPTIONS_PREFIX
  2596. #else
  2597. #define DOCTEST_OPTIONS_PREFIX_DISPLAY ""
  2598. #endif
  2599. #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
  2600. #define DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS
  2601. #endif
  2602. #ifndef DOCTEST_CDECL
  2603. #define DOCTEST_CDECL __cdecl
  2604. #endif
  2605. namespace doctest {
  2606. bool is_running_in_test = false;
  2607. namespace {
  2608. using namespace detail;
  2609. template <typename Ex>
  2610. DOCTEST_NORETURN void throw_exception(Ex const& e) {
  2611. #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
  2612. throw e;
  2613. #else // DOCTEST_CONFIG_NO_EXCEPTIONS
  2614. std::cerr << "doctest will terminate because it needed to throw an exception.\n"
  2615. << "The message was: " << e.what() << '\n';
  2616. std::terminate();
  2617. #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
  2618. }
  2619. #ifndef DOCTEST_INTERNAL_ERROR
  2620. #define DOCTEST_INTERNAL_ERROR(msg) \
  2621. throw_exception(std::logic_error( \
  2622. __FILE__ ":" DOCTEST_TOSTR(__LINE__) ": Internal doctest error: " msg))
  2623. #endif // DOCTEST_INTERNAL_ERROR
  2624. // case insensitive strcmp
  2625. int stricmp(const char* a, const char* b) {
  2626. for(;; a++, b++) {
  2627. const int d = tolower(*a) - tolower(*b);
  2628. if(d != 0 || !*a)
  2629. return d;
  2630. }
  2631. }
  2632. template <typename T>
  2633. String fpToString(T value, int precision) {
  2634. std::ostringstream oss;
  2635. oss << std::setprecision(precision) << std::fixed << value;
  2636. std::string d = oss.str();
  2637. size_t i = d.find_last_not_of('0');
  2638. if(i != std::string::npos && i != d.size() - 1) {
  2639. if(d[i] == '.')
  2640. i++;
  2641. d = d.substr(0, i + 1);
  2642. }
  2643. return d.c_str();
  2644. }
  2645. struct Endianness
  2646. {
  2647. enum Arch
  2648. {
  2649. Big,
  2650. Little
  2651. };
  2652. static Arch which() {
  2653. int x = 1;
  2654. // casting any data pointer to char* is allowed
  2655. auto ptr = reinterpret_cast<char*>(&x);
  2656. if(*ptr)
  2657. return Little;
  2658. return Big;
  2659. }
  2660. };
  2661. } // namespace
  2662. namespace detail {
  2663. String rawMemoryToString(const void* object, unsigned size) {
  2664. // Reverse order for little endian architectures
  2665. int i = 0, end = static_cast<int>(size), inc = 1;
  2666. if(Endianness::which() == Endianness::Little) {
  2667. i = end - 1;
  2668. end = inc = -1;
  2669. }
  2670. unsigned const char* bytes = static_cast<unsigned const char*>(object);
  2671. std::ostream* oss = tlssPush();
  2672. *oss << "0x" << std::setfill('0') << std::hex;
  2673. for(; i != end; i += inc)
  2674. *oss << std::setw(2) << static_cast<unsigned>(bytes[i]);
  2675. return tlssPop();
  2676. }
  2677. DOCTEST_THREAD_LOCAL class
  2678. {
  2679. std::vector<std::streampos> stack;
  2680. std::stringstream ss;
  2681. public:
  2682. std::ostream* push() {
  2683. stack.push_back(ss.tellp());
  2684. return &ss;
  2685. }
  2686. String pop() {
  2687. if (stack.empty())
  2688. DOCTEST_INTERNAL_ERROR("TLSS was empty when trying to pop!");
  2689. std::streampos pos = stack.back();
  2690. stack.pop_back();
  2691. unsigned sz = static_cast<unsigned>(ss.tellp() - pos);
  2692. ss.rdbuf()->pubseekpos(pos, std::ios::in | std::ios::out);
  2693. return String(ss, sz);
  2694. }
  2695. } g_oss;
  2696. std::ostream* tlssPush() {
  2697. return g_oss.push();
  2698. }
  2699. String tlssPop() {
  2700. return g_oss.pop();
  2701. }
  2702. #ifndef DOCTEST_CONFIG_DISABLE
  2703. namespace timer_large_integer
  2704. {
  2705. #if defined(DOCTEST_PLATFORM_WINDOWS)
  2706. typedef ULONGLONG type;
  2707. #else // DOCTEST_PLATFORM_WINDOWS
  2708. typedef std::uint64_t type;
  2709. #endif // DOCTEST_PLATFORM_WINDOWS
  2710. }
  2711. typedef timer_large_integer::type ticks_t;
  2712. #ifdef DOCTEST_CONFIG_GETCURRENTTICKS
  2713. ticks_t getCurrentTicks() { return DOCTEST_CONFIG_GETCURRENTTICKS(); }
  2714. #elif defined(DOCTEST_PLATFORM_WINDOWS)
  2715. ticks_t getCurrentTicks() {
  2716. static LARGE_INTEGER hz{}, hzo{};
  2717. if(!hz.QuadPart) {
  2718. QueryPerformanceFrequency(&hz);
  2719. QueryPerformanceCounter(&hzo);
  2720. }
  2721. LARGE_INTEGER t;
  2722. QueryPerformanceCounter(&t);
  2723. return ((t.QuadPart - hzo.QuadPart) * LONGLONG(1000000)) / hz.QuadPart;
  2724. }
  2725. #else // DOCTEST_PLATFORM_WINDOWS
  2726. ticks_t getCurrentTicks() {
  2727. timeval t;
  2728. gettimeofday(&t, nullptr);
  2729. return static_cast<ticks_t>(t.tv_sec) * 1000000 + static_cast<ticks_t>(t.tv_usec);
  2730. }
  2731. #endif // DOCTEST_PLATFORM_WINDOWS
  2732. struct Timer
  2733. {
  2734. void start() { m_ticks = getCurrentTicks(); }
  2735. unsigned int getElapsedMicroseconds() const {
  2736. return static_cast<unsigned int>(getCurrentTicks() - m_ticks);
  2737. }
  2738. //unsigned int getElapsedMilliseconds() const {
  2739. // return static_cast<unsigned int>(getElapsedMicroseconds() / 1000);
  2740. //}
  2741. double getElapsedSeconds() const { return static_cast<double>(getCurrentTicks() - m_ticks) / 1000000.0; }
  2742. private:
  2743. ticks_t m_ticks = 0;
  2744. };
  2745. #ifdef DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS
  2746. template <typename T>
  2747. using AtomicOrMultiLaneAtomic = std::atomic<T>;
  2748. #else // DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS
  2749. // Provides a multilane implementation of an atomic variable that supports add, sub, load,
  2750. // store. Instead of using a single atomic variable, this splits up into multiple ones,
  2751. // each sitting on a separate cache line. The goal is to provide a speedup when most
  2752. // operations are modifying. It achieves this with two properties:
  2753. //
  2754. // * Multiple atomics are used, so chance of congestion from the same atomic is reduced.
  2755. // * Each atomic sits on a separate cache line, so false sharing is reduced.
  2756. //
  2757. // The disadvantage is that there is a small overhead due to the use of TLS, and load/store
  2758. // is slower because all atomics have to be accessed.
  2759. template <typename T>
  2760. class MultiLaneAtomic
  2761. {
  2762. struct CacheLineAlignedAtomic
  2763. {
  2764. std::atomic<T> atomic{};
  2765. char padding[DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE - sizeof(std::atomic<T>)];
  2766. };
  2767. CacheLineAlignedAtomic m_atomics[DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES];
  2768. static_assert(sizeof(CacheLineAlignedAtomic) == DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE,
  2769. "guarantee one atomic takes exactly one cache line");
  2770. public:
  2771. T operator++() DOCTEST_NOEXCEPT { return fetch_add(1) + 1; }
  2772. T operator++(int) DOCTEST_NOEXCEPT { return fetch_add(1); }
  2773. T fetch_add(T arg, std::memory_order order = std::memory_order_seq_cst) DOCTEST_NOEXCEPT {
  2774. return myAtomic().fetch_add(arg, order);
  2775. }
  2776. T fetch_sub(T arg, std::memory_order order = std::memory_order_seq_cst) DOCTEST_NOEXCEPT {
  2777. return myAtomic().fetch_sub(arg, order);
  2778. }
  2779. operator T() const DOCTEST_NOEXCEPT { return load(); }
  2780. T load(std::memory_order order = std::memory_order_seq_cst) const DOCTEST_NOEXCEPT {
  2781. auto result = T();
  2782. for(auto const& c : m_atomics) {
  2783. result += c.atomic.load(order);
  2784. }
  2785. return result;
  2786. }
  2787. T operator=(T desired) DOCTEST_NOEXCEPT { // lgtm [cpp/assignment-does-not-return-this]
  2788. store(desired);
  2789. return desired;
  2790. }
  2791. void store(T desired, std::memory_order order = std::memory_order_seq_cst) DOCTEST_NOEXCEPT {
  2792. // first value becomes desired", all others become 0.
  2793. for(auto& c : m_atomics) {
  2794. c.atomic.store(desired, order);
  2795. desired = {};
  2796. }
  2797. }
  2798. private:
  2799. // Each thread has a different atomic that it operates on. If more than NumLanes threads
  2800. // use this, some will use the same atomic. So performance will degrade a bit, but still
  2801. // everything will work.
  2802. //
  2803. // The logic here is a bit tricky. The call should be as fast as possible, so that there
  2804. // is minimal to no overhead in determining the correct atomic for the current thread.
  2805. //
  2806. // 1. A global static counter laneCounter counts continuously up.
  2807. // 2. Each successive thread will use modulo operation of that counter so it gets an atomic
  2808. // assigned in a round-robin fashion.
  2809. // 3. This tlsLaneIdx is stored in the thread local data, so it is directly available with
  2810. // little overhead.
  2811. std::atomic<T>& myAtomic() DOCTEST_NOEXCEPT {
  2812. static std::atomic<size_t> laneCounter;
  2813. DOCTEST_THREAD_LOCAL size_t tlsLaneIdx =
  2814. laneCounter++ % DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES;
  2815. return m_atomics[tlsLaneIdx].atomic;
  2816. }
  2817. };
  2818. template <typename T>
  2819. using AtomicOrMultiLaneAtomic = MultiLaneAtomic<T>;
  2820. #endif // DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS
  2821. // this holds both parameters from the command line and runtime data for tests
  2822. struct ContextState : ContextOptions, TestRunStats, CurrentTestCaseStats
  2823. {
  2824. AtomicOrMultiLaneAtomic<int> numAssertsCurrentTest_atomic;
  2825. AtomicOrMultiLaneAtomic<int> numAssertsFailedCurrentTest_atomic;
  2826. std::vector<std::vector<String>> filters = decltype(filters)(9); // 9 different filters
  2827. std::vector<IReporter*> reporters_currently_used;
  2828. assert_handler ah = nullptr;
  2829. Timer timer;
  2830. std::vector<String> stringifiedContexts; // logging from INFO() due to an exception
  2831. // stuff for subcases
  2832. std::vector<SubcaseSignature> subcasesStack;
  2833. std::set<decltype(subcasesStack)> subcasesPassed;
  2834. int subcasesCurrentMaxLevel;
  2835. bool should_reenter;
  2836. std::atomic<bool> shouldLogCurrentException;
  2837. void resetRunData() {
  2838. numTestCases = 0;
  2839. numTestCasesPassingFilters = 0;
  2840. numTestSuitesPassingFilters = 0;
  2841. numTestCasesFailed = 0;
  2842. numAsserts = 0;
  2843. numAssertsFailed = 0;
  2844. numAssertsCurrentTest = 0;
  2845. numAssertsFailedCurrentTest = 0;
  2846. }
  2847. void finalizeTestCaseData() {
  2848. seconds = timer.getElapsedSeconds();
  2849. // update the non-atomic counters
  2850. numAsserts += numAssertsCurrentTest_atomic;
  2851. numAssertsFailed += numAssertsFailedCurrentTest_atomic;
  2852. numAssertsCurrentTest = numAssertsCurrentTest_atomic;
  2853. numAssertsFailedCurrentTest = numAssertsFailedCurrentTest_atomic;
  2854. if(numAssertsFailedCurrentTest)
  2855. failure_flags |= TestCaseFailureReason::AssertFailure;
  2856. if(Approx(currentTest->m_timeout).epsilon(DBL_EPSILON) != 0 &&
  2857. Approx(seconds).epsilon(DBL_EPSILON) > currentTest->m_timeout)
  2858. failure_flags |= TestCaseFailureReason::Timeout;
  2859. if(currentTest->m_should_fail) {
  2860. if(failure_flags) {
  2861. failure_flags |= TestCaseFailureReason::ShouldHaveFailedAndDid;
  2862. } else {
  2863. failure_flags |= TestCaseFailureReason::ShouldHaveFailedButDidnt;
  2864. }
  2865. } else if(failure_flags && currentTest->m_may_fail) {
  2866. failure_flags |= TestCaseFailureReason::CouldHaveFailedAndDid;
  2867. } else if(currentTest->m_expected_failures > 0) {
  2868. if(numAssertsFailedCurrentTest == currentTest->m_expected_failures) {
  2869. failure_flags |= TestCaseFailureReason::FailedExactlyNumTimes;
  2870. } else {
  2871. failure_flags |= TestCaseFailureReason::DidntFailExactlyNumTimes;
  2872. }
  2873. }
  2874. bool ok_to_fail = (TestCaseFailureReason::ShouldHaveFailedAndDid & failure_flags) ||
  2875. (TestCaseFailureReason::CouldHaveFailedAndDid & failure_flags) ||
  2876. (TestCaseFailureReason::FailedExactlyNumTimes & failure_flags);
  2877. // if any subcase has failed - the whole test case has failed
  2878. testCaseSuccess = !(failure_flags && !ok_to_fail);
  2879. if(!testCaseSuccess)
  2880. numTestCasesFailed++;
  2881. }
  2882. };
  2883. ContextState* g_cs = nullptr;
  2884. // used to avoid locks for the debug output
  2885. // TODO: figure out if this is indeed necessary/correct - seems like either there still
  2886. // could be a race or that there wouldn't be a race even if using the context directly
  2887. DOCTEST_THREAD_LOCAL bool g_no_colors;
  2888. #endif // DOCTEST_CONFIG_DISABLE
  2889. } // namespace detail
  2890. char* String::allocate(unsigned sz) {
  2891. if (sz <= last) {
  2892. buf[sz] = '\0';
  2893. setLast(last - sz);
  2894. return buf;
  2895. } else {
  2896. setOnHeap();
  2897. data.size = sz;
  2898. data.capacity = data.size + 1;
  2899. data.ptr = new char[data.capacity];
  2900. data.ptr[sz] = '\0';
  2901. return data.ptr;
  2902. }
  2903. }
  2904. void String::setOnHeap() { *reinterpret_cast<unsigned char*>(&buf[last]) = 128; }
  2905. void String::setLast(unsigned in) { buf[last] = char(in); }
  2906. void String::copy(const String& other) {
  2907. if(other.isOnStack()) {
  2908. memcpy(buf, other.buf, len);
  2909. } else {
  2910. memcpy(allocate(other.data.size), other.data.ptr, other.data.size);
  2911. }
  2912. }
  2913. String::String() {
  2914. buf[0] = '\0';
  2915. setLast();
  2916. }
  2917. String::~String() {
  2918. if(!isOnStack())
  2919. delete[] data.ptr;
  2920. // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
  2921. }
  2922. String::String(const char* in)
  2923. : String(in, strlen(in)) {}
  2924. String::String(const char* in, unsigned in_size) {
  2925. memcpy(allocate(in_size), in, in_size);
  2926. }
  2927. String::String(std::istream& in, unsigned in_size) {
  2928. in.read(allocate(in_size), in_size);
  2929. }
  2930. String::String(const String& other) { copy(other); }
  2931. String& String::operator=(const String& other) {
  2932. if(this != &other) {
  2933. if(!isOnStack())
  2934. delete[] data.ptr;
  2935. copy(other);
  2936. }
  2937. return *this;
  2938. }
  2939. String& String::operator+=(const String& other) {
  2940. const unsigned my_old_size = size();
  2941. const unsigned other_size = other.size();
  2942. const unsigned total_size = my_old_size + other_size;
  2943. if(isOnStack()) {
  2944. if(total_size < len) {
  2945. // append to the current stack space
  2946. memcpy(buf + my_old_size, other.c_str(), other_size + 1);
  2947. // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
  2948. setLast(last - total_size);
  2949. } else {
  2950. // alloc new chunk
  2951. char* temp = new char[total_size + 1];
  2952. // copy current data to new location before writing in the union
  2953. memcpy(temp, buf, my_old_size); // skip the +1 ('\0') for speed
  2954. // update data in union
  2955. setOnHeap();
  2956. data.size = total_size;
  2957. data.capacity = data.size + 1;
  2958. data.ptr = temp;
  2959. // transfer the rest of the data
  2960. memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1);
  2961. }
  2962. } else {
  2963. if(data.capacity > total_size) {
  2964. // append to the current heap block
  2965. data.size = total_size;
  2966. memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1);
  2967. } else {
  2968. // resize
  2969. data.capacity *= 2;
  2970. if(data.capacity <= total_size)
  2971. data.capacity = total_size + 1;
  2972. // alloc new chunk
  2973. char* temp = new char[data.capacity];
  2974. // copy current data to new location before releasing it
  2975. memcpy(temp, data.ptr, my_old_size); // skip the +1 ('\0') for speed
  2976. // release old chunk
  2977. delete[] data.ptr;
  2978. // update the rest of the union members
  2979. data.size = total_size;
  2980. data.ptr = temp;
  2981. // transfer the rest of the data
  2982. memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1);
  2983. }
  2984. }
  2985. return *this;
  2986. }
  2987. String::String(String&& other) {
  2988. memcpy(buf, other.buf, len);
  2989. other.buf[0] = '\0';
  2990. other.setLast();
  2991. }
  2992. String& String::operator=(String&& other) {
  2993. if(this != &other) {
  2994. if(!isOnStack())
  2995. delete[] data.ptr;
  2996. memcpy(buf, other.buf, len);
  2997. other.buf[0] = '\0';
  2998. other.setLast();
  2999. }
  3000. return *this;
  3001. }
  3002. char String::operator[](unsigned i) const {
  3003. return const_cast<String*>(this)->operator[](i); // NOLINT
  3004. }
  3005. char& String::operator[](unsigned i) {
  3006. if(isOnStack())
  3007. return reinterpret_cast<char*>(buf)[i];
  3008. return data.ptr[i];
  3009. }
  3010. DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wmaybe-uninitialized")
  3011. unsigned String::size() const {
  3012. if(isOnStack())
  3013. return last - (unsigned(buf[last]) & 31); // using "last" would work only if "len" is 32
  3014. return data.size;
  3015. }
  3016. DOCTEST_GCC_SUPPRESS_WARNING_POP
  3017. unsigned String::capacity() const {
  3018. if(isOnStack())
  3019. return len;
  3020. return data.capacity;
  3021. }
  3022. int String::compare(const char* other, bool no_case) const {
  3023. if(no_case)
  3024. return doctest::stricmp(c_str(), other);
  3025. return std::strcmp(c_str(), other);
  3026. }
  3027. int String::compare(const String& other, bool no_case) const {
  3028. return compare(other.c_str(), no_case);
  3029. }
  3030. // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
  3031. String operator+(const String& lhs, const String& rhs) { return String(lhs) += rhs; }
  3032. // clang-format off
  3033. bool operator==(const String& lhs, const String& rhs) { return lhs.compare(rhs) == 0; }
  3034. bool operator!=(const String& lhs, const String& rhs) { return lhs.compare(rhs) != 0; }
  3035. bool operator< (const String& lhs, const String& rhs) { return lhs.compare(rhs) < 0; }
  3036. bool operator> (const String& lhs, const String& rhs) { return lhs.compare(rhs) > 0; }
  3037. bool operator<=(const String& lhs, const String& rhs) { return (lhs != rhs) ? lhs.compare(rhs) < 0 : true; }
  3038. bool operator>=(const String& lhs, const String& rhs) { return (lhs != rhs) ? lhs.compare(rhs) > 0 : true; }
  3039. // clang-format on
  3040. std::ostream& operator<<(std::ostream& s, const String& in) { return s << in.c_str(); }
  3041. namespace {
  3042. void color_to_stream(std::ostream&, Color::Enum) DOCTEST_BRANCH_ON_DISABLED({}, ;)
  3043. } // namespace
  3044. namespace Color {
  3045. std::ostream& operator<<(std::ostream& s, Color::Enum code) {
  3046. color_to_stream(s, code);
  3047. return s;
  3048. }
  3049. } // namespace Color
  3050. // clang-format off
  3051. const char* assertString(assertType::Enum at) {
  3052. DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4062) // enum 'x' in switch of enum 'y' is not handled
  3053. switch(at) { //!OCLINT missing default in switch statements
  3054. case assertType::DT_WARN : return "WARN";
  3055. case assertType::DT_CHECK : return "CHECK";
  3056. case assertType::DT_REQUIRE : return "REQUIRE";
  3057. case assertType::DT_WARN_FALSE : return "WARN_FALSE";
  3058. case assertType::DT_CHECK_FALSE : return "CHECK_FALSE";
  3059. case assertType::DT_REQUIRE_FALSE : return "REQUIRE_FALSE";
  3060. case assertType::DT_WARN_THROWS : return "WARN_THROWS";
  3061. case assertType::DT_CHECK_THROWS : return "CHECK_THROWS";
  3062. case assertType::DT_REQUIRE_THROWS : return "REQUIRE_THROWS";
  3063. case assertType::DT_WARN_THROWS_AS : return "WARN_THROWS_AS";
  3064. case assertType::DT_CHECK_THROWS_AS : return "CHECK_THROWS_AS";
  3065. case assertType::DT_REQUIRE_THROWS_AS : return "REQUIRE_THROWS_AS";
  3066. case assertType::DT_WARN_THROWS_WITH : return "WARN_THROWS_WITH";
  3067. case assertType::DT_CHECK_THROWS_WITH : return "CHECK_THROWS_WITH";
  3068. case assertType::DT_REQUIRE_THROWS_WITH : return "REQUIRE_THROWS_WITH";
  3069. case assertType::DT_WARN_THROWS_WITH_AS : return "WARN_THROWS_WITH_AS";
  3070. case assertType::DT_CHECK_THROWS_WITH_AS : return "CHECK_THROWS_WITH_AS";
  3071. case assertType::DT_REQUIRE_THROWS_WITH_AS : return "REQUIRE_THROWS_WITH_AS";
  3072. case assertType::DT_WARN_NOTHROW : return "WARN_NOTHROW";
  3073. case assertType::DT_CHECK_NOTHROW : return "CHECK_NOTHROW";
  3074. case assertType::DT_REQUIRE_NOTHROW : return "REQUIRE_NOTHROW";
  3075. case assertType::DT_WARN_EQ : return "WARN_EQ";
  3076. case assertType::DT_CHECK_EQ : return "CHECK_EQ";
  3077. case assertType::DT_REQUIRE_EQ : return "REQUIRE_EQ";
  3078. case assertType::DT_WARN_NE : return "WARN_NE";
  3079. case assertType::DT_CHECK_NE : return "CHECK_NE";
  3080. case assertType::DT_REQUIRE_NE : return "REQUIRE_NE";
  3081. case assertType::DT_WARN_GT : return "WARN_GT";
  3082. case assertType::DT_CHECK_GT : return "CHECK_GT";
  3083. case assertType::DT_REQUIRE_GT : return "REQUIRE_GT";
  3084. case assertType::DT_WARN_LT : return "WARN_LT";
  3085. case assertType::DT_CHECK_LT : return "CHECK_LT";
  3086. case assertType::DT_REQUIRE_LT : return "REQUIRE_LT";
  3087. case assertType::DT_WARN_GE : return "WARN_GE";
  3088. case assertType::DT_CHECK_GE : return "CHECK_GE";
  3089. case assertType::DT_REQUIRE_GE : return "REQUIRE_GE";
  3090. case assertType::DT_WARN_LE : return "WARN_LE";
  3091. case assertType::DT_CHECK_LE : return "CHECK_LE";
  3092. case assertType::DT_REQUIRE_LE : return "REQUIRE_LE";
  3093. case assertType::DT_WARN_UNARY : return "WARN_UNARY";
  3094. case assertType::DT_CHECK_UNARY : return "CHECK_UNARY";
  3095. case assertType::DT_REQUIRE_UNARY : return "REQUIRE_UNARY";
  3096. case assertType::DT_WARN_UNARY_FALSE : return "WARN_UNARY_FALSE";
  3097. case assertType::DT_CHECK_UNARY_FALSE : return "CHECK_UNARY_FALSE";
  3098. case assertType::DT_REQUIRE_UNARY_FALSE : return "REQUIRE_UNARY_FALSE";
  3099. }
  3100. DOCTEST_MSVC_SUPPRESS_WARNING_POP
  3101. return "";
  3102. }
  3103. // clang-format on
  3104. const char* failureString(assertType::Enum at) {
  3105. if(at & assertType::is_warn) //!OCLINT bitwise operator in conditional
  3106. return "WARNING";
  3107. if(at & assertType::is_check) //!OCLINT bitwise operator in conditional
  3108. return "ERROR";
  3109. if(at & assertType::is_require) //!OCLINT bitwise operator in conditional
  3110. return "FATAL ERROR";
  3111. return "";
  3112. }
  3113. DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wnull-dereference")
  3114. DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wnull-dereference")
  3115. // depending on the current options this will remove the path of filenames
  3116. const char* skipPathFromFilename(const char* file) {
  3117. #ifndef DOCTEST_CONFIG_DISABLE
  3118. if(getContextOptions()->no_path_in_filenames) {
  3119. auto back = std::strrchr(file, '\\');
  3120. auto forward = std::strrchr(file, '/');
  3121. if(back || forward) {
  3122. if(back > forward)
  3123. forward = back;
  3124. return forward + 1;
  3125. }
  3126. }
  3127. #endif // DOCTEST_CONFIG_DISABLE
  3128. return file;
  3129. }
  3130. DOCTEST_CLANG_SUPPRESS_WARNING_POP
  3131. DOCTEST_GCC_SUPPRESS_WARNING_POP
  3132. bool SubcaseSignature::operator<(const SubcaseSignature& other) const {
  3133. if(m_line != other.m_line)
  3134. return m_line < other.m_line;
  3135. if(std::strcmp(m_file, other.m_file) != 0)
  3136. return std::strcmp(m_file, other.m_file) < 0;
  3137. return m_name.compare(other.m_name) < 0;
  3138. }
  3139. IContextScope::IContextScope() = default;
  3140. IContextScope::~IContextScope() = default;
  3141. #ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
  3142. String toString(char* in) { return toString(static_cast<const char*>(in)); }
  3143. // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
  3144. String toString(const char* in) { return String("\"") + (in ? in : "{null string}") + "\""; }
  3145. #endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
  3146. String toString(bool in) { return in ? "true" : "false"; }
  3147. String toString(float in) { return fpToString(in, 5) + "f"; }
  3148. String toString(double in) { return fpToString(in, 10); }
  3149. String toString(double long in) { return fpToString(in, 15); }
  3150. #define DOCTEST_TO_STRING_OVERLOAD(type, fmt) \
  3151. String toString(type in) { \
  3152. char buf[64]; \
  3153. std::sprintf(buf, fmt, in); \
  3154. return buf; \
  3155. }
  3156. DOCTEST_TO_STRING_OVERLOAD(char, "%d")
  3157. DOCTEST_TO_STRING_OVERLOAD(char signed, "%d")
  3158. DOCTEST_TO_STRING_OVERLOAD(char unsigned, "%u")
  3159. DOCTEST_TO_STRING_OVERLOAD(int short, "%d")
  3160. DOCTEST_TO_STRING_OVERLOAD(int short unsigned, "%u")
  3161. DOCTEST_TO_STRING_OVERLOAD(int, "%d")
  3162. DOCTEST_TO_STRING_OVERLOAD(unsigned, "%u")
  3163. DOCTEST_TO_STRING_OVERLOAD(int long, "%ld")
  3164. DOCTEST_TO_STRING_OVERLOAD(int long unsigned, "%lu")
  3165. DOCTEST_TO_STRING_OVERLOAD(int long long, "%lld")
  3166. DOCTEST_TO_STRING_OVERLOAD(int long long unsigned, "%llu")
  3167. String toString(std::nullptr_t) { return "NULL"; }
  3168. #if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0)
  3169. // see this issue on why this is needed: https://github.com/doctest/doctest/issues/183
  3170. String toString(const std::string& in) { return in.c_str(); }
  3171. #endif // VS 2019
  3172. Approx::Approx(double value)
  3173. : m_epsilon(static_cast<double>(std::numeric_limits<float>::epsilon()) * 100)
  3174. , m_scale(1.0)
  3175. , m_value(value) {}
  3176. Approx Approx::operator()(double value) const {
  3177. Approx approx(value);
  3178. approx.epsilon(m_epsilon);
  3179. approx.scale(m_scale);
  3180. return approx;
  3181. }
  3182. Approx& Approx::epsilon(double newEpsilon) {
  3183. m_epsilon = newEpsilon;
  3184. return *this;
  3185. }
  3186. Approx& Approx::scale(double newScale) {
  3187. m_scale = newScale;
  3188. return *this;
  3189. }
  3190. bool operator==(double lhs, const Approx& rhs) {
  3191. // Thanks to Richard Harris for his help refining this formula
  3192. return std::fabs(lhs - rhs.m_value) <
  3193. rhs.m_epsilon * (rhs.m_scale + std::max<double>(std::fabs(lhs), std::fabs(rhs.m_value)));
  3194. }
  3195. bool operator==(const Approx& lhs, double rhs) { return operator==(rhs, lhs); }
  3196. bool operator!=(double lhs, const Approx& rhs) { return !operator==(lhs, rhs); }
  3197. bool operator!=(const Approx& lhs, double rhs) { return !operator==(rhs, lhs); }
  3198. bool operator<=(double lhs, const Approx& rhs) { return lhs < rhs.m_value || lhs == rhs; }
  3199. bool operator<=(const Approx& lhs, double rhs) { return lhs.m_value < rhs || lhs == rhs; }
  3200. bool operator>=(double lhs, const Approx& rhs) { return lhs > rhs.m_value || lhs == rhs; }
  3201. bool operator>=(const Approx& lhs, double rhs) { return lhs.m_value > rhs || lhs == rhs; }
  3202. bool operator<(double lhs, const Approx& rhs) { return lhs < rhs.m_value && lhs != rhs; }
  3203. bool operator<(const Approx& lhs, double rhs) { return lhs.m_value < rhs && lhs != rhs; }
  3204. bool operator>(double lhs, const Approx& rhs) { return lhs > rhs.m_value && lhs != rhs; }
  3205. bool operator>(const Approx& lhs, double rhs) { return lhs.m_value > rhs && lhs != rhs; }
  3206. String toString(const Approx& in) {
  3207. // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
  3208. return "Approx( " + doctest::toString(in.m_value) + " )";
  3209. }
  3210. const ContextOptions* getContextOptions() { return DOCTEST_BRANCH_ON_DISABLED(nullptr, g_cs); }
  3211. } // namespace doctest
  3212. #ifdef DOCTEST_CONFIG_DISABLE
  3213. namespace doctest {
  3214. Context::Context(int, const char* const*) {}
  3215. Context::~Context() = default;
  3216. void Context::applyCommandLine(int, const char* const*) {}
  3217. void Context::addFilter(const char*, const char*) {}
  3218. void Context::clearFilters() {}
  3219. void Context::setOption(const char*, bool) {}
  3220. void Context::setOption(const char*, int) {}
  3221. void Context::setOption(const char*, const char*) {}
  3222. bool Context::shouldExit() { return false; }
  3223. void Context::setAsDefaultForAssertsOutOfTestCases() {}
  3224. void Context::setAssertHandler(detail::assert_handler) {}
  3225. void Context::setCout(std::ostream* out) {}
  3226. int Context::run() { return 0; }
  3227. IReporter::~IReporter() = default;
  3228. int IReporter::get_num_active_contexts() { return 0; }
  3229. const IContextScope* const* IReporter::get_active_contexts() { return nullptr; }
  3230. int IReporter::get_num_stringified_contexts() { return 0; }
  3231. const String* IReporter::get_stringified_contexts() { return nullptr; }
  3232. int registerReporter(const char*, int, IReporter*) { return 0; }
  3233. } // namespace doctest
  3234. #else // DOCTEST_CONFIG_DISABLE
  3235. #if !defined(DOCTEST_CONFIG_COLORS_NONE)
  3236. #if !defined(DOCTEST_CONFIG_COLORS_WINDOWS) && !defined(DOCTEST_CONFIG_COLORS_ANSI)
  3237. #ifdef DOCTEST_PLATFORM_WINDOWS
  3238. #define DOCTEST_CONFIG_COLORS_WINDOWS
  3239. #else // linux
  3240. #define DOCTEST_CONFIG_COLORS_ANSI
  3241. #endif // platform
  3242. #endif // DOCTEST_CONFIG_COLORS_WINDOWS && DOCTEST_CONFIG_COLORS_ANSI
  3243. #endif // DOCTEST_CONFIG_COLORS_NONE
  3244. namespace doctest_detail_test_suite_ns {
  3245. // holds the current test suite
  3246. doctest::detail::TestSuite& getCurrentTestSuite() {
  3247. static doctest::detail::TestSuite data{};
  3248. return data;
  3249. }
  3250. } // namespace doctest_detail_test_suite_ns
  3251. namespace doctest {
  3252. namespace {
  3253. // the int (priority) is part of the key for automatic sorting - sadly one can register a
  3254. // reporter with a duplicate name and a different priority but hopefully that won't happen often :|
  3255. typedef std::map<std::pair<int, String>, reporterCreatorFunc> reporterMap;
  3256. reporterMap& getReporters() {
  3257. static reporterMap data;
  3258. return data;
  3259. }
  3260. reporterMap& getListeners() {
  3261. static reporterMap data;
  3262. return data;
  3263. }
  3264. } // namespace
  3265. namespace detail {
  3266. #define DOCTEST_ITERATE_THROUGH_REPORTERS(function, ...) \
  3267. for(auto& curr_rep : g_cs->reporters_currently_used) \
  3268. curr_rep->function(__VA_ARGS__)
  3269. bool checkIfShouldThrow(assertType::Enum at) {
  3270. if(at & assertType::is_require) //!OCLINT bitwise operator in conditional
  3271. return true;
  3272. if((at & assertType::is_check) //!OCLINT bitwise operator in conditional
  3273. && getContextOptions()->abort_after > 0 &&
  3274. (g_cs->numAssertsFailed + g_cs->numAssertsFailedCurrentTest_atomic) >=
  3275. getContextOptions()->abort_after)
  3276. return true;
  3277. return false;
  3278. }
  3279. #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
  3280. DOCTEST_NORETURN void throwException() {
  3281. g_cs->shouldLogCurrentException = false;
  3282. throw TestFailureException();
  3283. } // NOLINT(cert-err60-cpp)
  3284. #else // DOCTEST_CONFIG_NO_EXCEPTIONS
  3285. void throwException() {}
  3286. #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
  3287. } // namespace detail
  3288. namespace {
  3289. using namespace detail;
  3290. // matching of a string against a wildcard mask (case sensitivity configurable) taken from
  3291. // https://www.codeproject.com/Articles/1088/Wildcard-string-compare-globbing
  3292. int wildcmp(const char* str, const char* wild, bool caseSensitive) {
  3293. const char* cp = str;
  3294. const char* mp = wild;
  3295. while((*str) && (*wild != '*')) {
  3296. if((caseSensitive ? (*wild != *str) : (tolower(*wild) != tolower(*str))) &&
  3297. (*wild != '?')) {
  3298. return 0;
  3299. }
  3300. wild++;
  3301. str++;
  3302. }
  3303. while(*str) {
  3304. if(*wild == '*') {
  3305. if(!*++wild) {
  3306. return 1;
  3307. }
  3308. mp = wild;
  3309. cp = str + 1;
  3310. } else if((caseSensitive ? (*wild == *str) : (tolower(*wild) == tolower(*str))) ||
  3311. (*wild == '?')) {
  3312. wild++;
  3313. str++;
  3314. } else {
  3315. wild = mp; //!OCLINT parameter reassignment
  3316. str = cp++; //!OCLINT parameter reassignment
  3317. }
  3318. }
  3319. while(*wild == '*') {
  3320. wild++;
  3321. }
  3322. return !*wild;
  3323. }
  3324. //// C string hash function (djb2) - taken from http://www.cse.yorku.ca/~oz/hash.html
  3325. //unsigned hashStr(unsigned const char* str) {
  3326. // unsigned long hash = 5381;
  3327. // char c;
  3328. // while((c = *str++))
  3329. // hash = ((hash << 5) + hash) + c; // hash * 33 + c
  3330. // return hash;
  3331. //}
  3332. // checks if the name matches any of the filters (and can be configured what to do when empty)
  3333. bool matchesAny(const char* name, const std::vector<String>& filters, bool matchEmpty,
  3334. bool caseSensitive) {
  3335. if(filters.empty() && matchEmpty)
  3336. return true;
  3337. for(auto& curr : filters)
  3338. if(wildcmp(name, curr.c_str(), caseSensitive))
  3339. return true;
  3340. return false;
  3341. }
  3342. } // namespace
  3343. namespace detail {
  3344. Subcase::Subcase(const String& name, const char* file, int line)
  3345. : m_signature({name, file, line}) {
  3346. auto* s = g_cs;
  3347. // check subcase filters
  3348. if(s->subcasesStack.size() < size_t(s->subcase_filter_levels)) {
  3349. if(!matchesAny(m_signature.m_name.c_str(), s->filters[6], true, s->case_sensitive))
  3350. return;
  3351. if(matchesAny(m_signature.m_name.c_str(), s->filters[7], false, s->case_sensitive))
  3352. return;
  3353. }
  3354. // if a Subcase on the same level has already been entered
  3355. if(s->subcasesStack.size() < size_t(s->subcasesCurrentMaxLevel)) {
  3356. s->should_reenter = true;
  3357. return;
  3358. }
  3359. // push the current signature to the stack so we can check if the
  3360. // current stack + the current new subcase have been traversed
  3361. s->subcasesStack.push_back(m_signature);
  3362. if(s->subcasesPassed.count(s->subcasesStack) != 0) {
  3363. // pop - revert to previous stack since we've already passed this
  3364. s->subcasesStack.pop_back();
  3365. return;
  3366. }
  3367. s->subcasesCurrentMaxLevel = s->subcasesStack.size();
  3368. m_entered = true;
  3369. DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_start, m_signature);
  3370. }
  3371. DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4996) // std::uncaught_exception is deprecated in C++17
  3372. DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
  3373. DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
  3374. Subcase::~Subcase() {
  3375. if(m_entered) {
  3376. // only mark the subcase stack as passed if no subcases have been skipped
  3377. if(g_cs->should_reenter == false)
  3378. g_cs->subcasesPassed.insert(g_cs->subcasesStack);
  3379. g_cs->subcasesStack.pop_back();
  3380. #if defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411L && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200)
  3381. if(std::uncaught_exceptions() > 0
  3382. #else
  3383. if(std::uncaught_exception()
  3384. #endif
  3385. && g_cs->shouldLogCurrentException) {
  3386. DOCTEST_ITERATE_THROUGH_REPORTERS(
  3387. test_case_exception, {"exception thrown in subcase - will translate later "
  3388. "when the whole test case has been exited (cannot "
  3389. "translate while there is an active exception)",
  3390. false});
  3391. g_cs->shouldLogCurrentException = false;
  3392. }
  3393. DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_end, DOCTEST_EMPTY);
  3394. }
  3395. }
  3396. DOCTEST_CLANG_SUPPRESS_WARNING_POP
  3397. DOCTEST_GCC_SUPPRESS_WARNING_POP
  3398. DOCTEST_MSVC_SUPPRESS_WARNING_POP
  3399. Subcase::operator bool() const { return m_entered; }
  3400. Result::Result(bool passed, const String& decomposition)
  3401. : m_passed(passed)
  3402. , m_decomp(decomposition) {}
  3403. ExpressionDecomposer::ExpressionDecomposer(assertType::Enum at)
  3404. : m_at(at) {}
  3405. TestSuite& TestSuite::operator*(const char* in) {
  3406. m_test_suite = in;
  3407. return *this;
  3408. }
  3409. TestCase::TestCase(funcType test, const char* file, unsigned line, const TestSuite& test_suite,
  3410. const char* type, int template_id) {
  3411. m_file = file;
  3412. m_line = line;
  3413. m_name = nullptr; // will be later overridden in operator*
  3414. m_test_suite = test_suite.m_test_suite;
  3415. m_description = test_suite.m_description;
  3416. m_skip = test_suite.m_skip;
  3417. m_no_breaks = test_suite.m_no_breaks;
  3418. m_no_output = test_suite.m_no_output;
  3419. m_may_fail = test_suite.m_may_fail;
  3420. m_should_fail = test_suite.m_should_fail;
  3421. m_expected_failures = test_suite.m_expected_failures;
  3422. m_timeout = test_suite.m_timeout;
  3423. m_test = test;
  3424. m_type = type;
  3425. m_template_id = template_id;
  3426. }
  3427. TestCase::TestCase(const TestCase& other)
  3428. : TestCaseData() {
  3429. *this = other;
  3430. }
  3431. DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(26434) // hides a non-virtual function
  3432. DOCTEST_MSVC_SUPPRESS_WARNING(26437) // Do not slice
  3433. TestCase& TestCase::operator=(const TestCase& other) {
  3434. static_cast<TestCaseData&>(*this) = static_cast<const TestCaseData&>(other);
  3435. m_test = other.m_test;
  3436. m_type = other.m_type;
  3437. m_template_id = other.m_template_id;
  3438. m_full_name = other.m_full_name;
  3439. if(m_template_id != -1)
  3440. m_name = m_full_name.c_str();
  3441. return *this;
  3442. }
  3443. DOCTEST_MSVC_SUPPRESS_WARNING_POP
  3444. TestCase& TestCase::operator*(const char* in) {
  3445. m_name = in;
  3446. // make a new name with an appended type for templated test case
  3447. if(m_template_id != -1) {
  3448. m_full_name = String(m_name) + m_type;
  3449. // redirect the name to point to the newly constructed full name
  3450. m_name = m_full_name.c_str();
  3451. }
  3452. return *this;
  3453. }
  3454. bool TestCase::operator<(const TestCase& other) const {
  3455. // this will be used only to differentiate between test cases - not relevant for sorting
  3456. if(m_line != other.m_line)
  3457. return m_line < other.m_line;
  3458. const int name_cmp = strcmp(m_name, other.m_name);
  3459. if(name_cmp != 0)
  3460. return name_cmp < 0;
  3461. const int file_cmp = m_file.compare(other.m_file);
  3462. if(file_cmp != 0)
  3463. return file_cmp < 0;
  3464. return m_template_id < other.m_template_id;
  3465. }
  3466. // all the registered tests
  3467. std::set<TestCase>& getRegisteredTests() {
  3468. static std::set<TestCase> data;
  3469. return data;
  3470. }
  3471. } // namespace detail
  3472. namespace {
  3473. using namespace detail;
  3474. // for sorting tests by file/line
  3475. bool fileOrderComparator(const TestCase* lhs, const TestCase* rhs) {
  3476. // this is needed because MSVC gives different case for drive letters
  3477. // for __FILE__ when evaluated in a header and a source file
  3478. const int res = lhs->m_file.compare(rhs->m_file, bool(DOCTEST_MSVC));
  3479. if(res != 0)
  3480. return res < 0;
  3481. if(lhs->m_line != rhs->m_line)
  3482. return lhs->m_line < rhs->m_line;
  3483. return lhs->m_template_id < rhs->m_template_id;
  3484. }
  3485. // for sorting tests by suite/file/line
  3486. bool suiteOrderComparator(const TestCase* lhs, const TestCase* rhs) {
  3487. const int res = std::strcmp(lhs->m_test_suite, rhs->m_test_suite);
  3488. if(res != 0)
  3489. return res < 0;
  3490. return fileOrderComparator(lhs, rhs);
  3491. }
  3492. // for sorting tests by name/suite/file/line
  3493. bool nameOrderComparator(const TestCase* lhs, const TestCase* rhs) {
  3494. const int res = std::strcmp(lhs->m_name, rhs->m_name);
  3495. if(res != 0)
  3496. return res < 0;
  3497. return suiteOrderComparator(lhs, rhs);
  3498. }
  3499. DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
  3500. void color_to_stream(std::ostream& s, Color::Enum code) {
  3501. static_cast<void>(s); // for DOCTEST_CONFIG_COLORS_NONE or DOCTEST_CONFIG_COLORS_WINDOWS
  3502. static_cast<void>(code); // for DOCTEST_CONFIG_COLORS_NONE
  3503. #ifdef DOCTEST_CONFIG_COLORS_ANSI
  3504. if(g_no_colors ||
  3505. (isatty(STDOUT_FILENO) == false && getContextOptions()->force_colors == false))
  3506. return;
  3507. auto col = "";
  3508. // clang-format off
  3509. switch(code) { //!OCLINT missing break in switch statement / unnecessary default statement in covered switch statement
  3510. case Color::Red: col = "[0;31m"; break;
  3511. case Color::Green: col = "[0;32m"; break;
  3512. case Color::Blue: col = "[0;34m"; break;
  3513. case Color::Cyan: col = "[0;36m"; break;
  3514. case Color::Yellow: col = "[0;33m"; break;
  3515. case Color::Grey: col = "[1;30m"; break;
  3516. case Color::LightGrey: col = "[0;37m"; break;
  3517. case Color::BrightRed: col = "[1;31m"; break;
  3518. case Color::BrightGreen: col = "[1;32m"; break;
  3519. case Color::BrightWhite: col = "[1;37m"; break;
  3520. case Color::Bright: // invalid
  3521. case Color::None:
  3522. case Color::White:
  3523. default: col = "[0m";
  3524. }
  3525. // clang-format on
  3526. s << "\033" << col;
  3527. #endif // DOCTEST_CONFIG_COLORS_ANSI
  3528. #ifdef DOCTEST_CONFIG_COLORS_WINDOWS
  3529. if(g_no_colors ||
  3530. (_isatty(_fileno(stdout)) == false && getContextOptions()->force_colors == false))
  3531. return;
  3532. static struct ConsoleHelper {
  3533. HANDLE stdoutHandle;
  3534. WORD origFgAttrs;
  3535. WORD origBgAttrs;
  3536. ConsoleHelper() {
  3537. stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE);
  3538. CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
  3539. GetConsoleScreenBufferInfo(stdoutHandle, &csbiInfo);
  3540. origFgAttrs = csbiInfo.wAttributes & ~(BACKGROUND_GREEN | BACKGROUND_RED |
  3541. BACKGROUND_BLUE | BACKGROUND_INTENSITY);
  3542. origBgAttrs = csbiInfo.wAttributes & ~(FOREGROUND_GREEN | FOREGROUND_RED |
  3543. FOREGROUND_BLUE | FOREGROUND_INTENSITY);
  3544. }
  3545. } ch;
  3546. #define DOCTEST_SET_ATTR(x) SetConsoleTextAttribute(ch.stdoutHandle, x | ch.origBgAttrs)
  3547. // clang-format off
  3548. switch (code) {
  3549. case Color::White: DOCTEST_SET_ATTR(FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE); break;
  3550. case Color::Red: DOCTEST_SET_ATTR(FOREGROUND_RED); break;
  3551. case Color::Green: DOCTEST_SET_ATTR(FOREGROUND_GREEN); break;
  3552. case Color::Blue: DOCTEST_SET_ATTR(FOREGROUND_BLUE); break;
  3553. case Color::Cyan: DOCTEST_SET_ATTR(FOREGROUND_BLUE | FOREGROUND_GREEN); break;
  3554. case Color::Yellow: DOCTEST_SET_ATTR(FOREGROUND_RED | FOREGROUND_GREEN); break;
  3555. case Color::Grey: DOCTEST_SET_ATTR(0); break;
  3556. case Color::LightGrey: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY); break;
  3557. case Color::BrightRed: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_RED); break;
  3558. case Color::BrightGreen: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_GREEN); break;
  3559. case Color::BrightWhite: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE); break;
  3560. case Color::None:
  3561. case Color::Bright: // invalid
  3562. default: DOCTEST_SET_ATTR(ch.origFgAttrs);
  3563. }
  3564. // clang-format on
  3565. #endif // DOCTEST_CONFIG_COLORS_WINDOWS
  3566. }
  3567. DOCTEST_CLANG_SUPPRESS_WARNING_POP
  3568. std::vector<const IExceptionTranslator*>& getExceptionTranslators() {
  3569. static std::vector<const IExceptionTranslator*> data;
  3570. return data;
  3571. }
  3572. String translateActiveException() {
  3573. #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
  3574. String res;
  3575. auto& translators = getExceptionTranslators();
  3576. for(auto& curr : translators)
  3577. if(curr->translate(res))
  3578. return res;
  3579. // clang-format off
  3580. DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wcatch-value")
  3581. try {
  3582. throw;
  3583. } catch(std::exception& ex) {
  3584. return ex.what();
  3585. } catch(std::string& msg) {
  3586. return msg.c_str();
  3587. } catch(const char* msg) {
  3588. return msg;
  3589. } catch(...) {
  3590. return "unknown exception";
  3591. }
  3592. DOCTEST_GCC_SUPPRESS_WARNING_POP
  3593. // clang-format on
  3594. #else // DOCTEST_CONFIG_NO_EXCEPTIONS
  3595. return "";
  3596. #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
  3597. }
  3598. } // namespace
  3599. namespace detail {
  3600. // used by the macros for registering tests
  3601. int regTest(const TestCase& tc) {
  3602. getRegisteredTests().insert(tc);
  3603. return 0;
  3604. }
  3605. // sets the current test suite
  3606. int setTestSuite(const TestSuite& ts) {
  3607. doctest_detail_test_suite_ns::getCurrentTestSuite() = ts;
  3608. return 0;
  3609. }
  3610. #ifdef DOCTEST_IS_DEBUGGER_ACTIVE
  3611. bool isDebuggerActive() { return DOCTEST_IS_DEBUGGER_ACTIVE(); }
  3612. #else // DOCTEST_IS_DEBUGGER_ACTIVE
  3613. #ifdef DOCTEST_PLATFORM_LINUX
  3614. class ErrnoGuard {
  3615. public:
  3616. ErrnoGuard() : m_oldErrno(errno) {}
  3617. ~ErrnoGuard() { errno = m_oldErrno; }
  3618. private:
  3619. int m_oldErrno;
  3620. };
  3621. // See the comments in Catch2 for the reasoning behind this implementation:
  3622. // https://github.com/catchorg/Catch2/blob/v2.13.1/include/internal/catch_debugger.cpp#L79-L102
  3623. bool isDebuggerActive() {
  3624. ErrnoGuard guard;
  3625. std::ifstream in("/proc/self/status");
  3626. for(std::string line; std::getline(in, line);) {
  3627. static const int PREFIX_LEN = 11;
  3628. if(line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0) {
  3629. return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
  3630. }
  3631. }
  3632. return false;
  3633. }
  3634. #elif defined(DOCTEST_PLATFORM_MAC)
  3635. // The following function is taken directly from the following technical note:
  3636. // https://developer.apple.com/library/archive/qa/qa1361/_index.html
  3637. // Returns true if the current process is being debugged (either
  3638. // running under the debugger or has a debugger attached post facto).
  3639. bool isDebuggerActive() {
  3640. int mib[4];
  3641. kinfo_proc info;
  3642. size_t size;
  3643. // Initialize the flags so that, if sysctl fails for some bizarre
  3644. // reason, we get a predictable result.
  3645. info.kp_proc.p_flag = 0;
  3646. // Initialize mib, which tells sysctl the info we want, in this case
  3647. // we're looking for information about a specific process ID.
  3648. mib[0] = CTL_KERN;
  3649. mib[1] = KERN_PROC;
  3650. mib[2] = KERN_PROC_PID;
  3651. mib[3] = getpid();
  3652. // Call sysctl.
  3653. size = sizeof(info);
  3654. if(sysctl(mib, DOCTEST_COUNTOF(mib), &info, &size, 0, 0) != 0) {
  3655. std::cerr << "\nCall to sysctl failed - unable to determine if debugger is active **\n";
  3656. return false;
  3657. }
  3658. // We're being debugged if the P_TRACED flag is set.
  3659. return ((info.kp_proc.p_flag & P_TRACED) != 0);
  3660. }
  3661. #elif DOCTEST_MSVC || defined(__MINGW32__) || defined(__MINGW64__)
  3662. bool isDebuggerActive() { return ::IsDebuggerPresent() != 0; }
  3663. #else
  3664. bool isDebuggerActive() { return false; }
  3665. #endif // Platform
  3666. #endif // DOCTEST_IS_DEBUGGER_ACTIVE
  3667. void registerExceptionTranslatorImpl(const IExceptionTranslator* et) {
  3668. if(std::find(getExceptionTranslators().begin(), getExceptionTranslators().end(), et) ==
  3669. getExceptionTranslators().end())
  3670. getExceptionTranslators().push_back(et);
  3671. }
  3672. #ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
  3673. void toStream(std::ostream* s, char* in) { *s << in; }
  3674. void toStream(std::ostream* s, const char* in) { *s << in; }
  3675. #endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
  3676. void toStream(std::ostream* s, bool in) { *s << std::boolalpha << in << std::noboolalpha; }
  3677. void toStream(std::ostream* s, float in) { *s << in; }
  3678. void toStream(std::ostream* s, double in) { *s << in; }
  3679. void toStream(std::ostream* s, double long in) { *s << in; }
  3680. void toStream(std::ostream* s, char in) { *s << in; }
  3681. void toStream(std::ostream* s, char signed in) { *s << in; }
  3682. void toStream(std::ostream* s, char unsigned in) { *s << in; }
  3683. void toStream(std::ostream* s, int short in) { *s << in; }
  3684. void toStream(std::ostream* s, int short unsigned in) { *s << in; }
  3685. void toStream(std::ostream* s, int in) { *s << in; }
  3686. void toStream(std::ostream* s, int unsigned in) { *s << in; }
  3687. void toStream(std::ostream* s, int long in) { *s << in; }
  3688. void toStream(std::ostream* s, int long unsigned in) { *s << in; }
  3689. void toStream(std::ostream* s, int long long in) { *s << in; }
  3690. void toStream(std::ostream* s, int long long unsigned in) { *s << in; }
  3691. DOCTEST_THREAD_LOCAL std::vector<IContextScope*> g_infoContexts; // for logging with INFO()
  3692. ContextScopeBase::ContextScopeBase() {
  3693. g_infoContexts.push_back(this);
  3694. }
  3695. ContextScopeBase::ContextScopeBase(ContextScopeBase&& other) {
  3696. if (other.need_to_destroy) {
  3697. other.destroy();
  3698. }
  3699. other.need_to_destroy = false;
  3700. g_infoContexts.push_back(this);
  3701. }
  3702. DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4996) // std::uncaught_exception is deprecated in C++17
  3703. DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
  3704. DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
  3705. // destroy cannot be inlined into the destructor because that would mean calling stringify after
  3706. // ContextScope has been destroyed (base class destructors run after derived class destructors).
  3707. // Instead, ContextScope calls this method directly from its destructor.
  3708. void ContextScopeBase::destroy() {
  3709. #if defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411L && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200)
  3710. if(std::uncaught_exceptions() > 0) {
  3711. #else
  3712. if(std::uncaught_exception()) {
  3713. #endif
  3714. std::ostringstream s;
  3715. this->stringify(&s);
  3716. g_cs->stringifiedContexts.push_back(s.str().c_str());
  3717. }
  3718. g_infoContexts.pop_back();
  3719. }
  3720. DOCTEST_CLANG_SUPPRESS_WARNING_POP
  3721. DOCTEST_GCC_SUPPRESS_WARNING_POP
  3722. DOCTEST_MSVC_SUPPRESS_WARNING_POP
  3723. } // namespace detail
  3724. namespace {
  3725. using namespace detail;
  3726. #if !defined(DOCTEST_CONFIG_POSIX_SIGNALS) && !defined(DOCTEST_CONFIG_WINDOWS_SEH)
  3727. struct FatalConditionHandler
  3728. {
  3729. static void reset() {}
  3730. static void allocateAltStackMem() {}
  3731. static void freeAltStackMem() {}
  3732. };
  3733. #else // DOCTEST_CONFIG_POSIX_SIGNALS || DOCTEST_CONFIG_WINDOWS_SEH
  3734. void reportFatal(const std::string&);
  3735. #ifdef DOCTEST_PLATFORM_WINDOWS
  3736. struct SignalDefs
  3737. {
  3738. DWORD id;
  3739. const char* name;
  3740. };
  3741. // There is no 1-1 mapping between signals and windows exceptions.
  3742. // Windows can easily distinguish between SO and SigSegV,
  3743. // but SigInt, SigTerm, etc are handled differently.
  3744. SignalDefs signalDefs[] = {
  3745. {static_cast<DWORD>(EXCEPTION_ILLEGAL_INSTRUCTION),
  3746. "SIGILL - Illegal instruction signal"},
  3747. {static_cast<DWORD>(EXCEPTION_STACK_OVERFLOW), "SIGSEGV - Stack overflow"},
  3748. {static_cast<DWORD>(EXCEPTION_ACCESS_VIOLATION),
  3749. "SIGSEGV - Segmentation violation signal"},
  3750. {static_cast<DWORD>(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error"},
  3751. };
  3752. struct FatalConditionHandler
  3753. {
  3754. static LONG CALLBACK handleException(PEXCEPTION_POINTERS ExceptionInfo) {
  3755. // Multiple threads may enter this filter/handler at once. We want the error message to be printed on the
  3756. // console just once no matter how many threads have crashed.
  3757. static std::mutex mutex;
  3758. static bool execute = true;
  3759. {
  3760. std::lock_guard<std::mutex> lock(mutex);
  3761. if(execute) {
  3762. bool reported = false;
  3763. for(size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) {
  3764. if(ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) {
  3765. reportFatal(signalDefs[i].name);
  3766. reported = true;
  3767. break;
  3768. }
  3769. }
  3770. if(reported == false)
  3771. reportFatal("Unhandled SEH exception caught");
  3772. if(isDebuggerActive() && !g_cs->no_breaks)
  3773. DOCTEST_BREAK_INTO_DEBUGGER();
  3774. }
  3775. execute = false;
  3776. }
  3777. std::exit(EXIT_FAILURE);
  3778. }
  3779. static void allocateAltStackMem() {}
  3780. static void freeAltStackMem() {}
  3781. FatalConditionHandler() {
  3782. isSet = true;
  3783. // 32k seems enough for doctest to handle stack overflow,
  3784. // but the value was found experimentally, so there is no strong guarantee
  3785. guaranteeSize = 32 * 1024;
  3786. // Register an unhandled exception filter
  3787. previousTop = SetUnhandledExceptionFilter(handleException);
  3788. // Pass in guarantee size to be filled
  3789. SetThreadStackGuarantee(&guaranteeSize);
  3790. // On Windows uncaught exceptions from another thread, exceptions from
  3791. // destructors, or calls to std::terminate are not a SEH exception
  3792. // The terminal handler gets called when:
  3793. // - std::terminate is called FROM THE TEST RUNNER THREAD
  3794. // - an exception is thrown from a destructor FROM THE TEST RUNNER THREAD
  3795. original_terminate_handler = std::get_terminate();
  3796. std::set_terminate([]() DOCTEST_NOEXCEPT {
  3797. reportFatal("Terminate handler called");
  3798. if(isDebuggerActive() && !g_cs->no_breaks)
  3799. DOCTEST_BREAK_INTO_DEBUGGER();
  3800. std::exit(EXIT_FAILURE); // explicitly exit - otherwise the SIGABRT handler may be called as well
  3801. });
  3802. // SIGABRT is raised when:
  3803. // - std::terminate is called FROM A DIFFERENT THREAD
  3804. // - an exception is thrown from a destructor FROM A DIFFERENT THREAD
  3805. // - an uncaught exception is thrown FROM A DIFFERENT THREAD
  3806. prev_sigabrt_handler = std::signal(SIGABRT, [](int signal) DOCTEST_NOEXCEPT {
  3807. if(signal == SIGABRT) {
  3808. reportFatal("SIGABRT - Abort (abnormal termination) signal");
  3809. if(isDebuggerActive() && !g_cs->no_breaks)
  3810. DOCTEST_BREAK_INTO_DEBUGGER();
  3811. std::exit(EXIT_FAILURE);
  3812. }
  3813. });
  3814. // The following settings are taken from google test, and more
  3815. // specifically from UnitTest::Run() inside of gtest.cc
  3816. // the user does not want to see pop-up dialogs about crashes
  3817. prev_error_mode_1 = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT |
  3818. SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
  3819. // This forces the abort message to go to stderr in all circumstances.
  3820. prev_error_mode_2 = _set_error_mode(_OUT_TO_STDERR);
  3821. // In the debug version, Visual Studio pops up a separate dialog
  3822. // offering a choice to debug the aborted program - we want to disable that.
  3823. prev_abort_behavior = _set_abort_behavior(0x0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
  3824. // In debug mode, the Windows CRT can crash with an assertion over invalid
  3825. // input (e.g. passing an invalid file descriptor). The default handling
  3826. // for these assertions is to pop up a dialog and wait for user input.
  3827. // Instead ask the CRT to dump such assertions to stderr non-interactively.
  3828. prev_report_mode = _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
  3829. prev_report_file = _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
  3830. }
  3831. static void reset() {
  3832. if(isSet) {
  3833. // Unregister handler and restore the old guarantee
  3834. SetUnhandledExceptionFilter(previousTop);
  3835. SetThreadStackGuarantee(&guaranteeSize);
  3836. std::set_terminate(original_terminate_handler);
  3837. std::signal(SIGABRT, prev_sigabrt_handler);
  3838. SetErrorMode(prev_error_mode_1);
  3839. _set_error_mode(prev_error_mode_2);
  3840. _set_abort_behavior(prev_abort_behavior, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
  3841. static_cast<void>(_CrtSetReportMode(_CRT_ASSERT, prev_report_mode));
  3842. static_cast<void>(_CrtSetReportFile(_CRT_ASSERT, prev_report_file));
  3843. isSet = false;
  3844. }
  3845. }
  3846. ~FatalConditionHandler() { reset(); }
  3847. private:
  3848. static UINT prev_error_mode_1;
  3849. static int prev_error_mode_2;
  3850. static unsigned int prev_abort_behavior;
  3851. static int prev_report_mode;
  3852. static _HFILE prev_report_file;
  3853. static void (DOCTEST_CDECL *prev_sigabrt_handler)(int);
  3854. static std::terminate_handler original_terminate_handler;
  3855. static bool isSet;
  3856. static ULONG guaranteeSize;
  3857. static LPTOP_LEVEL_EXCEPTION_FILTER previousTop;
  3858. };
  3859. UINT FatalConditionHandler::prev_error_mode_1;
  3860. int FatalConditionHandler::prev_error_mode_2;
  3861. unsigned int FatalConditionHandler::prev_abort_behavior;
  3862. int FatalConditionHandler::prev_report_mode;
  3863. _HFILE FatalConditionHandler::prev_report_file;
  3864. void (DOCTEST_CDECL *FatalConditionHandler::prev_sigabrt_handler)(int);
  3865. std::terminate_handler FatalConditionHandler::original_terminate_handler;
  3866. bool FatalConditionHandler::isSet = false;
  3867. ULONG FatalConditionHandler::guaranteeSize = 0;
  3868. LPTOP_LEVEL_EXCEPTION_FILTER FatalConditionHandler::previousTop = nullptr;
  3869. #else // DOCTEST_PLATFORM_WINDOWS
  3870. struct SignalDefs
  3871. {
  3872. int id;
  3873. const char* name;
  3874. };
  3875. SignalDefs signalDefs[] = {{SIGINT, "SIGINT - Terminal interrupt signal"},
  3876. {SIGILL, "SIGILL - Illegal instruction signal"},
  3877. {SIGFPE, "SIGFPE - Floating point error signal"},
  3878. {SIGSEGV, "SIGSEGV - Segmentation violation signal"},
  3879. {SIGTERM, "SIGTERM - Termination request signal"},
  3880. {SIGABRT, "SIGABRT - Abort (abnormal termination) signal"}};
  3881. struct FatalConditionHandler
  3882. {
  3883. static bool isSet;
  3884. static struct sigaction oldSigActions[DOCTEST_COUNTOF(signalDefs)];
  3885. static stack_t oldSigStack;
  3886. static size_t altStackSize;
  3887. static char* altStackMem;
  3888. static void handleSignal(int sig) {
  3889. const char* name = "<unknown signal>";
  3890. for(std::size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) {
  3891. SignalDefs& def = signalDefs[i];
  3892. if(sig == def.id) {
  3893. name = def.name;
  3894. break;
  3895. }
  3896. }
  3897. reset();
  3898. reportFatal(name);
  3899. raise(sig);
  3900. }
  3901. static void allocateAltStackMem() {
  3902. altStackMem = new char[altStackSize];
  3903. }
  3904. static void freeAltStackMem() {
  3905. delete[] altStackMem;
  3906. }
  3907. FatalConditionHandler() {
  3908. isSet = true;
  3909. stack_t sigStack;
  3910. sigStack.ss_sp = altStackMem;
  3911. sigStack.ss_size = altStackSize;
  3912. sigStack.ss_flags = 0;
  3913. sigaltstack(&sigStack, &oldSigStack);
  3914. struct sigaction sa = {};
  3915. sa.sa_handler = handleSignal; // NOLINT
  3916. sa.sa_flags = SA_ONSTACK;
  3917. for(std::size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) {
  3918. sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
  3919. }
  3920. }
  3921. ~FatalConditionHandler() { reset(); }
  3922. static void reset() {
  3923. if(isSet) {
  3924. // Set signals back to previous values -- hopefully nobody overwrote them in the meantime
  3925. for(std::size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) {
  3926. sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
  3927. }
  3928. // Return the old stack
  3929. sigaltstack(&oldSigStack, nullptr);
  3930. isSet = false;
  3931. }
  3932. }
  3933. };
  3934. bool FatalConditionHandler::isSet = false;
  3935. struct sigaction FatalConditionHandler::oldSigActions[DOCTEST_COUNTOF(signalDefs)] = {};
  3936. stack_t FatalConditionHandler::oldSigStack = {};
  3937. size_t FatalConditionHandler::altStackSize = 4 * SIGSTKSZ;
  3938. char* FatalConditionHandler::altStackMem = nullptr;
  3939. #endif // DOCTEST_PLATFORM_WINDOWS
  3940. #endif // DOCTEST_CONFIG_POSIX_SIGNALS || DOCTEST_CONFIG_WINDOWS_SEH
  3941. } // namespace
  3942. namespace {
  3943. using namespace detail;
  3944. #ifdef DOCTEST_PLATFORM_WINDOWS
  3945. #define DOCTEST_OUTPUT_DEBUG_STRING(text) ::OutputDebugStringA(text)
  3946. #else
  3947. // TODO: integration with XCode and other IDEs
  3948. #define DOCTEST_OUTPUT_DEBUG_STRING(text) // NOLINT(clang-diagnostic-unused-macros)
  3949. #endif // Platform
  3950. void addAssert(assertType::Enum at) {
  3951. if((at & assertType::is_warn) == 0) //!OCLINT bitwise operator in conditional
  3952. g_cs->numAssertsCurrentTest_atomic++;
  3953. }
  3954. void addFailedAssert(assertType::Enum at) {
  3955. if((at & assertType::is_warn) == 0) //!OCLINT bitwise operator in conditional
  3956. g_cs->numAssertsFailedCurrentTest_atomic++;
  3957. }
  3958. #if defined(DOCTEST_CONFIG_POSIX_SIGNALS) || defined(DOCTEST_CONFIG_WINDOWS_SEH)
  3959. void reportFatal(const std::string& message) {
  3960. g_cs->failure_flags |= TestCaseFailureReason::Crash;
  3961. DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_exception, {message.c_str(), true});
  3962. while(g_cs->subcasesStack.size()) {
  3963. g_cs->subcasesStack.pop_back();
  3964. DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_end, DOCTEST_EMPTY);
  3965. }
  3966. g_cs->finalizeTestCaseData();
  3967. DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_end, *g_cs);
  3968. DOCTEST_ITERATE_THROUGH_REPORTERS(test_run_end, *g_cs);
  3969. }
  3970. #endif // DOCTEST_CONFIG_POSIX_SIGNALS || DOCTEST_CONFIG_WINDOWS_SEH
  3971. } // namespace
  3972. namespace detail {
  3973. ResultBuilder::ResultBuilder(assertType::Enum at, const char* file, int line, const char* expr,
  3974. const char* exception_type, const char* exception_string) {
  3975. m_test_case = g_cs->currentTest;
  3976. m_at = at;
  3977. m_file = file;
  3978. m_line = line;
  3979. m_expr = expr;
  3980. m_failed = true;
  3981. m_threw = false;
  3982. m_threw_as = false;
  3983. m_exception_type = exception_type;
  3984. m_exception_string = exception_string;
  3985. #if DOCTEST_MSVC
  3986. if(m_expr[0] == ' ') // this happens when variadic macros are disabled under MSVC
  3987. ++m_expr;
  3988. #endif // MSVC
  3989. }
  3990. void ResultBuilder::setResult(const Result& res) {
  3991. m_decomp = res.m_decomp;
  3992. m_failed = !res.m_passed;
  3993. }
  3994. void ResultBuilder::translateException() {
  3995. m_threw = true;
  3996. m_exception = translateActiveException();
  3997. }
  3998. bool ResultBuilder::log() {
  3999. if(m_at & assertType::is_throws) { //!OCLINT bitwise operator in conditional
  4000. m_failed = !m_threw;
  4001. } else if((m_at & assertType::is_throws_as) && (m_at & assertType::is_throws_with)) { //!OCLINT
  4002. m_failed = !m_threw_as || (m_exception != m_exception_string);
  4003. } else if(m_at & assertType::is_throws_as) { //!OCLINT bitwise operator in conditional
  4004. m_failed = !m_threw_as;
  4005. } else if(m_at & assertType::is_throws_with) { //!OCLINT bitwise operator in conditional
  4006. m_failed = m_exception != m_exception_string;
  4007. } else if(m_at & assertType::is_nothrow) { //!OCLINT bitwise operator in conditional
  4008. m_failed = m_threw;
  4009. }
  4010. if(m_exception.size())
  4011. m_exception = "\"" + m_exception + "\"";
  4012. if(is_running_in_test) {
  4013. addAssert(m_at);
  4014. DOCTEST_ITERATE_THROUGH_REPORTERS(log_assert, *this);
  4015. if(m_failed)
  4016. addFailedAssert(m_at);
  4017. } else if(m_failed) {
  4018. failed_out_of_a_testing_context(*this);
  4019. }
  4020. return m_failed && isDebuggerActive() && !getContextOptions()->no_breaks &&
  4021. (g_cs->currentTest == nullptr || !g_cs->currentTest->m_no_breaks); // break into debugger
  4022. }
  4023. void ResultBuilder::react() const {
  4024. if(m_failed && checkIfShouldThrow(m_at))
  4025. throwException();
  4026. }
  4027. void failed_out_of_a_testing_context(const AssertData& ad) {
  4028. if(g_cs->ah)
  4029. g_cs->ah(ad);
  4030. else
  4031. std::abort();
  4032. }
  4033. bool decomp_assert(assertType::Enum at, const char* file, int line, const char* expr,
  4034. Result result) {
  4035. bool failed = !result.m_passed;
  4036. // ###################################################################################
  4037. // IF THE DEBUGGER BREAKS HERE - GO 1 LEVEL UP IN THE CALLSTACK FOR THE FAILING ASSERT
  4038. // THIS IS THE EFFECT OF HAVING 'DOCTEST_CONFIG_SUPER_FAST_ASSERTS' DEFINED
  4039. // ###################################################################################
  4040. DOCTEST_ASSERT_OUT_OF_TESTS(result.m_decomp);
  4041. DOCTEST_ASSERT_IN_TESTS(result.m_decomp);
  4042. // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
  4043. return !failed;
  4044. }
  4045. MessageBuilder::MessageBuilder(const char* file, int line, assertType::Enum severity) {
  4046. m_stream = tlssPush();
  4047. m_file = file;
  4048. m_line = line;
  4049. m_severity = severity;
  4050. }
  4051. MessageBuilder::~MessageBuilder() {
  4052. if (!logged)
  4053. tlssPop();
  4054. }
  4055. IExceptionTranslator::IExceptionTranslator() = default;
  4056. IExceptionTranslator::~IExceptionTranslator() = default;
  4057. bool MessageBuilder::log() {
  4058. if (!logged) {
  4059. m_string = tlssPop();
  4060. logged = true;
  4061. }
  4062. DOCTEST_ITERATE_THROUGH_REPORTERS(log_message, *this);
  4063. const bool isWarn = m_severity & assertType::is_warn;
  4064. // warn is just a message in this context so we don't treat it as an assert
  4065. if(!isWarn) {
  4066. addAssert(m_severity);
  4067. addFailedAssert(m_severity);
  4068. }
  4069. return isDebuggerActive() && !getContextOptions()->no_breaks && !isWarn &&
  4070. (g_cs->currentTest == nullptr || !g_cs->currentTest->m_no_breaks); // break into debugger
  4071. }
  4072. void MessageBuilder::react() {
  4073. if(m_severity & assertType::is_require) //!OCLINT bitwise operator in conditional
  4074. throwException();
  4075. }
  4076. } // namespace detail
  4077. namespace {
  4078. using namespace detail;
  4079. // clang-format off
  4080. // =================================================================================================
  4081. // The following code has been taken verbatim from Catch2/include/internal/catch_xmlwriter.h/cpp
  4082. // This is done so cherry-picking bug fixes is trivial - even the style/formatting is untouched.
  4083. // =================================================================================================
  4084. class XmlEncode {
  4085. public:
  4086. enum ForWhat { ForTextNodes, ForAttributes };
  4087. XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes );
  4088. void encodeTo( std::ostream& os ) const;
  4089. friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode );
  4090. private:
  4091. std::string m_str;
  4092. ForWhat m_forWhat;
  4093. };
  4094. class XmlWriter {
  4095. public:
  4096. class ScopedElement {
  4097. public:
  4098. ScopedElement( XmlWriter* writer );
  4099. ScopedElement( ScopedElement&& other ) DOCTEST_NOEXCEPT;
  4100. ScopedElement& operator=( ScopedElement&& other ) DOCTEST_NOEXCEPT;
  4101. ~ScopedElement();
  4102. ScopedElement& writeText( std::string const& text, bool indent = true );
  4103. template<typename T>
  4104. ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
  4105. m_writer->writeAttribute( name, attribute );
  4106. return *this;
  4107. }
  4108. private:
  4109. mutable XmlWriter* m_writer = nullptr;
  4110. };
  4111. XmlWriter( std::ostream& os = std::cout );
  4112. ~XmlWriter();
  4113. XmlWriter( XmlWriter const& ) = delete;
  4114. XmlWriter& operator=( XmlWriter const& ) = delete;
  4115. XmlWriter& startElement( std::string const& name );
  4116. ScopedElement scopedElement( std::string const& name );
  4117. XmlWriter& endElement();
  4118. XmlWriter& writeAttribute( std::string const& name, std::string const& attribute );
  4119. XmlWriter& writeAttribute( std::string const& name, const char* attribute );
  4120. XmlWriter& writeAttribute( std::string const& name, bool attribute );
  4121. template<typename T>
  4122. XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
  4123. std::stringstream rss;
  4124. rss << attribute;
  4125. return writeAttribute( name, rss.str() );
  4126. }
  4127. XmlWriter& writeText( std::string const& text, bool indent = true );
  4128. //XmlWriter& writeComment( std::string const& text );
  4129. //void writeStylesheetRef( std::string const& url );
  4130. //XmlWriter& writeBlankLine();
  4131. void ensureTagClosed();
  4132. private:
  4133. void writeDeclaration();
  4134. void newlineIfNecessary();
  4135. bool m_tagIsOpen = false;
  4136. bool m_needsNewline = false;
  4137. std::vector<std::string> m_tags;
  4138. std::string m_indent;
  4139. std::ostream& m_os;
  4140. };
  4141. // =================================================================================================
  4142. // The following code has been taken verbatim from Catch2/include/internal/catch_xmlwriter.h/cpp
  4143. // This is done so cherry-picking bug fixes is trivial - even the style/formatting is untouched.
  4144. // =================================================================================================
  4145. using uchar = unsigned char;
  4146. namespace {
  4147. size_t trailingBytes(unsigned char c) {
  4148. if ((c & 0xE0) == 0xC0) {
  4149. return 2;
  4150. }
  4151. if ((c & 0xF0) == 0xE0) {
  4152. return 3;
  4153. }
  4154. if ((c & 0xF8) == 0xF0) {
  4155. return 4;
  4156. }
  4157. DOCTEST_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
  4158. }
  4159. uint32_t headerValue(unsigned char c) {
  4160. if ((c & 0xE0) == 0xC0) {
  4161. return c & 0x1F;
  4162. }
  4163. if ((c & 0xF0) == 0xE0) {
  4164. return c & 0x0F;
  4165. }
  4166. if ((c & 0xF8) == 0xF0) {
  4167. return c & 0x07;
  4168. }
  4169. DOCTEST_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
  4170. }
  4171. void hexEscapeChar(std::ostream& os, unsigned char c) {
  4172. std::ios_base::fmtflags f(os.flags());
  4173. os << "\\x"
  4174. << std::uppercase << std::hex << std::setfill('0') << std::setw(2)
  4175. << static_cast<int>(c);
  4176. os.flags(f);
  4177. }
  4178. } // anonymous namespace
  4179. XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat )
  4180. : m_str( str ),
  4181. m_forWhat( forWhat )
  4182. {}
  4183. void XmlEncode::encodeTo( std::ostream& os ) const {
  4184. // Apostrophe escaping not necessary if we always use " to write attributes
  4185. // (see: https://www.w3.org/TR/xml/#syntax)
  4186. for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) {
  4187. uchar c = m_str[idx];
  4188. switch (c) {
  4189. case '<': os << "&lt;"; break;
  4190. case '&': os << "&amp;"; break;
  4191. case '>':
  4192. // See: https://www.w3.org/TR/xml/#syntax
  4193. if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']')
  4194. os << "&gt;";
  4195. else
  4196. os << c;
  4197. break;
  4198. case '\"':
  4199. if (m_forWhat == ForAttributes)
  4200. os << "&quot;";
  4201. else
  4202. os << c;
  4203. break;
  4204. default:
  4205. // Check for control characters and invalid utf-8
  4206. // Escape control characters in standard ascii
  4207. // see https://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
  4208. if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {
  4209. hexEscapeChar(os, c);
  4210. break;
  4211. }
  4212. // Plain ASCII: Write it to stream
  4213. if (c < 0x7F) {
  4214. os << c;
  4215. break;
  4216. }
  4217. // UTF-8 territory
  4218. // Check if the encoding is valid and if it is not, hex escape bytes.
  4219. // Important: We do not check the exact decoded values for validity, only the encoding format
  4220. // First check that this bytes is a valid lead byte:
  4221. // This means that it is not encoded as 1111 1XXX
  4222. // Or as 10XX XXXX
  4223. if (c < 0xC0 ||
  4224. c >= 0xF8) {
  4225. hexEscapeChar(os, c);
  4226. break;
  4227. }
  4228. auto encBytes = trailingBytes(c);
  4229. // Are there enough bytes left to avoid accessing out-of-bounds memory?
  4230. if (idx + encBytes - 1 >= m_str.size()) {
  4231. hexEscapeChar(os, c);
  4232. break;
  4233. }
  4234. // The header is valid, check data
  4235. // The next encBytes bytes must together be a valid utf-8
  4236. // This means: bitpattern 10XX XXXX and the extracted value is sane (ish)
  4237. bool valid = true;
  4238. uint32_t value = headerValue(c);
  4239. for (std::size_t n = 1; n < encBytes; ++n) {
  4240. uchar nc = m_str[idx + n];
  4241. valid &= ((nc & 0xC0) == 0x80);
  4242. value = (value << 6) | (nc & 0x3F);
  4243. }
  4244. if (
  4245. // Wrong bit pattern of following bytes
  4246. (!valid) ||
  4247. // Overlong encodings
  4248. (value < 0x80) ||
  4249. ( value < 0x800 && encBytes > 2) || // removed "0x80 <= value &&" because redundant
  4250. (0x800 < value && value < 0x10000 && encBytes > 3) ||
  4251. // Encoded value out of range
  4252. (value >= 0x110000)
  4253. ) {
  4254. hexEscapeChar(os, c);
  4255. break;
  4256. }
  4257. // If we got here, this is in fact a valid(ish) utf-8 sequence
  4258. for (std::size_t n = 0; n < encBytes; ++n) {
  4259. os << m_str[idx + n];
  4260. }
  4261. idx += encBytes - 1;
  4262. break;
  4263. }
  4264. }
  4265. }
  4266. std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
  4267. xmlEncode.encodeTo( os );
  4268. return os;
  4269. }
  4270. XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer )
  4271. : m_writer( writer )
  4272. {}
  4273. XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) DOCTEST_NOEXCEPT
  4274. : m_writer( other.m_writer ){
  4275. other.m_writer = nullptr;
  4276. }
  4277. XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) DOCTEST_NOEXCEPT {
  4278. if ( m_writer ) {
  4279. m_writer->endElement();
  4280. }
  4281. m_writer = other.m_writer;
  4282. other.m_writer = nullptr;
  4283. return *this;
  4284. }
  4285. XmlWriter::ScopedElement::~ScopedElement() {
  4286. if( m_writer )
  4287. m_writer->endElement();
  4288. }
  4289. XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, bool indent ) {
  4290. m_writer->writeText( text, indent );
  4291. return *this;
  4292. }
  4293. XmlWriter::XmlWriter( std::ostream& os ) : m_os( os )
  4294. {
  4295. writeDeclaration();
  4296. }
  4297. XmlWriter::~XmlWriter() {
  4298. while( !m_tags.empty() )
  4299. endElement();
  4300. }
  4301. XmlWriter& XmlWriter::startElement( std::string const& name ) {
  4302. ensureTagClosed();
  4303. newlineIfNecessary();
  4304. m_os << m_indent << '<' << name;
  4305. m_tags.push_back( name );
  4306. m_indent += " ";
  4307. m_tagIsOpen = true;
  4308. return *this;
  4309. }
  4310. XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name ) {
  4311. ScopedElement scoped( this );
  4312. startElement( name );
  4313. return scoped;
  4314. }
  4315. XmlWriter& XmlWriter::endElement() {
  4316. newlineIfNecessary();
  4317. m_indent = m_indent.substr( 0, m_indent.size()-2 );
  4318. if( m_tagIsOpen ) {
  4319. m_os << "/>";
  4320. m_tagIsOpen = false;
  4321. }
  4322. else {
  4323. m_os << m_indent << "</" << m_tags.back() << ">";
  4324. }
  4325. m_os << std::endl;
  4326. m_tags.pop_back();
  4327. return *this;
  4328. }
  4329. XmlWriter& XmlWriter::writeAttribute( std::string const& name, std::string const& attribute ) {
  4330. if( !name.empty() && !attribute.empty() )
  4331. m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"';
  4332. return *this;
  4333. }
  4334. XmlWriter& XmlWriter::writeAttribute( std::string const& name, const char* attribute ) {
  4335. if( !name.empty() && attribute && attribute[0] != '\0' )
  4336. m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"';
  4337. return *this;
  4338. }
  4339. XmlWriter& XmlWriter::writeAttribute( std::string const& name, bool attribute ) {
  4340. m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"';
  4341. return *this;
  4342. }
  4343. XmlWriter& XmlWriter::writeText( std::string const& text, bool indent ) {
  4344. if( !text.empty() ){
  4345. bool tagWasOpen = m_tagIsOpen;
  4346. ensureTagClosed();
  4347. if( tagWasOpen && indent )
  4348. m_os << m_indent;
  4349. m_os << XmlEncode( text );
  4350. m_needsNewline = true;
  4351. }
  4352. return *this;
  4353. }
  4354. //XmlWriter& XmlWriter::writeComment( std::string const& text ) {
  4355. // ensureTagClosed();
  4356. // m_os << m_indent << "<!--" << text << "-->";
  4357. // m_needsNewline = true;
  4358. // return *this;
  4359. //}
  4360. //void XmlWriter::writeStylesheetRef( std::string const& url ) {
  4361. // m_os << "<?xml-stylesheet type=\"text/xsl\" href=\"" << url << "\"?>\n";
  4362. //}
  4363. //XmlWriter& XmlWriter::writeBlankLine() {
  4364. // ensureTagClosed();
  4365. // m_os << '\n';
  4366. // return *this;
  4367. //}
  4368. void XmlWriter::ensureTagClosed() {
  4369. if( m_tagIsOpen ) {
  4370. m_os << ">" << std::endl;
  4371. m_tagIsOpen = false;
  4372. }
  4373. }
  4374. void XmlWriter::writeDeclaration() {
  4375. m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
  4376. }
  4377. void XmlWriter::newlineIfNecessary() {
  4378. if( m_needsNewline ) {
  4379. m_os << std::endl;
  4380. m_needsNewline = false;
  4381. }
  4382. }
  4383. // =================================================================================================
  4384. // End of copy-pasted code from Catch
  4385. // =================================================================================================
  4386. // clang-format on
  4387. struct XmlReporter : public IReporter
  4388. {
  4389. XmlWriter xml;
  4390. std::mutex mutex;
  4391. // caching pointers/references to objects of these types - safe to do
  4392. const ContextOptions& opt;
  4393. const TestCaseData* tc = nullptr;
  4394. XmlReporter(const ContextOptions& co)
  4395. : xml(*co.cout)
  4396. , opt(co) {}
  4397. void log_contexts() {
  4398. int num_contexts = get_num_active_contexts();
  4399. if(num_contexts) {
  4400. auto contexts = get_active_contexts();
  4401. std::stringstream ss;
  4402. for(int i = 0; i < num_contexts; ++i) {
  4403. contexts[i]->stringify(&ss);
  4404. xml.scopedElement("Info").writeText(ss.str());
  4405. ss.str("");
  4406. }
  4407. }
  4408. }
  4409. unsigned line(unsigned l) const { return opt.no_line_numbers ? 0 : l; }
  4410. void test_case_start_impl(const TestCaseData& in) {
  4411. bool open_ts_tag = false;
  4412. if(tc != nullptr) { // we have already opened a test suite
  4413. if(std::strcmp(tc->m_test_suite, in.m_test_suite) != 0) {
  4414. xml.endElement();
  4415. open_ts_tag = true;
  4416. }
  4417. }
  4418. else {
  4419. open_ts_tag = true; // first test case ==> first test suite
  4420. }
  4421. if(open_ts_tag) {
  4422. xml.startElement("TestSuite");
  4423. xml.writeAttribute("name", in.m_test_suite);
  4424. }
  4425. tc = &in;
  4426. xml.startElement("TestCase")
  4427. .writeAttribute("name", in.m_name)
  4428. .writeAttribute("filename", skipPathFromFilename(in.m_file.c_str()))
  4429. .writeAttribute("line", line(in.m_line))
  4430. .writeAttribute("description", in.m_description);
  4431. if(Approx(in.m_timeout) != 0)
  4432. xml.writeAttribute("timeout", in.m_timeout);
  4433. if(in.m_may_fail)
  4434. xml.writeAttribute("may_fail", true);
  4435. if(in.m_should_fail)
  4436. xml.writeAttribute("should_fail", true);
  4437. }
  4438. // =========================================================================================
  4439. // WHAT FOLLOWS ARE OVERRIDES OF THE VIRTUAL METHODS OF THE REPORTER INTERFACE
  4440. // =========================================================================================
  4441. void report_query(const QueryData& in) override {
  4442. test_run_start();
  4443. if(opt.list_reporters) {
  4444. for(auto& curr : getListeners())
  4445. xml.scopedElement("Listener")
  4446. .writeAttribute("priority", curr.first.first)
  4447. .writeAttribute("name", curr.first.second);
  4448. for(auto& curr : getReporters())
  4449. xml.scopedElement("Reporter")
  4450. .writeAttribute("priority", curr.first.first)
  4451. .writeAttribute("name", curr.first.second);
  4452. } else if(opt.count || opt.list_test_cases) {
  4453. for(unsigned i = 0; i < in.num_data; ++i) {
  4454. xml.scopedElement("TestCase").writeAttribute("name", in.data[i]->m_name)
  4455. .writeAttribute("testsuite", in.data[i]->m_test_suite)
  4456. .writeAttribute("filename", skipPathFromFilename(in.data[i]->m_file.c_str()))
  4457. .writeAttribute("line", line(in.data[i]->m_line))
  4458. .writeAttribute("skipped", in.data[i]->m_skip);
  4459. }
  4460. xml.scopedElement("OverallResultsTestCases")
  4461. .writeAttribute("unskipped", in.run_stats->numTestCasesPassingFilters);
  4462. } else if(opt.list_test_suites) {
  4463. for(unsigned i = 0; i < in.num_data; ++i)
  4464. xml.scopedElement("TestSuite").writeAttribute("name", in.data[i]->m_test_suite);
  4465. xml.scopedElement("OverallResultsTestCases")
  4466. .writeAttribute("unskipped", in.run_stats->numTestCasesPassingFilters);
  4467. xml.scopedElement("OverallResultsTestSuites")
  4468. .writeAttribute("unskipped", in.run_stats->numTestSuitesPassingFilters);
  4469. }
  4470. xml.endElement();
  4471. }
  4472. void test_run_start() override {
  4473. // remove .exe extension - mainly to have the same output on UNIX and Windows
  4474. std::string binary_name = skipPathFromFilename(opt.binary_name.c_str());
  4475. #ifdef DOCTEST_PLATFORM_WINDOWS
  4476. if(binary_name.rfind(".exe") != std::string::npos)
  4477. binary_name = binary_name.substr(0, binary_name.length() - 4);
  4478. #endif // DOCTEST_PLATFORM_WINDOWS
  4479. xml.startElement("doctest").writeAttribute("binary", binary_name);
  4480. if(opt.no_version == false)
  4481. xml.writeAttribute("version", DOCTEST_VERSION_STR);
  4482. // only the consequential ones (TODO: filters)
  4483. xml.scopedElement("Options")
  4484. .writeAttribute("order_by", opt.order_by.c_str())
  4485. .writeAttribute("rand_seed", opt.rand_seed)
  4486. .writeAttribute("first", opt.first)
  4487. .writeAttribute("last", opt.last)
  4488. .writeAttribute("abort_after", opt.abort_after)
  4489. .writeAttribute("subcase_filter_levels", opt.subcase_filter_levels)
  4490. .writeAttribute("case_sensitive", opt.case_sensitive)
  4491. .writeAttribute("no_throw", opt.no_throw)
  4492. .writeAttribute("no_skip", opt.no_skip);
  4493. }
  4494. void test_run_end(const TestRunStats& p) override {
  4495. if(tc) // the TestSuite tag - only if there has been at least 1 test case
  4496. xml.endElement();
  4497. xml.scopedElement("OverallResultsAsserts")
  4498. .writeAttribute("successes", p.numAsserts - p.numAssertsFailed)
  4499. .writeAttribute("failures", p.numAssertsFailed);
  4500. xml.startElement("OverallResultsTestCases")
  4501. .writeAttribute("successes",
  4502. p.numTestCasesPassingFilters - p.numTestCasesFailed)
  4503. .writeAttribute("failures", p.numTestCasesFailed);
  4504. if(opt.no_skipped_summary == false)
  4505. xml.writeAttribute("skipped", p.numTestCases - p.numTestCasesPassingFilters);
  4506. xml.endElement();
  4507. xml.endElement();
  4508. }
  4509. void test_case_start(const TestCaseData& in) override {
  4510. test_case_start_impl(in);
  4511. xml.ensureTagClosed();
  4512. }
  4513. void test_case_reenter(const TestCaseData&) override {}
  4514. void test_case_end(const CurrentTestCaseStats& st) override {
  4515. xml.startElement("OverallResultsAsserts")
  4516. .writeAttribute("successes",
  4517. st.numAssertsCurrentTest - st.numAssertsFailedCurrentTest)
  4518. .writeAttribute("failures", st.numAssertsFailedCurrentTest)
  4519. .writeAttribute("test_case_success", st.testCaseSuccess);
  4520. if(opt.duration)
  4521. xml.writeAttribute("duration", st.seconds);
  4522. if(tc->m_expected_failures)
  4523. xml.writeAttribute("expected_failures", tc->m_expected_failures);
  4524. xml.endElement();
  4525. xml.endElement();
  4526. }
  4527. void test_case_exception(const TestCaseException& e) override {
  4528. std::lock_guard<std::mutex> lock(mutex);
  4529. xml.scopedElement("Exception")
  4530. .writeAttribute("crash", e.is_crash)
  4531. .writeText(e.error_string.c_str());
  4532. }
  4533. void subcase_start(const SubcaseSignature& in) override {
  4534. xml.startElement("SubCase")
  4535. .writeAttribute("name", in.m_name)
  4536. .writeAttribute("filename", skipPathFromFilename(in.m_file))
  4537. .writeAttribute("line", line(in.m_line));
  4538. xml.ensureTagClosed();
  4539. }
  4540. void subcase_end() override { xml.endElement(); }
  4541. void log_assert(const AssertData& rb) override {
  4542. if(!rb.m_failed && !opt.success)
  4543. return;
  4544. std::lock_guard<std::mutex> lock(mutex);
  4545. xml.startElement("Expression")
  4546. .writeAttribute("success", !rb.m_failed)
  4547. .writeAttribute("type", assertString(rb.m_at))
  4548. .writeAttribute("filename", skipPathFromFilename(rb.m_file))
  4549. .writeAttribute("line", line(rb.m_line));
  4550. xml.scopedElement("Original").writeText(rb.m_expr);
  4551. if(rb.m_threw)
  4552. xml.scopedElement("Exception").writeText(rb.m_exception.c_str());
  4553. if(rb.m_at & assertType::is_throws_as)
  4554. xml.scopedElement("ExpectedException").writeText(rb.m_exception_type);
  4555. if(rb.m_at & assertType::is_throws_with)
  4556. xml.scopedElement("ExpectedExceptionString").writeText(rb.m_exception_string);
  4557. if((rb.m_at & assertType::is_normal) && !rb.m_threw)
  4558. xml.scopedElement("Expanded").writeText(rb.m_decomp.c_str());
  4559. log_contexts();
  4560. xml.endElement();
  4561. }
  4562. void log_message(const MessageData& mb) override {
  4563. std::lock_guard<std::mutex> lock(mutex);
  4564. xml.startElement("Message")
  4565. .writeAttribute("type", failureString(mb.m_severity))
  4566. .writeAttribute("filename", skipPathFromFilename(mb.m_file))
  4567. .writeAttribute("line", line(mb.m_line));
  4568. xml.scopedElement("Text").writeText(mb.m_string.c_str());
  4569. log_contexts();
  4570. xml.endElement();
  4571. }
  4572. void test_case_skipped(const TestCaseData& in) override {
  4573. if(opt.no_skipped_summary == false) {
  4574. test_case_start_impl(in);
  4575. xml.writeAttribute("skipped", "true");
  4576. xml.endElement();
  4577. }
  4578. }
  4579. };
  4580. DOCTEST_REGISTER_REPORTER("xml", 0, XmlReporter);
  4581. void fulltext_log_assert_to_stream(std::ostream& s, const AssertData& rb) {
  4582. if((rb.m_at & (assertType::is_throws_as | assertType::is_throws_with)) ==
  4583. 0) //!OCLINT bitwise operator in conditional
  4584. s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << " ) "
  4585. << Color::None;
  4586. if(rb.m_at & assertType::is_throws) { //!OCLINT bitwise operator in conditional
  4587. s << (rb.m_threw ? "threw as expected!" : "did NOT throw at all!") << "\n";
  4588. } else if((rb.m_at & assertType::is_throws_as) &&
  4589. (rb.m_at & assertType::is_throws_with)) { //!OCLINT
  4590. s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << ", \""
  4591. << rb.m_exception_string << "\", " << rb.m_exception_type << " ) " << Color::None;
  4592. if(rb.m_threw) {
  4593. if(!rb.m_failed) {
  4594. s << "threw as expected!\n";
  4595. } else {
  4596. s << "threw a DIFFERENT exception! (contents: " << rb.m_exception << ")\n";
  4597. }
  4598. } else {
  4599. s << "did NOT throw at all!\n";
  4600. }
  4601. } else if(rb.m_at &
  4602. assertType::is_throws_as) { //!OCLINT bitwise operator in conditional
  4603. s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << ", "
  4604. << rb.m_exception_type << " ) " << Color::None
  4605. << (rb.m_threw ? (rb.m_threw_as ? "threw as expected!" :
  4606. "threw a DIFFERENT exception: ") :
  4607. "did NOT throw at all!")
  4608. << Color::Cyan << rb.m_exception << "\n";
  4609. } else if(rb.m_at &
  4610. assertType::is_throws_with) { //!OCLINT bitwise operator in conditional
  4611. s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << ", \""
  4612. << rb.m_exception_string << "\" ) " << Color::None
  4613. << (rb.m_threw ? (!rb.m_failed ? "threw as expected!" :
  4614. "threw a DIFFERENT exception: ") :
  4615. "did NOT throw at all!")
  4616. << Color::Cyan << rb.m_exception << "\n";
  4617. } else if(rb.m_at & assertType::is_nothrow) { //!OCLINT bitwise operator in conditional
  4618. s << (rb.m_threw ? "THREW exception: " : "didn't throw!") << Color::Cyan
  4619. << rb.m_exception << "\n";
  4620. } else {
  4621. s << (rb.m_threw ? "THREW exception: " :
  4622. (!rb.m_failed ? "is correct!\n" : "is NOT correct!\n"));
  4623. if(rb.m_threw)
  4624. s << rb.m_exception << "\n";
  4625. else
  4626. s << " values: " << assertString(rb.m_at) << "( " << rb.m_decomp << " )\n";
  4627. }
  4628. }
  4629. // TODO:
  4630. // - log_message()
  4631. // - respond to queries
  4632. // - honor remaining options
  4633. // - more attributes in tags
  4634. struct JUnitReporter : public IReporter
  4635. {
  4636. XmlWriter xml;
  4637. std::mutex mutex;
  4638. Timer timer;
  4639. std::vector<String> deepestSubcaseStackNames;
  4640. struct JUnitTestCaseData
  4641. {
  4642. static std::string getCurrentTimestamp() {
  4643. // Beware, this is not reentrant because of backward compatibility issues
  4644. // Also, UTC only, again because of backward compatibility (%z is C++11)
  4645. time_t rawtime;
  4646. std::time(&rawtime);
  4647. auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
  4648. std::tm timeInfo;
  4649. #ifdef DOCTEST_PLATFORM_WINDOWS
  4650. gmtime_s(&timeInfo, &rawtime);
  4651. #else // DOCTEST_PLATFORM_WINDOWS
  4652. gmtime_r(&rawtime, &timeInfo);
  4653. #endif // DOCTEST_PLATFORM_WINDOWS
  4654. char timeStamp[timeStampSize];
  4655. const char* const fmt = "%Y-%m-%dT%H:%M:%SZ";
  4656. std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
  4657. return std::string(timeStamp);
  4658. }
  4659. struct JUnitTestMessage
  4660. {
  4661. JUnitTestMessage(const std::string& _message, const std::string& _type, const std::string& _details)
  4662. : message(_message), type(_type), details(_details) {}
  4663. JUnitTestMessage(const std::string& _message, const std::string& _details)
  4664. : message(_message), type(), details(_details) {}
  4665. std::string message, type, details;
  4666. };
  4667. struct JUnitTestCase
  4668. {
  4669. JUnitTestCase(const std::string& _classname, const std::string& _name)
  4670. : classname(_classname), name(_name), time(0), failures() {}
  4671. std::string classname, name;
  4672. double time;
  4673. std::vector<JUnitTestMessage> failures, errors;
  4674. };
  4675. void add(const std::string& classname, const std::string& name) {
  4676. testcases.emplace_back(classname, name);
  4677. }
  4678. void appendSubcaseNamesToLastTestcase(std::vector<String> nameStack) {
  4679. for(auto& curr: nameStack)
  4680. if(curr.size())
  4681. testcases.back().name += std::string("/") + curr.c_str();
  4682. }
  4683. void addTime(double time) {
  4684. if(time < 1e-4)
  4685. time = 0;
  4686. testcases.back().time = time;
  4687. totalSeconds += time;
  4688. }
  4689. void addFailure(const std::string& message, const std::string& type, const std::string& details) {
  4690. testcases.back().failures.emplace_back(message, type, details);
  4691. ++totalFailures;
  4692. }
  4693. void addError(const std::string& message, const std::string& details) {
  4694. testcases.back().errors.emplace_back(message, details);
  4695. ++totalErrors;
  4696. }
  4697. std::vector<JUnitTestCase> testcases;
  4698. double totalSeconds = 0;
  4699. int totalErrors = 0, totalFailures = 0;
  4700. };
  4701. JUnitTestCaseData testCaseData;
  4702. // caching pointers/references to objects of these types - safe to do
  4703. const ContextOptions& opt;
  4704. const TestCaseData* tc = nullptr;
  4705. JUnitReporter(const ContextOptions& co)
  4706. : xml(*co.cout)
  4707. , opt(co) {}
  4708. unsigned line(unsigned l) const { return opt.no_line_numbers ? 0 : l; }
  4709. // =========================================================================================
  4710. // WHAT FOLLOWS ARE OVERRIDES OF THE VIRTUAL METHODS OF THE REPORTER INTERFACE
  4711. // =========================================================================================
  4712. void report_query(const QueryData&) override {}
  4713. void test_run_start() override {}
  4714. void test_run_end(const TestRunStats& p) override {
  4715. // remove .exe extension - mainly to have the same output on UNIX and Windows
  4716. std::string binary_name = skipPathFromFilename(opt.binary_name.c_str());
  4717. #ifdef DOCTEST_PLATFORM_WINDOWS
  4718. if(binary_name.rfind(".exe") != std::string::npos)
  4719. binary_name = binary_name.substr(0, binary_name.length() - 4);
  4720. #endif // DOCTEST_PLATFORM_WINDOWS
  4721. xml.startElement("testsuites");
  4722. xml.startElement("testsuite").writeAttribute("name", binary_name)
  4723. .writeAttribute("errors", testCaseData.totalErrors)
  4724. .writeAttribute("failures", testCaseData.totalFailures)
  4725. .writeAttribute("tests", p.numAsserts);
  4726. if(opt.no_time_in_output == false) {
  4727. xml.writeAttribute("time", testCaseData.totalSeconds);
  4728. xml.writeAttribute("timestamp", JUnitTestCaseData::getCurrentTimestamp());
  4729. }
  4730. if(opt.no_version == false)
  4731. xml.writeAttribute("doctest_version", DOCTEST_VERSION_STR);
  4732. for(const auto& testCase : testCaseData.testcases) {
  4733. xml.startElement("testcase")
  4734. .writeAttribute("classname", testCase.classname)
  4735. .writeAttribute("name", testCase.name);
  4736. if(opt.no_time_in_output == false)
  4737. xml.writeAttribute("time", testCase.time);
  4738. // This is not ideal, but it should be enough to mimic gtest's junit output.
  4739. xml.writeAttribute("status", "run");
  4740. for(const auto& failure : testCase.failures) {
  4741. xml.scopedElement("failure")
  4742. .writeAttribute("message", failure.message)
  4743. .writeAttribute("type", failure.type)
  4744. .writeText(failure.details, false);
  4745. }
  4746. for(const auto& error : testCase.errors) {
  4747. xml.scopedElement("error")
  4748. .writeAttribute("message", error.message)
  4749. .writeText(error.details);
  4750. }
  4751. xml.endElement();
  4752. }
  4753. xml.endElement();
  4754. xml.endElement();
  4755. }
  4756. void test_case_start(const TestCaseData& in) override {
  4757. testCaseData.add(skipPathFromFilename(in.m_file.c_str()), in.m_name);
  4758. timer.start();
  4759. }
  4760. void test_case_reenter(const TestCaseData& in) override {
  4761. testCaseData.addTime(timer.getElapsedSeconds());
  4762. testCaseData.appendSubcaseNamesToLastTestcase(deepestSubcaseStackNames);
  4763. deepestSubcaseStackNames.clear();
  4764. timer.start();
  4765. testCaseData.add(skipPathFromFilename(in.m_file.c_str()), in.m_name);
  4766. }
  4767. void test_case_end(const CurrentTestCaseStats&) override {
  4768. testCaseData.addTime(timer.getElapsedSeconds());
  4769. testCaseData.appendSubcaseNamesToLastTestcase(deepestSubcaseStackNames);
  4770. deepestSubcaseStackNames.clear();
  4771. }
  4772. void test_case_exception(const TestCaseException& e) override {
  4773. std::lock_guard<std::mutex> lock(mutex);
  4774. testCaseData.addError("exception", e.error_string.c_str());
  4775. }
  4776. void subcase_start(const SubcaseSignature& in) override {
  4777. deepestSubcaseStackNames.push_back(in.m_name);
  4778. }
  4779. void subcase_end() override {}
  4780. void log_assert(const AssertData& rb) override {
  4781. if(!rb.m_failed) // report only failures & ignore the `success` option
  4782. return;
  4783. std::lock_guard<std::mutex> lock(mutex);
  4784. std::ostringstream os;
  4785. os << skipPathFromFilename(rb.m_file) << (opt.gnu_file_line ? ":" : "(")
  4786. << line(rb.m_line) << (opt.gnu_file_line ? ":" : "):") << std::endl;
  4787. fulltext_log_assert_to_stream(os, rb);
  4788. log_contexts(os);
  4789. testCaseData.addFailure(rb.m_decomp.c_str(), assertString(rb.m_at), os.str());
  4790. }
  4791. void log_message(const MessageData&) override {}
  4792. void test_case_skipped(const TestCaseData&) override {}
  4793. void log_contexts(std::ostringstream& s) {
  4794. int num_contexts = get_num_active_contexts();
  4795. if(num_contexts) {
  4796. auto contexts = get_active_contexts();
  4797. s << " logged: ";
  4798. for(int i = 0; i < num_contexts; ++i) {
  4799. s << (i == 0 ? "" : " ");
  4800. contexts[i]->stringify(&s);
  4801. s << std::endl;
  4802. }
  4803. }
  4804. }
  4805. };
  4806. DOCTEST_REGISTER_REPORTER("junit", 0, JUnitReporter);
  4807. struct Whitespace
  4808. {
  4809. int nrSpaces;
  4810. explicit Whitespace(int nr)
  4811. : nrSpaces(nr) {}
  4812. };
  4813. std::ostream& operator<<(std::ostream& out, const Whitespace& ws) {
  4814. if(ws.nrSpaces != 0)
  4815. out << std::setw(ws.nrSpaces) << ' ';
  4816. return out;
  4817. }
  4818. struct ConsoleReporter : public IReporter
  4819. {
  4820. std::ostream& s;
  4821. bool hasLoggedCurrentTestStart;
  4822. std::vector<SubcaseSignature> subcasesStack;
  4823. size_t currentSubcaseLevel;
  4824. std::mutex mutex;
  4825. // caching pointers/references to objects of these types - safe to do
  4826. const ContextOptions& opt;
  4827. const TestCaseData* tc;
  4828. ConsoleReporter(const ContextOptions& co)
  4829. : s(*co.cout)
  4830. , opt(co) {}
  4831. ConsoleReporter(const ContextOptions& co, std::ostream& ostr)
  4832. : s(ostr)
  4833. , opt(co) {}
  4834. // =========================================================================================
  4835. // WHAT FOLLOWS ARE HELPERS USED BY THE OVERRIDES OF THE VIRTUAL METHODS OF THE INTERFACE
  4836. // =========================================================================================
  4837. void separator_to_stream() {
  4838. s << Color::Yellow
  4839. << "==============================================================================="
  4840. "\n";
  4841. }
  4842. const char* getSuccessOrFailString(bool success, assertType::Enum at,
  4843. const char* success_str) {
  4844. if(success)
  4845. return success_str;
  4846. return failureString(at);
  4847. }
  4848. Color::Enum getSuccessOrFailColor(bool success, assertType::Enum at) {
  4849. return success ? Color::BrightGreen :
  4850. (at & assertType::is_warn) ? Color::Yellow : Color::Red;
  4851. }
  4852. void successOrFailColoredStringToStream(bool success, assertType::Enum at,
  4853. const char* success_str = "SUCCESS") {
  4854. s << getSuccessOrFailColor(success, at)
  4855. << getSuccessOrFailString(success, at, success_str) << ": ";
  4856. }
  4857. void log_contexts() {
  4858. int num_contexts = get_num_active_contexts();
  4859. if(num_contexts) {
  4860. auto contexts = get_active_contexts();
  4861. s << Color::None << " logged: ";
  4862. for(int i = 0; i < num_contexts; ++i) {
  4863. s << (i == 0 ? "" : " ");
  4864. contexts[i]->stringify(&s);
  4865. s << "\n";
  4866. }
  4867. }
  4868. s << "\n";
  4869. }
  4870. // this was requested to be made virtual so users could override it
  4871. virtual void file_line_to_stream(const char* file, int line,
  4872. const char* tail = "") {
  4873. s << Color::LightGrey << skipPathFromFilename(file) << (opt.gnu_file_line ? ":" : "(")
  4874. << (opt.no_line_numbers ? 0 : line) // 0 or the real num depending on the option
  4875. << (opt.gnu_file_line ? ":" : "):") << tail;
  4876. }
  4877. void logTestStart() {
  4878. if(hasLoggedCurrentTestStart)
  4879. return;
  4880. separator_to_stream();
  4881. file_line_to_stream(tc->m_file.c_str(), tc->m_line, "\n");
  4882. if(tc->m_description)
  4883. s << Color::Yellow << "DESCRIPTION: " << Color::None << tc->m_description << "\n";
  4884. if(tc->m_test_suite && tc->m_test_suite[0] != '\0')
  4885. s << Color::Yellow << "TEST SUITE: " << Color::None << tc->m_test_suite << "\n";
  4886. if(strncmp(tc->m_name, " Scenario:", 11) != 0)
  4887. s << Color::Yellow << "TEST CASE: ";
  4888. s << Color::None << tc->m_name << "\n";
  4889. for(size_t i = 0; i < currentSubcaseLevel; ++i) {
  4890. if(subcasesStack[i].m_name[0] != '\0')
  4891. s << " " << subcasesStack[i].m_name << "\n";
  4892. }
  4893. if(currentSubcaseLevel != subcasesStack.size()) {
  4894. s << Color::Yellow << "\nDEEPEST SUBCASE STACK REACHED (DIFFERENT FROM THE CURRENT ONE):\n" << Color::None;
  4895. for(size_t i = 0; i < subcasesStack.size(); ++i) {
  4896. if(subcasesStack[i].m_name[0] != '\0')
  4897. s << " " << subcasesStack[i].m_name << "\n";
  4898. }
  4899. }
  4900. s << "\n";
  4901. hasLoggedCurrentTestStart = true;
  4902. }
  4903. void printVersion() {
  4904. if(opt.no_version == false)
  4905. s << Color::Cyan << "[doctest] " << Color::None << "doctest version is \""
  4906. << DOCTEST_VERSION_STR << "\"\n";
  4907. }
  4908. void printIntro() {
  4909. if(opt.no_intro == false) {
  4910. printVersion();
  4911. s << Color::Cyan << "[doctest] " << Color::None
  4912. << "run with \"--" DOCTEST_OPTIONS_PREFIX_DISPLAY "help\" for options\n";
  4913. }
  4914. }
  4915. void printHelp() {
  4916. int sizePrefixDisplay = static_cast<int>(strlen(DOCTEST_OPTIONS_PREFIX_DISPLAY));
  4917. printVersion();
  4918. // clang-format off
  4919. s << Color::Cyan << "[doctest]\n" << Color::None;
  4920. s << Color::Cyan << "[doctest] " << Color::None;
  4921. s << "boolean values: \"1/on/yes/true\" or \"0/off/no/false\"\n";
  4922. s << Color::Cyan << "[doctest] " << Color::None;
  4923. s << "filter values: \"str1,str2,str3\" (comma separated strings)\n";
  4924. s << Color::Cyan << "[doctest]\n" << Color::None;
  4925. s << Color::Cyan << "[doctest] " << Color::None;
  4926. s << "filters use wildcards for matching strings\n";
  4927. s << Color::Cyan << "[doctest] " << Color::None;
  4928. s << "something passes a filter if any of the strings in a filter matches\n";
  4929. #ifndef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
  4930. s << Color::Cyan << "[doctest]\n" << Color::None;
  4931. s << Color::Cyan << "[doctest] " << Color::None;
  4932. s << "ALL FLAGS, OPTIONS AND FILTERS ALSO AVAILABLE WITH A \"" DOCTEST_CONFIG_OPTIONS_PREFIX "\" PREFIX!!!\n";
  4933. #endif
  4934. s << Color::Cyan << "[doctest]\n" << Color::None;
  4935. s << Color::Cyan << "[doctest] " << Color::None;
  4936. s << "Query flags - the program quits after them. Available:\n\n";
  4937. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "?, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "help, -" DOCTEST_OPTIONS_PREFIX_DISPLAY "h "
  4938. << Whitespace(sizePrefixDisplay*0) << "prints this message\n";
  4939. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "v, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "version "
  4940. << Whitespace(sizePrefixDisplay*1) << "prints the version\n";
  4941. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "c, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "count "
  4942. << Whitespace(sizePrefixDisplay*1) << "prints the number of matching tests\n";
  4943. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ltc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "list-test-cases "
  4944. << Whitespace(sizePrefixDisplay*1) << "lists all matching tests by name\n";
  4945. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "lts, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "list-test-suites "
  4946. << Whitespace(sizePrefixDisplay*1) << "lists all matching test suites\n";
  4947. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "lr, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "list-reporters "
  4948. << Whitespace(sizePrefixDisplay*1) << "lists all registered reporters\n\n";
  4949. // ================================================================================== << 79
  4950. s << Color::Cyan << "[doctest] " << Color::None;
  4951. s << "The available <int>/<string> options/filters are:\n\n";
  4952. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "tc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "test-case=<filters> "
  4953. << Whitespace(sizePrefixDisplay*1) << "filters tests by their name\n";
  4954. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "tce, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "test-case-exclude=<filters> "
  4955. << Whitespace(sizePrefixDisplay*1) << "filters OUT tests by their name\n";
  4956. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "sf, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "source-file=<filters> "
  4957. << Whitespace(sizePrefixDisplay*1) << "filters tests by their file\n";
  4958. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "sfe, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "source-file-exclude=<filters> "
  4959. << Whitespace(sizePrefixDisplay*1) << "filters OUT tests by their file\n";
  4960. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ts, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "test-suite=<filters> "
  4961. << Whitespace(sizePrefixDisplay*1) << "filters tests by their test suite\n";
  4962. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "tse, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "test-suite-exclude=<filters> "
  4963. << Whitespace(sizePrefixDisplay*1) << "filters OUT tests by their test suite\n";
  4964. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "sc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "subcase=<filters> "
  4965. << Whitespace(sizePrefixDisplay*1) << "filters subcases by their name\n";
  4966. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "sce, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "subcase-exclude=<filters> "
  4967. << Whitespace(sizePrefixDisplay*1) << "filters OUT subcases by their name\n";
  4968. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "r, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "reporters=<filters> "
  4969. << Whitespace(sizePrefixDisplay*1) << "reporters to use (console is default)\n";
  4970. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "o, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "out=<string> "
  4971. << Whitespace(sizePrefixDisplay*1) << "output filename\n";
  4972. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ob, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "order-by=<string> "
  4973. << Whitespace(sizePrefixDisplay*1) << "how the tests should be ordered\n";
  4974. s << Whitespace(sizePrefixDisplay*3) << " <string> - [file/suite/name/rand/none]\n";
  4975. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "rs, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "rand-seed=<int> "
  4976. << Whitespace(sizePrefixDisplay*1) << "seed for random ordering\n";
  4977. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "f, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "first=<int> "
  4978. << Whitespace(sizePrefixDisplay*1) << "the first test passing the filters to\n";
  4979. s << Whitespace(sizePrefixDisplay*3) << " execute - for range-based execution\n";
  4980. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "l, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "last=<int> "
  4981. << Whitespace(sizePrefixDisplay*1) << "the last test passing the filters to\n";
  4982. s << Whitespace(sizePrefixDisplay*3) << " execute - for range-based execution\n";
  4983. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "aa, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "abort-after=<int> "
  4984. << Whitespace(sizePrefixDisplay*1) << "stop after <int> failed assertions\n";
  4985. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "scfl,--" DOCTEST_OPTIONS_PREFIX_DISPLAY "subcase-filter-levels=<int> "
  4986. << Whitespace(sizePrefixDisplay*1) << "apply filters for the first <int> levels\n";
  4987. s << Color::Cyan << "\n[doctest] " << Color::None;
  4988. s << "Bool options - can be used like flags and true is assumed. Available:\n\n";
  4989. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "s, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "success=<bool> "
  4990. << Whitespace(sizePrefixDisplay*1) << "include successful assertions in output\n";
  4991. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "cs, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "case-sensitive=<bool> "
  4992. << Whitespace(sizePrefixDisplay*1) << "filters being treated as case sensitive\n";
  4993. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "e, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "exit=<bool> "
  4994. << Whitespace(sizePrefixDisplay*1) << "exits after the tests finish\n";
  4995. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "d, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "duration=<bool> "
  4996. << Whitespace(sizePrefixDisplay*1) << "prints the time duration of each test\n";
  4997. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "m, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "minimal=<bool> "
  4998. << Whitespace(sizePrefixDisplay*1) << "minimal console output (only failures)\n";
  4999. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "q, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "quiet=<bool> "
  5000. << Whitespace(sizePrefixDisplay*1) << "no console output\n";
  5001. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nt, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-throw=<bool> "
  5002. << Whitespace(sizePrefixDisplay*1) << "skips exceptions-related assert checks\n";
  5003. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ne, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-exitcode=<bool> "
  5004. << Whitespace(sizePrefixDisplay*1) << "returns (or exits) always with success\n";
  5005. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nr, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-run=<bool> "
  5006. << Whitespace(sizePrefixDisplay*1) << "skips all runtime doctest operations\n";
  5007. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ni, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-intro=<bool> "
  5008. << Whitespace(sizePrefixDisplay*1) << "omit the framework intro in the output\n";
  5009. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nv, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-version=<bool> "
  5010. << Whitespace(sizePrefixDisplay*1) << "omit the framework version in the output\n";
  5011. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-colors=<bool> "
  5012. << Whitespace(sizePrefixDisplay*1) << "disables colors in output\n";
  5013. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "fc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "force-colors=<bool> "
  5014. << Whitespace(sizePrefixDisplay*1) << "use colors even when not in a tty\n";
  5015. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nb, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-breaks=<bool> "
  5016. << Whitespace(sizePrefixDisplay*1) << "disables breakpoints in debuggers\n";
  5017. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ns, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-skip=<bool> "
  5018. << Whitespace(sizePrefixDisplay*1) << "don't skip test cases marked as skip\n";
  5019. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "gfl, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "gnu-file-line=<bool> "
  5020. << Whitespace(sizePrefixDisplay*1) << ":n: vs (n): for line numbers in output\n";
  5021. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "npf, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-path-filenames=<bool> "
  5022. << Whitespace(sizePrefixDisplay*1) << "only filenames and no paths in output\n";
  5023. s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nln, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-line-numbers=<bool> "
  5024. << Whitespace(sizePrefixDisplay*1) << "0 instead of real line numbers in output\n";
  5025. // ================================================================================== << 79
  5026. // clang-format on
  5027. s << Color::Cyan << "\n[doctest] " << Color::None;
  5028. s << "for more information visit the project documentation\n\n";
  5029. }
  5030. void printRegisteredReporters() {
  5031. printVersion();
  5032. auto printReporters = [this] (const reporterMap& reporters, const char* type) {
  5033. if(reporters.size()) {
  5034. s << Color::Cyan << "[doctest] " << Color::None << "listing all registered " << type << "\n";
  5035. for(auto& curr : reporters)
  5036. s << "priority: " << std::setw(5) << curr.first.first
  5037. << " name: " << curr.first.second << "\n";
  5038. }
  5039. };
  5040. printReporters(getListeners(), "listeners");
  5041. printReporters(getReporters(), "reporters");
  5042. }
  5043. // =========================================================================================
  5044. // WHAT FOLLOWS ARE OVERRIDES OF THE VIRTUAL METHODS OF THE REPORTER INTERFACE
  5045. // =========================================================================================
  5046. void report_query(const QueryData& in) override {
  5047. if(opt.version) {
  5048. printVersion();
  5049. } else if(opt.help) {
  5050. printHelp();
  5051. } else if(opt.list_reporters) {
  5052. printRegisteredReporters();
  5053. } else if(opt.count || opt.list_test_cases) {
  5054. if(opt.list_test_cases) {
  5055. s << Color::Cyan << "[doctest] " << Color::None
  5056. << "listing all test case names\n";
  5057. separator_to_stream();
  5058. }
  5059. for(unsigned i = 0; i < in.num_data; ++i)
  5060. s << Color::None << in.data[i]->m_name << "\n";
  5061. separator_to_stream();
  5062. s << Color::Cyan << "[doctest] " << Color::None
  5063. << "unskipped test cases passing the current filters: "
  5064. << g_cs->numTestCasesPassingFilters << "\n";
  5065. } else if(opt.list_test_suites) {
  5066. s << Color::Cyan << "[doctest] " << Color::None << "listing all test suites\n";
  5067. separator_to_stream();
  5068. for(unsigned i = 0; i < in.num_data; ++i)
  5069. s << Color::None << in.data[i]->m_test_suite << "\n";
  5070. separator_to_stream();
  5071. s << Color::Cyan << "[doctest] " << Color::None
  5072. << "unskipped test cases passing the current filters: "
  5073. << g_cs->numTestCasesPassingFilters << "\n";
  5074. s << Color::Cyan << "[doctest] " << Color::None
  5075. << "test suites with unskipped test cases passing the current filters: "
  5076. << g_cs->numTestSuitesPassingFilters << "\n";
  5077. }
  5078. }
  5079. void test_run_start() override {
  5080. if(!opt.minimal)
  5081. printIntro();
  5082. }
  5083. void test_run_end(const TestRunStats& p) override {
  5084. if(opt.minimal && p.numTestCasesFailed == 0)
  5085. return;
  5086. separator_to_stream();
  5087. s << std::dec;
  5088. auto totwidth = int(std::ceil(log10((std::max(p.numTestCasesPassingFilters, static_cast<unsigned>(p.numAsserts))) + 1)));
  5089. auto passwidth = int(std::ceil(log10((std::max(p.numTestCasesPassingFilters - p.numTestCasesFailed, static_cast<unsigned>(p.numAsserts - p.numAssertsFailed))) + 1)));
  5090. auto failwidth = int(std::ceil(log10((std::max(p.numTestCasesFailed, static_cast<unsigned>(p.numAssertsFailed))) + 1)));
  5091. const bool anythingFailed = p.numTestCasesFailed > 0 || p.numAssertsFailed > 0;
  5092. s << Color::Cyan << "[doctest] " << Color::None << "test cases: " << std::setw(totwidth)
  5093. << p.numTestCasesPassingFilters << " | "
  5094. << ((p.numTestCasesPassingFilters == 0 || anythingFailed) ? Color::None :
  5095. Color::Green)
  5096. << std::setw(passwidth) << p.numTestCasesPassingFilters - p.numTestCasesFailed << " passed"
  5097. << Color::None << " | " << (p.numTestCasesFailed > 0 ? Color::Red : Color::None)
  5098. << std::setw(failwidth) << p.numTestCasesFailed << " failed" << Color::None << " |";
  5099. if(opt.no_skipped_summary == false) {
  5100. const int numSkipped = p.numTestCases - p.numTestCasesPassingFilters;
  5101. s << " " << (numSkipped == 0 ? Color::None : Color::Yellow) << numSkipped
  5102. << " skipped" << Color::None;
  5103. }
  5104. s << "\n";
  5105. s << Color::Cyan << "[doctest] " << Color::None << "assertions: " << std::setw(totwidth)
  5106. << p.numAsserts << " | "
  5107. << ((p.numAsserts == 0 || anythingFailed) ? Color::None : Color::Green)
  5108. << std::setw(passwidth) << (p.numAsserts - p.numAssertsFailed) << " passed" << Color::None
  5109. << " | " << (p.numAssertsFailed > 0 ? Color::Red : Color::None) << std::setw(failwidth)
  5110. << p.numAssertsFailed << " failed" << Color::None << " |\n";
  5111. s << Color::Cyan << "[doctest] " << Color::None
  5112. << "Status: " << (p.numTestCasesFailed > 0 ? Color::Red : Color::Green)
  5113. << ((p.numTestCasesFailed > 0) ? "FAILURE!" : "SUCCESS!") << Color::None << std::endl;
  5114. }
  5115. void test_case_start(const TestCaseData& in) override {
  5116. hasLoggedCurrentTestStart = false;
  5117. tc = &in;
  5118. subcasesStack.clear();
  5119. currentSubcaseLevel = 0;
  5120. }
  5121. void test_case_reenter(const TestCaseData&) override {
  5122. subcasesStack.clear();
  5123. }
  5124. void test_case_end(const CurrentTestCaseStats& st) override {
  5125. if(tc->m_no_output)
  5126. return;
  5127. // log the preamble of the test case only if there is something
  5128. // else to print - something other than that an assert has failed
  5129. if(opt.duration ||
  5130. (st.failure_flags && st.failure_flags != TestCaseFailureReason::AssertFailure))
  5131. logTestStart();
  5132. if(opt.duration)
  5133. s << Color::None << std::setprecision(6) << std::fixed << st.seconds
  5134. << " s: " << tc->m_name << "\n";
  5135. if(st.failure_flags & TestCaseFailureReason::Timeout)
  5136. s << Color::Red << "Test case exceeded time limit of " << std::setprecision(6)
  5137. << std::fixed << tc->m_timeout << "!\n";
  5138. if(st.failure_flags & TestCaseFailureReason::ShouldHaveFailedButDidnt) {
  5139. s << Color::Red << "Should have failed but didn't! Marking it as failed!\n";
  5140. } else if(st.failure_flags & TestCaseFailureReason::ShouldHaveFailedAndDid) {
  5141. s << Color::Yellow << "Failed as expected so marking it as not failed\n";
  5142. } else if(st.failure_flags & TestCaseFailureReason::CouldHaveFailedAndDid) {
  5143. s << Color::Yellow << "Allowed to fail so marking it as not failed\n";
  5144. } else if(st.failure_flags & TestCaseFailureReason::DidntFailExactlyNumTimes) {
  5145. s << Color::Red << "Didn't fail exactly " << tc->m_expected_failures
  5146. << " times so marking it as failed!\n";
  5147. } else if(st.failure_flags & TestCaseFailureReason::FailedExactlyNumTimes) {
  5148. s << Color::Yellow << "Failed exactly " << tc->m_expected_failures
  5149. << " times as expected so marking it as not failed!\n";
  5150. }
  5151. if(st.failure_flags & TestCaseFailureReason::TooManyFailedAsserts) {
  5152. s << Color::Red << "Aborting - too many failed asserts!\n";
  5153. }
  5154. s << Color::None; // lgtm [cpp/useless-expression]
  5155. }
  5156. void test_case_exception(const TestCaseException& e) override {
  5157. std::lock_guard<std::mutex> lock(mutex);
  5158. if(tc->m_no_output)
  5159. return;
  5160. logTestStart();
  5161. file_line_to_stream(tc->m_file.c_str(), tc->m_line, " ");
  5162. successOrFailColoredStringToStream(false, e.is_crash ? assertType::is_require :
  5163. assertType::is_check);
  5164. s << Color::Red << (e.is_crash ? "test case CRASHED: " : "test case THREW exception: ")
  5165. << Color::Cyan << e.error_string << "\n";
  5166. int num_stringified_contexts = get_num_stringified_contexts();
  5167. if(num_stringified_contexts) {
  5168. auto stringified_contexts = get_stringified_contexts();
  5169. s << Color::None << " logged: ";
  5170. for(int i = num_stringified_contexts; i > 0; --i) {
  5171. s << (i == num_stringified_contexts ? "" : " ")
  5172. << stringified_contexts[i - 1] << "\n";
  5173. }
  5174. }
  5175. s << "\n" << Color::None;
  5176. }
  5177. void subcase_start(const SubcaseSignature& subc) override {
  5178. subcasesStack.push_back(subc);
  5179. ++currentSubcaseLevel;
  5180. hasLoggedCurrentTestStart = false;
  5181. }
  5182. void subcase_end() override {
  5183. --currentSubcaseLevel;
  5184. hasLoggedCurrentTestStart = false;
  5185. }
  5186. void log_assert(const AssertData& rb) override {
  5187. if((!rb.m_failed && !opt.success) || tc->m_no_output)
  5188. return;
  5189. std::lock_guard<std::mutex> lock(mutex);
  5190. logTestStart();
  5191. file_line_to_stream(rb.m_file, rb.m_line, " ");
  5192. successOrFailColoredStringToStream(!rb.m_failed, rb.m_at);
  5193. fulltext_log_assert_to_stream(s, rb);
  5194. log_contexts();
  5195. }
  5196. void log_message(const MessageData& mb) override {
  5197. if(tc->m_no_output)
  5198. return;
  5199. std::lock_guard<std::mutex> lock(mutex);
  5200. logTestStart();
  5201. file_line_to_stream(mb.m_file, mb.m_line, " ");
  5202. s << getSuccessOrFailColor(false, mb.m_severity)
  5203. << getSuccessOrFailString(mb.m_severity & assertType::is_warn, mb.m_severity,
  5204. "MESSAGE") << ": ";
  5205. s << Color::None << mb.m_string << "\n";
  5206. log_contexts();
  5207. }
  5208. void test_case_skipped(const TestCaseData&) override {}
  5209. };
  5210. DOCTEST_REGISTER_REPORTER("console", 0, ConsoleReporter);
  5211. #ifdef DOCTEST_PLATFORM_WINDOWS
  5212. struct DebugOutputWindowReporter : public ConsoleReporter
  5213. {
  5214. DOCTEST_THREAD_LOCAL static std::ostringstream oss;
  5215. DebugOutputWindowReporter(const ContextOptions& co)
  5216. : ConsoleReporter(co, oss) {}
  5217. #define DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(func, type, arg) \
  5218. void func(type arg) override { \
  5219. bool with_col = g_no_colors; \
  5220. g_no_colors = false; \
  5221. ConsoleReporter::func(arg); \
  5222. if(oss.tellp() != std::streampos{}) { \
  5223. DOCTEST_OUTPUT_DEBUG_STRING(oss.str().c_str()); \
  5224. oss.str(""); \
  5225. } \
  5226. g_no_colors = with_col; \
  5227. }
  5228. DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_run_start, DOCTEST_EMPTY, DOCTEST_EMPTY)
  5229. DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_run_end, const TestRunStats&, in)
  5230. DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_start, const TestCaseData&, in)
  5231. DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_reenter, const TestCaseData&, in)
  5232. DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_end, const CurrentTestCaseStats&, in)
  5233. DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_exception, const TestCaseException&, in)
  5234. DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(subcase_start, const SubcaseSignature&, in)
  5235. DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(subcase_end, DOCTEST_EMPTY, DOCTEST_EMPTY)
  5236. DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(log_assert, const AssertData&, in)
  5237. DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(log_message, const MessageData&, in)
  5238. DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_skipped, const TestCaseData&, in)
  5239. };
  5240. DOCTEST_THREAD_LOCAL std::ostringstream DebugOutputWindowReporter::oss;
  5241. #endif // DOCTEST_PLATFORM_WINDOWS
  5242. // the implementation of parseOption()
  5243. bool parseOptionImpl(int argc, const char* const* argv, const char* pattern, String* value) {
  5244. // going from the end to the beginning and stopping on the first occurrence from the end
  5245. for(int i = argc; i > 0; --i) {
  5246. auto index = i - 1;
  5247. auto temp = std::strstr(argv[index], pattern);
  5248. if(temp && (value || strlen(temp) == strlen(pattern))) { //!OCLINT prefer early exits and continue
  5249. // eliminate matches in which the chars before the option are not '-'
  5250. bool noBadCharsFound = true;
  5251. auto curr = argv[index];
  5252. while(curr != temp) {
  5253. if(*curr++ != '-') {
  5254. noBadCharsFound = false;
  5255. break;
  5256. }
  5257. }
  5258. if(noBadCharsFound && argv[index][0] == '-') {
  5259. if(value) {
  5260. // parsing the value of an option
  5261. temp += strlen(pattern);
  5262. const unsigned len = strlen(temp);
  5263. if(len) {
  5264. *value = temp;
  5265. return true;
  5266. }
  5267. } else {
  5268. // just a flag - no value
  5269. return true;
  5270. }
  5271. }
  5272. }
  5273. }
  5274. return false;
  5275. }
  5276. // parses an option and returns the string after the '=' character
  5277. bool parseOption(int argc, const char* const* argv, const char* pattern, String* value = nullptr,
  5278. const String& defaultVal = String()) {
  5279. if(value)
  5280. *value = defaultVal;
  5281. #ifndef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
  5282. // offset (normally 3 for "dt-") to skip prefix
  5283. if(parseOptionImpl(argc, argv, pattern + strlen(DOCTEST_CONFIG_OPTIONS_PREFIX), value))
  5284. return true;
  5285. #endif // DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
  5286. return parseOptionImpl(argc, argv, pattern, value);
  5287. }
  5288. // locates a flag on the command line
  5289. bool parseFlag(int argc, const char* const* argv, const char* pattern) {
  5290. return parseOption(argc, argv, pattern);
  5291. }
  5292. // parses a comma separated list of words after a pattern in one of the arguments in argv
  5293. bool parseCommaSepArgs(int argc, const char* const* argv, const char* pattern,
  5294. std::vector<String>& res) {
  5295. String filtersString;
  5296. if(parseOption(argc, argv, pattern, &filtersString)) {
  5297. // tokenize with "," as a separator, unless escaped with backslash
  5298. std::ostringstream s;
  5299. auto flush = [&s, &res]() {
  5300. auto string = s.str();
  5301. if(string.size() > 0) {
  5302. res.push_back(string.c_str());
  5303. }
  5304. s.str("");
  5305. };
  5306. bool seenBackslash = false;
  5307. const char* current = filtersString.c_str();
  5308. const char* end = current + strlen(current);
  5309. while(current != end) {
  5310. char character = *current++;
  5311. if(seenBackslash) {
  5312. seenBackslash = false;
  5313. if(character == ',') {
  5314. s.put(',');
  5315. continue;
  5316. }
  5317. s.put('\\');
  5318. }
  5319. if(character == '\\') {
  5320. seenBackslash = true;
  5321. } else if(character == ',') {
  5322. flush();
  5323. } else {
  5324. s.put(character);
  5325. }
  5326. }
  5327. if(seenBackslash) {
  5328. s.put('\\');
  5329. }
  5330. flush();
  5331. return true;
  5332. }
  5333. return false;
  5334. }
  5335. enum optionType
  5336. {
  5337. option_bool,
  5338. option_int
  5339. };
  5340. // parses an int/bool option from the command line
  5341. bool parseIntOption(int argc, const char* const* argv, const char* pattern, optionType type,
  5342. int& res) {
  5343. String parsedValue;
  5344. if(!parseOption(argc, argv, pattern, &parsedValue))
  5345. return false;
  5346. if(type == 0) {
  5347. // boolean
  5348. const char positive[][5] = {"1", "true", "on", "yes"}; // 5 - strlen("true") + 1
  5349. const char negative[][6] = {"0", "false", "off", "no"}; // 6 - strlen("false") + 1
  5350. // if the value matches any of the positive/negative possibilities
  5351. for(unsigned i = 0; i < 4; i++) {
  5352. if(parsedValue.compare(positive[i], true) == 0) {
  5353. res = 1; //!OCLINT parameter reassignment
  5354. return true;
  5355. }
  5356. if(parsedValue.compare(negative[i], true) == 0) {
  5357. res = 0; //!OCLINT parameter reassignment
  5358. return true;
  5359. }
  5360. }
  5361. } else {
  5362. // integer
  5363. // TODO: change this to use std::stoi or something else! currently it uses undefined behavior - assumes '0' on failed parse...
  5364. int theInt = std::atoi(parsedValue.c_str()); // NOLINT
  5365. if(theInt != 0) {
  5366. res = theInt; //!OCLINT parameter reassignment
  5367. return true;
  5368. }
  5369. }
  5370. return false;
  5371. }
  5372. } // namespace
  5373. Context::Context(int argc, const char* const* argv)
  5374. : p(new detail::ContextState) {
  5375. parseArgs(argc, argv, true);
  5376. if(argc)
  5377. p->binary_name = argv[0];
  5378. }
  5379. Context::~Context() {
  5380. if(g_cs == p)
  5381. g_cs = nullptr;
  5382. delete p;
  5383. }
  5384. void Context::applyCommandLine(int argc, const char* const* argv) {
  5385. parseArgs(argc, argv);
  5386. if(argc)
  5387. p->binary_name = argv[0];
  5388. }
  5389. // parses args
  5390. void Context::parseArgs(int argc, const char* const* argv, bool withDefaults) {
  5391. using namespace detail;
  5392. // clang-format off
  5393. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "source-file=", p->filters[0]);
  5394. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "sf=", p->filters[0]);
  5395. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "source-file-exclude=",p->filters[1]);
  5396. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "sfe=", p->filters[1]);
  5397. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "test-suite=", p->filters[2]);
  5398. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "ts=", p->filters[2]);
  5399. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "test-suite-exclude=", p->filters[3]);
  5400. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "tse=", p->filters[3]);
  5401. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "test-case=", p->filters[4]);
  5402. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "tc=", p->filters[4]);
  5403. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "test-case-exclude=", p->filters[5]);
  5404. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "tce=", p->filters[5]);
  5405. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "subcase=", p->filters[6]);
  5406. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "sc=", p->filters[6]);
  5407. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "subcase-exclude=", p->filters[7]);
  5408. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "sce=", p->filters[7]);
  5409. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "reporters=", p->filters[8]);
  5410. parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "r=", p->filters[8]);
  5411. // clang-format on
  5412. int intRes = 0;
  5413. String strRes;
  5414. #define DOCTEST_PARSE_AS_BOOL_OR_FLAG(name, sname, var, default) \
  5415. if(parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name "=", option_bool, intRes) || \
  5416. parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname "=", option_bool, intRes)) \
  5417. p->var = static_cast<bool>(intRes); \
  5418. else if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name) || \
  5419. parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname)) \
  5420. p->var = true; \
  5421. else if(withDefaults) \
  5422. p->var = default
  5423. #define DOCTEST_PARSE_INT_OPTION(name, sname, var, default) \
  5424. if(parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name "=", option_int, intRes) || \
  5425. parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname "=", option_int, intRes)) \
  5426. p->var = intRes; \
  5427. else if(withDefaults) \
  5428. p->var = default
  5429. #define DOCTEST_PARSE_STR_OPTION(name, sname, var, default) \
  5430. if(parseOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name "=", &strRes, default) || \
  5431. parseOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname "=", &strRes, default) || \
  5432. withDefaults) \
  5433. p->var = strRes
  5434. // clang-format off
  5435. DOCTEST_PARSE_STR_OPTION("out", "o", out, "");
  5436. DOCTEST_PARSE_STR_OPTION("order-by", "ob", order_by, "file");
  5437. DOCTEST_PARSE_INT_OPTION("rand-seed", "rs", rand_seed, 0);
  5438. DOCTEST_PARSE_INT_OPTION("first", "f", first, 0);
  5439. DOCTEST_PARSE_INT_OPTION("last", "l", last, UINT_MAX);
  5440. DOCTEST_PARSE_INT_OPTION("abort-after", "aa", abort_after, 0);
  5441. DOCTEST_PARSE_INT_OPTION("subcase-filter-levels", "scfl", subcase_filter_levels, INT_MAX);
  5442. DOCTEST_PARSE_AS_BOOL_OR_FLAG("success", "s", success, false);
  5443. DOCTEST_PARSE_AS_BOOL_OR_FLAG("case-sensitive", "cs", case_sensitive, false);
  5444. DOCTEST_PARSE_AS_BOOL_OR_FLAG("exit", "e", exit, false);
  5445. DOCTEST_PARSE_AS_BOOL_OR_FLAG("duration", "d", duration, false);
  5446. DOCTEST_PARSE_AS_BOOL_OR_FLAG("minimal", "m", minimal, false);
  5447. DOCTEST_PARSE_AS_BOOL_OR_FLAG("quiet", "q", quiet, false);
  5448. DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-throw", "nt", no_throw, false);
  5449. DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-exitcode", "ne", no_exitcode, false);
  5450. DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-run", "nr", no_run, false);
  5451. DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-intro", "ni", no_intro, false);
  5452. DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-version", "nv", no_version, false);
  5453. DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-colors", "nc", no_colors, false);
  5454. DOCTEST_PARSE_AS_BOOL_OR_FLAG("force-colors", "fc", force_colors, false);
  5455. DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-breaks", "nb", no_breaks, false);
  5456. DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-skip", "ns", no_skip, false);
  5457. DOCTEST_PARSE_AS_BOOL_OR_FLAG("gnu-file-line", "gfl", gnu_file_line, !bool(DOCTEST_MSVC));
  5458. DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-path-filenames", "npf", no_path_in_filenames, false);
  5459. DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-line-numbers", "nln", no_line_numbers, false);
  5460. DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-debug-output", "ndo", no_debug_output, false);
  5461. DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-skipped-summary", "nss", no_skipped_summary, false);
  5462. DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-time-in-output", "ntio", no_time_in_output, false);
  5463. // clang-format on
  5464. if(withDefaults) {
  5465. p->help = false;
  5466. p->version = false;
  5467. p->count = false;
  5468. p->list_test_cases = false;
  5469. p->list_test_suites = false;
  5470. p->list_reporters = false;
  5471. }
  5472. if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "help") ||
  5473. parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "h") ||
  5474. parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "?")) {
  5475. p->help = true;
  5476. p->exit = true;
  5477. }
  5478. if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "version") ||
  5479. parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "v")) {
  5480. p->version = true;
  5481. p->exit = true;
  5482. }
  5483. if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "count") ||
  5484. parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "c")) {
  5485. p->count = true;
  5486. p->exit = true;
  5487. }
  5488. if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "list-test-cases") ||
  5489. parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "ltc")) {
  5490. p->list_test_cases = true;
  5491. p->exit = true;
  5492. }
  5493. if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "list-test-suites") ||
  5494. parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "lts")) {
  5495. p->list_test_suites = true;
  5496. p->exit = true;
  5497. }
  5498. if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "list-reporters") ||
  5499. parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "lr")) {
  5500. p->list_reporters = true;
  5501. p->exit = true;
  5502. }
  5503. }
  5504. // allows the user to add procedurally to the filters from the command line
  5505. void Context::addFilter(const char* filter, const char* value) { setOption(filter, value); }
  5506. // allows the user to clear all filters from the command line
  5507. void Context::clearFilters() {
  5508. for(auto& curr : p->filters)
  5509. curr.clear();
  5510. }
  5511. // allows the user to override procedurally the bool options from the command line
  5512. void Context::setOption(const char* option, bool value) {
  5513. setOption(option, value ? "true" : "false");
  5514. }
  5515. // allows the user to override procedurally the int options from the command line
  5516. void Context::setOption(const char* option, int value) {
  5517. setOption(option, toString(value).c_str());
  5518. // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
  5519. }
  5520. // allows the user to override procedurally the string options from the command line
  5521. void Context::setOption(const char* option, const char* value) {
  5522. auto argv = String("-") + option + "=" + value;
  5523. auto lvalue = argv.c_str();
  5524. parseArgs(1, &lvalue);
  5525. }
  5526. // users should query this in their main() and exit the program if true
  5527. bool Context::shouldExit() { return p->exit; }
  5528. void Context::setAsDefaultForAssertsOutOfTestCases() { g_cs = p; }
  5529. void Context::setAssertHandler(detail::assert_handler ah) { p->ah = ah; }
  5530. void Context::setCout(std::ostream* out) { p->cout = out; }
  5531. static class DiscardOStream : public std::ostream
  5532. {
  5533. private:
  5534. class : public std::streambuf
  5535. {
  5536. private:
  5537. // allowing some buffering decreases the amount of calls to overflow
  5538. char buf[1024];
  5539. protected:
  5540. std::streamsize xsputn(const char_type*, std::streamsize count) override { return count; }
  5541. int_type overflow(int_type ch) override {
  5542. setp(std::begin(buf), std::end(buf));
  5543. return traits_type::not_eof(ch);
  5544. }
  5545. } discardBuf;
  5546. public:
  5547. DiscardOStream()
  5548. : std::ostream(&discardBuf) {}
  5549. } discardOut;
  5550. // the main function that does all the filtering and test running
  5551. int Context::run() {
  5552. using namespace detail;
  5553. // save the old context state in case such was setup - for using asserts out of a testing context
  5554. auto old_cs = g_cs;
  5555. // this is the current contest
  5556. g_cs = p;
  5557. is_running_in_test = true;
  5558. g_no_colors = p->no_colors;
  5559. p->resetRunData();
  5560. std::fstream fstr;
  5561. if(p->cout == nullptr) {
  5562. if(p->quiet) {
  5563. p->cout = &discardOut;
  5564. } else if(p->out.size()) {
  5565. // to a file if specified
  5566. fstr.open(p->out.c_str(), std::fstream::out);
  5567. p->cout = &fstr;
  5568. } else {
  5569. // stdout by default
  5570. p->cout = &std::cout;
  5571. }
  5572. }
  5573. FatalConditionHandler::allocateAltStackMem();
  5574. auto cleanup_and_return = [&]() {
  5575. FatalConditionHandler::freeAltStackMem();
  5576. if(fstr.is_open())
  5577. fstr.close();
  5578. // restore context
  5579. g_cs = old_cs;
  5580. is_running_in_test = false;
  5581. // we have to free the reporters which were allocated when the run started
  5582. for(auto& curr : p->reporters_currently_used)
  5583. delete curr;
  5584. p->reporters_currently_used.clear();
  5585. if(p->numTestCasesFailed && !p->no_exitcode)
  5586. return EXIT_FAILURE;
  5587. return EXIT_SUCCESS;
  5588. };
  5589. // setup default reporter if none is given through the command line
  5590. if(p->filters[8].empty())
  5591. p->filters[8].push_back("console");
  5592. // check to see if any of the registered reporters has been selected
  5593. for(auto& curr : getReporters()) {
  5594. if(matchesAny(curr.first.second.c_str(), p->filters[8], false, p->case_sensitive))
  5595. p->reporters_currently_used.push_back(curr.second(*g_cs));
  5596. }
  5597. // TODO: check if there is nothing in reporters_currently_used
  5598. // prepend all listeners
  5599. for(auto& curr : getListeners())
  5600. p->reporters_currently_used.insert(p->reporters_currently_used.begin(), curr.second(*g_cs));
  5601. #ifdef DOCTEST_PLATFORM_WINDOWS
  5602. if(isDebuggerActive() && p->no_debug_output == false)
  5603. p->reporters_currently_used.push_back(new DebugOutputWindowReporter(*g_cs));
  5604. #endif // DOCTEST_PLATFORM_WINDOWS
  5605. // handle version, help and no_run
  5606. if(p->no_run || p->version || p->help || p->list_reporters) {
  5607. DOCTEST_ITERATE_THROUGH_REPORTERS(report_query, QueryData());
  5608. return cleanup_and_return();
  5609. }
  5610. std::vector<const TestCase*> testArray;
  5611. for(auto& curr : getRegisteredTests())
  5612. testArray.push_back(&curr);
  5613. p->numTestCases = testArray.size();
  5614. // sort the collected records
  5615. if(!testArray.empty()) {
  5616. if(p->order_by.compare("file", true) == 0) {
  5617. std::sort(testArray.begin(), testArray.end(), fileOrderComparator);
  5618. } else if(p->order_by.compare("suite", true) == 0) {
  5619. std::sort(testArray.begin(), testArray.end(), suiteOrderComparator);
  5620. } else if(p->order_by.compare("name", true) == 0) {
  5621. std::sort(testArray.begin(), testArray.end(), nameOrderComparator);
  5622. } else if(p->order_by.compare("rand", true) == 0) {
  5623. std::srand(p->rand_seed);
  5624. // random_shuffle implementation
  5625. const auto first = &testArray[0];
  5626. for(size_t i = testArray.size() - 1; i > 0; --i) {
  5627. int idxToSwap = std::rand() % (i + 1); // NOLINT
  5628. const auto temp = first[i];
  5629. first[i] = first[idxToSwap];
  5630. first[idxToSwap] = temp;
  5631. }
  5632. } else if(p->order_by.compare("none", true) == 0) {
  5633. // means no sorting - beneficial for death tests which call into the executable
  5634. // with a specific test case in mind - we don't want to slow down the startup times
  5635. }
  5636. }
  5637. std::set<String> testSuitesPassingFilt;
  5638. bool query_mode = p->count || p->list_test_cases || p->list_test_suites;
  5639. std::vector<const TestCaseData*> queryResults;
  5640. if(!query_mode)
  5641. DOCTEST_ITERATE_THROUGH_REPORTERS(test_run_start, DOCTEST_EMPTY);
  5642. // invoke the registered functions if they match the filter criteria (or just count them)
  5643. for(auto& curr : testArray) {
  5644. const auto& tc = *curr;
  5645. bool skip_me = false;
  5646. if(tc.m_skip && !p->no_skip)
  5647. skip_me = true;
  5648. if(!matchesAny(tc.m_file.c_str(), p->filters[0], true, p->case_sensitive))
  5649. skip_me = true;
  5650. if(matchesAny(tc.m_file.c_str(), p->filters[1], false, p->case_sensitive))
  5651. skip_me = true;
  5652. if(!matchesAny(tc.m_test_suite, p->filters[2], true, p->case_sensitive))
  5653. skip_me = true;
  5654. if(matchesAny(tc.m_test_suite, p->filters[3], false, p->case_sensitive))
  5655. skip_me = true;
  5656. if(!matchesAny(tc.m_name, p->filters[4], true, p->case_sensitive))
  5657. skip_me = true;
  5658. if(matchesAny(tc.m_name, p->filters[5], false, p->case_sensitive))
  5659. skip_me = true;
  5660. if(!skip_me)
  5661. p->numTestCasesPassingFilters++;
  5662. // skip the test if it is not in the execution range
  5663. if((p->last < p->numTestCasesPassingFilters && p->first <= p->last) ||
  5664. (p->first > p->numTestCasesPassingFilters))
  5665. skip_me = true;
  5666. if(skip_me) {
  5667. if(!query_mode)
  5668. DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_skipped, tc);
  5669. continue;
  5670. }
  5671. // do not execute the test if we are to only count the number of filter passing tests
  5672. if(p->count)
  5673. continue;
  5674. // print the name of the test and don't execute it
  5675. if(p->list_test_cases) {
  5676. queryResults.push_back(&tc);
  5677. continue;
  5678. }
  5679. // print the name of the test suite if not done already and don't execute it
  5680. if(p->list_test_suites) {
  5681. if((testSuitesPassingFilt.count(tc.m_test_suite) == 0) && tc.m_test_suite[0] != '\0') {
  5682. queryResults.push_back(&tc);
  5683. testSuitesPassingFilt.insert(tc.m_test_suite);
  5684. p->numTestSuitesPassingFilters++;
  5685. }
  5686. continue;
  5687. }
  5688. // execute the test if it passes all the filtering
  5689. {
  5690. p->currentTest = &tc;
  5691. p->failure_flags = TestCaseFailureReason::None;
  5692. p->seconds = 0;
  5693. // reset atomic counters
  5694. p->numAssertsFailedCurrentTest_atomic = 0;
  5695. p->numAssertsCurrentTest_atomic = 0;
  5696. p->subcasesPassed.clear();
  5697. DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_start, tc);
  5698. p->timer.start();
  5699. bool run_test = true;
  5700. do {
  5701. // reset some of the fields for subcases (except for the set of fully passed ones)
  5702. p->should_reenter = false;
  5703. p->subcasesCurrentMaxLevel = 0;
  5704. p->subcasesStack.clear();
  5705. p->shouldLogCurrentException = true;
  5706. // reset stuff for logging with INFO()
  5707. p->stringifiedContexts.clear();
  5708. #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
  5709. try {
  5710. #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
  5711. // MSVC 2015 diagnoses fatalConditionHandler as unused (because reset() is a static method)
  5712. DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4101) // unreferenced local variable
  5713. FatalConditionHandler fatalConditionHandler; // Handle signals
  5714. // execute the test
  5715. tc.m_test();
  5716. fatalConditionHandler.reset();
  5717. DOCTEST_MSVC_SUPPRESS_WARNING_POP
  5718. #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
  5719. } catch(const TestFailureException&) {
  5720. p->failure_flags |= TestCaseFailureReason::AssertFailure;
  5721. } catch(...) {
  5722. DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_exception,
  5723. {translateActiveException(), false});
  5724. p->failure_flags |= TestCaseFailureReason::Exception;
  5725. }
  5726. #endif // DOCTEST_CONFIG_NO_EXCEPTIONS
  5727. // exit this loop if enough assertions have failed - even if there are more subcases
  5728. if(p->abort_after > 0 &&
  5729. p->numAssertsFailed + p->numAssertsFailedCurrentTest_atomic >= p->abort_after) {
  5730. run_test = false;
  5731. p->failure_flags |= TestCaseFailureReason::TooManyFailedAsserts;
  5732. }
  5733. if(p->should_reenter && run_test)
  5734. DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_reenter, tc);
  5735. if(!p->should_reenter)
  5736. run_test = false;
  5737. } while(run_test);
  5738. p->finalizeTestCaseData();
  5739. DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_end, *g_cs);
  5740. p->currentTest = nullptr;
  5741. // stop executing tests if enough assertions have failed
  5742. if(p->abort_after > 0 && p->numAssertsFailed >= p->abort_after)
  5743. break;
  5744. }
  5745. }
  5746. if(!query_mode) {
  5747. DOCTEST_ITERATE_THROUGH_REPORTERS(test_run_end, *g_cs);
  5748. } else {
  5749. QueryData qdata;
  5750. qdata.run_stats = g_cs;
  5751. qdata.data = queryResults.data();
  5752. qdata.num_data = unsigned(queryResults.size());
  5753. DOCTEST_ITERATE_THROUGH_REPORTERS(report_query, qdata);
  5754. }
  5755. return cleanup_and_return();
  5756. }
  5757. IReporter::~IReporter() = default;
  5758. int IReporter::get_num_active_contexts() { return detail::g_infoContexts.size(); }
  5759. const IContextScope* const* IReporter::get_active_contexts() {
  5760. return get_num_active_contexts() ? &detail::g_infoContexts[0] : nullptr;
  5761. }
  5762. int IReporter::get_num_stringified_contexts() { return detail::g_cs->stringifiedContexts.size(); }
  5763. const String* IReporter::get_stringified_contexts() {
  5764. return get_num_stringified_contexts() ? &detail::g_cs->stringifiedContexts[0] : nullptr;
  5765. }
  5766. namespace detail {
  5767. void registerReporterImpl(const char* name, int priority, reporterCreatorFunc c, bool isReporter) {
  5768. if(isReporter)
  5769. getReporters().insert(reporterMap::value_type(reporterMap::key_type(priority, name), c));
  5770. else
  5771. getListeners().insert(reporterMap::value_type(reporterMap::key_type(priority, name), c));
  5772. }
  5773. } // namespace detail
  5774. } // namespace doctest
  5775. #endif // DOCTEST_CONFIG_DISABLE
  5776. #ifdef DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
  5777. DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4007) // 'function' : must be 'attribute' - see issue #182
  5778. int main(int argc, char** argv) { return doctest::Context(argc, argv).run(); }
  5779. DOCTEST_MSVC_SUPPRESS_WARNING_POP
  5780. #endif // DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
  5781. DOCTEST_CLANG_SUPPRESS_WARNING_POP
  5782. DOCTEST_MSVC_SUPPRESS_WARNING_POP
  5783. DOCTEST_GCC_SUPPRESS_WARNING_POP
  5784. DOCTEST_SUPPRESS_COMMON_WARNINGS_POP
  5785. #endif // DOCTEST_LIBRARY_IMPLEMENTATION
  5786. #endif // DOCTEST_CONFIG_IMPLEMENT