You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

doctest.h 292KB

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