catch.hpp 329 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460
  1. /*
  2. * CATCH v1.1 build 3 (master branch)
  3. * Generated: 2015-05-21 06:16:00.388118
  4. * ----------------------------------------------------------
  5. * This file has been merged from multiple headers. Please don't edit it directly
  6. * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
  7. *
  8. * Distributed under the Boost Software License, Version 1.0. (See accompanying
  9. * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  10. */
  11. #ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
  12. #define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
  13. #define TWOBLUECUBES_CATCH_HPP_INCLUDED
  14. #ifdef __clang__
  15. # pragma clang system_header
  16. #elif defined __GNUC__
  17. # pragma GCC system_header
  18. #endif
  19. // #included from: internal/catch_suppress_warnings.h
  20. #define TWOBLUECUBES_CATCH_SUPPRESS_WARNINGS_H_INCLUDED
  21. #ifdef __clang__
  22. # ifdef __ICC // icpc defines the __clang__ macro
  23. # pragma warning(push)
  24. # pragma warning(disable: 161 1682)
  25. # else // __ICC
  26. # pragma clang diagnostic ignored "-Wglobal-constructors"
  27. # pragma clang diagnostic ignored "-Wvariadic-macros"
  28. # pragma clang diagnostic ignored "-Wc99-extensions"
  29. # pragma clang diagnostic ignored "-Wunused-variable"
  30. # pragma clang diagnostic push
  31. # pragma clang diagnostic ignored "-Wpadded"
  32. # pragma clang diagnostic ignored "-Wc++98-compat"
  33. # pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
  34. # pragma clang diagnostic ignored "-Wswitch-enum"
  35. # endif
  36. #elif defined __GNUC__
  37. # pragma GCC diagnostic ignored "-Wvariadic-macros"
  38. # pragma GCC diagnostic ignored "-Wunused-variable"
  39. # pragma GCC diagnostic push
  40. # pragma GCC diagnostic ignored "-Wpadded"
  41. #endif
  42. #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
  43. # define CATCH_IMPL
  44. #endif
  45. #ifdef CATCH_IMPL
  46. # ifndef CLARA_CONFIG_MAIN
  47. # define CLARA_CONFIG_MAIN_NOT_DEFINED
  48. # define CLARA_CONFIG_MAIN
  49. # endif
  50. #endif
  51. // #included from: internal/catch_notimplemented_exception.h
  52. #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED
  53. // #included from: catch_common.h
  54. #define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED
  55. #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
  56. #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
  57. #define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
  58. #define INTERNAL_CATCH_STRINGIFY2( expr ) #expr
  59. #define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
  60. #include <sstream>
  61. #include <stdexcept>
  62. #include <algorithm>
  63. // #included from: catch_compiler_capabilities.h
  64. #define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
  65. // Detect a number of compiler features - mostly C++11/14 conformance - by compiler
  66. // The following features are defined:
  67. //
  68. // CATCH_CONFIG_CPP11_NULLPTR : is nullptr supported?
  69. // CATCH_CONFIG_CPP11_NOEXCEPT : is noexcept supported?
  70. // CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods
  71. // CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported?
  72. // CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported
  73. // CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
  74. // CATCH_CONFIG_SFINAE : is basic (C++03) SFINAE supported?
  75. // CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported?
  76. // A lot of this code is based on Boost (1.53)
  77. #ifdef __clang__
  78. # if __has_feature(cxx_nullptr)
  79. # define CATCH_CONFIG_CPP11_NULLPTR
  80. # endif
  81. # if __has_feature(cxx_noexcept)
  82. # define CATCH_CONFIG_CPP11_NOEXCEPT
  83. # endif
  84. #endif // __clang__
  85. ////////////////////////////////////////////////////////////////////////////////
  86. // Borland
  87. #ifdef __BORLANDC__
  88. #if (__BORLANDC__ > 0x582 )
  89. //#define CATCH_CONFIG_SFINAE // Not confirmed
  90. #endif
  91. #endif // __BORLANDC__
  92. ////////////////////////////////////////////////////////////////////////////////
  93. // EDG
  94. #ifdef __EDG_VERSION__
  95. #if (__EDG_VERSION__ > 238 )
  96. //#define CATCH_CONFIG_SFINAE // Not confirmed
  97. #endif
  98. #endif // __EDG_VERSION__
  99. ////////////////////////////////////////////////////////////////////////////////
  100. // Digital Mars
  101. #ifdef __DMC__
  102. #if (__DMC__ > 0x840 )
  103. //#define CATCH_CONFIG_SFINAE // Not confirmed
  104. #endif
  105. #endif // __DMC__
  106. ////////////////////////////////////////////////////////////////////////////////
  107. // GCC
  108. #ifdef __GNUC__
  109. #if __GNUC__ < 3
  110. #if (__GNUC_MINOR__ >= 96 )
  111. //#define CATCH_CONFIG_SFINAE
  112. #endif
  113. #elif __GNUC__ >= 3
  114. // #define CATCH_CONFIG_SFINAE // Taking this out completely for now
  115. #endif // __GNUC__ < 3
  116. #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) )
  117. #define CATCH_CONFIG_CPP11_NULLPTR
  118. #endif
  119. #endif // __GNUC__
  120. ////////////////////////////////////////////////////////////////////////////////
  121. // Visual C++
  122. #ifdef _MSC_VER
  123. #if (_MSC_VER >= 1310 ) // (VC++ 7.0+)
  124. //#define CATCH_CONFIG_SFINAE // Not confirmed
  125. #endif
  126. #if (_MSC_VER >= 1600)
  127. #define CATCH_CONFIG_CPP11_NULLPTR
  128. #endif
  129. #if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))
  130. #define CATCH_CONFIG_CPP11_NOEXCEPT
  131. #define CATCH_CONFIG_CPP11_GENERATED_METHODS
  132. #endif
  133. #endif // _MSC_VER
  134. // Use variadic macros if the compiler supports them
  135. #if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \
  136. ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \
  137. ( defined __GNUC__ && __GNUC__ >= 3 ) || \
  138. ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L )
  139. #ifndef CATCH_CONFIG_NO_VARIADIC_MACROS
  140. #define CATCH_CONFIG_VARIADIC_MACROS
  141. #endif
  142. #endif
  143. ////////////////////////////////////////////////////////////////////////////////
  144. // C++ language feature support
  145. // catch all support for C++11
  146. #if (__cplusplus >= 201103L)
  147. # define CATCH_CPP11_OR_GREATER
  148. # ifndef CATCH_CONFIG_CPP11_NULLPTR
  149. # define CATCH_CONFIG_CPP11_NULLPTR
  150. # endif
  151. # ifndef CATCH_CONFIG_CPP11_NOEXCEPT
  152. # define CATCH_CONFIG_CPP11_NOEXCEPT
  153. # endif
  154. # ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS
  155. # define CATCH_CONFIG_CPP11_GENERATED_METHODS
  156. # endif
  157. # ifndef CATCH_CONFIG_CPP11_IS_ENUM
  158. # define CATCH_CONFIG_CPP11_IS_ENUM
  159. # endif
  160. # ifndef CATCH_CONFIG_CPP11_TUPLE
  161. # define CATCH_CONFIG_CPP11_TUPLE
  162. # endif
  163. # ifndef CATCH_CONFIG_SFINAE
  164. //# define CATCH_CONFIG_SFINAE // Don't use, for now
  165. # endif
  166. # ifndef CATCH_CONFIG_VARIADIC_MACROS
  167. # define CATCH_CONFIG_VARIADIC_MACROS
  168. # endif
  169. #endif // __cplusplus >= 201103L
  170. // noexcept support:
  171. #if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT)
  172. # define CATCH_NOEXCEPT noexcept
  173. # define CATCH_NOEXCEPT_IS(x) noexcept(x)
  174. #else
  175. # define CATCH_NOEXCEPT throw()
  176. # define CATCH_NOEXCEPT_IS(x)
  177. #endif
  178. namespace Catch {
  179. class NonCopyable {
  180. #ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
  181. NonCopyable( NonCopyable const& ) = delete;
  182. NonCopyable( NonCopyable && ) = delete;
  183. NonCopyable& operator = ( NonCopyable const& ) = delete;
  184. NonCopyable& operator = ( NonCopyable && ) = delete;
  185. #else
  186. NonCopyable( NonCopyable const& info );
  187. NonCopyable& operator = ( NonCopyable const& );
  188. #endif
  189. protected:
  190. NonCopyable() {}
  191. virtual ~NonCopyable();
  192. };
  193. class SafeBool {
  194. public:
  195. typedef void (SafeBool::*type)() const;
  196. static type makeSafe( bool value ) {
  197. return value ? &SafeBool::trueValue : 0;
  198. }
  199. private:
  200. void trueValue() const {}
  201. };
  202. template<typename ContainerT>
  203. inline void deleteAll( ContainerT& container ) {
  204. typename ContainerT::const_iterator it = container.begin();
  205. typename ContainerT::const_iterator itEnd = container.end();
  206. for(; it != itEnd; ++it )
  207. delete *it;
  208. }
  209. template<typename AssociativeContainerT>
  210. inline void deleteAllValues( AssociativeContainerT& container ) {
  211. typename AssociativeContainerT::const_iterator it = container.begin();
  212. typename AssociativeContainerT::const_iterator itEnd = container.end();
  213. for(; it != itEnd; ++it )
  214. delete it->second;
  215. }
  216. bool startsWith( std::string const& s, std::string const& prefix );
  217. bool endsWith( std::string const& s, std::string const& suffix );
  218. bool contains( std::string const& s, std::string const& infix );
  219. void toLowerInPlace( std::string& s );
  220. std::string toLower( std::string const& s );
  221. std::string trim( std::string const& str );
  222. bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
  223. struct pluralise {
  224. pluralise( std::size_t count, std::string const& label );
  225. friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
  226. std::size_t m_count;
  227. std::string m_label;
  228. };
  229. struct SourceLineInfo {
  230. SourceLineInfo();
  231. SourceLineInfo( char const* _file, std::size_t _line );
  232. SourceLineInfo( SourceLineInfo const& other );
  233. # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
  234. SourceLineInfo( SourceLineInfo && ) = default;
  235. SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
  236. SourceLineInfo& operator = ( SourceLineInfo && ) = default;
  237. # endif
  238. bool empty() const;
  239. bool operator == ( SourceLineInfo const& other ) const;
  240. bool operator < ( SourceLineInfo const& other ) const;
  241. std::string file;
  242. std::size_t line;
  243. };
  244. std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
  245. // This is just here to avoid compiler warnings with macro constants and boolean literals
  246. inline bool isTrue( bool value ){ return value; }
  247. inline bool alwaysTrue() { return true; }
  248. inline bool alwaysFalse() { return false; }
  249. void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo );
  250. // Use this in variadic streaming macros to allow
  251. // >> +StreamEndStop
  252. // as well as
  253. // >> stuff +StreamEndStop
  254. struct StreamEndStop {
  255. std::string operator+() {
  256. return std::string();
  257. }
  258. };
  259. template<typename T>
  260. T const& operator + ( T const& value, StreamEndStop ) {
  261. return value;
  262. }
  263. }
  264. #define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
  265. #define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO );
  266. #include <ostream>
  267. namespace Catch {
  268. class NotImplementedException : public std::exception
  269. {
  270. public:
  271. NotImplementedException( SourceLineInfo const& lineInfo );
  272. NotImplementedException( NotImplementedException const& ) {}
  273. virtual ~NotImplementedException() CATCH_NOEXCEPT {}
  274. virtual const char* what() const CATCH_NOEXCEPT;
  275. private:
  276. std::string m_what;
  277. SourceLineInfo m_lineInfo;
  278. };
  279. } // end namespace Catch
  280. ///////////////////////////////////////////////////////////////////////////////
  281. #define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO )
  282. // #included from: internal/catch_context.h
  283. #define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED
  284. // #included from: catch_interfaces_generators.h
  285. #define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED
  286. #include <string>
  287. namespace Catch {
  288. struct IGeneratorInfo {
  289. virtual ~IGeneratorInfo();
  290. virtual bool moveNext() = 0;
  291. virtual std::size_t getCurrentIndex() const = 0;
  292. };
  293. struct IGeneratorsForTest {
  294. virtual ~IGeneratorsForTest();
  295. virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0;
  296. virtual bool moveNext() = 0;
  297. };
  298. IGeneratorsForTest* createGeneratorsForTest();
  299. } // end namespace Catch
  300. // #included from: catch_ptr.hpp
  301. #define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED
  302. #ifdef __clang__
  303. #pragma clang diagnostic push
  304. #pragma clang diagnostic ignored "-Wpadded"
  305. #endif
  306. namespace Catch {
  307. // An intrusive reference counting smart pointer.
  308. // T must implement addRef() and release() methods
  309. // typically implementing the IShared interface
  310. template<typename T>
  311. class Ptr {
  312. public:
  313. Ptr() : m_p( NULL ){}
  314. Ptr( T* p ) : m_p( p ){
  315. if( m_p )
  316. m_p->addRef();
  317. }
  318. Ptr( Ptr const& other ) : m_p( other.m_p ){
  319. if( m_p )
  320. m_p->addRef();
  321. }
  322. ~Ptr(){
  323. if( m_p )
  324. m_p->release();
  325. }
  326. void reset() {
  327. if( m_p )
  328. m_p->release();
  329. m_p = NULL;
  330. }
  331. Ptr& operator = ( T* p ){
  332. Ptr temp( p );
  333. swap( temp );
  334. return *this;
  335. }
  336. Ptr& operator = ( Ptr const& other ){
  337. Ptr temp( other );
  338. swap( temp );
  339. return *this;
  340. }
  341. void swap( Ptr& other ) { std::swap( m_p, other.m_p ); }
  342. T* get() { return m_p; }
  343. const T* get() const{ return m_p; }
  344. T& operator*() const { return *m_p; }
  345. T* operator->() const { return m_p; }
  346. bool operator !() const { return m_p == NULL; }
  347. operator SafeBool::type() const { return SafeBool::makeSafe( m_p != NULL ); }
  348. private:
  349. T* m_p;
  350. };
  351. struct IShared : NonCopyable {
  352. virtual ~IShared();
  353. virtual void addRef() const = 0;
  354. virtual void release() const = 0;
  355. };
  356. template<typename T = IShared>
  357. struct SharedImpl : T {
  358. SharedImpl() : m_rc( 0 ){}
  359. virtual void addRef() const {
  360. ++m_rc;
  361. }
  362. virtual void release() const {
  363. if( --m_rc == 0 )
  364. delete this;
  365. }
  366. mutable unsigned int m_rc;
  367. };
  368. } // end namespace Catch
  369. #ifdef __clang__
  370. #pragma clang diagnostic pop
  371. #endif
  372. #include <memory>
  373. #include <vector>
  374. #include <stdlib.h>
  375. namespace Catch {
  376. class TestCase;
  377. class Stream;
  378. struct IResultCapture;
  379. struct IRunner;
  380. struct IGeneratorsForTest;
  381. struct IConfig;
  382. struct IContext
  383. {
  384. virtual ~IContext();
  385. virtual IResultCapture* getResultCapture() = 0;
  386. virtual IRunner* getRunner() = 0;
  387. virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0;
  388. virtual bool advanceGeneratorsForCurrentTest() = 0;
  389. virtual Ptr<IConfig const> getConfig() const = 0;
  390. };
  391. struct IMutableContext : IContext
  392. {
  393. virtual ~IMutableContext();
  394. virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
  395. virtual void setRunner( IRunner* runner ) = 0;
  396. virtual void setConfig( Ptr<IConfig const> const& config ) = 0;
  397. };
  398. IContext& getCurrentContext();
  399. IMutableContext& getCurrentMutableContext();
  400. void cleanUpContext();
  401. Stream createStream( std::string const& streamName );
  402. }
  403. // #included from: internal/catch_test_registry.hpp
  404. #define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
  405. // #included from: catch_interfaces_testcase.h
  406. #define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED
  407. #include <vector>
  408. namespace Catch {
  409. class TestSpec;
  410. struct ITestCase : IShared {
  411. virtual void invoke () const = 0;
  412. protected:
  413. virtual ~ITestCase();
  414. };
  415. class TestCase;
  416. struct IConfig;
  417. struct ITestCaseRegistry {
  418. virtual ~ITestCaseRegistry();
  419. virtual std::vector<TestCase> const& getAllTests() const = 0;
  420. virtual void getFilteredTests( TestSpec const& testSpec, IConfig const& config, std::vector<TestCase>& matchingTestCases, bool negated = false ) const = 0;
  421. };
  422. }
  423. namespace Catch {
  424. template<typename C>
  425. class MethodTestCase : public SharedImpl<ITestCase> {
  426. public:
  427. MethodTestCase( void (C::*method)() ) : m_method( method ) {}
  428. virtual void invoke() const {
  429. C obj;
  430. (obj.*m_method)();
  431. }
  432. private:
  433. virtual ~MethodTestCase() {}
  434. void (C::*m_method)();
  435. };
  436. typedef void(*TestFunction)();
  437. struct NameAndDesc {
  438. NameAndDesc( const char* _name = "", const char* _description= "" )
  439. : name( _name ), description( _description )
  440. {}
  441. const char* name;
  442. const char* description;
  443. };
  444. struct AutoReg {
  445. AutoReg( TestFunction function,
  446. SourceLineInfo const& lineInfo,
  447. NameAndDesc const& nameAndDesc );
  448. template<typename C>
  449. AutoReg( void (C::*method)(),
  450. char const* className,
  451. NameAndDesc const& nameAndDesc,
  452. SourceLineInfo const& lineInfo ) {
  453. registerTestCase( new MethodTestCase<C>( method ),
  454. className,
  455. nameAndDesc,
  456. lineInfo );
  457. }
  458. void registerTestCase( ITestCase* testCase,
  459. char const* className,
  460. NameAndDesc const& nameAndDesc,
  461. SourceLineInfo const& lineInfo );
  462. ~AutoReg();
  463. private:
  464. AutoReg( AutoReg const& );
  465. void operator= ( AutoReg const& );
  466. };
  467. } // end namespace Catch
  468. #ifdef CATCH_CONFIG_VARIADIC_MACROS
  469. ///////////////////////////////////////////////////////////////////////////////
  470. #define INTERNAL_CATCH_TESTCASE( ... ) \
  471. static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \
  472. namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\
  473. static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )()
  474. ///////////////////////////////////////////////////////////////////////////////
  475. #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
  476. namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); }
  477. ///////////////////////////////////////////////////////////////////////////////
  478. #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... )\
  479. namespace{ \
  480. struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \
  481. void test(); \
  482. }; \
  483. Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \
  484. } \
  485. void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
  486. #else
  487. ///////////////////////////////////////////////////////////////////////////////
  488. #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
  489. static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \
  490. namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\
  491. static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )()
  492. ///////////////////////////////////////////////////////////////////////////////
  493. #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
  494. namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); }
  495. ///////////////////////////////////////////////////////////////////////////////
  496. #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
  497. namespace{ \
  498. struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \
  499. void test(); \
  500. }; \
  501. Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \
  502. } \
  503. void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
  504. #endif
  505. // #included from: internal/catch_capture.hpp
  506. #define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
  507. // #included from: catch_result_builder.h
  508. #define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED
  509. // #included from: catch_result_type.h
  510. #define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED
  511. namespace Catch {
  512. // ResultWas::OfType enum
  513. struct ResultWas { enum OfType {
  514. Unknown = -1,
  515. Ok = 0,
  516. Info = 1,
  517. Warning = 2,
  518. FailureBit = 0x10,
  519. ExpressionFailed = FailureBit | 1,
  520. ExplicitFailure = FailureBit | 2,
  521. Exception = 0x100 | FailureBit,
  522. ThrewException = Exception | 1,
  523. DidntThrowException = Exception | 2,
  524. FatalErrorCondition = 0x200 | FailureBit
  525. }; };
  526. inline bool isOk( ResultWas::OfType resultType ) {
  527. return ( resultType & ResultWas::FailureBit ) == 0;
  528. }
  529. inline bool isJustInfo( int flags ) {
  530. return flags == ResultWas::Info;
  531. }
  532. // ResultDisposition::Flags enum
  533. struct ResultDisposition { enum Flags {
  534. Normal = 0x01,
  535. ContinueOnFailure = 0x02, // Failures fail test, but execution continues
  536. FalseTest = 0x04, // Prefix expression with !
  537. SuppressFail = 0x08 // Failures are reported but do not fail the test
  538. }; };
  539. inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
  540. return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
  541. }
  542. inline bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
  543. inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
  544. inline bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; }
  545. } // end namespace Catch
  546. // #included from: catch_assertionresult.h
  547. #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED
  548. #include <string>
  549. namespace Catch {
  550. struct AssertionInfo
  551. {
  552. AssertionInfo() {}
  553. AssertionInfo( std::string const& _macroName,
  554. SourceLineInfo const& _lineInfo,
  555. std::string const& _capturedExpression,
  556. ResultDisposition::Flags _resultDisposition );
  557. std::string macroName;
  558. SourceLineInfo lineInfo;
  559. std::string capturedExpression;
  560. ResultDisposition::Flags resultDisposition;
  561. };
  562. struct AssertionResultData
  563. {
  564. AssertionResultData() : resultType( ResultWas::Unknown ) {}
  565. std::string reconstructedExpression;
  566. std::string message;
  567. ResultWas::OfType resultType;
  568. };
  569. class AssertionResult {
  570. public:
  571. AssertionResult();
  572. AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
  573. ~AssertionResult();
  574. # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
  575. AssertionResult( AssertionResult const& ) = default;
  576. AssertionResult( AssertionResult && ) = default;
  577. AssertionResult& operator = ( AssertionResult const& ) = default;
  578. AssertionResult& operator = ( AssertionResult && ) = default;
  579. # endif
  580. bool isOk() const;
  581. bool succeeded() const;
  582. ResultWas::OfType getResultType() const;
  583. bool hasExpression() const;
  584. bool hasMessage() const;
  585. std::string getExpression() const;
  586. std::string getExpressionInMacro() const;
  587. bool hasExpandedExpression() const;
  588. std::string getExpandedExpression() const;
  589. std::string getMessage() const;
  590. SourceLineInfo getSourceInfo() const;
  591. std::string getTestMacroName() const;
  592. protected:
  593. AssertionInfo m_info;
  594. AssertionResultData m_resultData;
  595. };
  596. } // end namespace Catch
  597. namespace Catch {
  598. struct TestFailureException{};
  599. template<typename T> class ExpressionLhs;
  600. struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
  601. struct CopyableStream {
  602. CopyableStream() {}
  603. CopyableStream( CopyableStream const& other ) {
  604. oss << other.oss.str();
  605. }
  606. CopyableStream& operator=( CopyableStream const& other ) {
  607. oss.str("");
  608. oss << other.oss.str();
  609. return *this;
  610. }
  611. std::ostringstream oss;
  612. };
  613. class ResultBuilder {
  614. public:
  615. ResultBuilder( char const* macroName,
  616. SourceLineInfo const& lineInfo,
  617. char const* capturedExpression,
  618. ResultDisposition::Flags resultDisposition );
  619. template<typename T>
  620. ExpressionLhs<T const&> operator->* ( T const& operand );
  621. ExpressionLhs<bool> operator->* ( bool value );
  622. template<typename T>
  623. ResultBuilder& operator << ( T const& value ) {
  624. m_stream.oss << value;
  625. return *this;
  626. }
  627. template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
  628. template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
  629. ResultBuilder& setResultType( ResultWas::OfType result );
  630. ResultBuilder& setResultType( bool result );
  631. ResultBuilder& setLhs( std::string const& lhs );
  632. ResultBuilder& setRhs( std::string const& rhs );
  633. ResultBuilder& setOp( std::string const& op );
  634. void endExpression();
  635. std::string reconstructExpression() const;
  636. AssertionResult build() const;
  637. void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal );
  638. void captureResult( ResultWas::OfType resultType );
  639. void captureExpression();
  640. void react();
  641. bool shouldDebugBreak() const;
  642. bool allowThrows() const;
  643. private:
  644. AssertionInfo m_assertionInfo;
  645. AssertionResultData m_data;
  646. struct ExprComponents {
  647. ExprComponents() : testFalse( false ) {}
  648. bool testFalse;
  649. std::string lhs, rhs, op;
  650. } m_exprComponents;
  651. CopyableStream m_stream;
  652. bool m_shouldDebugBreak;
  653. bool m_shouldThrow;
  654. };
  655. } // namespace Catch
  656. // Include after due to circular dependency:
  657. // #included from: catch_expression_lhs.hpp
  658. #define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED
  659. // #included from: catch_evaluate.hpp
  660. #define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED
  661. #ifdef _MSC_VER
  662. #pragma warning(push)
  663. #pragma warning(disable:4389) // '==' : signed/unsigned mismatch
  664. #endif
  665. #include <cstddef>
  666. namespace Catch {
  667. namespace Internal {
  668. enum Operator {
  669. IsEqualTo,
  670. IsNotEqualTo,
  671. IsLessThan,
  672. IsGreaterThan,
  673. IsLessThanOrEqualTo,
  674. IsGreaterThanOrEqualTo
  675. };
  676. template<Operator Op> struct OperatorTraits { static const char* getName(){ return "*error*"; } };
  677. template<> struct OperatorTraits<IsEqualTo> { static const char* getName(){ return "=="; } };
  678. template<> struct OperatorTraits<IsNotEqualTo> { static const char* getName(){ return "!="; } };
  679. template<> struct OperatorTraits<IsLessThan> { static const char* getName(){ return "<"; } };
  680. template<> struct OperatorTraits<IsGreaterThan> { static const char* getName(){ return ">"; } };
  681. template<> struct OperatorTraits<IsLessThanOrEqualTo> { static const char* getName(){ return "<="; } };
  682. template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } };
  683. template<typename T>
  684. inline T& opCast(T const& t) { return const_cast<T&>(t); }
  685. // nullptr_t support based on pull request #154 from Konstantin Baumann
  686. #ifdef CATCH_CONFIG_CPP11_NULLPTR
  687. inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; }
  688. #endif // CATCH_CONFIG_CPP11_NULLPTR
  689. // So the compare overloads can be operator agnostic we convey the operator as a template
  690. // enum, which is used to specialise an Evaluator for doing the comparison.
  691. template<typename T1, typename T2, Operator Op>
  692. class Evaluator{};
  693. template<typename T1, typename T2>
  694. struct Evaluator<T1, T2, IsEqualTo> {
  695. static bool evaluate( T1 const& lhs, T2 const& rhs) {
  696. return opCast( lhs ) == opCast( rhs );
  697. }
  698. };
  699. template<typename T1, typename T2>
  700. struct Evaluator<T1, T2, IsNotEqualTo> {
  701. static bool evaluate( T1 const& lhs, T2 const& rhs ) {
  702. return opCast( lhs ) != opCast( rhs );
  703. }
  704. };
  705. template<typename T1, typename T2>
  706. struct Evaluator<T1, T2, IsLessThan> {
  707. static bool evaluate( T1 const& lhs, T2 const& rhs ) {
  708. return opCast( lhs ) < opCast( rhs );
  709. }
  710. };
  711. template<typename T1, typename T2>
  712. struct Evaluator<T1, T2, IsGreaterThan> {
  713. static bool evaluate( T1 const& lhs, T2 const& rhs ) {
  714. return opCast( lhs ) > opCast( rhs );
  715. }
  716. };
  717. template<typename T1, typename T2>
  718. struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {
  719. static bool evaluate( T1 const& lhs, T2 const& rhs ) {
  720. return opCast( lhs ) >= opCast( rhs );
  721. }
  722. };
  723. template<typename T1, typename T2>
  724. struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
  725. static bool evaluate( T1 const& lhs, T2 const& rhs ) {
  726. return opCast( lhs ) <= opCast( rhs );
  727. }
  728. };
  729. template<Operator Op, typename T1, typename T2>
  730. bool applyEvaluator( T1 const& lhs, T2 const& rhs ) {
  731. return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
  732. }
  733. // This level of indirection allows us to specialise for integer types
  734. // to avoid signed/ unsigned warnings
  735. // "base" overload
  736. template<Operator Op, typename T1, typename T2>
  737. bool compare( T1 const& lhs, T2 const& rhs ) {
  738. return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
  739. }
  740. // unsigned X to int
  741. template<Operator Op> bool compare( unsigned int lhs, int rhs ) {
  742. return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
  743. }
  744. template<Operator Op> bool compare( unsigned long lhs, int rhs ) {
  745. return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
  746. }
  747. template<Operator Op> bool compare( unsigned char lhs, int rhs ) {
  748. return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
  749. }
  750. // unsigned X to long
  751. template<Operator Op> bool compare( unsigned int lhs, long rhs ) {
  752. return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
  753. }
  754. template<Operator Op> bool compare( unsigned long lhs, long rhs ) {
  755. return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
  756. }
  757. template<Operator Op> bool compare( unsigned char lhs, long rhs ) {
  758. return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
  759. }
  760. // int to unsigned X
  761. template<Operator Op> bool compare( int lhs, unsigned int rhs ) {
  762. return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
  763. }
  764. template<Operator Op> bool compare( int lhs, unsigned long rhs ) {
  765. return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
  766. }
  767. template<Operator Op> bool compare( int lhs, unsigned char rhs ) {
  768. return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
  769. }
  770. // long to unsigned X
  771. template<Operator Op> bool compare( long lhs, unsigned int rhs ) {
  772. return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
  773. }
  774. template<Operator Op> bool compare( long lhs, unsigned long rhs ) {
  775. return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
  776. }
  777. template<Operator Op> bool compare( long lhs, unsigned char rhs ) {
  778. return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
  779. }
  780. // pointer to long (when comparing against NULL)
  781. template<Operator Op, typename T> bool compare( long lhs, T* rhs ) {
  782. return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
  783. }
  784. template<Operator Op, typename T> bool compare( T* lhs, long rhs ) {
  785. return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
  786. }
  787. // pointer to int (when comparing against NULL)
  788. template<Operator Op, typename T> bool compare( int lhs, T* rhs ) {
  789. return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
  790. }
  791. template<Operator Op, typename T> bool compare( T* lhs, int rhs ) {
  792. return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
  793. }
  794. #ifdef CATCH_CONFIG_CPP11_NULLPTR
  795. // pointer to nullptr_t (when comparing against nullptr)
  796. template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) {
  797. return Evaluator<T*, T*, Op>::evaluate( NULL, rhs );
  798. }
  799. template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t ) {
  800. return Evaluator<T*, T*, Op>::evaluate( lhs, NULL );
  801. }
  802. #endif // CATCH_CONFIG_CPP11_NULLPTR
  803. } // end of namespace Internal
  804. } // end of namespace Catch
  805. #ifdef _MSC_VER
  806. #pragma warning(pop)
  807. #endif
  808. // #included from: catch_tostring.h
  809. #define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED
  810. // #included from: catch_sfinae.hpp
  811. #define TWOBLUECUBES_CATCH_SFINAE_HPP_INCLUDED
  812. // Try to detect if the current compiler supports SFINAE
  813. namespace Catch {
  814. struct TrueType {
  815. static const bool value = true;
  816. typedef void Enable;
  817. char sizer[1];
  818. };
  819. struct FalseType {
  820. static const bool value = false;
  821. typedef void Disable;
  822. char sizer[2];
  823. };
  824. #ifdef CATCH_CONFIG_SFINAE
  825. template<bool> struct NotABooleanExpression;
  826. template<bool c> struct If : NotABooleanExpression<c> {};
  827. template<> struct If<true> : TrueType {};
  828. template<> struct If<false> : FalseType {};
  829. template<int size> struct SizedIf;
  830. template<> struct SizedIf<sizeof(TrueType)> : TrueType {};
  831. template<> struct SizedIf<sizeof(FalseType)> : FalseType {};
  832. #endif // CATCH_CONFIG_SFINAE
  833. } // end namespace Catch
  834. #include <sstream>
  835. #include <iomanip>
  836. #include <limits>
  837. #include <vector>
  838. #include <cstddef>
  839. #ifdef __OBJC__
  840. // #included from: catch_objc_arc.hpp
  841. #define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED
  842. #import <Foundation/Foundation.h>
  843. #ifdef __has_feature
  844. #define CATCH_ARC_ENABLED __has_feature(objc_arc)
  845. #else
  846. #define CATCH_ARC_ENABLED 0
  847. #endif
  848. void arcSafeRelease( NSObject* obj );
  849. id performOptionalSelector( id obj, SEL sel );
  850. #if !CATCH_ARC_ENABLED
  851. inline void arcSafeRelease( NSObject* obj ) {
  852. [obj release];
  853. }
  854. inline id performOptionalSelector( id obj, SEL sel ) {
  855. if( [obj respondsToSelector: sel] )
  856. return [obj performSelector: sel];
  857. return nil;
  858. }
  859. #define CATCH_UNSAFE_UNRETAINED
  860. #define CATCH_ARC_STRONG
  861. #else
  862. inline void arcSafeRelease( NSObject* ){}
  863. inline id performOptionalSelector( id obj, SEL sel ) {
  864. #ifdef __clang__
  865. #pragma clang diagnostic push
  866. #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
  867. #endif
  868. if( [obj respondsToSelector: sel] )
  869. return [obj performSelector: sel];
  870. #ifdef __clang__
  871. #pragma clang diagnostic pop
  872. #endif
  873. return nil;
  874. }
  875. #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
  876. #define CATCH_ARC_STRONG __strong
  877. #endif
  878. #endif
  879. #ifdef CATCH_CONFIG_CPP11_TUPLE
  880. #include <tuple>
  881. #endif
  882. #ifdef CATCH_CONFIG_CPP11_IS_ENUM
  883. #include <type_traits>
  884. #endif
  885. namespace Catch {
  886. // Why we're here.
  887. template<typename T>
  888. std::string toString( T const& value );
  889. // Built in overloads
  890. std::string toString( std::string const& value );
  891. std::string toString( std::wstring const& value );
  892. std::string toString( const char* const value );
  893. std::string toString( char* const value );
  894. std::string toString( const wchar_t* const value );
  895. std::string toString( wchar_t* const value );
  896. std::string toString( int value );
  897. std::string toString( unsigned long value );
  898. std::string toString( unsigned int value );
  899. std::string toString( const double value );
  900. std::string toString( const float value );
  901. std::string toString( bool value );
  902. std::string toString( char value );
  903. std::string toString( signed char value );
  904. std::string toString( unsigned char value );
  905. #ifdef CATCH_CONFIG_CPP11_NULLPTR
  906. std::string toString( std::nullptr_t );
  907. #endif
  908. #ifdef __OBJC__
  909. std::string toString( NSString const * const& nsstring );
  910. std::string toString( NSString * CATCH_ARC_STRONG const& nsstring );
  911. std::string toString( NSObject* const& nsObject );
  912. #endif
  913. namespace Detail {
  914. extern std::string unprintableString;
  915. // SFINAE is currently disabled by default for all compilers.
  916. // If the non SFINAE version of IsStreamInsertable is ambiguous for you
  917. // and your compiler supports SFINAE, try #defining CATCH_CONFIG_SFINAE
  918. #ifdef CATCH_CONFIG_SFINAE
  919. template<typename T>
  920. class IsStreamInsertableHelper {
  921. template<int N> struct TrueIfSizeable : TrueType {};
  922. template<typename T2>
  923. static TrueIfSizeable<sizeof((*(std::ostream*)0) << *((T2 const*)0))> dummy(T2*);
  924. static FalseType dummy(...);
  925. public:
  926. typedef SizedIf<sizeof(dummy((T*)0))> type;
  927. };
  928. template<typename T>
  929. struct IsStreamInsertable : IsStreamInsertableHelper<T>::type {};
  930. #else
  931. struct BorgType {
  932. template<typename T> BorgType( T const& );
  933. };
  934. TrueType& testStreamable( std::ostream& );
  935. FalseType testStreamable( FalseType );
  936. FalseType operator<<( std::ostream const&, BorgType const& );
  937. template<typename T>
  938. struct IsStreamInsertable {
  939. static std::ostream &s;
  940. static T const&t;
  941. enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) };
  942. };
  943. #endif
  944. #if defined(CATCH_CONFIG_CPP11_IS_ENUM)
  945. template<typename T,
  946. bool IsEnum = std::is_enum<T>::value
  947. >
  948. struct EnumStringMaker
  949. {
  950. static std::string convert( T const& ) { return unprintableString; }
  951. };
  952. template<typename T>
  953. struct EnumStringMaker<T,true>
  954. {
  955. static std::string convert( T const& v )
  956. {
  957. return ::Catch::toString(
  958. static_cast<typename std::underlying_type<T>::type>(v)
  959. );
  960. }
  961. };
  962. #endif
  963. template<bool C>
  964. struct StringMakerBase {
  965. #if defined(CATCH_CONFIG_CPP11_IS_ENUM)
  966. template<typename T>
  967. static std::string convert( T const& v )
  968. {
  969. return EnumStringMaker<T>::convert( v );
  970. }
  971. #else
  972. template<typename T>
  973. static std::string convert( T const& ) { return unprintableString; }
  974. #endif
  975. };
  976. template<>
  977. struct StringMakerBase<true> {
  978. template<typename T>
  979. static std::string convert( T const& _value ) {
  980. std::ostringstream oss;
  981. oss << _value;
  982. return oss.str();
  983. }
  984. };
  985. std::string rawMemoryToString( const void *object, std::size_t size );
  986. template<typename T>
  987. inline std::string rawMemoryToString( const T& object ) {
  988. return rawMemoryToString( &object, sizeof(object) );
  989. }
  990. } // end namespace Detail
  991. template<typename T>
  992. struct StringMaker :
  993. Detail::StringMakerBase<Detail::IsStreamInsertable<T>::value> {};
  994. template<typename T>
  995. struct StringMaker<T*> {
  996. template<typename U>
  997. static std::string convert( U* p ) {
  998. if( !p )
  999. return INTERNAL_CATCH_STRINGIFY( NULL );
  1000. else
  1001. return Detail::rawMemoryToString( p );
  1002. }
  1003. };
  1004. template<typename R, typename C>
  1005. struct StringMaker<R C::*> {
  1006. static std::string convert( R C::* p ) {
  1007. if( !p )
  1008. return INTERNAL_CATCH_STRINGIFY( NULL );
  1009. else
  1010. return Detail::rawMemoryToString( p );
  1011. }
  1012. };
  1013. namespace Detail {
  1014. template<typename InputIterator>
  1015. std::string rangeToString( InputIterator first, InputIterator last );
  1016. }
  1017. //template<typename T, typename Allocator>
  1018. //struct StringMaker<std::vector<T, Allocator> > {
  1019. // static std::string convert( std::vector<T,Allocator> const& v ) {
  1020. // return Detail::rangeToString( v.begin(), v.end() );
  1021. // }
  1022. //};
  1023. template<typename T, typename Allocator>
  1024. std::string toString( std::vector<T,Allocator> const& v ) {
  1025. return Detail::rangeToString( v.begin(), v.end() );
  1026. }
  1027. #ifdef CATCH_CONFIG_CPP11_TUPLE
  1028. // toString for tuples
  1029. namespace TupleDetail {
  1030. template<
  1031. typename Tuple,
  1032. std::size_t N = 0,
  1033. bool = (N < std::tuple_size<Tuple>::value)
  1034. >
  1035. struct ElementPrinter {
  1036. static void print( const Tuple& tuple, std::ostream& os )
  1037. {
  1038. os << ( N ? ", " : " " )
  1039. << Catch::toString(std::get<N>(tuple));
  1040. ElementPrinter<Tuple,N+1>::print(tuple,os);
  1041. }
  1042. };
  1043. template<
  1044. typename Tuple,
  1045. std::size_t N
  1046. >
  1047. struct ElementPrinter<Tuple,N,false> {
  1048. static void print( const Tuple&, std::ostream& ) {}
  1049. };
  1050. }
  1051. template<typename ...Types>
  1052. struct StringMaker<std::tuple<Types...>> {
  1053. static std::string convert( const std::tuple<Types...>& tuple )
  1054. {
  1055. std::ostringstream os;
  1056. os << '{';
  1057. TupleDetail::ElementPrinter<std::tuple<Types...>>::print( tuple, os );
  1058. os << " }";
  1059. return os.str();
  1060. }
  1061. };
  1062. #endif // CATCH_CONFIG_CPP11_TUPLE
  1063. namespace Detail {
  1064. template<typename T>
  1065. std::string makeString( T const& value ) {
  1066. return StringMaker<T>::convert( value );
  1067. }
  1068. } // end namespace Detail
  1069. /// \brief converts any type to a string
  1070. ///
  1071. /// The default template forwards on to ostringstream - except when an
  1072. /// ostringstream overload does not exist - in which case it attempts to detect
  1073. /// that and writes {?}.
  1074. /// Overload (not specialise) this template for custom typs that you don't want
  1075. /// to provide an ostream overload for.
  1076. template<typename T>
  1077. std::string toString( T const& value ) {
  1078. return StringMaker<T>::convert( value );
  1079. }
  1080. namespace Detail {
  1081. template<typename InputIterator>
  1082. std::string rangeToString( InputIterator first, InputIterator last ) {
  1083. std::ostringstream oss;
  1084. oss << "{ ";
  1085. if( first != last ) {
  1086. oss << Catch::toString( *first );
  1087. for( ++first ; first != last ; ++first )
  1088. oss << ", " << Catch::toString( *first );
  1089. }
  1090. oss << " }";
  1091. return oss.str();
  1092. }
  1093. }
  1094. } // end namespace Catch
  1095. namespace Catch {
  1096. // Wraps the LHS of an expression and captures the operator and RHS (if any) -
  1097. // wrapping them all in a ResultBuilder object
  1098. template<typename T>
  1099. class ExpressionLhs {
  1100. ExpressionLhs& operator = ( ExpressionLhs const& );
  1101. # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
  1102. ExpressionLhs& operator = ( ExpressionLhs && ) = delete;
  1103. # endif
  1104. public:
  1105. ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ) {}
  1106. # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
  1107. ExpressionLhs( ExpressionLhs const& ) = default;
  1108. ExpressionLhs( ExpressionLhs && ) = default;
  1109. # endif
  1110. template<typename RhsT>
  1111. ResultBuilder& operator == ( RhsT const& rhs ) {
  1112. return captureExpression<Internal::IsEqualTo>( rhs );
  1113. }
  1114. template<typename RhsT>
  1115. ResultBuilder& operator != ( RhsT const& rhs ) {
  1116. return captureExpression<Internal::IsNotEqualTo>( rhs );
  1117. }
  1118. template<typename RhsT>
  1119. ResultBuilder& operator < ( RhsT const& rhs ) {
  1120. return captureExpression<Internal::IsLessThan>( rhs );
  1121. }
  1122. template<typename RhsT>
  1123. ResultBuilder& operator > ( RhsT const& rhs ) {
  1124. return captureExpression<Internal::IsGreaterThan>( rhs );
  1125. }
  1126. template<typename RhsT>
  1127. ResultBuilder& operator <= ( RhsT const& rhs ) {
  1128. return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );
  1129. }
  1130. template<typename RhsT>
  1131. ResultBuilder& operator >= ( RhsT const& rhs ) {
  1132. return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );
  1133. }
  1134. ResultBuilder& operator == ( bool rhs ) {
  1135. return captureExpression<Internal::IsEqualTo>( rhs );
  1136. }
  1137. ResultBuilder& operator != ( bool rhs ) {
  1138. return captureExpression<Internal::IsNotEqualTo>( rhs );
  1139. }
  1140. void endExpression() {
  1141. bool value = m_lhs ? true : false;
  1142. m_rb
  1143. .setLhs( Catch::toString( value ) )
  1144. .setResultType( value )
  1145. .endExpression();
  1146. }
  1147. // Only simple binary expressions are allowed on the LHS.
  1148. // If more complex compositions are required then place the sub expression in parentheses
  1149. template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( RhsT const& );
  1150. template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( RhsT const& );
  1151. template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( RhsT const& );
  1152. template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( RhsT const& );
  1153. template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
  1154. template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
  1155. private:
  1156. template<Internal::Operator Op, typename RhsT>
  1157. ResultBuilder& captureExpression( RhsT const& rhs ) {
  1158. return m_rb
  1159. .setResultType( Internal::compare<Op>( m_lhs, rhs ) )
  1160. .setLhs( Catch::toString( m_lhs ) )
  1161. .setRhs( Catch::toString( rhs ) )
  1162. .setOp( Internal::OperatorTraits<Op>::getName() );
  1163. }
  1164. private:
  1165. ResultBuilder& m_rb;
  1166. T m_lhs;
  1167. };
  1168. } // end namespace Catch
  1169. namespace Catch {
  1170. template<typename T>
  1171. inline ExpressionLhs<T const&> ResultBuilder::operator->* ( T const& operand ) {
  1172. return ExpressionLhs<T const&>( *this, operand );
  1173. }
  1174. inline ExpressionLhs<bool> ResultBuilder::operator->* ( bool value ) {
  1175. return ExpressionLhs<bool>( *this, value );
  1176. }
  1177. } // namespace Catch
  1178. // #included from: catch_message.h
  1179. #define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
  1180. #include <string>
  1181. namespace Catch {
  1182. struct MessageInfo {
  1183. MessageInfo( std::string const& _macroName,
  1184. SourceLineInfo const& _lineInfo,
  1185. ResultWas::OfType _type );
  1186. std::string macroName;
  1187. SourceLineInfo lineInfo;
  1188. ResultWas::OfType type;
  1189. std::string message;
  1190. unsigned int sequence;
  1191. bool operator == ( MessageInfo const& other ) const {
  1192. return sequence == other.sequence;
  1193. }
  1194. bool operator < ( MessageInfo const& other ) const {
  1195. return sequence < other.sequence;
  1196. }
  1197. private:
  1198. static unsigned int globalCount;
  1199. };
  1200. struct MessageBuilder {
  1201. MessageBuilder( std::string const& macroName,
  1202. SourceLineInfo const& lineInfo,
  1203. ResultWas::OfType type )
  1204. : m_info( macroName, lineInfo, type )
  1205. {}
  1206. template<typename T>
  1207. MessageBuilder& operator << ( T const& value ) {
  1208. m_stream << value;
  1209. return *this;
  1210. }
  1211. MessageInfo m_info;
  1212. std::ostringstream m_stream;
  1213. };
  1214. class ScopedMessage {
  1215. public:
  1216. ScopedMessage( MessageBuilder const& builder );
  1217. ScopedMessage( ScopedMessage const& other );
  1218. ~ScopedMessage();
  1219. MessageInfo m_info;
  1220. };
  1221. } // end namespace Catch
  1222. // #included from: catch_interfaces_capture.h
  1223. #define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED
  1224. #include <string>
  1225. namespace Catch {
  1226. class TestCase;
  1227. class AssertionResult;
  1228. struct AssertionInfo;
  1229. struct SectionInfo;
  1230. struct MessageInfo;
  1231. class ScopedMessageBuilder;
  1232. struct Counts;
  1233. struct IResultCapture {
  1234. virtual ~IResultCapture();
  1235. virtual void assertionEnded( AssertionResult const& result ) = 0;
  1236. virtual bool sectionStarted( SectionInfo const& sectionInfo,
  1237. Counts& assertions ) = 0;
  1238. virtual void sectionEnded( SectionInfo const& name, Counts const& assertions, double _durationInSeconds ) = 0;
  1239. virtual void pushScopedMessage( MessageInfo const& message ) = 0;
  1240. virtual void popScopedMessage( MessageInfo const& message ) = 0;
  1241. virtual std::string getCurrentTestName() const = 0;
  1242. virtual const AssertionResult* getLastResult() const = 0;
  1243. virtual void handleFatalErrorCondition( std::string const& message ) = 0;
  1244. };
  1245. IResultCapture& getResultCapture();
  1246. }
  1247. // #included from: catch_debugger.h
  1248. #define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED
  1249. // #included from: catch_platform.h
  1250. #define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED
  1251. #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
  1252. #define CATCH_PLATFORM_MAC
  1253. #elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
  1254. #define CATCH_PLATFORM_IPHONE
  1255. #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
  1256. #define CATCH_PLATFORM_WINDOWS
  1257. #endif
  1258. #include <string>
  1259. namespace Catch{
  1260. bool isDebuggerActive();
  1261. void writeToDebugConsole( std::string const& text );
  1262. }
  1263. #ifdef CATCH_PLATFORM_MAC
  1264. // The following code snippet based on:
  1265. // http://cocoawithlove.com/2008/03/break-into-debugger.html
  1266. #ifdef DEBUG
  1267. #if defined(__ppc64__) || defined(__ppc__)
  1268. #define CATCH_BREAK_INTO_DEBUGGER() \
  1269. if( Catch::isDebuggerActive() ) { \
  1270. __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
  1271. : : : "memory","r0","r3","r4" ); \
  1272. }
  1273. #else
  1274. #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) {__asm__("int $3\n" : : );}
  1275. #endif
  1276. #endif
  1277. #elif defined(_MSC_VER)
  1278. #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { __debugbreak(); }
  1279. #elif defined(__MINGW32__)
  1280. extern "C" __declspec(dllimport) void __stdcall DebugBreak();
  1281. #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { DebugBreak(); }
  1282. #endif
  1283. #ifndef CATCH_BREAK_INTO_DEBUGGER
  1284. #define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue();
  1285. #endif
  1286. // #included from: catch_interfaces_runner.h
  1287. #define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED
  1288. namespace Catch {
  1289. class TestCase;
  1290. struct IRunner {
  1291. virtual ~IRunner();
  1292. virtual bool aborting() const = 0;
  1293. };
  1294. }
  1295. ///////////////////////////////////////////////////////////////////////////////
  1296. // In the event of a failure works out if the debugger needs to be invoked
  1297. // and/or an exception thrown and takes appropriate action.
  1298. // This needs to be done as a macro so the debugger will stop in the user
  1299. // source code rather than in Catch library code
  1300. #define INTERNAL_CATCH_REACT( resultBuilder ) \
  1301. if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \
  1302. resultBuilder.react();
  1303. ///////////////////////////////////////////////////////////////////////////////
  1304. #define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \
  1305. do { \
  1306. Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
  1307. try { \
  1308. ( __catchResult->*expr ).endExpression(); \
  1309. } \
  1310. catch( ... ) { \
  1311. __catchResult.useActiveException( Catch::ResultDisposition::Normal ); \
  1312. } \
  1313. INTERNAL_CATCH_REACT( __catchResult ) \
  1314. } while( Catch::isTrue( false && (expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
  1315. ///////////////////////////////////////////////////////////////////////////////
  1316. #define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \
  1317. INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
  1318. if( Catch::getResultCapture().getLastResult()->succeeded() )
  1319. ///////////////////////////////////////////////////////////////////////////////
  1320. #define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \
  1321. INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
  1322. if( !Catch::getResultCapture().getLastResult()->succeeded() )
  1323. ///////////////////////////////////////////////////////////////////////////////
  1324. #define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \
  1325. do { \
  1326. Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
  1327. try { \
  1328. expr; \
  1329. __catchResult.captureResult( Catch::ResultWas::Ok ); \
  1330. } \
  1331. catch( ... ) { \
  1332. __catchResult.useActiveException( resultDisposition ); \
  1333. } \
  1334. INTERNAL_CATCH_REACT( __catchResult ) \
  1335. } while( Catch::alwaysFalse() )
  1336. ///////////////////////////////////////////////////////////////////////////////
  1337. #define INTERNAL_CATCH_THROWS( expr, resultDisposition, macroName ) \
  1338. do { \
  1339. Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
  1340. if( __catchResult.allowThrows() ) \
  1341. try { \
  1342. expr; \
  1343. __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
  1344. } \
  1345. catch( ... ) { \
  1346. __catchResult.captureResult( Catch::ResultWas::Ok ); \
  1347. } \
  1348. else \
  1349. __catchResult.captureResult( Catch::ResultWas::Ok ); \
  1350. INTERNAL_CATCH_REACT( __catchResult ) \
  1351. } while( Catch::alwaysFalse() )
  1352. ///////////////////////////////////////////////////////////////////////////////
  1353. #define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \
  1354. do { \
  1355. Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
  1356. if( __catchResult.allowThrows() ) \
  1357. try { \
  1358. expr; \
  1359. __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
  1360. } \
  1361. catch( exceptionType ) { \
  1362. __catchResult.captureResult( Catch::ResultWas::Ok ); \
  1363. } \
  1364. catch( ... ) { \
  1365. __catchResult.useActiveException( resultDisposition ); \
  1366. } \
  1367. else \
  1368. __catchResult.captureResult( Catch::ResultWas::Ok ); \
  1369. INTERNAL_CATCH_REACT( __catchResult ) \
  1370. } while( Catch::alwaysFalse() )
  1371. ///////////////////////////////////////////////////////////////////////////////
  1372. #ifdef CATCH_CONFIG_VARIADIC_MACROS
  1373. #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \
  1374. do { \
  1375. Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
  1376. __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \
  1377. __catchResult.captureResult( messageType ); \
  1378. INTERNAL_CATCH_REACT( __catchResult ) \
  1379. } while( Catch::alwaysFalse() )
  1380. #else
  1381. #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \
  1382. do { \
  1383. Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
  1384. __catchResult << log + ::Catch::StreamEndStop(); \
  1385. __catchResult.captureResult( messageType ); \
  1386. INTERNAL_CATCH_REACT( __catchResult ) \
  1387. } while( Catch::alwaysFalse() )
  1388. #endif
  1389. ///////////////////////////////////////////////////////////////////////////////
  1390. #define INTERNAL_CATCH_INFO( log, macroName ) \
  1391. Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log;
  1392. ///////////////////////////////////////////////////////////////////////////////
  1393. #define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \
  1394. do { \
  1395. Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg " " #matcher, resultDisposition ); \
  1396. try { \
  1397. std::string matcherAsString = ::Catch::Matchers::matcher.toString(); \
  1398. __catchResult \
  1399. .setLhs( Catch::toString( arg ) ) \
  1400. .setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \
  1401. .setOp( "matches" ) \
  1402. .setResultType( ::Catch::Matchers::matcher.match( arg ) ); \
  1403. __catchResult.captureExpression(); \
  1404. } catch( ... ) { \
  1405. __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \
  1406. } \
  1407. INTERNAL_CATCH_REACT( __catchResult ) \
  1408. } while( Catch::alwaysFalse() )
  1409. // #included from: internal/catch_section.h
  1410. #define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
  1411. // #included from: catch_section_info.h
  1412. #define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED
  1413. namespace Catch {
  1414. struct SectionInfo {
  1415. SectionInfo
  1416. ( SourceLineInfo const& _lineInfo,
  1417. std::string const& _name,
  1418. std::string const& _description = std::string() );
  1419. std::string name;
  1420. std::string description;
  1421. SourceLineInfo lineInfo;
  1422. };
  1423. } // end namespace Catch
  1424. // #included from: catch_totals.hpp
  1425. #define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED
  1426. #include <cstddef>
  1427. namespace Catch {
  1428. struct Counts {
  1429. Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {}
  1430. Counts operator - ( Counts const& other ) const {
  1431. Counts diff;
  1432. diff.passed = passed - other.passed;
  1433. diff.failed = failed - other.failed;
  1434. diff.failedButOk = failedButOk - other.failedButOk;
  1435. return diff;
  1436. }
  1437. Counts& operator += ( Counts const& other ) {
  1438. passed += other.passed;
  1439. failed += other.failed;
  1440. failedButOk += other.failedButOk;
  1441. return *this;
  1442. }
  1443. std::size_t total() const {
  1444. return passed + failed + failedButOk;
  1445. }
  1446. bool allPassed() const {
  1447. return failed == 0 && failedButOk == 0;
  1448. }
  1449. bool allOk() const {
  1450. return failed == 0;
  1451. }
  1452. std::size_t passed;
  1453. std::size_t failed;
  1454. std::size_t failedButOk;
  1455. };
  1456. struct Totals {
  1457. Totals operator - ( Totals const& other ) const {
  1458. Totals diff;
  1459. diff.assertions = assertions - other.assertions;
  1460. diff.testCases = testCases - other.testCases;
  1461. return diff;
  1462. }
  1463. Totals delta( Totals const& prevTotals ) const {
  1464. Totals diff = *this - prevTotals;
  1465. if( diff.assertions.failed > 0 )
  1466. ++diff.testCases.failed;
  1467. else if( diff.assertions.failedButOk > 0 )
  1468. ++diff.testCases.failedButOk;
  1469. else
  1470. ++diff.testCases.passed;
  1471. return diff;
  1472. }
  1473. Totals& operator += ( Totals const& other ) {
  1474. assertions += other.assertions;
  1475. testCases += other.testCases;
  1476. return *this;
  1477. }
  1478. Counts assertions;
  1479. Counts testCases;
  1480. };
  1481. }
  1482. // #included from: catch_timer.h
  1483. #define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED
  1484. #ifdef CATCH_PLATFORM_WINDOWS
  1485. typedef unsigned long long uint64_t;
  1486. #else
  1487. #include <stdint.h>
  1488. #endif
  1489. namespace Catch {
  1490. class Timer {
  1491. public:
  1492. Timer() : m_ticks( 0 ) {}
  1493. void start();
  1494. unsigned int getElapsedMicroseconds() const;
  1495. unsigned int getElapsedMilliseconds() const;
  1496. double getElapsedSeconds() const;
  1497. private:
  1498. uint64_t m_ticks;
  1499. };
  1500. } // namespace Catch
  1501. #include <string>
  1502. namespace Catch {
  1503. class Section : NonCopyable {
  1504. public:
  1505. Section( SectionInfo const& info );
  1506. ~Section();
  1507. // This indicates whether the section should be executed or not
  1508. operator bool() const;
  1509. private:
  1510. SectionInfo m_info;
  1511. std::string m_name;
  1512. Counts m_assertions;
  1513. bool m_sectionIncluded;
  1514. Timer m_timer;
  1515. };
  1516. } // end namespace Catch
  1517. #ifdef CATCH_CONFIG_VARIADIC_MACROS
  1518. #define INTERNAL_CATCH_SECTION( ... ) \
  1519. if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
  1520. #else
  1521. #define INTERNAL_CATCH_SECTION( name, desc ) \
  1522. if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) )
  1523. #endif
  1524. // #included from: internal/catch_generators.hpp
  1525. #define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
  1526. #include <iterator>
  1527. #include <vector>
  1528. #include <string>
  1529. #include <stdlib.h>
  1530. namespace Catch {
  1531. template<typename T>
  1532. struct IGenerator {
  1533. virtual ~IGenerator() {}
  1534. virtual T getValue( std::size_t index ) const = 0;
  1535. virtual std::size_t size () const = 0;
  1536. };
  1537. template<typename T>
  1538. class BetweenGenerator : public IGenerator<T> {
  1539. public:
  1540. BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){}
  1541. virtual T getValue( std::size_t index ) const {
  1542. return m_from+static_cast<int>( index );
  1543. }
  1544. virtual std::size_t size() const {
  1545. return static_cast<std::size_t>( 1+m_to-m_from );
  1546. }
  1547. private:
  1548. T m_from;
  1549. T m_to;
  1550. };
  1551. template<typename T>
  1552. class ValuesGenerator : public IGenerator<T> {
  1553. public:
  1554. ValuesGenerator(){}
  1555. void add( T value ) {
  1556. m_values.push_back( value );
  1557. }
  1558. virtual T getValue( std::size_t index ) const {
  1559. return m_values[index];
  1560. }
  1561. virtual std::size_t size() const {
  1562. return m_values.size();
  1563. }
  1564. private:
  1565. std::vector<T> m_values;
  1566. };
  1567. template<typename T>
  1568. class CompositeGenerator {
  1569. public:
  1570. CompositeGenerator() : m_totalSize( 0 ) {}
  1571. // *** Move semantics, similar to auto_ptr ***
  1572. CompositeGenerator( CompositeGenerator& other )
  1573. : m_fileInfo( other.m_fileInfo ),
  1574. m_totalSize( 0 )
  1575. {
  1576. move( other );
  1577. }
  1578. CompositeGenerator& setFileInfo( const char* fileInfo ) {
  1579. m_fileInfo = fileInfo;
  1580. return *this;
  1581. }
  1582. ~CompositeGenerator() {
  1583. deleteAll( m_composed );
  1584. }
  1585. operator T () const {
  1586. size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize );
  1587. typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin();
  1588. typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end();
  1589. for( size_t index = 0; it != itEnd; ++it )
  1590. {
  1591. const IGenerator<T>* generator = *it;
  1592. if( overallIndex >= index && overallIndex < index + generator->size() )
  1593. {
  1594. return generator->getValue( overallIndex-index );
  1595. }
  1596. index += generator->size();
  1597. }
  1598. CATCH_INTERNAL_ERROR( "Indexed past end of generated range" );
  1599. return T(); // Suppress spurious "not all control paths return a value" warning in Visual Studio - if you know how to fix this please do so
  1600. }
  1601. void add( const IGenerator<T>* generator ) {
  1602. m_totalSize += generator->size();
  1603. m_composed.push_back( generator );
  1604. }
  1605. CompositeGenerator& then( CompositeGenerator& other ) {
  1606. move( other );
  1607. return *this;
  1608. }
  1609. CompositeGenerator& then( T value ) {
  1610. ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
  1611. valuesGen->add( value );
  1612. add( valuesGen );
  1613. return *this;
  1614. }
  1615. private:
  1616. void move( CompositeGenerator& other ) {
  1617. std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) );
  1618. m_totalSize += other.m_totalSize;
  1619. other.m_composed.clear();
  1620. }
  1621. std::vector<const IGenerator<T>*> m_composed;
  1622. std::string m_fileInfo;
  1623. size_t m_totalSize;
  1624. };
  1625. namespace Generators
  1626. {
  1627. template<typename T>
  1628. CompositeGenerator<T> between( T from, T to ) {
  1629. CompositeGenerator<T> generators;
  1630. generators.add( new BetweenGenerator<T>( from, to ) );
  1631. return generators;
  1632. }
  1633. template<typename T>
  1634. CompositeGenerator<T> values( T val1, T val2 ) {
  1635. CompositeGenerator<T> generators;
  1636. ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
  1637. valuesGen->add( val1 );
  1638. valuesGen->add( val2 );
  1639. generators.add( valuesGen );
  1640. return generators;
  1641. }
  1642. template<typename T>
  1643. CompositeGenerator<T> values( T val1, T val2, T val3 ){
  1644. CompositeGenerator<T> generators;
  1645. ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
  1646. valuesGen->add( val1 );
  1647. valuesGen->add( val2 );
  1648. valuesGen->add( val3 );
  1649. generators.add( valuesGen );
  1650. return generators;
  1651. }
  1652. template<typename T>
  1653. CompositeGenerator<T> values( T val1, T val2, T val3, T val4 ) {
  1654. CompositeGenerator<T> generators;
  1655. ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
  1656. valuesGen->add( val1 );
  1657. valuesGen->add( val2 );
  1658. valuesGen->add( val3 );
  1659. valuesGen->add( val4 );
  1660. generators.add( valuesGen );
  1661. return generators;
  1662. }
  1663. } // end namespace Generators
  1664. using namespace Generators;
  1665. } // end namespace Catch
  1666. #define INTERNAL_CATCH_LINESTR2( line ) #line
  1667. #define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line )
  1668. #define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" )
  1669. // #included from: internal/catch_interfaces_exception.h
  1670. #define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED
  1671. #include <string>
  1672. // #included from: catch_interfaces_registry_hub.h
  1673. #define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED
  1674. #include <string>
  1675. namespace Catch {
  1676. class TestCase;
  1677. struct ITestCaseRegistry;
  1678. struct IExceptionTranslatorRegistry;
  1679. struct IExceptionTranslator;
  1680. struct IReporterRegistry;
  1681. struct IReporterFactory;
  1682. struct IRegistryHub {
  1683. virtual ~IRegistryHub();
  1684. virtual IReporterRegistry const& getReporterRegistry() const = 0;
  1685. virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
  1686. virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
  1687. };
  1688. struct IMutableRegistryHub {
  1689. virtual ~IMutableRegistryHub();
  1690. virtual void registerReporter( std::string const& name, IReporterFactory* factory ) = 0;
  1691. virtual void registerTest( TestCase const& testInfo ) = 0;
  1692. virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
  1693. };
  1694. IRegistryHub& getRegistryHub();
  1695. IMutableRegistryHub& getMutableRegistryHub();
  1696. void cleanUp();
  1697. std::string translateActiveException();
  1698. }
  1699. namespace Catch {
  1700. typedef std::string(*exceptionTranslateFunction)();
  1701. struct IExceptionTranslator {
  1702. virtual ~IExceptionTranslator();
  1703. virtual std::string translate() const = 0;
  1704. };
  1705. struct IExceptionTranslatorRegistry {
  1706. virtual ~IExceptionTranslatorRegistry();
  1707. virtual std::string translateActiveException() const = 0;
  1708. };
  1709. class ExceptionTranslatorRegistrar {
  1710. template<typename T>
  1711. class ExceptionTranslator : public IExceptionTranslator {
  1712. public:
  1713. ExceptionTranslator( std::string(*translateFunction)( T& ) )
  1714. : m_translateFunction( translateFunction )
  1715. {}
  1716. virtual std::string translate() const {
  1717. try {
  1718. throw;
  1719. }
  1720. catch( T& ex ) {
  1721. return m_translateFunction( ex );
  1722. }
  1723. }
  1724. protected:
  1725. std::string(*m_translateFunction)( T& );
  1726. };
  1727. public:
  1728. template<typename T>
  1729. ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
  1730. getMutableRegistryHub().registerTranslator
  1731. ( new ExceptionTranslator<T>( translateFunction ) );
  1732. }
  1733. };
  1734. }
  1735. ///////////////////////////////////////////////////////////////////////////////
  1736. #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) \
  1737. static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature ); \
  1738. namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ) ); }\
  1739. static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature )
  1740. // #included from: internal/catch_approx.hpp
  1741. #define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
  1742. #include <cmath>
  1743. #include <limits>
  1744. namespace Catch {
  1745. namespace Detail {
  1746. class Approx {
  1747. public:
  1748. explicit Approx ( double value )
  1749. : m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
  1750. m_scale( 1.0 ),
  1751. m_value( value )
  1752. {}
  1753. Approx( Approx const& other )
  1754. : m_epsilon( other.m_epsilon ),
  1755. m_scale( other.m_scale ),
  1756. m_value( other.m_value )
  1757. {}
  1758. static Approx custom() {
  1759. return Approx( 0 );
  1760. }
  1761. Approx operator()( double value ) {
  1762. Approx approx( value );
  1763. approx.epsilon( m_epsilon );
  1764. approx.scale( m_scale );
  1765. return approx;
  1766. }
  1767. friend bool operator == ( double lhs, Approx const& rhs ) {
  1768. // Thanks to Richard Harris for his help refining this formula
  1769. return fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) );
  1770. }
  1771. friend bool operator == ( Approx const& lhs, double rhs ) {
  1772. return operator==( rhs, lhs );
  1773. }
  1774. friend bool operator != ( double lhs, Approx const& rhs ) {
  1775. return !operator==( lhs, rhs );
  1776. }
  1777. friend bool operator != ( Approx const& lhs, double rhs ) {
  1778. return !operator==( rhs, lhs );
  1779. }
  1780. Approx& epsilon( double newEpsilon ) {
  1781. m_epsilon = newEpsilon;
  1782. return *this;
  1783. }
  1784. Approx& scale( double newScale ) {
  1785. m_scale = newScale;
  1786. return *this;
  1787. }
  1788. std::string toString() const {
  1789. std::ostringstream oss;
  1790. oss << "Approx( " << Catch::toString( m_value ) << " )";
  1791. return oss.str();
  1792. }
  1793. private:
  1794. double m_epsilon;
  1795. double m_scale;
  1796. double m_value;
  1797. };
  1798. }
  1799. template<>
  1800. inline std::string toString<Detail::Approx>( Detail::Approx const& value ) {
  1801. return value.toString();
  1802. }
  1803. } // end namespace Catch
  1804. // #included from: internal/catch_matchers.hpp
  1805. #define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
  1806. namespace Catch {
  1807. namespace Matchers {
  1808. namespace Impl {
  1809. template<typename ExpressionT>
  1810. struct Matcher : SharedImpl<IShared>
  1811. {
  1812. typedef ExpressionT ExpressionType;
  1813. virtual ~Matcher() {}
  1814. virtual Ptr<Matcher> clone() const = 0;
  1815. virtual bool match( ExpressionT const& expr ) const = 0;
  1816. virtual std::string toString() const = 0;
  1817. };
  1818. template<typename DerivedT, typename ExpressionT>
  1819. struct MatcherImpl : Matcher<ExpressionT> {
  1820. virtual Ptr<Matcher<ExpressionT> > clone() const {
  1821. return Ptr<Matcher<ExpressionT> >( new DerivedT( static_cast<DerivedT const&>( *this ) ) );
  1822. }
  1823. };
  1824. namespace Generic {
  1825. template<typename ExpressionT>
  1826. class AllOf : public MatcherImpl<AllOf<ExpressionT>, ExpressionT> {
  1827. public:
  1828. AllOf() {}
  1829. AllOf( AllOf const& other ) : m_matchers( other.m_matchers ) {}
  1830. AllOf& add( Matcher<ExpressionT> const& matcher ) {
  1831. m_matchers.push_back( matcher.clone() );
  1832. return *this;
  1833. }
  1834. virtual bool match( ExpressionT const& expr ) const
  1835. {
  1836. for( std::size_t i = 0; i < m_matchers.size(); ++i )
  1837. if( !m_matchers[i]->match( expr ) )
  1838. return false;
  1839. return true;
  1840. }
  1841. virtual std::string toString() const {
  1842. std::ostringstream oss;
  1843. oss << "( ";
  1844. for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
  1845. if( i != 0 )
  1846. oss << " and ";
  1847. oss << m_matchers[i]->toString();
  1848. }
  1849. oss << " )";
  1850. return oss.str();
  1851. }
  1852. private:
  1853. std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
  1854. };
  1855. template<typename ExpressionT>
  1856. class AnyOf : public MatcherImpl<AnyOf<ExpressionT>, ExpressionT> {
  1857. public:
  1858. AnyOf() {}
  1859. AnyOf( AnyOf const& other ) : m_matchers( other.m_matchers ) {}
  1860. AnyOf& add( Matcher<ExpressionT> const& matcher ) {
  1861. m_matchers.push_back( matcher.clone() );
  1862. return *this;
  1863. }
  1864. virtual bool match( ExpressionT const& expr ) const
  1865. {
  1866. for( std::size_t i = 0; i < m_matchers.size(); ++i )
  1867. if( m_matchers[i]->match( expr ) )
  1868. return true;
  1869. return false;
  1870. }
  1871. virtual std::string toString() const {
  1872. std::ostringstream oss;
  1873. oss << "( ";
  1874. for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
  1875. if( i != 0 )
  1876. oss << " or ";
  1877. oss << m_matchers[i]->toString();
  1878. }
  1879. oss << " )";
  1880. return oss.str();
  1881. }
  1882. private:
  1883. std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
  1884. };
  1885. }
  1886. namespace StdString {
  1887. inline std::string makeString( std::string const& str ) { return str; }
  1888. inline std::string makeString( const char* str ) { return str ? std::string( str ) : std::string(); }
  1889. struct Equals : MatcherImpl<Equals, std::string> {
  1890. Equals( std::string const& str ) : m_str( str ){}
  1891. Equals( Equals const& other ) : m_str( other.m_str ){}
  1892. virtual ~Equals();
  1893. virtual bool match( std::string const& expr ) const {
  1894. return m_str == expr;
  1895. }
  1896. virtual std::string toString() const {
  1897. return "equals: \"" + m_str + "\"";
  1898. }
  1899. std::string m_str;
  1900. };
  1901. struct Contains : MatcherImpl<Contains, std::string> {
  1902. Contains( std::string const& substr ) : m_substr( substr ){}
  1903. Contains( Contains const& other ) : m_substr( other.m_substr ){}
  1904. virtual ~Contains();
  1905. virtual bool match( std::string const& expr ) const {
  1906. return expr.find( m_substr ) != std::string::npos;
  1907. }
  1908. virtual std::string toString() const {
  1909. return "contains: \"" + m_substr + "\"";
  1910. }
  1911. std::string m_substr;
  1912. };
  1913. struct StartsWith : MatcherImpl<StartsWith, std::string> {
  1914. StartsWith( std::string const& substr ) : m_substr( substr ){}
  1915. StartsWith( StartsWith const& other ) : m_substr( other.m_substr ){}
  1916. virtual ~StartsWith();
  1917. virtual bool match( std::string const& expr ) const {
  1918. return expr.find( m_substr ) == 0;
  1919. }
  1920. virtual std::string toString() const {
  1921. return "starts with: \"" + m_substr + "\"";
  1922. }
  1923. std::string m_substr;
  1924. };
  1925. struct EndsWith : MatcherImpl<EndsWith, std::string> {
  1926. EndsWith( std::string const& substr ) : m_substr( substr ){}
  1927. EndsWith( EndsWith const& other ) : m_substr( other.m_substr ){}
  1928. virtual ~EndsWith();
  1929. virtual bool match( std::string const& expr ) const {
  1930. return expr.find( m_substr ) == expr.size() - m_substr.size();
  1931. }
  1932. virtual std::string toString() const {
  1933. return "ends with: \"" + m_substr + "\"";
  1934. }
  1935. std::string m_substr;
  1936. };
  1937. } // namespace StdString
  1938. } // namespace Impl
  1939. // The following functions create the actual matcher objects.
  1940. // This allows the types to be inferred
  1941. template<typename ExpressionT>
  1942. inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
  1943. Impl::Matcher<ExpressionT> const& m2 ) {
  1944. return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 );
  1945. }
  1946. template<typename ExpressionT>
  1947. inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
  1948. Impl::Matcher<ExpressionT> const& m2,
  1949. Impl::Matcher<ExpressionT> const& m3 ) {
  1950. return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
  1951. }
  1952. template<typename ExpressionT>
  1953. inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
  1954. Impl::Matcher<ExpressionT> const& m2 ) {
  1955. return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 );
  1956. }
  1957. template<typename ExpressionT>
  1958. inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
  1959. Impl::Matcher<ExpressionT> const& m2,
  1960. Impl::Matcher<ExpressionT> const& m3 ) {
  1961. return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
  1962. }
  1963. inline Impl::StdString::Equals Equals( std::string const& str ) {
  1964. return Impl::StdString::Equals( str );
  1965. }
  1966. inline Impl::StdString::Equals Equals( const char* str ) {
  1967. return Impl::StdString::Equals( Impl::StdString::makeString( str ) );
  1968. }
  1969. inline Impl::StdString::Contains Contains( std::string const& substr ) {
  1970. return Impl::StdString::Contains( substr );
  1971. }
  1972. inline Impl::StdString::Contains Contains( const char* substr ) {
  1973. return Impl::StdString::Contains( Impl::StdString::makeString( substr ) );
  1974. }
  1975. inline Impl::StdString::StartsWith StartsWith( std::string const& substr ) {
  1976. return Impl::StdString::StartsWith( substr );
  1977. }
  1978. inline Impl::StdString::StartsWith StartsWith( const char* substr ) {
  1979. return Impl::StdString::StartsWith( Impl::StdString::makeString( substr ) );
  1980. }
  1981. inline Impl::StdString::EndsWith EndsWith( std::string const& substr ) {
  1982. return Impl::StdString::EndsWith( substr );
  1983. }
  1984. inline Impl::StdString::EndsWith EndsWith( const char* substr ) {
  1985. return Impl::StdString::EndsWith( Impl::StdString::makeString( substr ) );
  1986. }
  1987. } // namespace Matchers
  1988. using namespace Matchers;
  1989. } // namespace Catch
  1990. // #included from: internal/catch_interfaces_tag_alias_registry.h
  1991. #define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED
  1992. // #included from: catch_tag_alias.h
  1993. #define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED
  1994. #include <string>
  1995. namespace Catch {
  1996. struct TagAlias {
  1997. TagAlias( std::string _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {}
  1998. std::string tag;
  1999. SourceLineInfo lineInfo;
  2000. };
  2001. struct RegistrarForTagAliases {
  2002. RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
  2003. };
  2004. } // end namespace Catch
  2005. #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); }
  2006. // #included from: catch_option.hpp
  2007. #define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED
  2008. namespace Catch {
  2009. // An optional type
  2010. template<typename T>
  2011. class Option {
  2012. public:
  2013. Option() : nullableValue( NULL ) {}
  2014. Option( T const& _value )
  2015. : nullableValue( new( storage ) T( _value ) )
  2016. {}
  2017. Option( Option const& _other )
  2018. : nullableValue( _other ? new( storage ) T( *_other ) : NULL )
  2019. {}
  2020. ~Option() {
  2021. reset();
  2022. }
  2023. Option& operator= ( Option const& _other ) {
  2024. if( &_other != this ) {
  2025. reset();
  2026. if( _other )
  2027. nullableValue = new( storage ) T( *_other );
  2028. }
  2029. return *this;
  2030. }
  2031. Option& operator = ( T const& _value ) {
  2032. reset();
  2033. nullableValue = new( storage ) T( _value );
  2034. return *this;
  2035. }
  2036. void reset() {
  2037. if( nullableValue )
  2038. nullableValue->~T();
  2039. nullableValue = NULL;
  2040. }
  2041. T& operator*() { return *nullableValue; }
  2042. T const& operator*() const { return *nullableValue; }
  2043. T* operator->() { return nullableValue; }
  2044. const T* operator->() const { return nullableValue; }
  2045. T valueOr( T const& defaultValue ) const {
  2046. return nullableValue ? *nullableValue : defaultValue;
  2047. }
  2048. bool some() const { return nullableValue != NULL; }
  2049. bool none() const { return nullableValue == NULL; }
  2050. bool operator !() const { return nullableValue == NULL; }
  2051. operator SafeBool::type() const {
  2052. return SafeBool::makeSafe( some() );
  2053. }
  2054. private:
  2055. T* nullableValue;
  2056. char storage[sizeof(T)];
  2057. };
  2058. } // end namespace Catch
  2059. namespace Catch {
  2060. struct ITagAliasRegistry {
  2061. virtual ~ITagAliasRegistry();
  2062. virtual Option<TagAlias> find( std::string const& alias ) const = 0;
  2063. virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
  2064. static ITagAliasRegistry const& get();
  2065. };
  2066. } // end namespace Catch
  2067. // These files are included here so the single_include script doesn't put them
  2068. // in the conditionally compiled sections
  2069. // #included from: internal/catch_test_case_info.h
  2070. #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED
  2071. #include <string>
  2072. #include <set>
  2073. #ifdef __clang__
  2074. #pragma clang diagnostic push
  2075. #pragma clang diagnostic ignored "-Wpadded"
  2076. #endif
  2077. namespace Catch {
  2078. struct ITestCase;
  2079. struct TestCaseInfo {
  2080. enum SpecialProperties{
  2081. None = 0,
  2082. IsHidden = 1 << 1,
  2083. ShouldFail = 1 << 2,
  2084. MayFail = 1 << 3,
  2085. Throws = 1 << 4
  2086. };
  2087. TestCaseInfo( std::string const& _name,
  2088. std::string const& _className,
  2089. std::string const& _description,
  2090. std::set<std::string> const& _tags,
  2091. SourceLineInfo const& _lineInfo );
  2092. TestCaseInfo( TestCaseInfo const& other );
  2093. bool isHidden() const;
  2094. bool throws() const;
  2095. bool okToFail() const;
  2096. bool expectedToFail() const;
  2097. std::string name;
  2098. std::string className;
  2099. std::string description;
  2100. std::set<std::string> tags;
  2101. std::set<std::string> lcaseTags;
  2102. std::string tagsAsString;
  2103. SourceLineInfo lineInfo;
  2104. SpecialProperties properties;
  2105. };
  2106. class TestCase : public TestCaseInfo {
  2107. public:
  2108. TestCase( ITestCase* testCase, TestCaseInfo const& info );
  2109. TestCase( TestCase const& other );
  2110. TestCase withName( std::string const& _newName ) const;
  2111. void invoke() const;
  2112. TestCaseInfo const& getTestCaseInfo() const;
  2113. void swap( TestCase& other );
  2114. bool operator == ( TestCase const& other ) const;
  2115. bool operator < ( TestCase const& other ) const;
  2116. TestCase& operator = ( TestCase const& other );
  2117. private:
  2118. Ptr<ITestCase> test;
  2119. };
  2120. TestCase makeTestCase( ITestCase* testCase,
  2121. std::string const& className,
  2122. std::string const& name,
  2123. std::string const& description,
  2124. SourceLineInfo const& lineInfo );
  2125. }
  2126. #ifdef __clang__
  2127. #pragma clang diagnostic pop
  2128. #endif
  2129. #ifdef __OBJC__
  2130. // #included from: internal/catch_objc.hpp
  2131. #define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED
  2132. #import <objc/runtime.h>
  2133. #include <string>
  2134. // NB. Any general catch headers included here must be included
  2135. // in catch.hpp first to make sure they are included by the single
  2136. // header for non obj-usage
  2137. ///////////////////////////////////////////////////////////////////////////////
  2138. // This protocol is really only here for (self) documenting purposes, since
  2139. // all its methods are optional.
  2140. @protocol OcFixture
  2141. @optional
  2142. -(void) setUp;
  2143. -(void) tearDown;
  2144. @end
  2145. namespace Catch {
  2146. class OcMethod : public SharedImpl<ITestCase> {
  2147. public:
  2148. OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
  2149. virtual void invoke() const {
  2150. id obj = [[m_cls alloc] init];
  2151. performOptionalSelector( obj, @selector(setUp) );
  2152. performOptionalSelector( obj, m_sel );
  2153. performOptionalSelector( obj, @selector(tearDown) );
  2154. arcSafeRelease( obj );
  2155. }
  2156. private:
  2157. virtual ~OcMethod() {}
  2158. Class m_cls;
  2159. SEL m_sel;
  2160. };
  2161. namespace Detail{
  2162. inline std::string getAnnotation( Class cls,
  2163. std::string const& annotationName,
  2164. std::string const& testCaseName ) {
  2165. NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
  2166. SEL sel = NSSelectorFromString( selStr );
  2167. arcSafeRelease( selStr );
  2168. id value = performOptionalSelector( cls, sel );
  2169. if( value )
  2170. return [(NSString*)value UTF8String];
  2171. return "";
  2172. }
  2173. }
  2174. inline size_t registerTestMethods() {
  2175. size_t noTestMethods = 0;
  2176. int noClasses = objc_getClassList( NULL, 0 );
  2177. Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
  2178. objc_getClassList( classes, noClasses );
  2179. for( int c = 0; c < noClasses; c++ ) {
  2180. Class cls = classes[c];
  2181. {
  2182. u_int count;
  2183. Method* methods = class_copyMethodList( cls, &count );
  2184. for( u_int m = 0; m < count ; m++ ) {
  2185. SEL selector = method_getName(methods[m]);
  2186. std::string methodName = sel_getName(selector);
  2187. if( startsWith( methodName, "Catch_TestCase_" ) ) {
  2188. std::string testCaseName = methodName.substr( 15 );
  2189. std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
  2190. std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
  2191. const char* className = class_getName( cls );
  2192. getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) );
  2193. noTestMethods++;
  2194. }
  2195. }
  2196. free(methods);
  2197. }
  2198. }
  2199. return noTestMethods;
  2200. }
  2201. namespace Matchers {
  2202. namespace Impl {
  2203. namespace NSStringMatchers {
  2204. template<typename MatcherT>
  2205. struct StringHolder : MatcherImpl<MatcherT, NSString*>{
  2206. StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
  2207. StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
  2208. StringHolder() {
  2209. arcSafeRelease( m_substr );
  2210. }
  2211. NSString* m_substr;
  2212. };
  2213. struct Equals : StringHolder<Equals> {
  2214. Equals( NSString* substr ) : StringHolder( substr ){}
  2215. virtual bool match( ExpressionType const& str ) const {
  2216. return (str != nil || m_substr == nil ) &&
  2217. [str isEqualToString:m_substr];
  2218. }
  2219. virtual std::string toString() const {
  2220. return "equals string: " + Catch::toString( m_substr );
  2221. }
  2222. };
  2223. struct Contains : StringHolder<Contains> {
  2224. Contains( NSString* substr ) : StringHolder( substr ){}
  2225. virtual bool match( ExpressionType const& str ) const {
  2226. return (str != nil || m_substr == nil ) &&
  2227. [str rangeOfString:m_substr].location != NSNotFound;
  2228. }
  2229. virtual std::string toString() const {
  2230. return "contains string: " + Catch::toString( m_substr );
  2231. }
  2232. };
  2233. struct StartsWith : StringHolder<StartsWith> {
  2234. StartsWith( NSString* substr ) : StringHolder( substr ){}
  2235. virtual bool match( ExpressionType const& str ) const {
  2236. return (str != nil || m_substr == nil ) &&
  2237. [str rangeOfString:m_substr].location == 0;
  2238. }
  2239. virtual std::string toString() const {
  2240. return "starts with: " + Catch::toString( m_substr );
  2241. }
  2242. };
  2243. struct EndsWith : StringHolder<EndsWith> {
  2244. EndsWith( NSString* substr ) : StringHolder( substr ){}
  2245. virtual bool match( ExpressionType const& str ) const {
  2246. return (str != nil || m_substr == nil ) &&
  2247. [str rangeOfString:m_substr].location == [str length] - [m_substr length];
  2248. }
  2249. virtual std::string toString() const {
  2250. return "ends with: " + Catch::toString( m_substr );
  2251. }
  2252. };
  2253. } // namespace NSStringMatchers
  2254. } // namespace Impl
  2255. inline Impl::NSStringMatchers::Equals
  2256. Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
  2257. inline Impl::NSStringMatchers::Contains
  2258. Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
  2259. inline Impl::NSStringMatchers::StartsWith
  2260. StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
  2261. inline Impl::NSStringMatchers::EndsWith
  2262. EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
  2263. } // namespace Matchers
  2264. using namespace Matchers;
  2265. } // namespace Catch
  2266. ///////////////////////////////////////////////////////////////////////////////
  2267. #define OC_TEST_CASE( name, desc )\
  2268. +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \
  2269. {\
  2270. return @ name; \
  2271. }\
  2272. +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \
  2273. { \
  2274. return @ desc; \
  2275. } \
  2276. -(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test )
  2277. #endif
  2278. #ifdef CATCH_IMPL
  2279. // #included from: internal/catch_impl.hpp
  2280. #define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED
  2281. // Collect all the implementation files together here
  2282. // These are the equivalent of what would usually be cpp files
  2283. #ifdef __clang__
  2284. #pragma clang diagnostic push
  2285. #pragma clang diagnostic ignored "-Wweak-vtables"
  2286. #endif
  2287. // #included from: ../catch_runner.hpp
  2288. #define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED
  2289. // #included from: internal/catch_commandline.hpp
  2290. #define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED
  2291. // #included from: catch_config.hpp
  2292. #define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED
  2293. // #included from: catch_test_spec_parser.hpp
  2294. #define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
  2295. #ifdef __clang__
  2296. #pragma clang diagnostic push
  2297. #pragma clang diagnostic ignored "-Wpadded"
  2298. #endif
  2299. // #included from: catch_test_spec.hpp
  2300. #define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED
  2301. #ifdef __clang__
  2302. #pragma clang diagnostic push
  2303. #pragma clang diagnostic ignored "-Wpadded"
  2304. #endif
  2305. #include <string>
  2306. #include <vector>
  2307. namespace Catch {
  2308. class TestSpec {
  2309. struct Pattern : SharedImpl<> {
  2310. virtual ~Pattern();
  2311. virtual bool matches( TestCaseInfo const& testCase ) const = 0;
  2312. };
  2313. class NamePattern : public Pattern {
  2314. enum WildcardPosition {
  2315. NoWildcard = 0,
  2316. WildcardAtStart = 1,
  2317. WildcardAtEnd = 2,
  2318. WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
  2319. };
  2320. public:
  2321. NamePattern( std::string const& name ) : m_name( toLower( name ) ), m_wildcard( NoWildcard ) {
  2322. if( startsWith( m_name, "*" ) ) {
  2323. m_name = m_name.substr( 1 );
  2324. m_wildcard = WildcardAtStart;
  2325. }
  2326. if( endsWith( m_name, "*" ) ) {
  2327. m_name = m_name.substr( 0, m_name.size()-1 );
  2328. m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
  2329. }
  2330. }
  2331. virtual ~NamePattern();
  2332. virtual bool matches( TestCaseInfo const& testCase ) const {
  2333. switch( m_wildcard ) {
  2334. case NoWildcard:
  2335. return m_name == toLower( testCase.name );
  2336. case WildcardAtStart:
  2337. return endsWith( toLower( testCase.name ), m_name );
  2338. case WildcardAtEnd:
  2339. return startsWith( toLower( testCase.name ), m_name );
  2340. case WildcardAtBothEnds:
  2341. return contains( toLower( testCase.name ), m_name );
  2342. }
  2343. #ifdef __clang__
  2344. #pragma clang diagnostic push
  2345. #pragma clang diagnostic ignored "-Wunreachable-code"
  2346. #endif
  2347. throw std::logic_error( "Unknown enum" );
  2348. #ifdef __clang__
  2349. #pragma clang diagnostic pop
  2350. #endif
  2351. }
  2352. private:
  2353. std::string m_name;
  2354. WildcardPosition m_wildcard;
  2355. };
  2356. class TagPattern : public Pattern {
  2357. public:
  2358. TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
  2359. virtual ~TagPattern();
  2360. virtual bool matches( TestCaseInfo const& testCase ) const {
  2361. return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end();
  2362. }
  2363. private:
  2364. std::string m_tag;
  2365. };
  2366. class ExcludedPattern : public Pattern {
  2367. public:
  2368. ExcludedPattern( Ptr<Pattern> const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
  2369. virtual ~ExcludedPattern();
  2370. virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }
  2371. private:
  2372. Ptr<Pattern> m_underlyingPattern;
  2373. };
  2374. struct Filter {
  2375. std::vector<Ptr<Pattern> > m_patterns;
  2376. bool matches( TestCaseInfo const& testCase ) const {
  2377. // All patterns in a filter must match for the filter to be a match
  2378. for( std::vector<Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it )
  2379. if( !(*it)->matches( testCase ) )
  2380. return false;
  2381. return true;
  2382. }
  2383. };
  2384. public:
  2385. bool hasFilters() const {
  2386. return !m_filters.empty();
  2387. }
  2388. bool matches( TestCaseInfo const& testCase ) const {
  2389. // A TestSpec matches if any filter matches
  2390. for( std::vector<Filter>::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it )
  2391. if( it->matches( testCase ) )
  2392. return true;
  2393. return false;
  2394. }
  2395. private:
  2396. std::vector<Filter> m_filters;
  2397. friend class TestSpecParser;
  2398. };
  2399. }
  2400. #ifdef __clang__
  2401. #pragma clang diagnostic pop
  2402. #endif
  2403. namespace Catch {
  2404. class TestSpecParser {
  2405. enum Mode{ None, Name, QuotedName, Tag };
  2406. Mode m_mode;
  2407. bool m_exclusion;
  2408. std::size_t m_start, m_pos;
  2409. std::string m_arg;
  2410. TestSpec::Filter m_currentFilter;
  2411. TestSpec m_testSpec;
  2412. ITagAliasRegistry const* m_tagAliases;
  2413. public:
  2414. TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
  2415. TestSpecParser& parse( std::string const& arg ) {
  2416. m_mode = None;
  2417. m_exclusion = false;
  2418. m_start = std::string::npos;
  2419. m_arg = m_tagAliases->expandAliases( arg );
  2420. for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
  2421. visitChar( m_arg[m_pos] );
  2422. if( m_mode == Name )
  2423. addPattern<TestSpec::NamePattern>();
  2424. return *this;
  2425. }
  2426. TestSpec testSpec() {
  2427. addFilter();
  2428. return m_testSpec;
  2429. }
  2430. private:
  2431. void visitChar( char c ) {
  2432. if( m_mode == None ) {
  2433. switch( c ) {
  2434. case ' ': return;
  2435. case '~': m_exclusion = true; return;
  2436. case '[': return startNewMode( Tag, ++m_pos );
  2437. case '"': return startNewMode( QuotedName, ++m_pos );
  2438. default: startNewMode( Name, m_pos ); break;
  2439. }
  2440. }
  2441. if( m_mode == Name ) {
  2442. if( c == ',' ) {
  2443. addPattern<TestSpec::NamePattern>();
  2444. addFilter();
  2445. }
  2446. else if( c == '[' ) {
  2447. if( subString() == "exclude:" )
  2448. m_exclusion = true;
  2449. else
  2450. addPattern<TestSpec::NamePattern>();
  2451. startNewMode( Tag, ++m_pos );
  2452. }
  2453. }
  2454. else if( m_mode == QuotedName && c == '"' )
  2455. addPattern<TestSpec::NamePattern>();
  2456. else if( m_mode == Tag && c == ']' )
  2457. addPattern<TestSpec::TagPattern>();
  2458. }
  2459. void startNewMode( Mode mode, std::size_t start ) {
  2460. m_mode = mode;
  2461. m_start = start;
  2462. }
  2463. std::string subString() const { return m_arg.substr( m_start, m_pos - m_start ); }
  2464. template<typename T>
  2465. void addPattern() {
  2466. std::string token = subString();
  2467. if( startsWith( token, "exclude:" ) ) {
  2468. m_exclusion = true;
  2469. token = token.substr( 8 );
  2470. }
  2471. if( !token.empty() ) {
  2472. Ptr<TestSpec::Pattern> pattern = new T( token );
  2473. if( m_exclusion )
  2474. pattern = new TestSpec::ExcludedPattern( pattern );
  2475. m_currentFilter.m_patterns.push_back( pattern );
  2476. }
  2477. m_exclusion = false;
  2478. m_mode = None;
  2479. }
  2480. void addFilter() {
  2481. if( !m_currentFilter.m_patterns.empty() ) {
  2482. m_testSpec.m_filters.push_back( m_currentFilter );
  2483. m_currentFilter = TestSpec::Filter();
  2484. }
  2485. }
  2486. };
  2487. inline TestSpec parseTestSpec( std::string const& arg ) {
  2488. return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
  2489. }
  2490. } // namespace Catch
  2491. #ifdef __clang__
  2492. #pragma clang diagnostic pop
  2493. #endif
  2494. // #included from: catch_interfaces_config.h
  2495. #define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED
  2496. #include <iostream>
  2497. #include <string>
  2498. #include <vector>
  2499. namespace Catch {
  2500. struct Verbosity { enum Level {
  2501. NoOutput = 0,
  2502. Quiet,
  2503. Normal
  2504. }; };
  2505. struct WarnAbout { enum What {
  2506. Nothing = 0x00,
  2507. NoAssertions = 0x01
  2508. }; };
  2509. struct ShowDurations { enum OrNot {
  2510. DefaultForReporter,
  2511. Always,
  2512. Never
  2513. }; };
  2514. struct RunTests { enum InWhatOrder {
  2515. InDeclarationOrder,
  2516. InLexicographicalOrder,
  2517. InRandomOrder
  2518. }; };
  2519. class TestSpec;
  2520. struct IConfig : IShared {
  2521. virtual ~IConfig();
  2522. virtual bool allowThrows() const = 0;
  2523. virtual std::ostream& stream() const = 0;
  2524. virtual std::string name() const = 0;
  2525. virtual bool includeSuccessfulResults() const = 0;
  2526. virtual bool shouldDebugBreak() const = 0;
  2527. virtual bool warnAboutMissingAssertions() const = 0;
  2528. virtual int abortAfter() const = 0;
  2529. virtual bool showInvisibles() const = 0;
  2530. virtual ShowDurations::OrNot showDurations() const = 0;
  2531. virtual TestSpec const& testSpec() const = 0;
  2532. virtual RunTests::InWhatOrder runOrder() const = 0;
  2533. virtual unsigned int rngSeed() const = 0;
  2534. virtual bool forceColour() const = 0;
  2535. };
  2536. }
  2537. // #included from: catch_stream.h
  2538. #define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
  2539. #include <streambuf>
  2540. #ifdef __clang__
  2541. #pragma clang diagnostic ignored "-Wpadded"
  2542. #endif
  2543. namespace Catch {
  2544. class Stream {
  2545. public:
  2546. Stream();
  2547. Stream( std::streambuf* _streamBuf, bool _isOwned );
  2548. void release();
  2549. std::streambuf* streamBuf;
  2550. private:
  2551. bool isOwned;
  2552. };
  2553. std::ostream& cout();
  2554. std::ostream& cerr();
  2555. }
  2556. #include <memory>
  2557. #include <vector>
  2558. #include <string>
  2559. #include <iostream>
  2560. #include <ctime>
  2561. #ifndef CATCH_CONFIG_CONSOLE_WIDTH
  2562. #define CATCH_CONFIG_CONSOLE_WIDTH 80
  2563. #endif
  2564. namespace Catch {
  2565. struct ConfigData {
  2566. ConfigData()
  2567. : listTests( false ),
  2568. listTags( false ),
  2569. listReporters( false ),
  2570. listTestNamesOnly( false ),
  2571. showSuccessfulTests( false ),
  2572. shouldDebugBreak( false ),
  2573. noThrow( false ),
  2574. showHelp( false ),
  2575. showInvisibles( false ),
  2576. forceColour( false ),
  2577. abortAfter( -1 ),
  2578. rngSeed( 0 ),
  2579. verbosity( Verbosity::Normal ),
  2580. warnings( WarnAbout::Nothing ),
  2581. showDurations( ShowDurations::DefaultForReporter ),
  2582. runOrder( RunTests::InDeclarationOrder )
  2583. {}
  2584. bool listTests;
  2585. bool listTags;
  2586. bool listReporters;
  2587. bool listTestNamesOnly;
  2588. bool showSuccessfulTests;
  2589. bool shouldDebugBreak;
  2590. bool noThrow;
  2591. bool showHelp;
  2592. bool showInvisibles;
  2593. bool forceColour;
  2594. int abortAfter;
  2595. unsigned int rngSeed;
  2596. Verbosity::Level verbosity;
  2597. WarnAbout::What warnings;
  2598. ShowDurations::OrNot showDurations;
  2599. RunTests::InWhatOrder runOrder;
  2600. std::string reporterName;
  2601. std::string outputFilename;
  2602. std::string name;
  2603. std::string processName;
  2604. std::vector<std::string> testsOrTags;
  2605. };
  2606. class Config : public SharedImpl<IConfig> {
  2607. private:
  2608. Config( Config const& other );
  2609. Config& operator = ( Config const& other );
  2610. virtual void dummy();
  2611. public:
  2612. Config()
  2613. : m_os( Catch::cout().rdbuf() )
  2614. {}
  2615. Config( ConfigData const& data )
  2616. : m_data( data ),
  2617. m_os( Catch::cout().rdbuf() )
  2618. {
  2619. if( !data.testsOrTags.empty() ) {
  2620. TestSpecParser parser( ITagAliasRegistry::get() );
  2621. for( std::size_t i = 0; i < data.testsOrTags.size(); ++i )
  2622. parser.parse( data.testsOrTags[i] );
  2623. m_testSpec = parser.testSpec();
  2624. }
  2625. }
  2626. virtual ~Config() {
  2627. m_os.rdbuf( Catch::cout().rdbuf() );
  2628. m_stream.release();
  2629. }
  2630. void setFilename( std::string const& filename ) {
  2631. m_data.outputFilename = filename;
  2632. }
  2633. std::string const& getFilename() const {
  2634. return m_data.outputFilename ;
  2635. }
  2636. bool listTests() const { return m_data.listTests; }
  2637. bool listTestNamesOnly() const { return m_data.listTestNamesOnly; }
  2638. bool listTags() const { return m_data.listTags; }
  2639. bool listReporters() const { return m_data.listReporters; }
  2640. std::string getProcessName() const { return m_data.processName; }
  2641. bool shouldDebugBreak() const { return m_data.shouldDebugBreak; }
  2642. void setStreamBuf( std::streambuf* buf ) {
  2643. m_os.rdbuf( buf ? buf : Catch::cout().rdbuf() );
  2644. }
  2645. void useStream( std::string const& streamName ) {
  2646. Stream stream = createStream( streamName );
  2647. setStreamBuf( stream.streamBuf );
  2648. m_stream.release();
  2649. m_stream = stream;
  2650. }
  2651. std::string getReporterName() const { return m_data.reporterName; }
  2652. int abortAfter() const { return m_data.abortAfter; }
  2653. TestSpec const& testSpec() const { return m_testSpec; }
  2654. bool showHelp() const { return m_data.showHelp; }
  2655. bool showInvisibles() const { return m_data.showInvisibles; }
  2656. // IConfig interface
  2657. virtual bool allowThrows() const { return !m_data.noThrow; }
  2658. virtual std::ostream& stream() const { return m_os; }
  2659. virtual std::string name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
  2660. virtual bool includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
  2661. virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; }
  2662. virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; }
  2663. virtual RunTests::InWhatOrder runOrder() const { return m_data.runOrder; }
  2664. virtual unsigned int rngSeed() const { return m_data.rngSeed; }
  2665. virtual bool forceColour() const { return m_data.forceColour; }
  2666. private:
  2667. ConfigData m_data;
  2668. Stream m_stream;
  2669. mutable std::ostream m_os;
  2670. TestSpec m_testSpec;
  2671. };
  2672. } // end namespace Catch
  2673. // #included from: catch_clara.h
  2674. #define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED
  2675. // Use Catch's value for console width (store Clara's off to the side, if present)
  2676. #ifdef CLARA_CONFIG_CONSOLE_WIDTH
  2677. #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH
  2678. #undef CLARA_CONFIG_CONSOLE_WIDTH
  2679. #endif
  2680. #define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
  2681. // Declare Clara inside the Catch namespace
  2682. #define STITCH_CLARA_OPEN_NAMESPACE namespace Catch {
  2683. // #included from: ../external/clara.h
  2684. // Only use header guard if we are not using an outer namespace
  2685. #if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE)
  2686. #ifndef STITCH_CLARA_OPEN_NAMESPACE
  2687. #define TWOBLUECUBES_CLARA_H_INCLUDED
  2688. #define STITCH_CLARA_OPEN_NAMESPACE
  2689. #define STITCH_CLARA_CLOSE_NAMESPACE
  2690. #else
  2691. #define STITCH_CLARA_CLOSE_NAMESPACE }
  2692. #endif
  2693. #define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE
  2694. // ----------- #included from tbc_text_format.h -----------
  2695. // Only use header guard if we are not using an outer namespace
  2696. #if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE)
  2697. #ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
  2698. #define TBC_TEXT_FORMAT_H_INCLUDED
  2699. #endif
  2700. #include <string>
  2701. #include <vector>
  2702. #include <sstream>
  2703. // Use optional outer namespace
  2704. #ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
  2705. namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
  2706. #endif
  2707. namespace Tbc {
  2708. #ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
  2709. const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
  2710. #else
  2711. const unsigned int consoleWidth = 80;
  2712. #endif
  2713. struct TextAttributes {
  2714. TextAttributes()
  2715. : initialIndent( std::string::npos ),
  2716. indent( 0 ),
  2717. width( consoleWidth-1 ),
  2718. tabChar( '\t' )
  2719. {}
  2720. TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; }
  2721. TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; }
  2722. TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; }
  2723. TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; }
  2724. std::size_t initialIndent; // indent of first line, or npos
  2725. std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos
  2726. std::size_t width; // maximum width of text, including indent. Longer text will wrap
  2727. char tabChar; // If this char is seen the indent is changed to current pos
  2728. };
  2729. class Text {
  2730. public:
  2731. Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
  2732. : attr( _attr )
  2733. {
  2734. std::string wrappableChars = " [({.,/|\\-";
  2735. std::size_t indent = _attr.initialIndent != std::string::npos
  2736. ? _attr.initialIndent
  2737. : _attr.indent;
  2738. std::string remainder = _str;
  2739. while( !remainder.empty() ) {
  2740. if( lines.size() >= 1000 ) {
  2741. lines.push_back( "... message truncated due to excessive size" );
  2742. return;
  2743. }
  2744. std::size_t tabPos = std::string::npos;
  2745. std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
  2746. std::size_t pos = remainder.find_first_of( '\n' );
  2747. if( pos <= width ) {
  2748. width = pos;
  2749. }
  2750. pos = remainder.find_last_of( _attr.tabChar, width );
  2751. if( pos != std::string::npos ) {
  2752. tabPos = pos;
  2753. if( remainder[width] == '\n' )
  2754. width--;
  2755. remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
  2756. }
  2757. if( width == remainder.size() ) {
  2758. spliceLine( indent, remainder, width );
  2759. }
  2760. else if( remainder[width] == '\n' ) {
  2761. spliceLine( indent, remainder, width );
  2762. if( width <= 1 || remainder.size() != 1 )
  2763. remainder = remainder.substr( 1 );
  2764. indent = _attr.indent;
  2765. }
  2766. else {
  2767. pos = remainder.find_last_of( wrappableChars, width );
  2768. if( pos != std::string::npos && pos > 0 ) {
  2769. spliceLine( indent, remainder, pos );
  2770. if( remainder[0] == ' ' )
  2771. remainder = remainder.substr( 1 );
  2772. }
  2773. else {
  2774. spliceLine( indent, remainder, width-1 );
  2775. lines.back() += "-";
  2776. }
  2777. if( lines.size() == 1 )
  2778. indent = _attr.indent;
  2779. if( tabPos != std::string::npos )
  2780. indent += tabPos;
  2781. }
  2782. }
  2783. }
  2784. void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
  2785. lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
  2786. _remainder = _remainder.substr( _pos );
  2787. }
  2788. typedef std::vector<std::string>::const_iterator const_iterator;
  2789. const_iterator begin() const { return lines.begin(); }
  2790. const_iterator end() const { return lines.end(); }
  2791. std::string const& last() const { return lines.back(); }
  2792. std::size_t size() const { return lines.size(); }
  2793. std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
  2794. std::string toString() const {
  2795. std::ostringstream oss;
  2796. oss << *this;
  2797. return oss.str();
  2798. }
  2799. inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
  2800. for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
  2801. it != itEnd; ++it ) {
  2802. if( it != _text.begin() )
  2803. _stream << "\n";
  2804. _stream << *it;
  2805. }
  2806. return _stream;
  2807. }
  2808. private:
  2809. std::string str;
  2810. TextAttributes attr;
  2811. std::vector<std::string> lines;
  2812. };
  2813. } // end namespace Tbc
  2814. #ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
  2815. } // end outer namespace
  2816. #endif
  2817. #endif // TBC_TEXT_FORMAT_H_INCLUDED
  2818. // ----------- end of #include from tbc_text_format.h -----------
  2819. // ........... back in /Users/philnash/Dev/OSS/Clara/srcs/clara.h
  2820. #undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE
  2821. #include <map>
  2822. #include <algorithm>
  2823. #include <stdexcept>
  2824. #include <memory>
  2825. // Use optional outer namespace
  2826. #ifdef STITCH_CLARA_OPEN_NAMESPACE
  2827. STITCH_CLARA_OPEN_NAMESPACE
  2828. #endif
  2829. namespace Clara {
  2830. struct UnpositionalTag {};
  2831. extern UnpositionalTag _;
  2832. #ifdef CLARA_CONFIG_MAIN
  2833. UnpositionalTag _;
  2834. #endif
  2835. namespace Detail {
  2836. #ifdef CLARA_CONSOLE_WIDTH
  2837. const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH;
  2838. #else
  2839. const unsigned int consoleWidth = 80;
  2840. #endif
  2841. using namespace Tbc;
  2842. inline bool startsWith( std::string const& str, std::string const& prefix ) {
  2843. return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix;
  2844. }
  2845. template<typename T> struct RemoveConstRef{ typedef T type; };
  2846. template<typename T> struct RemoveConstRef<T&>{ typedef T type; };
  2847. template<typename T> struct RemoveConstRef<T const&>{ typedef T type; };
  2848. template<typename T> struct RemoveConstRef<T const>{ typedef T type; };
  2849. template<typename T> struct IsBool { static const bool value = false; };
  2850. template<> struct IsBool<bool> { static const bool value = true; };
  2851. template<typename T>
  2852. void convertInto( std::string const& _source, T& _dest ) {
  2853. std::stringstream ss;
  2854. ss << _source;
  2855. ss >> _dest;
  2856. if( ss.fail() )
  2857. throw std::runtime_error( "Unable to convert " + _source + " to destination type" );
  2858. }
  2859. inline void convertInto( std::string const& _source, std::string& _dest ) {
  2860. _dest = _source;
  2861. }
  2862. inline void convertInto( std::string const& _source, bool& _dest ) {
  2863. std::string sourceLC = _source;
  2864. std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), ::tolower );
  2865. if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" )
  2866. _dest = true;
  2867. else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" )
  2868. _dest = false;
  2869. else
  2870. throw std::runtime_error( "Expected a boolean value but did not recognise:\n '" + _source + "'" );
  2871. }
  2872. inline void convertInto( bool _source, bool& _dest ) {
  2873. _dest = _source;
  2874. }
  2875. template<typename T>
  2876. inline void convertInto( bool, T& ) {
  2877. throw std::runtime_error( "Invalid conversion" );
  2878. }
  2879. template<typename ConfigT>
  2880. struct IArgFunction {
  2881. virtual ~IArgFunction() {}
  2882. # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
  2883. IArgFunction() = default;
  2884. IArgFunction( IArgFunction const& ) = default;
  2885. # endif
  2886. virtual void set( ConfigT& config, std::string const& value ) const = 0;
  2887. virtual void setFlag( ConfigT& config ) const = 0;
  2888. virtual bool takesArg() const = 0;
  2889. virtual IArgFunction* clone() const = 0;
  2890. };
  2891. template<typename ConfigT>
  2892. class BoundArgFunction {
  2893. public:
  2894. BoundArgFunction() : functionObj( NULL ) {}
  2895. BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {}
  2896. BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : NULL ) {}
  2897. BoundArgFunction& operator = ( BoundArgFunction const& other ) {
  2898. IArgFunction<ConfigT>* newFunctionObj = other.functionObj ? other.functionObj->clone() : NULL;
  2899. delete functionObj;
  2900. functionObj = newFunctionObj;
  2901. return *this;
  2902. }
  2903. ~BoundArgFunction() { delete functionObj; }
  2904. void set( ConfigT& config, std::string const& value ) const {
  2905. functionObj->set( config, value );
  2906. }
  2907. void setFlag( ConfigT& config ) const {
  2908. functionObj->setFlag( config );
  2909. }
  2910. bool takesArg() const { return functionObj->takesArg(); }
  2911. bool isSet() const {
  2912. return functionObj != NULL;
  2913. }
  2914. private:
  2915. IArgFunction<ConfigT>* functionObj;
  2916. };
  2917. template<typename C>
  2918. struct NullBinder : IArgFunction<C>{
  2919. virtual void set( C&, std::string const& ) const {}
  2920. virtual void setFlag( C& ) const {}
  2921. virtual bool takesArg() const { return true; }
  2922. virtual IArgFunction<C>* clone() const { return new NullBinder( *this ); }
  2923. };
  2924. template<typename C, typename M>
  2925. struct BoundDataMember : IArgFunction<C>{
  2926. BoundDataMember( M C::* _member ) : member( _member ) {}
  2927. virtual void set( C& p, std::string const& stringValue ) const {
  2928. convertInto( stringValue, p.*member );
  2929. }
  2930. virtual void setFlag( C& p ) const {
  2931. convertInto( true, p.*member );
  2932. }
  2933. virtual bool takesArg() const { return !IsBool<M>::value; }
  2934. virtual IArgFunction<C>* clone() const { return new BoundDataMember( *this ); }
  2935. M C::* member;
  2936. };
  2937. template<typename C, typename M>
  2938. struct BoundUnaryMethod : IArgFunction<C>{
  2939. BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {}
  2940. virtual void set( C& p, std::string const& stringValue ) const {
  2941. typename RemoveConstRef<M>::type value;
  2942. convertInto( stringValue, value );
  2943. (p.*member)( value );
  2944. }
  2945. virtual void setFlag( C& p ) const {
  2946. typename RemoveConstRef<M>::type value;
  2947. convertInto( true, value );
  2948. (p.*member)( value );
  2949. }
  2950. virtual bool takesArg() const { return !IsBool<M>::value; }
  2951. virtual IArgFunction<C>* clone() const { return new BoundUnaryMethod( *this ); }
  2952. void (C::*member)( M );
  2953. };
  2954. template<typename C>
  2955. struct BoundNullaryMethod : IArgFunction<C>{
  2956. BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {}
  2957. virtual void set( C& p, std::string const& stringValue ) const {
  2958. bool value;
  2959. convertInto( stringValue, value );
  2960. if( value )
  2961. (p.*member)();
  2962. }
  2963. virtual void setFlag( C& p ) const {
  2964. (p.*member)();
  2965. }
  2966. virtual bool takesArg() const { return false; }
  2967. virtual IArgFunction<C>* clone() const { return new BoundNullaryMethod( *this ); }
  2968. void (C::*member)();
  2969. };
  2970. template<typename C>
  2971. struct BoundUnaryFunction : IArgFunction<C>{
  2972. BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {}
  2973. virtual void set( C& obj, std::string const& stringValue ) const {
  2974. bool value;
  2975. convertInto( stringValue, value );
  2976. if( value )
  2977. function( obj );
  2978. }
  2979. virtual void setFlag( C& p ) const {
  2980. function( p );
  2981. }
  2982. virtual bool takesArg() const { return false; }
  2983. virtual IArgFunction<C>* clone() const { return new BoundUnaryFunction( *this ); }
  2984. void (*function)( C& );
  2985. };
  2986. template<typename C, typename T>
  2987. struct BoundBinaryFunction : IArgFunction<C>{
  2988. BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {}
  2989. virtual void set( C& obj, std::string const& stringValue ) const {
  2990. typename RemoveConstRef<T>::type value;
  2991. convertInto( stringValue, value );
  2992. function( obj, value );
  2993. }
  2994. virtual void setFlag( C& obj ) const {
  2995. typename RemoveConstRef<T>::type value;
  2996. convertInto( true, value );
  2997. function( obj, value );
  2998. }
  2999. virtual bool takesArg() const { return !IsBool<T>::value; }
  3000. virtual IArgFunction<C>* clone() const { return new BoundBinaryFunction( *this ); }
  3001. void (*function)( C&, T );
  3002. };
  3003. } // namespace Detail
  3004. struct Parser {
  3005. Parser() : separators( " \t=:" ) {}
  3006. struct Token {
  3007. enum Type { Positional, ShortOpt, LongOpt };
  3008. Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {}
  3009. Type type;
  3010. std::string data;
  3011. };
  3012. void parseIntoTokens( int argc, char const * const * argv, std::vector<Parser::Token>& tokens ) const {
  3013. const std::string doubleDash = "--";
  3014. for( int i = 1; i < argc && argv[i] != doubleDash; ++i )
  3015. parseIntoTokens( argv[i] , tokens);
  3016. }
  3017. void parseIntoTokens( std::string arg, std::vector<Parser::Token>& tokens ) const {
  3018. while( !arg.empty() ) {
  3019. Parser::Token token( Parser::Token::Positional, arg );
  3020. arg = "";
  3021. if( token.data[0] == '-' ) {
  3022. if( token.data.size() > 1 && token.data[1] == '-' ) {
  3023. token = Parser::Token( Parser::Token::LongOpt, token.data.substr( 2 ) );
  3024. }
  3025. else {
  3026. token = Parser::Token( Parser::Token::ShortOpt, token.data.substr( 1 ) );
  3027. if( token.data.size() > 1 && separators.find( token.data[1] ) == std::string::npos ) {
  3028. arg = "-" + token.data.substr( 1 );
  3029. token.data = token.data.substr( 0, 1 );
  3030. }
  3031. }
  3032. }
  3033. if( token.type != Parser::Token::Positional ) {
  3034. std::size_t pos = token.data.find_first_of( separators );
  3035. if( pos != std::string::npos ) {
  3036. arg = token.data.substr( pos+1 );
  3037. token.data = token.data.substr( 0, pos );
  3038. }
  3039. }
  3040. tokens.push_back( token );
  3041. }
  3042. }
  3043. std::string separators;
  3044. };
  3045. template<typename ConfigT>
  3046. struct CommonArgProperties {
  3047. CommonArgProperties() {}
  3048. CommonArgProperties( Detail::BoundArgFunction<ConfigT> const& _boundField ) : boundField( _boundField ) {}
  3049. Detail::BoundArgFunction<ConfigT> boundField;
  3050. std::string description;
  3051. std::string detail;
  3052. std::string placeholder; // Only value if boundField takes an arg
  3053. bool takesArg() const {
  3054. return !placeholder.empty();
  3055. }
  3056. void validate() const {
  3057. if( !boundField.isSet() )
  3058. throw std::logic_error( "option not bound" );
  3059. }
  3060. };
  3061. struct OptionArgProperties {
  3062. std::vector<std::string> shortNames;
  3063. std::string longName;
  3064. bool hasShortName( std::string const& shortName ) const {
  3065. return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end();
  3066. }
  3067. bool hasLongName( std::string const& _longName ) const {
  3068. return _longName == longName;
  3069. }
  3070. };
  3071. struct PositionalArgProperties {
  3072. PositionalArgProperties() : position( -1 ) {}
  3073. int position; // -1 means non-positional (floating)
  3074. bool isFixedPositional() const {
  3075. return position != -1;
  3076. }
  3077. };
  3078. template<typename ConfigT>
  3079. class CommandLine {
  3080. struct Arg : CommonArgProperties<ConfigT>, OptionArgProperties, PositionalArgProperties {
  3081. Arg() {}
  3082. Arg( Detail::BoundArgFunction<ConfigT> const& _boundField ) : CommonArgProperties<ConfigT>( _boundField ) {}
  3083. using CommonArgProperties<ConfigT>::placeholder; // !TBD
  3084. std::string dbgName() const {
  3085. if( !longName.empty() )
  3086. return "--" + longName;
  3087. if( !shortNames.empty() )
  3088. return "-" + shortNames[0];
  3089. return "positional args";
  3090. }
  3091. std::string commands() const {
  3092. std::ostringstream oss;
  3093. bool first = true;
  3094. std::vector<std::string>::const_iterator it = shortNames.begin(), itEnd = shortNames.end();
  3095. for(; it != itEnd; ++it ) {
  3096. if( first )
  3097. first = false;
  3098. else
  3099. oss << ", ";
  3100. oss << "-" << *it;
  3101. }
  3102. if( !longName.empty() ) {
  3103. if( !first )
  3104. oss << ", ";
  3105. oss << "--" << longName;
  3106. }
  3107. if( !placeholder.empty() )
  3108. oss << " <" << placeholder << ">";
  3109. return oss.str();
  3110. }
  3111. };
  3112. // NOTE: std::auto_ptr is deprecated in c++11/c++0x
  3113. #if defined(__cplusplus) && __cplusplus > 199711L
  3114. typedef std::unique_ptr<Arg> ArgAutoPtr;
  3115. #else
  3116. typedef std::auto_ptr<Arg> ArgAutoPtr;
  3117. #endif
  3118. friend void addOptName( Arg& arg, std::string const& optName )
  3119. {
  3120. if( optName.empty() )
  3121. return;
  3122. if( Detail::startsWith( optName, "--" ) ) {
  3123. if( !arg.longName.empty() )
  3124. throw std::logic_error( "Only one long opt may be specified. '"
  3125. + arg.longName
  3126. + "' already specified, now attempting to add '"
  3127. + optName + "'" );
  3128. arg.longName = optName.substr( 2 );
  3129. }
  3130. else if( Detail::startsWith( optName, "-" ) )
  3131. arg.shortNames.push_back( optName.substr( 1 ) );
  3132. else
  3133. throw std::logic_error( "option must begin with - or --. Option was: '" + optName + "'" );
  3134. }
  3135. friend void setPositionalArg( Arg& arg, int position )
  3136. {
  3137. arg.position = position;
  3138. }
  3139. class ArgBuilder {
  3140. public:
  3141. ArgBuilder( Arg* arg ) : m_arg( arg ) {}
  3142. // Bind a non-boolean data member (requires placeholder string)
  3143. template<typename C, typename M>
  3144. void bind( M C::* field, std::string const& placeholder ) {
  3145. m_arg->boundField = new Detail::BoundDataMember<C,M>( field );
  3146. m_arg->placeholder = placeholder;
  3147. }
  3148. // Bind a boolean data member (no placeholder required)
  3149. template<typename C>
  3150. void bind( bool C::* field ) {
  3151. m_arg->boundField = new Detail::BoundDataMember<C,bool>( field );
  3152. }
  3153. // Bind a method taking a single, non-boolean argument (requires a placeholder string)
  3154. template<typename C, typename M>
  3155. void bind( void (C::* unaryMethod)( M ), std::string const& placeholder ) {
  3156. m_arg->boundField = new Detail::BoundUnaryMethod<C,M>( unaryMethod );
  3157. m_arg->placeholder = placeholder;
  3158. }
  3159. // Bind a method taking a single, boolean argument (no placeholder string required)
  3160. template<typename C>
  3161. void bind( void (C::* unaryMethod)( bool ) ) {
  3162. m_arg->boundField = new Detail::BoundUnaryMethod<C,bool>( unaryMethod );
  3163. }
  3164. // Bind a method that takes no arguments (will be called if opt is present)
  3165. template<typename C>
  3166. void bind( void (C::* nullaryMethod)() ) {
  3167. m_arg->boundField = new Detail::BoundNullaryMethod<C>( nullaryMethod );
  3168. }
  3169. // Bind a free function taking a single argument - the object to operate on (no placeholder string required)
  3170. template<typename C>
  3171. void bind( void (* unaryFunction)( C& ) ) {
  3172. m_arg->boundField = new Detail::BoundUnaryFunction<C>( unaryFunction );
  3173. }
  3174. // Bind a free function taking a single argument - the object to operate on (requires a placeholder string)
  3175. template<typename C, typename T>
  3176. void bind( void (* binaryFunction)( C&, T ), std::string const& placeholder ) {
  3177. m_arg->boundField = new Detail::BoundBinaryFunction<C, T>( binaryFunction );
  3178. m_arg->placeholder = placeholder;
  3179. }
  3180. ArgBuilder& describe( std::string const& description ) {
  3181. m_arg->description = description;
  3182. return *this;
  3183. }
  3184. ArgBuilder& detail( std::string const& detail ) {
  3185. m_arg->detail = detail;
  3186. return *this;
  3187. }
  3188. protected:
  3189. Arg* m_arg;
  3190. };
  3191. class OptBuilder : public ArgBuilder {
  3192. public:
  3193. OptBuilder( Arg* arg ) : ArgBuilder( arg ) {}
  3194. OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {}
  3195. OptBuilder& operator[]( std::string const& optName ) {
  3196. addOptName( *ArgBuilder::m_arg, optName );
  3197. return *this;
  3198. }
  3199. };
  3200. public:
  3201. CommandLine()
  3202. : m_boundProcessName( new Detail::NullBinder<ConfigT>() ),
  3203. m_highestSpecifiedArgPosition( 0 ),
  3204. m_throwOnUnrecognisedTokens( false )
  3205. {}
  3206. CommandLine( CommandLine const& other )
  3207. : m_boundProcessName( other.m_boundProcessName ),
  3208. m_options ( other.m_options ),
  3209. m_positionalArgs( other.m_positionalArgs ),
  3210. m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ),
  3211. m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens )
  3212. {
  3213. if( other.m_floatingArg.get() )
  3214. m_floatingArg.reset( new Arg( *other.m_floatingArg ) );
  3215. }
  3216. CommandLine& setThrowOnUnrecognisedTokens( bool shouldThrow = true ) {
  3217. m_throwOnUnrecognisedTokens = shouldThrow;
  3218. return *this;
  3219. }
  3220. OptBuilder operator[]( std::string const& optName ) {
  3221. m_options.push_back( Arg() );
  3222. addOptName( m_options.back(), optName );
  3223. OptBuilder builder( &m_options.back() );
  3224. return builder;
  3225. }
  3226. ArgBuilder operator[]( int position ) {
  3227. m_positionalArgs.insert( std::make_pair( position, Arg() ) );
  3228. if( position > m_highestSpecifiedArgPosition )
  3229. m_highestSpecifiedArgPosition = position;
  3230. setPositionalArg( m_positionalArgs[position], position );
  3231. ArgBuilder builder( &m_positionalArgs[position] );
  3232. return builder;
  3233. }
  3234. // Invoke this with the _ instance
  3235. ArgBuilder operator[]( UnpositionalTag ) {
  3236. if( m_floatingArg.get() )
  3237. throw std::logic_error( "Only one unpositional argument can be added" );
  3238. m_floatingArg.reset( new Arg() );
  3239. ArgBuilder builder( m_floatingArg.get() );
  3240. return builder;
  3241. }
  3242. template<typename C, typename M>
  3243. void bindProcessName( M C::* field ) {
  3244. m_boundProcessName = new Detail::BoundDataMember<C,M>( field );
  3245. }
  3246. template<typename C, typename M>
  3247. void bindProcessName( void (C::*_unaryMethod)( M ) ) {
  3248. m_boundProcessName = new Detail::BoundUnaryMethod<C,M>( _unaryMethod );
  3249. }
  3250. void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth ) const {
  3251. typename std::vector<Arg>::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it;
  3252. std::size_t maxWidth = 0;
  3253. for( it = itBegin; it != itEnd; ++it )
  3254. maxWidth = (std::max)( maxWidth, it->commands().size() );
  3255. for( it = itBegin; it != itEnd; ++it ) {
  3256. Detail::Text usage( it->commands(), Detail::TextAttributes()
  3257. .setWidth( maxWidth+indent )
  3258. .setIndent( indent ) );
  3259. Detail::Text desc( it->description, Detail::TextAttributes()
  3260. .setWidth( width - maxWidth - 3 ) );
  3261. for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) {
  3262. std::string usageCol = i < usage.size() ? usage[i] : "";
  3263. os << usageCol;
  3264. if( i < desc.size() && !desc[i].empty() )
  3265. os << std::string( indent + 2 + maxWidth - usageCol.size(), ' ' )
  3266. << desc[i];
  3267. os << "\n";
  3268. }
  3269. }
  3270. }
  3271. std::string optUsage() const {
  3272. std::ostringstream oss;
  3273. optUsage( oss );
  3274. return oss.str();
  3275. }
  3276. void argSynopsis( std::ostream& os ) const {
  3277. for( int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) {
  3278. if( i > 1 )
  3279. os << " ";
  3280. typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( i );
  3281. if( it != m_positionalArgs.end() )
  3282. os << "<" << it->second.placeholder << ">";
  3283. else if( m_floatingArg.get() )
  3284. os << "<" << m_floatingArg->placeholder << ">";
  3285. else
  3286. throw std::logic_error( "non consecutive positional arguments with no floating args" );
  3287. }
  3288. // !TBD No indication of mandatory args
  3289. if( m_floatingArg.get() ) {
  3290. if( m_highestSpecifiedArgPosition > 1 )
  3291. os << " ";
  3292. os << "[<" << m_floatingArg->placeholder << "> ...]";
  3293. }
  3294. }
  3295. std::string argSynopsis() const {
  3296. std::ostringstream oss;
  3297. argSynopsis( oss );
  3298. return oss.str();
  3299. }
  3300. void usage( std::ostream& os, std::string const& procName ) const {
  3301. validate();
  3302. os << "usage:\n " << procName << " ";
  3303. argSynopsis( os );
  3304. if( !m_options.empty() ) {
  3305. os << " [options]\n\nwhere options are: \n";
  3306. optUsage( os, 2 );
  3307. }
  3308. os << "\n";
  3309. }
  3310. std::string usage( std::string const& procName ) const {
  3311. std::ostringstream oss;
  3312. usage( oss, procName );
  3313. return oss.str();
  3314. }
  3315. ConfigT parse( int argc, char const * const * argv ) const {
  3316. ConfigT config;
  3317. parseInto( argc, argv, config );
  3318. return config;
  3319. }
  3320. std::vector<Parser::Token> parseInto( int argc, char const * const * argv, ConfigT& config ) const {
  3321. std::string processName = argv[0];
  3322. std::size_t lastSlash = processName.find_last_of( "/\\" );
  3323. if( lastSlash != std::string::npos )
  3324. processName = processName.substr( lastSlash+1 );
  3325. m_boundProcessName.set( config, processName );
  3326. std::vector<Parser::Token> tokens;
  3327. Parser parser;
  3328. parser.parseIntoTokens( argc, argv, tokens );
  3329. return populate( tokens, config );
  3330. }
  3331. std::vector<Parser::Token> populate( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
  3332. validate();
  3333. std::vector<Parser::Token> unusedTokens = populateOptions( tokens, config );
  3334. unusedTokens = populateFixedArgs( unusedTokens, config );
  3335. unusedTokens = populateFloatingArgs( unusedTokens, config );
  3336. return unusedTokens;
  3337. }
  3338. std::vector<Parser::Token> populateOptions( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
  3339. std::vector<Parser::Token> unusedTokens;
  3340. std::vector<std::string> errors;
  3341. for( std::size_t i = 0; i < tokens.size(); ++i ) {
  3342. Parser::Token const& token = tokens[i];
  3343. typename std::vector<Arg>::const_iterator it = m_options.begin(), itEnd = m_options.end();
  3344. for(; it != itEnd; ++it ) {
  3345. Arg const& arg = *it;
  3346. try {
  3347. if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) ||
  3348. ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) {
  3349. if( arg.takesArg() ) {
  3350. if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional )
  3351. errors.push_back( "Expected argument to option: " + token.data );
  3352. else
  3353. arg.boundField.set( config, tokens[++i].data );
  3354. }
  3355. else {
  3356. arg.boundField.setFlag( config );
  3357. }
  3358. break;
  3359. }
  3360. }
  3361. catch( std::exception& ex ) {
  3362. errors.push_back( std::string( ex.what() ) + "\n- while parsing: (" + arg.commands() + ")" );
  3363. }
  3364. }
  3365. if( it == itEnd ) {
  3366. if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens )
  3367. unusedTokens.push_back( token );
  3368. else if( errors.empty() && m_throwOnUnrecognisedTokens )
  3369. errors.push_back( "unrecognised option: " + token.data );
  3370. }
  3371. }
  3372. if( !errors.empty() ) {
  3373. std::ostringstream oss;
  3374. for( std::vector<std::string>::const_iterator it = errors.begin(), itEnd = errors.end();
  3375. it != itEnd;
  3376. ++it ) {
  3377. if( it != errors.begin() )
  3378. oss << "\n";
  3379. oss << *it;
  3380. }
  3381. throw std::runtime_error( oss.str() );
  3382. }
  3383. return unusedTokens;
  3384. }
  3385. std::vector<Parser::Token> populateFixedArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
  3386. std::vector<Parser::Token> unusedTokens;
  3387. int position = 1;
  3388. for( std::size_t i = 0; i < tokens.size(); ++i ) {
  3389. Parser::Token const& token = tokens[i];
  3390. typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( position );
  3391. if( it != m_positionalArgs.end() )
  3392. it->second.boundField.set( config, token.data );
  3393. else
  3394. unusedTokens.push_back( token );
  3395. if( token.type == Parser::Token::Positional )
  3396. position++;
  3397. }
  3398. return unusedTokens;
  3399. }
  3400. std::vector<Parser::Token> populateFloatingArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
  3401. if( !m_floatingArg.get() )
  3402. return tokens;
  3403. std::vector<Parser::Token> unusedTokens;
  3404. for( std::size_t i = 0; i < tokens.size(); ++i ) {
  3405. Parser::Token const& token = tokens[i];
  3406. if( token.type == Parser::Token::Positional )
  3407. m_floatingArg->boundField.set( config, token.data );
  3408. else
  3409. unusedTokens.push_back( token );
  3410. }
  3411. return unusedTokens;
  3412. }
  3413. void validate() const
  3414. {
  3415. if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() )
  3416. throw std::logic_error( "No options or arguments specified" );
  3417. for( typename std::vector<Arg>::const_iterator it = m_options.begin(),
  3418. itEnd = m_options.end();
  3419. it != itEnd; ++it )
  3420. it->validate();
  3421. }
  3422. private:
  3423. Detail::BoundArgFunction<ConfigT> m_boundProcessName;
  3424. std::vector<Arg> m_options;
  3425. std::map<int, Arg> m_positionalArgs;
  3426. ArgAutoPtr m_floatingArg;
  3427. int m_highestSpecifiedArgPosition;
  3428. bool m_throwOnUnrecognisedTokens;
  3429. };
  3430. } // end namespace Clara
  3431. STITCH_CLARA_CLOSE_NAMESPACE
  3432. #undef STITCH_CLARA_OPEN_NAMESPACE
  3433. #undef STITCH_CLARA_CLOSE_NAMESPACE
  3434. #endif // TWOBLUECUBES_CLARA_H_INCLUDED
  3435. #undef STITCH_CLARA_OPEN_NAMESPACE
  3436. // Restore Clara's value for console width, if present
  3437. #ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
  3438. #define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
  3439. #undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
  3440. #endif
  3441. #include <fstream>
  3442. namespace Catch {
  3443. inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; }
  3444. inline void abortAfterX( ConfigData& config, int x ) {
  3445. if( x < 1 )
  3446. throw std::runtime_error( "Value after -x or --abortAfter must be greater than zero" );
  3447. config.abortAfter = x;
  3448. }
  3449. inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); }
  3450. inline void addWarning( ConfigData& config, std::string const& _warning ) {
  3451. if( _warning == "NoAssertions" )
  3452. config.warnings = static_cast<WarnAbout::What>( config.warnings | WarnAbout::NoAssertions );
  3453. else
  3454. throw std::runtime_error( "Unrecognised warning: '" + _warning + "'" );
  3455. }
  3456. inline void setOrder( ConfigData& config, std::string const& order ) {
  3457. if( startsWith( "declared", order ) )
  3458. config.runOrder = RunTests::InDeclarationOrder;
  3459. else if( startsWith( "lexical", order ) )
  3460. config.runOrder = RunTests::InLexicographicalOrder;
  3461. else if( startsWith( "random", order ) )
  3462. config.runOrder = RunTests::InRandomOrder;
  3463. else
  3464. throw std::runtime_error( "Unrecognised ordering: '" + order + "'" );
  3465. }
  3466. inline void setRngSeed( ConfigData& config, std::string const& seed ) {
  3467. if( seed == "time" ) {
  3468. config.rngSeed = static_cast<unsigned int>( std::time(0) );
  3469. }
  3470. else {
  3471. std::stringstream ss;
  3472. ss << seed;
  3473. ss >> config.rngSeed;
  3474. if( ss.fail() )
  3475. throw std::runtime_error( "Argment to --rng-seed should be the word 'time' or a number" );
  3476. }
  3477. }
  3478. inline void setVerbosity( ConfigData& config, int level ) {
  3479. // !TBD: accept strings?
  3480. config.verbosity = static_cast<Verbosity::Level>( level );
  3481. }
  3482. inline void setShowDurations( ConfigData& config, bool _showDurations ) {
  3483. config.showDurations = _showDurations
  3484. ? ShowDurations::Always
  3485. : ShowDurations::Never;
  3486. }
  3487. inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) {
  3488. std::ifstream f( _filename.c_str() );
  3489. if( !f.is_open() )
  3490. throw std::domain_error( "Unable to load input file: " + _filename );
  3491. std::string line;
  3492. while( std::getline( f, line ) ) {
  3493. line = trim(line);
  3494. if( !line.empty() && !startsWith( line, "#" ) )
  3495. addTestOrTags( config, "\"" + line + "\"," );
  3496. }
  3497. }
  3498. inline Clara::CommandLine<ConfigData> makeCommandLineParser() {
  3499. using namespace Clara;
  3500. CommandLine<ConfigData> cli;
  3501. cli.bindProcessName( &ConfigData::processName );
  3502. cli["-?"]["-h"]["--help"]
  3503. .describe( "display usage information" )
  3504. .bind( &ConfigData::showHelp );
  3505. cli["-l"]["--list-tests"]
  3506. .describe( "list all/matching test cases" )
  3507. .bind( &ConfigData::listTests );
  3508. cli["-t"]["--list-tags"]
  3509. .describe( "list all/matching tags" )
  3510. .bind( &ConfigData::listTags );
  3511. cli["-s"]["--success"]
  3512. .describe( "include successful tests in output" )
  3513. .bind( &ConfigData::showSuccessfulTests );
  3514. cli["-b"]["--break"]
  3515. .describe( "break into debugger on failure" )
  3516. .bind( &ConfigData::shouldDebugBreak );
  3517. cli["-e"]["--nothrow"]
  3518. .describe( "skip exception tests" )
  3519. .bind( &ConfigData::noThrow );
  3520. cli["-i"]["--invisibles"]
  3521. .describe( "show invisibles (tabs, newlines)" )
  3522. .bind( &ConfigData::showInvisibles );
  3523. cli["-o"]["--out"]
  3524. .describe( "output filename" )
  3525. .bind( &ConfigData::outputFilename, "filename" );
  3526. cli["-r"]["--reporter"]
  3527. // .placeholder( "name[:filename]" )
  3528. .describe( "reporter to use (defaults to console)" )
  3529. .bind( &ConfigData::reporterName, "name" );
  3530. cli["-n"]["--name"]
  3531. .describe( "suite name" )
  3532. .bind( &ConfigData::name, "name" );
  3533. cli["-a"]["--abort"]
  3534. .describe( "abort at first failure" )
  3535. .bind( &abortAfterFirst );
  3536. cli["-x"]["--abortx"]
  3537. .describe( "abort after x failures" )
  3538. .bind( &abortAfterX, "no. failures" );
  3539. cli["-w"]["--warn"]
  3540. .describe( "enable warnings" )
  3541. .bind( &addWarning, "warning name" );
  3542. // - needs updating if reinstated
  3543. // cli.into( &setVerbosity )
  3544. // .describe( "level of verbosity (0=no output)" )
  3545. // .shortOpt( "v")
  3546. // .longOpt( "verbosity" )
  3547. // .placeholder( "level" );
  3548. cli[_]
  3549. .describe( "which test or tests to use" )
  3550. .bind( &addTestOrTags, "test name, pattern or tags" );
  3551. cli["-d"]["--durations"]
  3552. .describe( "show test durations" )
  3553. .bind( &setShowDurations, "yes/no" );
  3554. cli["-f"]["--input-file"]
  3555. .describe( "load test names to run from a file" )
  3556. .bind( &loadTestNamesFromFile, "filename" );
  3557. // Less common commands which don't have a short form
  3558. cli["--list-test-names-only"]
  3559. .describe( "list all/matching test cases names only" )
  3560. .bind( &ConfigData::listTestNamesOnly );
  3561. cli["--list-reporters"]
  3562. .describe( "list all reporters" )
  3563. .bind( &ConfigData::listReporters );
  3564. cli["--order"]
  3565. .describe( "test case order (defaults to decl)" )
  3566. .bind( &setOrder, "decl|lex|rand" );
  3567. cli["--rng-seed"]
  3568. .describe( "set a specific seed for random numbers" )
  3569. .bind( &setRngSeed, "'time'|number" );
  3570. cli["--force-colour"]
  3571. .describe( "force colourised output" )
  3572. .bind( &ConfigData::forceColour );
  3573. return cli;
  3574. }
  3575. } // end namespace Catch
  3576. // #included from: internal/catch_list.hpp
  3577. #define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED
  3578. // #included from: catch_text.h
  3579. #define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED
  3580. #define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
  3581. #define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch
  3582. // #included from: ../external/tbc_text_format.h
  3583. // Only use header guard if we are not using an outer namespace
  3584. #ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
  3585. # ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
  3586. # ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
  3587. # define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
  3588. # endif
  3589. # else
  3590. # define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
  3591. # endif
  3592. #endif
  3593. #ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
  3594. #include <string>
  3595. #include <vector>
  3596. #include <sstream>
  3597. // Use optional outer namespace
  3598. #ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
  3599. namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
  3600. #endif
  3601. namespace Tbc {
  3602. #ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
  3603. const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
  3604. #else
  3605. const unsigned int consoleWidth = 80;
  3606. #endif
  3607. struct TextAttributes {
  3608. TextAttributes()
  3609. : initialIndent( std::string::npos ),
  3610. indent( 0 ),
  3611. width( consoleWidth-1 ),
  3612. tabChar( '\t' )
  3613. {}
  3614. TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; }
  3615. TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; }
  3616. TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; }
  3617. TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; }
  3618. std::size_t initialIndent; // indent of first line, or npos
  3619. std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos
  3620. std::size_t width; // maximum width of text, including indent. Longer text will wrap
  3621. char tabChar; // If this char is seen the indent is changed to current pos
  3622. };
  3623. class Text {
  3624. public:
  3625. Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
  3626. : attr( _attr )
  3627. {
  3628. std::string wrappableChars = " [({.,/|\\-";
  3629. std::size_t indent = _attr.initialIndent != std::string::npos
  3630. ? _attr.initialIndent
  3631. : _attr.indent;
  3632. std::string remainder = _str;
  3633. while( !remainder.empty() ) {
  3634. if( lines.size() >= 1000 ) {
  3635. lines.push_back( "... message truncated due to excessive size" );
  3636. return;
  3637. }
  3638. std::size_t tabPos = std::string::npos;
  3639. std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
  3640. std::size_t pos = remainder.find_first_of( '\n' );
  3641. if( pos <= width ) {
  3642. width = pos;
  3643. }
  3644. pos = remainder.find_last_of( _attr.tabChar, width );
  3645. if( pos != std::string::npos ) {
  3646. tabPos = pos;
  3647. if( remainder[width] == '\n' )
  3648. width--;
  3649. remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
  3650. }
  3651. if( width == remainder.size() ) {
  3652. spliceLine( indent, remainder, width );
  3653. }
  3654. else if( remainder[width] == '\n' ) {
  3655. spliceLine( indent, remainder, width );
  3656. if( width <= 1 || remainder.size() != 1 )
  3657. remainder = remainder.substr( 1 );
  3658. indent = _attr.indent;
  3659. }
  3660. else {
  3661. pos = remainder.find_last_of( wrappableChars, width );
  3662. if( pos != std::string::npos && pos > 0 ) {
  3663. spliceLine( indent, remainder, pos );
  3664. if( remainder[0] == ' ' )
  3665. remainder = remainder.substr( 1 );
  3666. }
  3667. else {
  3668. spliceLine( indent, remainder, width-1 );
  3669. lines.back() += "-";
  3670. }
  3671. if( lines.size() == 1 )
  3672. indent = _attr.indent;
  3673. if( tabPos != std::string::npos )
  3674. indent += tabPos;
  3675. }
  3676. }
  3677. }
  3678. void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
  3679. lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
  3680. _remainder = _remainder.substr( _pos );
  3681. }
  3682. typedef std::vector<std::string>::const_iterator const_iterator;
  3683. const_iterator begin() const { return lines.begin(); }
  3684. const_iterator end() const { return lines.end(); }
  3685. std::string const& last() const { return lines.back(); }
  3686. std::size_t size() const { return lines.size(); }
  3687. std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
  3688. std::string toString() const {
  3689. std::ostringstream oss;
  3690. oss << *this;
  3691. return oss.str();
  3692. }
  3693. inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
  3694. for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
  3695. it != itEnd; ++it ) {
  3696. if( it != _text.begin() )
  3697. _stream << "\n";
  3698. _stream << *it;
  3699. }
  3700. return _stream;
  3701. }
  3702. private:
  3703. std::string str;
  3704. TextAttributes attr;
  3705. std::vector<std::string> lines;
  3706. };
  3707. } // end namespace Tbc
  3708. #ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
  3709. } // end outer namespace
  3710. #endif
  3711. #endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
  3712. #undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
  3713. namespace Catch {
  3714. using Tbc::Text;
  3715. using Tbc::TextAttributes;
  3716. }
  3717. // #included from: catch_console_colour.hpp
  3718. #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED
  3719. namespace Catch {
  3720. struct Colour {
  3721. enum Code {
  3722. None = 0,
  3723. White,
  3724. Red,
  3725. Green,
  3726. Blue,
  3727. Cyan,
  3728. Yellow,
  3729. Grey,
  3730. Bright = 0x10,
  3731. BrightRed = Bright | Red,
  3732. BrightGreen = Bright | Green,
  3733. LightGrey = Bright | Grey,
  3734. BrightWhite = Bright | White,
  3735. // By intention
  3736. FileName = LightGrey,
  3737. Warning = Yellow,
  3738. ResultError = BrightRed,
  3739. ResultSuccess = BrightGreen,
  3740. ResultExpectedFailure = Warning,
  3741. Error = BrightRed,
  3742. Success = Green,
  3743. OriginalExpression = Cyan,
  3744. ReconstructedExpression = Yellow,
  3745. SecondaryText = LightGrey,
  3746. Headers = White
  3747. };
  3748. // Use constructed object for RAII guard
  3749. Colour( Code _colourCode );
  3750. Colour( Colour const& other );
  3751. ~Colour();
  3752. // Use static method for one-shot changes
  3753. static void use( Code _colourCode );
  3754. private:
  3755. bool m_moved;
  3756. };
  3757. inline std::ostream& operator << ( std::ostream& os, Colour const& ) { return os; }
  3758. } // end namespace Catch
  3759. // #included from: catch_interfaces_reporter.h
  3760. #define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED
  3761. #include <string>
  3762. #include <ostream>
  3763. #include <map>
  3764. #include <assert.h>
  3765. namespace Catch
  3766. {
  3767. struct ReporterConfig {
  3768. explicit ReporterConfig( Ptr<IConfig> const& _fullConfig )
  3769. : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
  3770. ReporterConfig( Ptr<IConfig> const& _fullConfig, std::ostream& _stream )
  3771. : m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
  3772. std::ostream& stream() const { return *m_stream; }
  3773. Ptr<IConfig> fullConfig() const { return m_fullConfig; }
  3774. private:
  3775. std::ostream* m_stream;
  3776. Ptr<IConfig> m_fullConfig;
  3777. };
  3778. struct ReporterPreferences {
  3779. ReporterPreferences()
  3780. : shouldRedirectStdOut( false )
  3781. {}
  3782. bool shouldRedirectStdOut;
  3783. };
  3784. template<typename T>
  3785. struct LazyStat : Option<T> {
  3786. LazyStat() : used( false ) {}
  3787. LazyStat& operator=( T const& _value ) {
  3788. Option<T>::operator=( _value );
  3789. used = false;
  3790. return *this;
  3791. }
  3792. void reset() {
  3793. Option<T>::reset();
  3794. used = false;
  3795. }
  3796. bool used;
  3797. };
  3798. struct TestRunInfo {
  3799. TestRunInfo( std::string const& _name ) : name( _name ) {}
  3800. std::string name;
  3801. };
  3802. struct GroupInfo {
  3803. GroupInfo( std::string const& _name,
  3804. std::size_t _groupIndex,
  3805. std::size_t _groupsCount )
  3806. : name( _name ),
  3807. groupIndex( _groupIndex ),
  3808. groupsCounts( _groupsCount )
  3809. {}
  3810. std::string name;
  3811. std::size_t groupIndex;
  3812. std::size_t groupsCounts;
  3813. };
  3814. struct AssertionStats {
  3815. AssertionStats( AssertionResult const& _assertionResult,
  3816. std::vector<MessageInfo> const& _infoMessages,
  3817. Totals const& _totals )
  3818. : assertionResult( _assertionResult ),
  3819. infoMessages( _infoMessages ),
  3820. totals( _totals )
  3821. {
  3822. if( assertionResult.hasMessage() ) {
  3823. // Copy message into messages list.
  3824. // !TBD This should have been done earlier, somewhere
  3825. MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
  3826. builder << assertionResult.getMessage();
  3827. builder.m_info.message = builder.m_stream.str();
  3828. infoMessages.push_back( builder.m_info );
  3829. }
  3830. }
  3831. virtual ~AssertionStats();
  3832. # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
  3833. AssertionStats( AssertionStats const& ) = default;
  3834. AssertionStats( AssertionStats && ) = default;
  3835. AssertionStats& operator = ( AssertionStats const& ) = default;
  3836. AssertionStats& operator = ( AssertionStats && ) = default;
  3837. # endif
  3838. AssertionResult assertionResult;
  3839. std::vector<MessageInfo> infoMessages;
  3840. Totals totals;
  3841. };
  3842. struct SectionStats {
  3843. SectionStats( SectionInfo const& _sectionInfo,
  3844. Counts const& _assertions,
  3845. double _durationInSeconds,
  3846. bool _missingAssertions )
  3847. : sectionInfo( _sectionInfo ),
  3848. assertions( _assertions ),
  3849. durationInSeconds( _durationInSeconds ),
  3850. missingAssertions( _missingAssertions )
  3851. {}
  3852. virtual ~SectionStats();
  3853. # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
  3854. SectionStats( SectionStats const& ) = default;
  3855. SectionStats( SectionStats && ) = default;
  3856. SectionStats& operator = ( SectionStats const& ) = default;
  3857. SectionStats& operator = ( SectionStats && ) = default;
  3858. # endif
  3859. SectionInfo sectionInfo;
  3860. Counts assertions;
  3861. double durationInSeconds;
  3862. bool missingAssertions;
  3863. };
  3864. struct TestCaseStats {
  3865. TestCaseStats( TestCaseInfo const& _testInfo,
  3866. Totals const& _totals,
  3867. std::string const& _stdOut,
  3868. std::string const& _stdErr,
  3869. bool _aborting )
  3870. : testInfo( _testInfo ),
  3871. totals( _totals ),
  3872. stdOut( _stdOut ),
  3873. stdErr( _stdErr ),
  3874. aborting( _aborting )
  3875. {}
  3876. virtual ~TestCaseStats();
  3877. # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
  3878. TestCaseStats( TestCaseStats const& ) = default;
  3879. TestCaseStats( TestCaseStats && ) = default;
  3880. TestCaseStats& operator = ( TestCaseStats const& ) = default;
  3881. TestCaseStats& operator = ( TestCaseStats && ) = default;
  3882. # endif
  3883. TestCaseInfo testInfo;
  3884. Totals totals;
  3885. std::string stdOut;
  3886. std::string stdErr;
  3887. bool aborting;
  3888. };
  3889. struct TestGroupStats {
  3890. TestGroupStats( GroupInfo const& _groupInfo,
  3891. Totals const& _totals,
  3892. bool _aborting )
  3893. : groupInfo( _groupInfo ),
  3894. totals( _totals ),
  3895. aborting( _aborting )
  3896. {}
  3897. TestGroupStats( GroupInfo const& _groupInfo )
  3898. : groupInfo( _groupInfo ),
  3899. aborting( false )
  3900. {}
  3901. virtual ~TestGroupStats();
  3902. # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
  3903. TestGroupStats( TestGroupStats const& ) = default;
  3904. TestGroupStats( TestGroupStats && ) = default;
  3905. TestGroupStats& operator = ( TestGroupStats const& ) = default;
  3906. TestGroupStats& operator = ( TestGroupStats && ) = default;
  3907. # endif
  3908. GroupInfo groupInfo;
  3909. Totals totals;
  3910. bool aborting;
  3911. };
  3912. struct TestRunStats {
  3913. TestRunStats( TestRunInfo const& _runInfo,
  3914. Totals const& _totals,
  3915. bool _aborting )
  3916. : runInfo( _runInfo ),
  3917. totals( _totals ),
  3918. aborting( _aborting )
  3919. {}
  3920. virtual ~TestRunStats();
  3921. # ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS
  3922. TestRunStats( TestRunStats const& _other )
  3923. : runInfo( _other.runInfo ),
  3924. totals( _other.totals ),
  3925. aborting( _other.aborting )
  3926. {}
  3927. # else
  3928. TestRunStats( TestRunStats const& ) = default;
  3929. TestRunStats( TestRunStats && ) = default;
  3930. TestRunStats& operator = ( TestRunStats const& ) = default;
  3931. TestRunStats& operator = ( TestRunStats && ) = default;
  3932. # endif
  3933. TestRunInfo runInfo;
  3934. Totals totals;
  3935. bool aborting;
  3936. };
  3937. struct IStreamingReporter : IShared {
  3938. virtual ~IStreamingReporter();
  3939. // Implementing class must also provide the following static method:
  3940. // static std::string getDescription();
  3941. virtual ReporterPreferences getPreferences() const = 0;
  3942. virtual void noMatchingTestCases( std::string const& spec ) = 0;
  3943. virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
  3944. virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
  3945. virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
  3946. virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
  3947. virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
  3948. // The return value indicates if the messages buffer should be cleared:
  3949. virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
  3950. virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
  3951. virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
  3952. virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
  3953. virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
  3954. virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
  3955. };
  3956. struct IReporterFactory {
  3957. virtual ~IReporterFactory();
  3958. virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0;
  3959. virtual std::string getDescription() const = 0;
  3960. };
  3961. struct IReporterRegistry {
  3962. typedef std::map<std::string, IReporterFactory*> FactoryMap;
  3963. virtual ~IReporterRegistry();
  3964. virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig> const& config ) const = 0;
  3965. virtual FactoryMap const& getFactories() const = 0;
  3966. };
  3967. }
  3968. #include <limits>
  3969. #include <algorithm>
  3970. namespace Catch {
  3971. inline std::size_t listTests( Config const& config ) {
  3972. TestSpec testSpec = config.testSpec();
  3973. if( config.testSpec().hasFilters() )
  3974. Catch::cout() << "Matching test cases:\n";
  3975. else {
  3976. Catch::cout() << "All available test cases:\n";
  3977. testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
  3978. }
  3979. std::size_t matchedTests = 0;
  3980. TextAttributes nameAttr, tagsAttr;
  3981. nameAttr.setInitialIndent( 2 ).setIndent( 4 );
  3982. tagsAttr.setIndent( 6 );
  3983. std::vector<TestCase> matchedTestCases;
  3984. getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases );
  3985. for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
  3986. it != itEnd;
  3987. ++it ) {
  3988. matchedTests++;
  3989. TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
  3990. Colour::Code colour = testCaseInfo.isHidden()
  3991. ? Colour::SecondaryText
  3992. : Colour::None;
  3993. Colour colourGuard( colour );
  3994. Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl;
  3995. if( !testCaseInfo.tags.empty() )
  3996. Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl;
  3997. }
  3998. if( !config.testSpec().hasFilters() )
  3999. Catch::cout() << pluralise( matchedTests, "test case" ) << "\n" << std::endl;
  4000. else
  4001. Catch::cout() << pluralise( matchedTests, "matching test case" ) << "\n" << std::endl;
  4002. return matchedTests;
  4003. }
  4004. inline std::size_t listTestsNamesOnly( Config const& config ) {
  4005. TestSpec testSpec = config.testSpec();
  4006. if( !config.testSpec().hasFilters() )
  4007. testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
  4008. std::size_t matchedTests = 0;
  4009. std::vector<TestCase> matchedTestCases;
  4010. getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases );
  4011. for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
  4012. it != itEnd;
  4013. ++it ) {
  4014. matchedTests++;
  4015. TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
  4016. Catch::cout() << testCaseInfo.name << std::endl;
  4017. }
  4018. return matchedTests;
  4019. }
  4020. struct TagInfo {
  4021. TagInfo() : count ( 0 ) {}
  4022. void add( std::string const& spelling ) {
  4023. ++count;
  4024. spellings.insert( spelling );
  4025. }
  4026. std::string all() const {
  4027. std::string out;
  4028. for( std::set<std::string>::const_iterator it = spellings.begin(), itEnd = spellings.end();
  4029. it != itEnd;
  4030. ++it )
  4031. out += "[" + *it + "]";
  4032. return out;
  4033. }
  4034. std::set<std::string> spellings;
  4035. std::size_t count;
  4036. };
  4037. inline std::size_t listTags( Config const& config ) {
  4038. TestSpec testSpec = config.testSpec();
  4039. if( config.testSpec().hasFilters() )
  4040. Catch::cout() << "Tags for matching test cases:\n";
  4041. else {
  4042. Catch::cout() << "All available tags:\n";
  4043. testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
  4044. }
  4045. std::map<std::string, TagInfo> tagCounts;
  4046. std::vector<TestCase> matchedTestCases;
  4047. getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases );
  4048. for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
  4049. it != itEnd;
  4050. ++it ) {
  4051. for( std::set<std::string>::const_iterator tagIt = it->getTestCaseInfo().tags.begin(),
  4052. tagItEnd = it->getTestCaseInfo().tags.end();
  4053. tagIt != tagItEnd;
  4054. ++tagIt ) {
  4055. std::string tagName = *tagIt;
  4056. std::string lcaseTagName = toLower( tagName );
  4057. std::map<std::string, TagInfo>::iterator countIt = tagCounts.find( lcaseTagName );
  4058. if( countIt == tagCounts.end() )
  4059. countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
  4060. countIt->second.add( tagName );
  4061. }
  4062. }
  4063. for( std::map<std::string, TagInfo>::const_iterator countIt = tagCounts.begin(),
  4064. countItEnd = tagCounts.end();
  4065. countIt != countItEnd;
  4066. ++countIt ) {
  4067. std::ostringstream oss;
  4068. oss << " " << std::setw(2) << countIt->second.count << " ";
  4069. Text wrapper( countIt->second.all(), TextAttributes()
  4070. .setInitialIndent( 0 )
  4071. .setIndent( oss.str().size() )
  4072. .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) );
  4073. Catch::cout() << oss.str() << wrapper << "\n";
  4074. }
  4075. Catch::cout() << pluralise( tagCounts.size(), "tag" ) << "\n" << std::endl;
  4076. return tagCounts.size();
  4077. }
  4078. inline std::size_t listReporters( Config const& /*config*/ ) {
  4079. Catch::cout() << "Available reporters:\n";
  4080. IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
  4081. IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it;
  4082. std::size_t maxNameLen = 0;
  4083. for(it = itBegin; it != itEnd; ++it )
  4084. maxNameLen = (std::max)( maxNameLen, it->first.size() );
  4085. for(it = itBegin; it != itEnd; ++it ) {
  4086. Text wrapper( it->second->getDescription(), TextAttributes()
  4087. .setInitialIndent( 0 )
  4088. .setIndent( 7+maxNameLen )
  4089. .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) );
  4090. Catch::cout() << " "
  4091. << it->first
  4092. << ":"
  4093. << std::string( maxNameLen - it->first.size() + 2, ' ' )
  4094. << wrapper << "\n";
  4095. }
  4096. Catch::cout() << std::endl;
  4097. return factories.size();
  4098. }
  4099. inline Option<std::size_t> list( Config const& config ) {
  4100. Option<std::size_t> listedCount;
  4101. if( config.listTests() )
  4102. listedCount = listedCount.valueOr(0) + listTests( config );
  4103. if( config.listTestNamesOnly() )
  4104. listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config );
  4105. if( config.listTags() )
  4106. listedCount = listedCount.valueOr(0) + listTags( config );
  4107. if( config.listReporters() )
  4108. listedCount = listedCount.valueOr(0) + listReporters( config );
  4109. return listedCount;
  4110. }
  4111. } // end namespace Catch
  4112. // #included from: internal/catch_runner_impl.hpp
  4113. #define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED
  4114. // #included from: catch_test_case_tracker.hpp
  4115. #define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
  4116. #include <map>
  4117. #include <string>
  4118. #include <assert.h>
  4119. namespace Catch {
  4120. namespace SectionTracking {
  4121. class TrackedSection {
  4122. typedef std::map<std::string, TrackedSection> TrackedSections;
  4123. public:
  4124. enum RunState {
  4125. NotStarted,
  4126. Executing,
  4127. ExecutingChildren,
  4128. Completed
  4129. };
  4130. TrackedSection( std::string const& name, TrackedSection* parent )
  4131. : m_name( name ), m_runState( NotStarted ), m_parent( parent )
  4132. {}
  4133. RunState runState() const { return m_runState; }
  4134. TrackedSection* findChild( std::string const& childName ) {
  4135. TrackedSections::iterator it = m_children.find( childName );
  4136. return it != m_children.end()
  4137. ? &it->second
  4138. : NULL;
  4139. }
  4140. TrackedSection* acquireChild( std::string const& childName ) {
  4141. if( TrackedSection* child = findChild( childName ) )
  4142. return child;
  4143. m_children.insert( std::make_pair( childName, TrackedSection( childName, this ) ) );
  4144. return findChild( childName );
  4145. }
  4146. void enter() {
  4147. if( m_runState == NotStarted )
  4148. m_runState = Executing;
  4149. }
  4150. void leave() {
  4151. for( TrackedSections::const_iterator it = m_children.begin(), itEnd = m_children.end();
  4152. it != itEnd;
  4153. ++it )
  4154. if( it->second.runState() != Completed ) {
  4155. m_runState = ExecutingChildren;
  4156. return;
  4157. }
  4158. m_runState = Completed;
  4159. }
  4160. TrackedSection* getParent() {
  4161. return m_parent;
  4162. }
  4163. bool hasChildren() const {
  4164. return !m_children.empty();
  4165. }
  4166. private:
  4167. std::string m_name;
  4168. RunState m_runState;
  4169. TrackedSections m_children;
  4170. TrackedSection* m_parent;
  4171. };
  4172. class TestCaseTracker {
  4173. public:
  4174. TestCaseTracker( std::string const& testCaseName )
  4175. : m_testCase( testCaseName, NULL ),
  4176. m_currentSection( &m_testCase ),
  4177. m_completedASectionThisRun( false )
  4178. {}
  4179. bool enterSection( std::string const& name ) {
  4180. TrackedSection* child = m_currentSection->acquireChild( name );
  4181. if( m_completedASectionThisRun || child->runState() == TrackedSection::Completed )
  4182. return false;
  4183. m_currentSection = child;
  4184. m_currentSection->enter();
  4185. return true;
  4186. }
  4187. void leaveSection() {
  4188. m_currentSection->leave();
  4189. m_currentSection = m_currentSection->getParent();
  4190. assert( m_currentSection != NULL );
  4191. m_completedASectionThisRun = true;
  4192. }
  4193. bool currentSectionHasChildren() const {
  4194. return m_currentSection->hasChildren();
  4195. }
  4196. bool isCompleted() const {
  4197. return m_testCase.runState() == TrackedSection::Completed;
  4198. }
  4199. class Guard {
  4200. public:
  4201. Guard( TestCaseTracker& tracker ) : m_tracker( tracker ) {
  4202. m_tracker.enterTestCase();
  4203. }
  4204. ~Guard() {
  4205. m_tracker.leaveTestCase();
  4206. }
  4207. private:
  4208. Guard( Guard const& );
  4209. void operator = ( Guard const& );
  4210. TestCaseTracker& m_tracker;
  4211. };
  4212. private:
  4213. void enterTestCase() {
  4214. m_currentSection = &m_testCase;
  4215. m_completedASectionThisRun = false;
  4216. m_testCase.enter();
  4217. }
  4218. void leaveTestCase() {
  4219. m_testCase.leave();
  4220. }
  4221. TrackedSection m_testCase;
  4222. TrackedSection* m_currentSection;
  4223. bool m_completedASectionThisRun;
  4224. };
  4225. } // namespace SectionTracking
  4226. using SectionTracking::TestCaseTracker;
  4227. } // namespace Catch
  4228. // #included from: catch_fatal_condition.hpp
  4229. #define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
  4230. namespace Catch {
  4231. // Report the error condition then exit the process
  4232. inline void fatal( std::string const& message, int exitCode ) {
  4233. IContext& context = Catch::getCurrentContext();
  4234. IResultCapture* resultCapture = context.getResultCapture();
  4235. resultCapture->handleFatalErrorCondition( message );
  4236. if( Catch::alwaysTrue() ) // avoids "no return" warnings
  4237. exit( exitCode );
  4238. }
  4239. } // namespace Catch
  4240. #if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
  4241. namespace Catch {
  4242. struct FatalConditionHandler {
  4243. void reset() {}
  4244. };
  4245. } // namespace Catch
  4246. #else // Not Windows - assumed to be POSIX compatible //////////////////////////
  4247. #include <signal.h>
  4248. namespace Catch {
  4249. struct SignalDefs { int id; const char* name; };
  4250. extern SignalDefs signalDefs[];
  4251. SignalDefs signalDefs[] = {
  4252. { SIGINT, "SIGINT - Terminal interrupt signal" },
  4253. { SIGILL, "SIGILL - Illegal instruction signal" },
  4254. { SIGFPE, "SIGFPE - Floating point error signal" },
  4255. { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
  4256. { SIGTERM, "SIGTERM - Termination request signal" },
  4257. { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
  4258. };
  4259. struct FatalConditionHandler {
  4260. static void handleSignal( int sig ) {
  4261. for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
  4262. if( sig == signalDefs[i].id )
  4263. fatal( signalDefs[i].name, -sig );
  4264. fatal( "<unknown signal>", -sig );
  4265. }
  4266. FatalConditionHandler() : m_isSet( true ) {
  4267. for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
  4268. signal( signalDefs[i].id, handleSignal );
  4269. }
  4270. ~FatalConditionHandler() {
  4271. reset();
  4272. }
  4273. void reset() {
  4274. if( m_isSet ) {
  4275. for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
  4276. signal( signalDefs[i].id, SIG_DFL );
  4277. m_isSet = false;
  4278. }
  4279. }
  4280. bool m_isSet;
  4281. };
  4282. } // namespace Catch
  4283. #endif // not Windows
  4284. #include <set>
  4285. #include <string>
  4286. namespace Catch {
  4287. class StreamRedirect {
  4288. public:
  4289. StreamRedirect( std::ostream& stream, std::string& targetString )
  4290. : m_stream( stream ),
  4291. m_prevBuf( stream.rdbuf() ),
  4292. m_targetString( targetString )
  4293. {
  4294. stream.rdbuf( m_oss.rdbuf() );
  4295. }
  4296. ~StreamRedirect() {
  4297. m_targetString += m_oss.str();
  4298. m_stream.rdbuf( m_prevBuf );
  4299. }
  4300. private:
  4301. std::ostream& m_stream;
  4302. std::streambuf* m_prevBuf;
  4303. std::ostringstream m_oss;
  4304. std::string& m_targetString;
  4305. };
  4306. ///////////////////////////////////////////////////////////////////////////
  4307. class RunContext : public IResultCapture, public IRunner {
  4308. RunContext( RunContext const& );
  4309. void operator =( RunContext const& );
  4310. public:
  4311. explicit RunContext( Ptr<IConfig const> const& config, Ptr<IStreamingReporter> const& reporter )
  4312. : m_runInfo( config->name() ),
  4313. m_context( getCurrentMutableContext() ),
  4314. m_activeTestCase( NULL ),
  4315. m_config( config ),
  4316. m_reporter( reporter ),
  4317. m_prevRunner( m_context.getRunner() ),
  4318. m_prevResultCapture( m_context.getResultCapture() ),
  4319. m_prevConfig( m_context.getConfig() )
  4320. {
  4321. m_context.setRunner( this );
  4322. m_context.setConfig( m_config );
  4323. m_context.setResultCapture( this );
  4324. m_reporter->testRunStarting( m_runInfo );
  4325. }
  4326. virtual ~RunContext() {
  4327. m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) );
  4328. m_context.setRunner( m_prevRunner );
  4329. m_context.setConfig( NULL );
  4330. m_context.setResultCapture( m_prevResultCapture );
  4331. m_context.setConfig( m_prevConfig );
  4332. }
  4333. void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {
  4334. m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) );
  4335. }
  4336. void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) {
  4337. m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) );
  4338. }
  4339. Totals runTest( TestCase const& testCase ) {
  4340. Totals prevTotals = m_totals;
  4341. std::string redirectedCout;
  4342. std::string redirectedCerr;
  4343. TestCaseInfo testInfo = testCase.getTestCaseInfo();
  4344. m_reporter->testCaseStarting( testInfo );
  4345. m_activeTestCase = &testCase;
  4346. m_testCaseTracker = TestCaseTracker( testInfo.name );
  4347. do {
  4348. do {
  4349. runCurrentTest( redirectedCout, redirectedCerr );
  4350. }
  4351. while( !m_testCaseTracker->isCompleted() && !aborting() );
  4352. }
  4353. while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() );
  4354. Totals deltaTotals = m_totals.delta( prevTotals );
  4355. m_totals.testCases += deltaTotals.testCases;
  4356. m_reporter->testCaseEnded( TestCaseStats( testInfo,
  4357. deltaTotals,
  4358. redirectedCout,
  4359. redirectedCerr,
  4360. aborting() ) );
  4361. m_activeTestCase = NULL;
  4362. m_testCaseTracker.reset();
  4363. return deltaTotals;
  4364. }
  4365. Ptr<IConfig const> config() const {
  4366. return m_config;
  4367. }
  4368. private: // IResultCapture
  4369. virtual void assertionEnded( AssertionResult const& result ) {
  4370. if( result.getResultType() == ResultWas::Ok ) {
  4371. m_totals.assertions.passed++;
  4372. }
  4373. else if( !result.isOk() ) {
  4374. m_totals.assertions.failed++;
  4375. }
  4376. if( m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ) )
  4377. m_messages.clear();
  4378. // Reset working state
  4379. m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition );
  4380. m_lastResult = result;
  4381. }
  4382. virtual bool sectionStarted (
  4383. SectionInfo const& sectionInfo,
  4384. Counts& assertions
  4385. )
  4386. {
  4387. std::ostringstream oss;
  4388. oss << sectionInfo.name << "@" << sectionInfo.lineInfo;
  4389. if( !m_testCaseTracker->enterSection( oss.str() ) )
  4390. return false;
  4391. m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
  4392. m_reporter->sectionStarting( sectionInfo );
  4393. assertions = m_totals.assertions;
  4394. return true;
  4395. }
  4396. bool testForMissingAssertions( Counts& assertions ) {
  4397. if( assertions.total() != 0 ||
  4398. !m_config->warnAboutMissingAssertions() ||
  4399. m_testCaseTracker->currentSectionHasChildren() )
  4400. return false;
  4401. m_totals.assertions.failed++;
  4402. assertions.failed++;
  4403. return true;
  4404. }
  4405. virtual void sectionEnded( SectionInfo const& info, Counts const& prevAssertions, double _durationInSeconds ) {
  4406. if( std::uncaught_exception() ) {
  4407. m_unfinishedSections.push_back( UnfinishedSections( info, prevAssertions, _durationInSeconds ) );
  4408. return;
  4409. }
  4410. Counts assertions = m_totals.assertions - prevAssertions;
  4411. bool missingAssertions = testForMissingAssertions( assertions );
  4412. m_testCaseTracker->leaveSection();
  4413. m_reporter->sectionEnded( SectionStats( info, assertions, _durationInSeconds, missingAssertions ) );
  4414. m_messages.clear();
  4415. }
  4416. virtual void pushScopedMessage( MessageInfo const& message ) {
  4417. m_messages.push_back( message );
  4418. }
  4419. virtual void popScopedMessage( MessageInfo const& message ) {
  4420. m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() );
  4421. }
  4422. virtual std::string getCurrentTestName() const {
  4423. return m_activeTestCase
  4424. ? m_activeTestCase->getTestCaseInfo().name
  4425. : "";
  4426. }
  4427. virtual const AssertionResult* getLastResult() const {
  4428. return &m_lastResult;
  4429. }
  4430. virtual void handleFatalErrorCondition( std::string const& message ) {
  4431. ResultBuilder resultBuilder = makeUnexpectedResultBuilder();
  4432. resultBuilder.setResultType( ResultWas::FatalErrorCondition );
  4433. resultBuilder << message;
  4434. resultBuilder.captureExpression();
  4435. handleUnfinishedSections();
  4436. // Recreate section for test case (as we will lose the one that was in scope)
  4437. TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
  4438. SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
  4439. Counts assertions;
  4440. assertions.failed = 1;
  4441. SectionStats testCaseSectionStats( testCaseSection, assertions, 0, false );
  4442. m_reporter->sectionEnded( testCaseSectionStats );
  4443. TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo();
  4444. Totals deltaTotals;
  4445. deltaTotals.testCases.failed = 1;
  4446. m_reporter->testCaseEnded( TestCaseStats( testInfo,
  4447. deltaTotals,
  4448. "",
  4449. "",
  4450. false ) );
  4451. m_totals.testCases.failed++;
  4452. testGroupEnded( "", m_totals, 1, 1 );
  4453. m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) );
  4454. }
  4455. public:
  4456. // !TBD We need to do this another way!
  4457. bool aborting() const {
  4458. return m_totals.assertions.failed == static_cast<std::size_t>( m_config->abortAfter() );
  4459. }
  4460. private:
  4461. void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) {
  4462. TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
  4463. SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
  4464. m_reporter->sectionStarting( testCaseSection );
  4465. Counts prevAssertions = m_totals.assertions;
  4466. double duration = 0;
  4467. try {
  4468. m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal );
  4469. TestCaseTracker::Guard guard( *m_testCaseTracker );
  4470. Timer timer;
  4471. timer.start();
  4472. if( m_reporter->getPreferences().shouldRedirectStdOut ) {
  4473. StreamRedirect coutRedir( Catch::cout(), redirectedCout );
  4474. StreamRedirect cerrRedir( Catch::cerr(), redirectedCerr );
  4475. invokeActiveTestCase();
  4476. }
  4477. else {
  4478. invokeActiveTestCase();
  4479. }
  4480. duration = timer.getElapsedSeconds();
  4481. }
  4482. catch( TestFailureException& ) {
  4483. // This just means the test was aborted due to failure
  4484. }
  4485. catch(...) {
  4486. makeUnexpectedResultBuilder().useActiveException();
  4487. }
  4488. handleUnfinishedSections();
  4489. m_messages.clear();
  4490. Counts assertions = m_totals.assertions - prevAssertions;
  4491. bool missingAssertions = testForMissingAssertions( assertions );
  4492. if( testCaseInfo.okToFail() ) {
  4493. std::swap( assertions.failedButOk, assertions.failed );
  4494. m_totals.assertions.failed -= assertions.failedButOk;
  4495. m_totals.assertions.failedButOk += assertions.failedButOk;
  4496. }
  4497. SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions );
  4498. m_reporter->sectionEnded( testCaseSectionStats );
  4499. }
  4500. void invokeActiveTestCase() {
  4501. FatalConditionHandler fatalConditionHandler; // Handle signals
  4502. m_activeTestCase->invoke();
  4503. fatalConditionHandler.reset();
  4504. }
  4505. private:
  4506. ResultBuilder makeUnexpectedResultBuilder() const {
  4507. return ResultBuilder( m_lastAssertionInfo.macroName.c_str(),
  4508. m_lastAssertionInfo.lineInfo,
  4509. m_lastAssertionInfo.capturedExpression.c_str(),
  4510. m_lastAssertionInfo.resultDisposition );
  4511. }
  4512. void handleUnfinishedSections() {
  4513. // If sections ended prematurely due to an exception we stored their
  4514. // infos here so we can tear them down outside the unwind process.
  4515. for( std::vector<UnfinishedSections>::const_reverse_iterator it = m_unfinishedSections.rbegin(),
  4516. itEnd = m_unfinishedSections.rend();
  4517. it != itEnd;
  4518. ++it )
  4519. sectionEnded( it->info, it->prevAssertions, it->durationInSeconds );
  4520. m_unfinishedSections.clear();
  4521. }
  4522. struct UnfinishedSections {
  4523. UnfinishedSections( SectionInfo const& _info, Counts const& _prevAssertions, double _durationInSeconds )
  4524. : info( _info ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
  4525. {}
  4526. SectionInfo info;
  4527. Counts prevAssertions;
  4528. double durationInSeconds;
  4529. };
  4530. TestRunInfo m_runInfo;
  4531. IMutableContext& m_context;
  4532. TestCase const* m_activeTestCase;
  4533. Option<TestCaseTracker> m_testCaseTracker;
  4534. AssertionResult m_lastResult;
  4535. Ptr<IConfig const> m_config;
  4536. Totals m_totals;
  4537. Ptr<IStreamingReporter> m_reporter;
  4538. std::vector<MessageInfo> m_messages;
  4539. IRunner* m_prevRunner;
  4540. IResultCapture* m_prevResultCapture;
  4541. Ptr<IConfig const> m_prevConfig;
  4542. AssertionInfo m_lastAssertionInfo;
  4543. std::vector<UnfinishedSections> m_unfinishedSections;
  4544. };
  4545. IResultCapture& getResultCapture() {
  4546. if( IResultCapture* capture = getCurrentContext().getResultCapture() )
  4547. return *capture;
  4548. else
  4549. throw std::logic_error( "No result capture instance" );
  4550. }
  4551. } // end namespace Catch
  4552. // #included from: internal/catch_version.h
  4553. #define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED
  4554. namespace Catch {
  4555. // Versioning information
  4556. struct Version {
  4557. Version( unsigned int _majorVersion,
  4558. unsigned int _minorVersion,
  4559. unsigned int _buildNumber,
  4560. char const* const _branchName )
  4561. : majorVersion( _majorVersion ),
  4562. minorVersion( _minorVersion ),
  4563. buildNumber( _buildNumber ),
  4564. branchName( _branchName )
  4565. {}
  4566. unsigned int const majorVersion;
  4567. unsigned int const minorVersion;
  4568. unsigned int const buildNumber;
  4569. char const* const branchName;
  4570. private:
  4571. void operator=( Version const& );
  4572. };
  4573. extern Version libraryVersion;
  4574. }
  4575. #include <fstream>
  4576. #include <stdlib.h>
  4577. #include <limits>
  4578. namespace Catch {
  4579. class Runner {
  4580. public:
  4581. Runner( Ptr<Config> const& config )
  4582. : m_config( config )
  4583. {
  4584. openStream();
  4585. makeReporter();
  4586. }
  4587. Totals runTests() {
  4588. RunContext context( m_config.get(), m_reporter );
  4589. Totals totals;
  4590. context.testGroupStarting( "all tests", 1, 1 ); // deprecated?
  4591. TestSpec testSpec = m_config->testSpec();
  4592. if( !testSpec.hasFilters() )
  4593. testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests
  4594. std::vector<TestCase> testCases;
  4595. getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, *m_config, testCases );
  4596. int testsRunForGroup = 0;
  4597. for( std::vector<TestCase>::const_iterator it = testCases.begin(), itEnd = testCases.end();
  4598. it != itEnd;
  4599. ++it ) {
  4600. testsRunForGroup++;
  4601. if( m_testsAlreadyRun.find( *it ) == m_testsAlreadyRun.end() ) {
  4602. if( context.aborting() )
  4603. break;
  4604. totals += context.runTest( *it );
  4605. m_testsAlreadyRun.insert( *it );
  4606. }
  4607. }
  4608. std::vector<TestCase> skippedTestCases;
  4609. getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, *m_config, skippedTestCases, true );
  4610. for( std::vector<TestCase>::const_iterator it = skippedTestCases.begin(), itEnd = skippedTestCases.end();
  4611. it != itEnd;
  4612. ++it )
  4613. m_reporter->skipTest( *it );
  4614. context.testGroupEnded( "all tests", totals, 1, 1 );
  4615. return totals;
  4616. }
  4617. private:
  4618. void openStream() {
  4619. // Open output file, if specified
  4620. if( !m_config->getFilename().empty() ) {
  4621. m_ofs.open( m_config->getFilename().c_str() );
  4622. if( m_ofs.fail() ) {
  4623. std::ostringstream oss;
  4624. oss << "Unable to open file: '" << m_config->getFilename() << "'";
  4625. throw std::domain_error( oss.str() );
  4626. }
  4627. m_config->setStreamBuf( m_ofs.rdbuf() );
  4628. }
  4629. }
  4630. void makeReporter() {
  4631. std::string reporterName = m_config->getReporterName().empty()
  4632. ? "console"
  4633. : m_config->getReporterName();
  4634. m_reporter = getRegistryHub().getReporterRegistry().create( reporterName, m_config.get() );
  4635. if( !m_reporter ) {
  4636. std::ostringstream oss;
  4637. oss << "No reporter registered with name: '" << reporterName << "'";
  4638. throw std::domain_error( oss.str() );
  4639. }
  4640. }
  4641. private:
  4642. Ptr<Config> m_config;
  4643. std::ofstream m_ofs;
  4644. Ptr<IStreamingReporter> m_reporter;
  4645. std::set<TestCase> m_testsAlreadyRun;
  4646. };
  4647. class Session : NonCopyable {
  4648. static bool alreadyInstantiated;
  4649. public:
  4650. struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; };
  4651. Session()
  4652. : m_cli( makeCommandLineParser() ) {
  4653. if( alreadyInstantiated ) {
  4654. std::string msg = "Only one instance of Catch::Session can ever be used";
  4655. Catch::cerr() << msg << std::endl;
  4656. throw std::logic_error( msg );
  4657. }
  4658. alreadyInstantiated = true;
  4659. }
  4660. ~Session() {
  4661. Catch::cleanUp();
  4662. }
  4663. void showHelp( std::string const& processName ) {
  4664. Catch::cout() << "\nCatch v" << libraryVersion.majorVersion << "."
  4665. << libraryVersion.minorVersion << " build "
  4666. << libraryVersion.buildNumber;
  4667. if( libraryVersion.branchName != std::string( "master" ) )
  4668. Catch::cout() << " (" << libraryVersion.branchName << " branch)";
  4669. Catch::cout() << "\n";
  4670. m_cli.usage( Catch::cout(), processName );
  4671. Catch::cout() << "For more detail usage please see the project docs\n" << std::endl;
  4672. }
  4673. int applyCommandLine( int argc, char* const argv[], OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {
  4674. try {
  4675. m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail );
  4676. m_unusedTokens = m_cli.parseInto( argc, argv, m_configData );
  4677. if( m_configData.showHelp )
  4678. showHelp( m_configData.processName );
  4679. m_config.reset();
  4680. }
  4681. catch( std::exception& ex ) {
  4682. {
  4683. Colour colourGuard( Colour::Red );
  4684. Catch::cerr() << "\nError(s) in input:\n"
  4685. << Text( ex.what(), TextAttributes().setIndent(2) )
  4686. << "\n\n";
  4687. }
  4688. m_cli.usage( Catch::cout(), m_configData.processName );
  4689. return (std::numeric_limits<int>::max)();
  4690. }
  4691. return 0;
  4692. }
  4693. void useConfigData( ConfigData const& _configData ) {
  4694. m_configData = _configData;
  4695. m_config.reset();
  4696. }
  4697. int run( int argc, char* const argv[] ) {
  4698. int returnCode = applyCommandLine( argc, argv );
  4699. if( returnCode == 0 )
  4700. returnCode = run();
  4701. return returnCode;
  4702. }
  4703. int run() {
  4704. if( m_configData.showHelp )
  4705. return 0;
  4706. try
  4707. {
  4708. config(); // Force config to be constructed
  4709. std::srand( m_configData.rngSeed );
  4710. Runner runner( m_config );
  4711. // Handle list request
  4712. if( Option<std::size_t> listed = list( config() ) )
  4713. return static_cast<int>( *listed );
  4714. return static_cast<int>( runner.runTests().assertions.failed );
  4715. }
  4716. catch( std::exception& ex ) {
  4717. Catch::cerr() << ex.what() << std::endl;
  4718. return (std::numeric_limits<int>::max)();
  4719. }
  4720. }
  4721. Clara::CommandLine<ConfigData> const& cli() const {
  4722. return m_cli;
  4723. }
  4724. std::vector<Clara::Parser::Token> const& unusedTokens() const {
  4725. return m_unusedTokens;
  4726. }
  4727. ConfigData& configData() {
  4728. return m_configData;
  4729. }
  4730. Config& config() {
  4731. if( !m_config )
  4732. m_config = new Config( m_configData );
  4733. return *m_config;
  4734. }
  4735. private:
  4736. Clara::CommandLine<ConfigData> m_cli;
  4737. std::vector<Clara::Parser::Token> m_unusedTokens;
  4738. ConfigData m_configData;
  4739. Ptr<Config> m_config;
  4740. };
  4741. bool Session::alreadyInstantiated = false;
  4742. } // end namespace Catch
  4743. // #included from: catch_registry_hub.hpp
  4744. #define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED
  4745. // #included from: catch_test_case_registry_impl.hpp
  4746. #define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
  4747. #include <vector>
  4748. #include <set>
  4749. #include <sstream>
  4750. #include <iostream>
  4751. #include <algorithm>
  4752. namespace Catch {
  4753. class TestRegistry : public ITestCaseRegistry {
  4754. struct LexSort {
  4755. bool operator() (TestCase i,TestCase j) const { return (i<j);}
  4756. };
  4757. struct RandomNumberGenerator {
  4758. int operator()( int n ) const { return std::rand() % n; }
  4759. };
  4760. public:
  4761. TestRegistry() : m_unnamedCount( 0 ) {}
  4762. virtual ~TestRegistry();
  4763. virtual void registerTest( TestCase const& testCase ) {
  4764. std::string name = testCase.getTestCaseInfo().name;
  4765. if( name == "" ) {
  4766. std::ostringstream oss;
  4767. oss << "Anonymous test case " << ++m_unnamedCount;
  4768. return registerTest( testCase.withName( oss.str() ) );
  4769. }
  4770. if( m_functions.find( testCase ) == m_functions.end() ) {
  4771. m_functions.insert( testCase );
  4772. m_functionsInOrder.push_back( testCase );
  4773. if( !testCase.isHidden() )
  4774. m_nonHiddenFunctions.push_back( testCase );
  4775. }
  4776. else {
  4777. TestCase const& prev = *m_functions.find( testCase );
  4778. {
  4779. Colour colourGuard( Colour::Red );
  4780. Catch::cerr() << "error: TEST_CASE( \"" << name << "\" ) already defined.\n"
  4781. << "\tFirst seen at " << prev.getTestCaseInfo().lineInfo << "\n"
  4782. << "\tRedefined at " << testCase.getTestCaseInfo().lineInfo << std::endl;
  4783. }
  4784. exit(1);
  4785. }
  4786. }
  4787. virtual std::vector<TestCase> const& getAllTests() const {
  4788. return m_functionsInOrder;
  4789. }
  4790. virtual std::vector<TestCase> const& getAllNonHiddenTests() const {
  4791. return m_nonHiddenFunctions;
  4792. }
  4793. virtual void getFilteredTests( TestSpec const& testSpec, IConfig const& config, std::vector<TestCase>& matchingTestCases, bool negated = false ) const {
  4794. for( std::vector<TestCase>::const_iterator it = m_functionsInOrder.begin(),
  4795. itEnd = m_functionsInOrder.end();
  4796. it != itEnd;
  4797. ++it ) {
  4798. bool includeTest = testSpec.matches( *it ) && ( config.allowThrows() || !it->throws() );
  4799. if( includeTest != negated )
  4800. matchingTestCases.push_back( *it );
  4801. }
  4802. sortTests( config, matchingTestCases );
  4803. }
  4804. private:
  4805. static void sortTests( IConfig const& config, std::vector<TestCase>& matchingTestCases ) {
  4806. switch( config.runOrder() ) {
  4807. case RunTests::InLexicographicalOrder:
  4808. std::sort( matchingTestCases.begin(), matchingTestCases.end(), LexSort() );
  4809. break;
  4810. case RunTests::InRandomOrder:
  4811. {
  4812. RandomNumberGenerator rng;
  4813. std::random_shuffle( matchingTestCases.begin(), matchingTestCases.end(), rng );
  4814. }
  4815. break;
  4816. case RunTests::InDeclarationOrder:
  4817. // already in declaration order
  4818. break;
  4819. }
  4820. }
  4821. std::set<TestCase> m_functions;
  4822. std::vector<TestCase> m_functionsInOrder;
  4823. std::vector<TestCase> m_nonHiddenFunctions;
  4824. size_t m_unnamedCount;
  4825. };
  4826. ///////////////////////////////////////////////////////////////////////////
  4827. class FreeFunctionTestCase : public SharedImpl<ITestCase> {
  4828. public:
  4829. FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {}
  4830. virtual void invoke() const {
  4831. m_fun();
  4832. }
  4833. private:
  4834. virtual ~FreeFunctionTestCase();
  4835. TestFunction m_fun;
  4836. };
  4837. inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) {
  4838. std::string className = classOrQualifiedMethodName;
  4839. if( startsWith( className, "&" ) )
  4840. {
  4841. std::size_t lastColons = className.rfind( "::" );
  4842. std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
  4843. if( penultimateColons == std::string::npos )
  4844. penultimateColons = 1;
  4845. className = className.substr( penultimateColons, lastColons-penultimateColons );
  4846. }
  4847. return className;
  4848. }
  4849. ///////////////////////////////////////////////////////////////////////////
  4850. AutoReg::AutoReg( TestFunction function,
  4851. SourceLineInfo const& lineInfo,
  4852. NameAndDesc const& nameAndDesc ) {
  4853. registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo );
  4854. }
  4855. AutoReg::~AutoReg() {}
  4856. void AutoReg::registerTestCase( ITestCase* testCase,
  4857. char const* classOrQualifiedMethodName,
  4858. NameAndDesc const& nameAndDesc,
  4859. SourceLineInfo const& lineInfo ) {
  4860. getMutableRegistryHub().registerTest
  4861. ( makeTestCase( testCase,
  4862. extractClassName( classOrQualifiedMethodName ),
  4863. nameAndDesc.name,
  4864. nameAndDesc.description,
  4865. lineInfo ) );
  4866. }
  4867. } // end namespace Catch
  4868. // #included from: catch_reporter_registry.hpp
  4869. #define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED
  4870. #include <map>
  4871. namespace Catch {
  4872. class ReporterRegistry : public IReporterRegistry {
  4873. public:
  4874. virtual ~ReporterRegistry() {
  4875. deleteAllValues( m_factories );
  4876. }
  4877. virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig> const& config ) const {
  4878. FactoryMap::const_iterator it = m_factories.find( name );
  4879. if( it == m_factories.end() )
  4880. return NULL;
  4881. return it->second->create( ReporterConfig( config ) );
  4882. }
  4883. void registerReporter( std::string const& name, IReporterFactory* factory ) {
  4884. m_factories.insert( std::make_pair( name, factory ) );
  4885. }
  4886. FactoryMap const& getFactories() const {
  4887. return m_factories;
  4888. }
  4889. private:
  4890. FactoryMap m_factories;
  4891. };
  4892. }
  4893. // #included from: catch_exception_translator_registry.hpp
  4894. #define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED
  4895. #ifdef __OBJC__
  4896. #import "Foundation/Foundation.h"
  4897. #endif
  4898. namespace Catch {
  4899. class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
  4900. public:
  4901. ~ExceptionTranslatorRegistry() {
  4902. deleteAll( m_translators );
  4903. }
  4904. virtual void registerTranslator( const IExceptionTranslator* translator ) {
  4905. m_translators.push_back( translator );
  4906. }
  4907. virtual std::string translateActiveException() const {
  4908. try {
  4909. #ifdef __OBJC__
  4910. // In Objective-C try objective-c exceptions first
  4911. @try {
  4912. throw;
  4913. }
  4914. @catch (NSException *exception) {
  4915. return Catch::toString( [exception description] );
  4916. }
  4917. #else
  4918. throw;
  4919. #endif
  4920. }
  4921. catch( TestFailureException& ) {
  4922. throw;
  4923. }
  4924. catch( std::exception& ex ) {
  4925. return ex.what();
  4926. }
  4927. catch( std::string& msg ) {
  4928. return msg;
  4929. }
  4930. catch( const char* msg ) {
  4931. return msg;
  4932. }
  4933. catch(...) {
  4934. return tryTranslators( m_translators.begin() );
  4935. }
  4936. }
  4937. std::string tryTranslators( std::vector<const IExceptionTranslator*>::const_iterator it ) const {
  4938. if( it == m_translators.end() )
  4939. return "Unknown exception";
  4940. try {
  4941. return (*it)->translate();
  4942. }
  4943. catch(...) {
  4944. return tryTranslators( it+1 );
  4945. }
  4946. }
  4947. private:
  4948. std::vector<const IExceptionTranslator*> m_translators;
  4949. };
  4950. }
  4951. namespace Catch {
  4952. namespace {
  4953. class RegistryHub : public IRegistryHub, public IMutableRegistryHub {
  4954. RegistryHub( RegistryHub const& );
  4955. void operator=( RegistryHub const& );
  4956. public: // IRegistryHub
  4957. RegistryHub() {
  4958. }
  4959. virtual IReporterRegistry const& getReporterRegistry() const {
  4960. return m_reporterRegistry;
  4961. }
  4962. virtual ITestCaseRegistry const& getTestCaseRegistry() const {
  4963. return m_testCaseRegistry;
  4964. }
  4965. virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() {
  4966. return m_exceptionTranslatorRegistry;
  4967. }
  4968. public: // IMutableRegistryHub
  4969. virtual void registerReporter( std::string const& name, IReporterFactory* factory ) {
  4970. m_reporterRegistry.registerReporter( name, factory );
  4971. }
  4972. virtual void registerTest( TestCase const& testInfo ) {
  4973. m_testCaseRegistry.registerTest( testInfo );
  4974. }
  4975. virtual void registerTranslator( const IExceptionTranslator* translator ) {
  4976. m_exceptionTranslatorRegistry.registerTranslator( translator );
  4977. }
  4978. private:
  4979. TestRegistry m_testCaseRegistry;
  4980. ReporterRegistry m_reporterRegistry;
  4981. ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
  4982. };
  4983. // Single, global, instance
  4984. inline RegistryHub*& getTheRegistryHub() {
  4985. static RegistryHub* theRegistryHub = NULL;
  4986. if( !theRegistryHub )
  4987. theRegistryHub = new RegistryHub();
  4988. return theRegistryHub;
  4989. }
  4990. }
  4991. IRegistryHub& getRegistryHub() {
  4992. return *getTheRegistryHub();
  4993. }
  4994. IMutableRegistryHub& getMutableRegistryHub() {
  4995. return *getTheRegistryHub();
  4996. }
  4997. void cleanUp() {
  4998. delete getTheRegistryHub();
  4999. getTheRegistryHub() = NULL;
  5000. cleanUpContext();
  5001. }
  5002. std::string translateActiveException() {
  5003. return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
  5004. }
  5005. } // end namespace Catch
  5006. // #included from: catch_notimplemented_exception.hpp
  5007. #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED
  5008. #include <ostream>
  5009. namespace Catch {
  5010. NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo )
  5011. : m_lineInfo( lineInfo ) {
  5012. std::ostringstream oss;
  5013. oss << lineInfo << ": function ";
  5014. oss << "not implemented";
  5015. m_what = oss.str();
  5016. }
  5017. const char* NotImplementedException::what() const CATCH_NOEXCEPT {
  5018. return m_what.c_str();
  5019. }
  5020. } // end namespace Catch
  5021. // #included from: catch_context_impl.hpp
  5022. #define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED
  5023. // #included from: catch_stream.hpp
  5024. #define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED
  5025. // #included from: catch_streambuf.h
  5026. #define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED
  5027. #include <streambuf>
  5028. namespace Catch {
  5029. class StreamBufBase : public std::streambuf {
  5030. public:
  5031. virtual ~StreamBufBase() CATCH_NOEXCEPT;
  5032. };
  5033. }
  5034. #include <stdexcept>
  5035. #include <cstdio>
  5036. #include <iostream>
  5037. namespace Catch {
  5038. template<typename WriterF, size_t bufferSize=256>
  5039. class StreamBufImpl : public StreamBufBase {
  5040. char data[bufferSize];
  5041. WriterF m_writer;
  5042. public:
  5043. StreamBufImpl() {
  5044. setp( data, data + sizeof(data) );
  5045. }
  5046. ~StreamBufImpl() CATCH_NOEXCEPT {
  5047. sync();
  5048. }
  5049. private:
  5050. int overflow( int c ) {
  5051. sync();
  5052. if( c != EOF ) {
  5053. if( pbase() == epptr() )
  5054. m_writer( std::string( 1, static_cast<char>( c ) ) );
  5055. else
  5056. sputc( static_cast<char>( c ) );
  5057. }
  5058. return 0;
  5059. }
  5060. int sync() {
  5061. if( pbase() != pptr() ) {
  5062. m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
  5063. setp( pbase(), epptr() );
  5064. }
  5065. return 0;
  5066. }
  5067. };
  5068. ///////////////////////////////////////////////////////////////////////////
  5069. struct OutputDebugWriter {
  5070. void operator()( std::string const&str ) {
  5071. writeToDebugConsole( str );
  5072. }
  5073. };
  5074. Stream::Stream()
  5075. : streamBuf( NULL ), isOwned( false )
  5076. {}
  5077. Stream::Stream( std::streambuf* _streamBuf, bool _isOwned )
  5078. : streamBuf( _streamBuf ), isOwned( _isOwned )
  5079. {}
  5080. void Stream::release() {
  5081. if( isOwned ) {
  5082. delete streamBuf;
  5083. streamBuf = NULL;
  5084. isOwned = false;
  5085. }
  5086. }
  5087. #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement this functions
  5088. std::ostream& cout() {
  5089. return std::cout;
  5090. }
  5091. std::ostream& cerr() {
  5092. return std::cerr;
  5093. }
  5094. #endif
  5095. }
  5096. namespace Catch {
  5097. class Context : public IMutableContext {
  5098. Context() : m_config( NULL ), m_runner( NULL ), m_resultCapture( NULL ) {}
  5099. Context( Context const& );
  5100. void operator=( Context const& );
  5101. public: // IContext
  5102. virtual IResultCapture* getResultCapture() {
  5103. return m_resultCapture;
  5104. }
  5105. virtual IRunner* getRunner() {
  5106. return m_runner;
  5107. }
  5108. virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) {
  5109. return getGeneratorsForCurrentTest()
  5110. .getGeneratorInfo( fileInfo, totalSize )
  5111. .getCurrentIndex();
  5112. }
  5113. virtual bool advanceGeneratorsForCurrentTest() {
  5114. IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
  5115. return generators && generators->moveNext();
  5116. }
  5117. virtual Ptr<IConfig const> getConfig() const {
  5118. return m_config;
  5119. }
  5120. public: // IMutableContext
  5121. virtual void setResultCapture( IResultCapture* resultCapture ) {
  5122. m_resultCapture = resultCapture;
  5123. }
  5124. virtual void setRunner( IRunner* runner ) {
  5125. m_runner = runner;
  5126. }
  5127. virtual void setConfig( Ptr<IConfig const> const& config ) {
  5128. m_config = config;
  5129. }
  5130. friend IMutableContext& getCurrentMutableContext();
  5131. private:
  5132. IGeneratorsForTest* findGeneratorsForCurrentTest() {
  5133. std::string testName = getResultCapture()->getCurrentTestName();
  5134. std::map<std::string, IGeneratorsForTest*>::const_iterator it =
  5135. m_generatorsByTestName.find( testName );
  5136. return it != m_generatorsByTestName.end()
  5137. ? it->second
  5138. : NULL;
  5139. }
  5140. IGeneratorsForTest& getGeneratorsForCurrentTest() {
  5141. IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
  5142. if( !generators ) {
  5143. std::string testName = getResultCapture()->getCurrentTestName();
  5144. generators = createGeneratorsForTest();
  5145. m_generatorsByTestName.insert( std::make_pair( testName, generators ) );
  5146. }
  5147. return *generators;
  5148. }
  5149. private:
  5150. Ptr<IConfig const> m_config;
  5151. IRunner* m_runner;
  5152. IResultCapture* m_resultCapture;
  5153. std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName;
  5154. };
  5155. namespace {
  5156. Context* currentContext = NULL;
  5157. }
  5158. IMutableContext& getCurrentMutableContext() {
  5159. if( !currentContext )
  5160. currentContext = new Context();
  5161. return *currentContext;
  5162. }
  5163. IContext& getCurrentContext() {
  5164. return getCurrentMutableContext();
  5165. }
  5166. Stream createStream( std::string const& streamName ) {
  5167. if( streamName == "stdout" ) return Stream( Catch::cout().rdbuf(), false );
  5168. if( streamName == "stderr" ) return Stream( Catch::cerr().rdbuf(), false );
  5169. if( streamName == "debug" ) return Stream( new StreamBufImpl<OutputDebugWriter>, true );
  5170. throw std::domain_error( "Unknown stream: " + streamName );
  5171. }
  5172. void cleanUpContext() {
  5173. delete currentContext;
  5174. currentContext = NULL;
  5175. }
  5176. }
  5177. // #included from: catch_console_colour_impl.hpp
  5178. #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED
  5179. namespace Catch {
  5180. namespace {
  5181. struct IColourImpl {
  5182. virtual ~IColourImpl() {}
  5183. virtual void use( Colour::Code _colourCode ) = 0;
  5184. };
  5185. struct NoColourImpl : IColourImpl {
  5186. void use( Colour::Code ) {}
  5187. static IColourImpl* instance() {
  5188. static NoColourImpl s_instance;
  5189. return &s_instance;
  5190. }
  5191. };
  5192. } // anon namespace
  5193. } // namespace Catch
  5194. #if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
  5195. # ifdef CATCH_PLATFORM_WINDOWS
  5196. # define CATCH_CONFIG_COLOUR_WINDOWS
  5197. # else
  5198. # define CATCH_CONFIG_COLOUR_ANSI
  5199. # endif
  5200. #endif
  5201. #if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
  5202. #ifndef NOMINMAX
  5203. #define NOMINMAX
  5204. #endif
  5205. #ifdef __AFXDLL
  5206. #include <AfxWin.h>
  5207. #else
  5208. #include <windows.h>
  5209. #endif
  5210. namespace Catch {
  5211. namespace {
  5212. class Win32ColourImpl : public IColourImpl {
  5213. public:
  5214. Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
  5215. {
  5216. CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
  5217. GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
  5218. originalAttributes = csbiInfo.wAttributes;
  5219. }
  5220. virtual void use( Colour::Code _colourCode ) {
  5221. switch( _colourCode ) {
  5222. case Colour::None: return setTextAttribute( originalAttributes );
  5223. case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
  5224. case Colour::Red: return setTextAttribute( FOREGROUND_RED );
  5225. case Colour::Green: return setTextAttribute( FOREGROUND_GREEN );
  5226. case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE );
  5227. case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
  5228. case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
  5229. case Colour::Grey: return setTextAttribute( 0 );
  5230. case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY );
  5231. case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
  5232. case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
  5233. case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
  5234. case Colour::Bright: throw std::logic_error( "not a colour" );
  5235. }
  5236. }
  5237. private:
  5238. void setTextAttribute( WORD _textAttribute ) {
  5239. SetConsoleTextAttribute( stdoutHandle, _textAttribute );
  5240. }
  5241. HANDLE stdoutHandle;
  5242. WORD originalAttributes;
  5243. };
  5244. IColourImpl* platformColourInstance() {
  5245. static Win32ColourImpl s_instance;
  5246. return &s_instance;
  5247. }
  5248. } // end anon namespace
  5249. } // end namespace Catch
  5250. #elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
  5251. #include <unistd.h>
  5252. namespace Catch {
  5253. namespace {
  5254. // use POSIX/ ANSI console terminal codes
  5255. // Thanks to Adam Strzelecki for original contribution
  5256. // (http://github.com/nanoant)
  5257. // https://github.com/philsquared/Catch/pull/131
  5258. class PosixColourImpl : public IColourImpl {
  5259. public:
  5260. virtual void use( Colour::Code _colourCode ) {
  5261. switch( _colourCode ) {
  5262. case Colour::None:
  5263. case Colour::White: return setColour( "[0m" );
  5264. case Colour::Red: return setColour( "[0;31m" );
  5265. case Colour::Green: return setColour( "[0;32m" );
  5266. case Colour::Blue: return setColour( "[0:34m" );
  5267. case Colour::Cyan: return setColour( "[0;36m" );
  5268. case Colour::Yellow: return setColour( "[0;33m" );
  5269. case Colour::Grey: return setColour( "[1;30m" );
  5270. case Colour::LightGrey: return setColour( "[0;37m" );
  5271. case Colour::BrightRed: return setColour( "[1;31m" );
  5272. case Colour::BrightGreen: return setColour( "[1;32m" );
  5273. case Colour::BrightWhite: return setColour( "[1;37m" );
  5274. case Colour::Bright: throw std::logic_error( "not a colour" );
  5275. }
  5276. }
  5277. static IColourImpl* instance() {
  5278. static PosixColourImpl s_instance;
  5279. return &s_instance;
  5280. }
  5281. private:
  5282. void setColour( const char* _escapeCode ) {
  5283. Catch::cout() << '\033' << _escapeCode;
  5284. }
  5285. };
  5286. IColourImpl* platformColourInstance() {
  5287. Ptr<IConfig const> config = getCurrentContext().getConfig();
  5288. return (config && config->forceColour()) || isatty(STDOUT_FILENO)
  5289. ? PosixColourImpl::instance()
  5290. : NoColourImpl::instance();
  5291. }
  5292. } // end anon namespace
  5293. } // end namespace Catch
  5294. #else // not Windows or ANSI ///////////////////////////////////////////////
  5295. namespace Catch {
  5296. static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
  5297. } // end namespace Catch
  5298. #endif // Windows/ ANSI/ None
  5299. namespace Catch {
  5300. Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); }
  5301. Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast<Colour&>( _other ).m_moved = true; }
  5302. Colour::~Colour(){ if( !m_moved ) use( None ); }
  5303. void Colour::use( Code _colourCode ) {
  5304. static IColourImpl* impl = isDebuggerActive()
  5305. ? NoColourImpl::instance()
  5306. : platformColourInstance();
  5307. impl->use( _colourCode );
  5308. }
  5309. } // end namespace Catch
  5310. // #included from: catch_generators_impl.hpp
  5311. #define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED
  5312. #include <vector>
  5313. #include <string>
  5314. #include <map>
  5315. namespace Catch {
  5316. struct GeneratorInfo : IGeneratorInfo {
  5317. GeneratorInfo( std::size_t size )
  5318. : m_size( size ),
  5319. m_currentIndex( 0 )
  5320. {}
  5321. bool moveNext() {
  5322. if( ++m_currentIndex == m_size ) {
  5323. m_currentIndex = 0;
  5324. return false;
  5325. }
  5326. return true;
  5327. }
  5328. std::size_t getCurrentIndex() const {
  5329. return m_currentIndex;
  5330. }
  5331. std::size_t m_size;
  5332. std::size_t m_currentIndex;
  5333. };
  5334. ///////////////////////////////////////////////////////////////////////////
  5335. class GeneratorsForTest : public IGeneratorsForTest {
  5336. public:
  5337. ~GeneratorsForTest() {
  5338. deleteAll( m_generatorsInOrder );
  5339. }
  5340. IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) {
  5341. std::map<std::string, IGeneratorInfo*>::const_iterator it = m_generatorsByName.find( fileInfo );
  5342. if( it == m_generatorsByName.end() ) {
  5343. IGeneratorInfo* info = new GeneratorInfo( size );
  5344. m_generatorsByName.insert( std::make_pair( fileInfo, info ) );
  5345. m_generatorsInOrder.push_back( info );
  5346. return *info;
  5347. }
  5348. return *it->second;
  5349. }
  5350. bool moveNext() {
  5351. std::vector<IGeneratorInfo*>::const_iterator it = m_generatorsInOrder.begin();
  5352. std::vector<IGeneratorInfo*>::const_iterator itEnd = m_generatorsInOrder.end();
  5353. for(; it != itEnd; ++it ) {
  5354. if( (*it)->moveNext() )
  5355. return true;
  5356. }
  5357. return false;
  5358. }
  5359. private:
  5360. std::map<std::string, IGeneratorInfo*> m_generatorsByName;
  5361. std::vector<IGeneratorInfo*> m_generatorsInOrder;
  5362. };
  5363. IGeneratorsForTest* createGeneratorsForTest()
  5364. {
  5365. return new GeneratorsForTest();
  5366. }
  5367. } // end namespace Catch
  5368. // #included from: catch_assertionresult.hpp
  5369. #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED
  5370. namespace Catch {
  5371. AssertionInfo::AssertionInfo( std::string const& _macroName,
  5372. SourceLineInfo const& _lineInfo,
  5373. std::string const& _capturedExpression,
  5374. ResultDisposition::Flags _resultDisposition )
  5375. : macroName( _macroName ),
  5376. lineInfo( _lineInfo ),
  5377. capturedExpression( _capturedExpression ),
  5378. resultDisposition( _resultDisposition )
  5379. {}
  5380. AssertionResult::AssertionResult() {}
  5381. AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
  5382. : m_info( info ),
  5383. m_resultData( data )
  5384. {}
  5385. AssertionResult::~AssertionResult() {}
  5386. // Result was a success
  5387. bool AssertionResult::succeeded() const {
  5388. return Catch::isOk( m_resultData.resultType );
  5389. }
  5390. // Result was a success, or failure is suppressed
  5391. bool AssertionResult::isOk() const {
  5392. return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
  5393. }
  5394. ResultWas::OfType AssertionResult::getResultType() const {
  5395. return m_resultData.resultType;
  5396. }
  5397. bool AssertionResult::hasExpression() const {
  5398. return !m_info.capturedExpression.empty();
  5399. }
  5400. bool AssertionResult::hasMessage() const {
  5401. return !m_resultData.message.empty();
  5402. }
  5403. std::string AssertionResult::getExpression() const {
  5404. if( isFalseTest( m_info.resultDisposition ) )
  5405. return "!" + m_info.capturedExpression;
  5406. else
  5407. return m_info.capturedExpression;
  5408. }
  5409. std::string AssertionResult::getExpressionInMacro() const {
  5410. if( m_info.macroName.empty() )
  5411. return m_info.capturedExpression;
  5412. else
  5413. return m_info.macroName + "( " + m_info.capturedExpression + " )";
  5414. }
  5415. bool AssertionResult::hasExpandedExpression() const {
  5416. return hasExpression() && getExpandedExpression() != getExpression();
  5417. }
  5418. std::string AssertionResult::getExpandedExpression() const {
  5419. return m_resultData.reconstructedExpression;
  5420. }
  5421. std::string AssertionResult::getMessage() const {
  5422. return m_resultData.message;
  5423. }
  5424. SourceLineInfo AssertionResult::getSourceInfo() const {
  5425. return m_info.lineInfo;
  5426. }
  5427. std::string AssertionResult::getTestMacroName() const {
  5428. return m_info.macroName;
  5429. }
  5430. } // end namespace Catch
  5431. // #included from: catch_test_case_info.hpp
  5432. #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED
  5433. namespace Catch {
  5434. inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
  5435. if( startsWith( tag, "." ) ||
  5436. tag == "hide" ||
  5437. tag == "!hide" )
  5438. return TestCaseInfo::IsHidden;
  5439. else if( tag == "!throws" )
  5440. return TestCaseInfo::Throws;
  5441. else if( tag == "!shouldfail" )
  5442. return TestCaseInfo::ShouldFail;
  5443. else if( tag == "!mayfail" )
  5444. return TestCaseInfo::MayFail;
  5445. else
  5446. return TestCaseInfo::None;
  5447. }
  5448. inline bool isReservedTag( std::string const& tag ) {
  5449. return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !isalnum( tag[0] );
  5450. }
  5451. inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
  5452. if( isReservedTag( tag ) ) {
  5453. {
  5454. Colour colourGuard( Colour::Red );
  5455. Catch::cerr()
  5456. << "Tag name [" << tag << "] not allowed.\n"
  5457. << "Tag names starting with non alpha-numeric characters are reserved\n";
  5458. }
  5459. {
  5460. Colour colourGuard( Colour::FileName );
  5461. Catch::cerr() << _lineInfo << std::endl;
  5462. }
  5463. exit(1);
  5464. }
  5465. }
  5466. TestCase makeTestCase( ITestCase* _testCase,
  5467. std::string const& _className,
  5468. std::string const& _name,
  5469. std::string const& _descOrTags,
  5470. SourceLineInfo const& _lineInfo )
  5471. {
  5472. bool isHidden( startsWith( _name, "./" ) ); // Legacy support
  5473. // Parse out tags
  5474. std::set<std::string> tags;
  5475. std::string desc, tag;
  5476. bool inTag = false;
  5477. for( std::size_t i = 0; i < _descOrTags.size(); ++i ) {
  5478. char c = _descOrTags[i];
  5479. if( !inTag ) {
  5480. if( c == '[' )
  5481. inTag = true;
  5482. else
  5483. desc += c;
  5484. }
  5485. else {
  5486. if( c == ']' ) {
  5487. TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
  5488. if( prop == TestCaseInfo::IsHidden )
  5489. isHidden = true;
  5490. else if( prop == TestCaseInfo::None )
  5491. enforceNotReservedTag( tag, _lineInfo );
  5492. tags.insert( tag );
  5493. tag.clear();
  5494. inTag = false;
  5495. }
  5496. else
  5497. tag += c;
  5498. }
  5499. }
  5500. if( isHidden ) {
  5501. tags.insert( "hide" );
  5502. tags.insert( "." );
  5503. }
  5504. TestCaseInfo info( _name, _className, desc, tags, _lineInfo );
  5505. return TestCase( _testCase, info );
  5506. }
  5507. TestCaseInfo::TestCaseInfo( std::string const& _name,
  5508. std::string const& _className,
  5509. std::string const& _description,
  5510. std::set<std::string> const& _tags,
  5511. SourceLineInfo const& _lineInfo )
  5512. : name( _name ),
  5513. className( _className ),
  5514. description( _description ),
  5515. tags( _tags ),
  5516. lineInfo( _lineInfo ),
  5517. properties( None )
  5518. {
  5519. std::ostringstream oss;
  5520. for( std::set<std::string>::const_iterator it = _tags.begin(), itEnd = _tags.end(); it != itEnd; ++it ) {
  5521. oss << "[" << *it << "]";
  5522. std::string lcaseTag = toLower( *it );
  5523. properties = static_cast<SpecialProperties>( properties | parseSpecialTag( lcaseTag ) );
  5524. lcaseTags.insert( lcaseTag );
  5525. }
  5526. tagsAsString = oss.str();
  5527. }
  5528. TestCaseInfo::TestCaseInfo( TestCaseInfo const& other )
  5529. : name( other.name ),
  5530. className( other.className ),
  5531. description( other.description ),
  5532. tags( other.tags ),
  5533. lcaseTags( other.lcaseTags ),
  5534. tagsAsString( other.tagsAsString ),
  5535. lineInfo( other.lineInfo ),
  5536. properties( other.properties )
  5537. {}
  5538. bool TestCaseInfo::isHidden() const {
  5539. return ( properties & IsHidden ) != 0;
  5540. }
  5541. bool TestCaseInfo::throws() const {
  5542. return ( properties & Throws ) != 0;
  5543. }
  5544. bool TestCaseInfo::okToFail() const {
  5545. return ( properties & (ShouldFail | MayFail ) ) != 0;
  5546. }
  5547. bool TestCaseInfo::expectedToFail() const {
  5548. return ( properties & (ShouldFail ) ) != 0;
  5549. }
  5550. TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {}
  5551. TestCase::TestCase( TestCase const& other )
  5552. : TestCaseInfo( other ),
  5553. test( other.test )
  5554. {}
  5555. TestCase TestCase::withName( std::string const& _newName ) const {
  5556. TestCase other( *this );
  5557. other.name = _newName;
  5558. return other;
  5559. }
  5560. void TestCase::swap( TestCase& other ) {
  5561. test.swap( other.test );
  5562. name.swap( other.name );
  5563. className.swap( other.className );
  5564. description.swap( other.description );
  5565. tags.swap( other.tags );
  5566. lcaseTags.swap( other.lcaseTags );
  5567. tagsAsString.swap( other.tagsAsString );
  5568. std::swap( TestCaseInfo::properties, static_cast<TestCaseInfo&>( other ).properties );
  5569. std::swap( lineInfo, other.lineInfo );
  5570. }
  5571. void TestCase::invoke() const {
  5572. test->invoke();
  5573. }
  5574. bool TestCase::operator == ( TestCase const& other ) const {
  5575. return test.get() == other.test.get() &&
  5576. name == other.name &&
  5577. className == other.className;
  5578. }
  5579. bool TestCase::operator < ( TestCase const& other ) const {
  5580. return name < other.name;
  5581. }
  5582. TestCase& TestCase::operator = ( TestCase const& other ) {
  5583. TestCase temp( other );
  5584. swap( temp );
  5585. return *this;
  5586. }
  5587. TestCaseInfo const& TestCase::getTestCaseInfo() const
  5588. {
  5589. return *this;
  5590. }
  5591. } // end namespace Catch
  5592. // #included from: catch_version.hpp
  5593. #define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED
  5594. namespace Catch {
  5595. // These numbers are maintained by a script
  5596. Version libraryVersion( 1, 1, 3, "master" );
  5597. }
  5598. // #included from: catch_message.hpp
  5599. #define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED
  5600. namespace Catch {
  5601. MessageInfo::MessageInfo( std::string const& _macroName,
  5602. SourceLineInfo const& _lineInfo,
  5603. ResultWas::OfType _type )
  5604. : macroName( _macroName ),
  5605. lineInfo( _lineInfo ),
  5606. type( _type ),
  5607. sequence( ++globalCount )
  5608. {}
  5609. // This may need protecting if threading support is added
  5610. unsigned int MessageInfo::globalCount = 0;
  5611. ////////////////////////////////////////////////////////////////////////////
  5612. ScopedMessage::ScopedMessage( MessageBuilder const& builder )
  5613. : m_info( builder.m_info )
  5614. {
  5615. m_info.message = builder.m_stream.str();
  5616. getResultCapture().pushScopedMessage( m_info );
  5617. }
  5618. ScopedMessage::ScopedMessage( ScopedMessage const& other )
  5619. : m_info( other.m_info )
  5620. {}
  5621. ScopedMessage::~ScopedMessage() {
  5622. getResultCapture().popScopedMessage( m_info );
  5623. }
  5624. } // end namespace Catch
  5625. // #included from: catch_legacy_reporter_adapter.hpp
  5626. #define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED
  5627. // #included from: catch_legacy_reporter_adapter.h
  5628. #define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED
  5629. namespace Catch
  5630. {
  5631. // Deprecated
  5632. struct IReporter : IShared {
  5633. virtual ~IReporter();
  5634. virtual bool shouldRedirectStdout() const = 0;
  5635. virtual void StartTesting() = 0;
  5636. virtual void EndTesting( Totals const& totals ) = 0;
  5637. virtual void StartGroup( std::string const& groupName ) = 0;
  5638. virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0;
  5639. virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0;
  5640. virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0;
  5641. virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0;
  5642. virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0;
  5643. virtual void NoAssertionsInSection( std::string const& sectionName ) = 0;
  5644. virtual void NoAssertionsInTestCase( std::string const& testName ) = 0;
  5645. virtual void Aborted() = 0;
  5646. virtual void Result( AssertionResult const& result ) = 0;
  5647. };
  5648. class LegacyReporterAdapter : public SharedImpl<IStreamingReporter>
  5649. {
  5650. public:
  5651. LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter );
  5652. virtual ~LegacyReporterAdapter();
  5653. virtual ReporterPreferences getPreferences() const;
  5654. virtual void noMatchingTestCases( std::string const& );
  5655. virtual void testRunStarting( TestRunInfo const& );
  5656. virtual void testGroupStarting( GroupInfo const& groupInfo );
  5657. virtual void testCaseStarting( TestCaseInfo const& testInfo );
  5658. virtual void sectionStarting( SectionInfo const& sectionInfo );
  5659. virtual void assertionStarting( AssertionInfo const& );
  5660. virtual bool assertionEnded( AssertionStats const& assertionStats );
  5661. virtual void sectionEnded( SectionStats const& sectionStats );
  5662. virtual void testCaseEnded( TestCaseStats const& testCaseStats );
  5663. virtual void testGroupEnded( TestGroupStats const& testGroupStats );
  5664. virtual void testRunEnded( TestRunStats const& testRunStats );
  5665. virtual void skipTest( TestCaseInfo const& );
  5666. private:
  5667. Ptr<IReporter> m_legacyReporter;
  5668. };
  5669. }
  5670. namespace Catch
  5671. {
  5672. LegacyReporterAdapter::LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter )
  5673. : m_legacyReporter( legacyReporter )
  5674. {}
  5675. LegacyReporterAdapter::~LegacyReporterAdapter() {}
  5676. ReporterPreferences LegacyReporterAdapter::getPreferences() const {
  5677. ReporterPreferences prefs;
  5678. prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout();
  5679. return prefs;
  5680. }
  5681. void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {}
  5682. void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) {
  5683. m_legacyReporter->StartTesting();
  5684. }
  5685. void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) {
  5686. m_legacyReporter->StartGroup( groupInfo.name );
  5687. }
  5688. void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) {
  5689. m_legacyReporter->StartTestCase( testInfo );
  5690. }
  5691. void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) {
  5692. m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description );
  5693. }
  5694. void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) {
  5695. // Not on legacy interface
  5696. }
  5697. bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) {
  5698. if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
  5699. for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
  5700. it != itEnd;
  5701. ++it ) {
  5702. if( it->type == ResultWas::Info ) {
  5703. ResultBuilder rb( it->macroName.c_str(), it->lineInfo, "", ResultDisposition::Normal );
  5704. rb << it->message;
  5705. rb.setResultType( ResultWas::Info );
  5706. AssertionResult result = rb.build();
  5707. m_legacyReporter->Result( result );
  5708. }
  5709. }
  5710. }
  5711. m_legacyReporter->Result( assertionStats.assertionResult );
  5712. return true;
  5713. }
  5714. void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) {
  5715. if( sectionStats.missingAssertions )
  5716. m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name );
  5717. m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions );
  5718. }
  5719. void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) {
  5720. m_legacyReporter->EndTestCase
  5721. ( testCaseStats.testInfo,
  5722. testCaseStats.totals,
  5723. testCaseStats.stdOut,
  5724. testCaseStats.stdErr );
  5725. }
  5726. void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) {
  5727. if( testGroupStats.aborting )
  5728. m_legacyReporter->Aborted();
  5729. m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals );
  5730. }
  5731. void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) {
  5732. m_legacyReporter->EndTesting( testRunStats.totals );
  5733. }
  5734. void LegacyReporterAdapter::skipTest( TestCaseInfo const& ) {
  5735. }
  5736. }
  5737. // #included from: catch_timer.hpp
  5738. #ifdef __clang__
  5739. #pragma clang diagnostic push
  5740. #pragma clang diagnostic ignored "-Wc++11-long-long"
  5741. #endif
  5742. #ifdef CATCH_PLATFORM_WINDOWS
  5743. #include <windows.h>
  5744. #else
  5745. #include <sys/time.h>
  5746. #endif
  5747. namespace Catch {
  5748. namespace {
  5749. #ifdef CATCH_PLATFORM_WINDOWS
  5750. uint64_t getCurrentTicks() {
  5751. static uint64_t hz=0, hzo=0;
  5752. if (!hz) {
  5753. QueryPerformanceFrequency( reinterpret_cast<LARGE_INTEGER*>( &hz ) );
  5754. QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &hzo ) );
  5755. }
  5756. uint64_t t;
  5757. QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &t ) );
  5758. return ((t-hzo)*1000000)/hz;
  5759. }
  5760. #else
  5761. uint64_t getCurrentTicks() {
  5762. timeval t;
  5763. gettimeofday(&t,NULL);
  5764. return static_cast<uint64_t>( t.tv_sec ) * 1000000ull + static_cast<uint64_t>( t.tv_usec );
  5765. }
  5766. #endif
  5767. }
  5768. void Timer::start() {
  5769. m_ticks = getCurrentTicks();
  5770. }
  5771. unsigned int Timer::getElapsedMicroseconds() const {
  5772. return static_cast<unsigned int>(getCurrentTicks() - m_ticks);
  5773. }
  5774. unsigned int Timer::getElapsedMilliseconds() const {
  5775. return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
  5776. }
  5777. double Timer::getElapsedSeconds() const {
  5778. return getElapsedMicroseconds()/1000000.0;
  5779. }
  5780. } // namespace Catch
  5781. #ifdef __clang__
  5782. #pragma clang diagnostic pop
  5783. #endif
  5784. // #included from: catch_common.hpp
  5785. #define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED
  5786. namespace Catch {
  5787. bool startsWith( std::string const& s, std::string const& prefix ) {
  5788. return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix;
  5789. }
  5790. bool endsWith( std::string const& s, std::string const& suffix ) {
  5791. return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix;
  5792. }
  5793. bool contains( std::string const& s, std::string const& infix ) {
  5794. return s.find( infix ) != std::string::npos;
  5795. }
  5796. void toLowerInPlace( std::string& s ) {
  5797. std::transform( s.begin(), s.end(), s.begin(), ::tolower );
  5798. }
  5799. std::string toLower( std::string const& s ) {
  5800. std::string lc = s;
  5801. toLowerInPlace( lc );
  5802. return lc;
  5803. }
  5804. std::string trim( std::string const& str ) {
  5805. static char const* whitespaceChars = "\n\r\t ";
  5806. std::string::size_type start = str.find_first_not_of( whitespaceChars );
  5807. std::string::size_type end = str.find_last_not_of( whitespaceChars );
  5808. return start != std::string::npos ? str.substr( start, 1+end-start ) : "";
  5809. }
  5810. bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
  5811. bool replaced = false;
  5812. std::size_t i = str.find( replaceThis );
  5813. while( i != std::string::npos ) {
  5814. replaced = true;
  5815. str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
  5816. if( i < str.size()-withThis.size() )
  5817. i = str.find( replaceThis, i+withThis.size() );
  5818. else
  5819. i = std::string::npos;
  5820. }
  5821. return replaced;
  5822. }
  5823. pluralise::pluralise( std::size_t count, std::string const& label )
  5824. : m_count( count ),
  5825. m_label( label )
  5826. {}
  5827. std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
  5828. os << pluraliser.m_count << " " << pluraliser.m_label;
  5829. if( pluraliser.m_count != 1 )
  5830. os << "s";
  5831. return os;
  5832. }
  5833. SourceLineInfo::SourceLineInfo() : line( 0 ){}
  5834. SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line )
  5835. : file( _file ),
  5836. line( _line )
  5837. {}
  5838. SourceLineInfo::SourceLineInfo( SourceLineInfo const& other )
  5839. : file( other.file ),
  5840. line( other.line )
  5841. {}
  5842. bool SourceLineInfo::empty() const {
  5843. return file.empty();
  5844. }
  5845. bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const {
  5846. return line == other.line && file == other.file;
  5847. }
  5848. bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const {
  5849. return line < other.line || ( line == other.line && file < other.file );
  5850. }
  5851. std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
  5852. #ifndef __GNUG__
  5853. os << info.file << "(" << info.line << ")";
  5854. #else
  5855. os << info.file << ":" << info.line;
  5856. #endif
  5857. return os;
  5858. }
  5859. void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) {
  5860. std::ostringstream oss;
  5861. oss << locationInfo << ": Internal Catch error: '" << message << "'";
  5862. if( alwaysTrue() )
  5863. throw std::logic_error( oss.str() );
  5864. }
  5865. }
  5866. // #included from: catch_section.hpp
  5867. #define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED
  5868. namespace Catch {
  5869. SectionInfo::SectionInfo
  5870. ( SourceLineInfo const& _lineInfo,
  5871. std::string const& _name,
  5872. std::string const& _description )
  5873. : name( _name ),
  5874. description( _description ),
  5875. lineInfo( _lineInfo )
  5876. {}
  5877. Section::Section( SectionInfo const& info )
  5878. : m_info( info ),
  5879. m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
  5880. {
  5881. m_timer.start();
  5882. }
  5883. Section::~Section() {
  5884. if( m_sectionIncluded )
  5885. getResultCapture().sectionEnded( m_info, m_assertions, m_timer.getElapsedSeconds() );
  5886. }
  5887. // This indicates whether the section should be executed or not
  5888. Section::operator bool() const {
  5889. return m_sectionIncluded;
  5890. }
  5891. } // end namespace Catch
  5892. // #included from: catch_debugger.hpp
  5893. #define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
  5894. #include <iostream>
  5895. #ifdef CATCH_PLATFORM_MAC
  5896. #include <assert.h>
  5897. #include <stdbool.h>
  5898. #include <sys/types.h>
  5899. #include <unistd.h>
  5900. #include <sys/sysctl.h>
  5901. namespace Catch{
  5902. // The following function is taken directly from the following technical note:
  5903. // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
  5904. // Returns true if the current process is being debugged (either
  5905. // running under the debugger or has a debugger attached post facto).
  5906. bool isDebuggerActive(){
  5907. int mib[4];
  5908. struct kinfo_proc info;
  5909. size_t size;
  5910. // Initialize the flags so that, if sysctl fails for some bizarre
  5911. // reason, we get a predictable result.
  5912. info.kp_proc.p_flag = 0;
  5913. // Initialize mib, which tells sysctl the info we want, in this case
  5914. // we're looking for information about a specific process ID.
  5915. mib[0] = CTL_KERN;
  5916. mib[1] = KERN_PROC;
  5917. mib[2] = KERN_PROC_PID;
  5918. mib[3] = getpid();
  5919. // Call sysctl.
  5920. size = sizeof(info);
  5921. if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0) != 0 ) {
  5922. Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
  5923. return false;
  5924. }
  5925. // We're being debugged if the P_TRACED flag is set.
  5926. return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
  5927. }
  5928. } // namespace Catch
  5929. #elif defined(_MSC_VER)
  5930. extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
  5931. namespace Catch {
  5932. bool isDebuggerActive() {
  5933. return IsDebuggerPresent() != 0;
  5934. }
  5935. }
  5936. #elif defined(__MINGW32__)
  5937. extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
  5938. namespace Catch {
  5939. bool isDebuggerActive() {
  5940. return IsDebuggerPresent() != 0;
  5941. }
  5942. }
  5943. #else
  5944. namespace Catch {
  5945. inline bool isDebuggerActive() { return false; }
  5946. }
  5947. #endif // Platform
  5948. #ifdef CATCH_PLATFORM_WINDOWS
  5949. extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA( const char* );
  5950. namespace Catch {
  5951. void writeToDebugConsole( std::string const& text ) {
  5952. ::OutputDebugStringA( text.c_str() );
  5953. }
  5954. }
  5955. #else
  5956. namespace Catch {
  5957. void writeToDebugConsole( std::string const& text ) {
  5958. // !TBD: Need a version for Mac/ XCode and other IDEs
  5959. Catch::cout() << text;
  5960. }
  5961. }
  5962. #endif // Platform
  5963. // #included from: catch_tostring.hpp
  5964. #define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED
  5965. namespace Catch {
  5966. namespace Detail {
  5967. std::string unprintableString = "{?}";
  5968. namespace {
  5969. struct Endianness {
  5970. enum Arch { Big, Little };
  5971. static Arch which() {
  5972. union _{
  5973. int asInt;
  5974. char asChar[sizeof (int)];
  5975. } u;
  5976. u.asInt = 1;
  5977. return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;
  5978. }
  5979. };
  5980. }
  5981. std::string rawMemoryToString( const void *object, std::size_t size )
  5982. {
  5983. // Reverse order for little endian architectures
  5984. int i = 0, end = static_cast<int>( size ), inc = 1;
  5985. if( Endianness::which() == Endianness::Little ) {
  5986. i = end-1;
  5987. end = inc = -1;
  5988. }
  5989. unsigned char const *bytes = static_cast<unsigned char const *>(object);
  5990. std::ostringstream os;
  5991. os << "0x" << std::setfill('0') << std::hex;
  5992. for( ; i != end; i += inc )
  5993. os << std::setw(2) << static_cast<unsigned>(bytes[i]);
  5994. return os.str();
  5995. }
  5996. }
  5997. std::string toString( std::string const& value ) {
  5998. std::string s = value;
  5999. if( getCurrentContext().getConfig()->showInvisibles() ) {
  6000. for(size_t i = 0; i < s.size(); ++i ) {
  6001. std::string subs;
  6002. switch( s[i] ) {
  6003. case '\n': subs = "\\n"; break;
  6004. case '\t': subs = "\\t"; break;
  6005. default: break;
  6006. }
  6007. if( !subs.empty() ) {
  6008. s = s.substr( 0, i ) + subs + s.substr( i+1 );
  6009. ++i;
  6010. }
  6011. }
  6012. }
  6013. return "\"" + s + "\"";
  6014. }
  6015. std::string toString( std::wstring const& value ) {
  6016. std::string s;
  6017. s.reserve( value.size() );
  6018. for(size_t i = 0; i < value.size(); ++i )
  6019. s += value[i] <= 0xff ? static_cast<char>( value[i] ) : '?';
  6020. return Catch::toString( s );
  6021. }
  6022. std::string toString( const char* const value ) {
  6023. return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" );
  6024. }
  6025. std::string toString( char* const value ) {
  6026. return Catch::toString( static_cast<const char*>( value ) );
  6027. }
  6028. std::string toString( const wchar_t* const value )
  6029. {
  6030. return value ? Catch::toString( std::wstring(value) ) : std::string( "{null string}" );
  6031. }
  6032. std::string toString( wchar_t* const value )
  6033. {
  6034. return Catch::toString( static_cast<const wchar_t*>( value ) );
  6035. }
  6036. std::string toString( int value ) {
  6037. std::ostringstream oss;
  6038. oss << value;
  6039. if( value >= 255 )
  6040. oss << " (0x" << std::hex << value << ")";
  6041. return oss.str();
  6042. }
  6043. std::string toString( unsigned long value ) {
  6044. std::ostringstream oss;
  6045. oss << value;
  6046. if( value >= 255 )
  6047. oss << " (0x" << std::hex << value << ")";
  6048. return oss.str();
  6049. }
  6050. std::string toString( unsigned int value ) {
  6051. return Catch::toString( static_cast<unsigned long>( value ) );
  6052. }
  6053. template<typename T>
  6054. std::string fpToString( T value, int precision ) {
  6055. std::ostringstream oss;
  6056. oss << std::setprecision( precision )
  6057. << std::fixed
  6058. << value;
  6059. std::string d = oss.str();
  6060. std::size_t i = d.find_last_not_of( '0' );
  6061. if( i != std::string::npos && i != d.size()-1 ) {
  6062. if( d[i] == '.' )
  6063. i++;
  6064. d = d.substr( 0, i+1 );
  6065. }
  6066. return d;
  6067. }
  6068. std::string toString( const double value ) {
  6069. return fpToString( value, 10 );
  6070. }
  6071. std::string toString( const float value ) {
  6072. return fpToString( value, 5 ) + "f";
  6073. }
  6074. std::string toString( bool value ) {
  6075. return value ? "true" : "false";
  6076. }
  6077. std::string toString( char value ) {
  6078. return value < ' '
  6079. ? toString( static_cast<unsigned int>( value ) )
  6080. : Detail::makeString( value );
  6081. }
  6082. std::string toString( signed char value ) {
  6083. return toString( static_cast<char>( value ) );
  6084. }
  6085. std::string toString( unsigned char value ) {
  6086. return toString( static_cast<char>( value ) );
  6087. }
  6088. #ifdef CATCH_CONFIG_CPP11_NULLPTR
  6089. std::string toString( std::nullptr_t ) {
  6090. return "nullptr";
  6091. }
  6092. #endif
  6093. #ifdef __OBJC__
  6094. std::string toString( NSString const * const& nsstring ) {
  6095. if( !nsstring )
  6096. return "nil";
  6097. return "@" + toString([nsstring UTF8String]);
  6098. }
  6099. std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ) {
  6100. if( !nsstring )
  6101. return "nil";
  6102. return "@" + toString([nsstring UTF8String]);
  6103. }
  6104. std::string toString( NSObject* const& nsObject ) {
  6105. return toString( [nsObject description] );
  6106. }
  6107. #endif
  6108. } // end namespace Catch
  6109. // #included from: catch_result_builder.hpp
  6110. #define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED
  6111. namespace Catch {
  6112. ResultBuilder::ResultBuilder( char const* macroName,
  6113. SourceLineInfo const& lineInfo,
  6114. char const* capturedExpression,
  6115. ResultDisposition::Flags resultDisposition )
  6116. : m_assertionInfo( macroName, lineInfo, capturedExpression, resultDisposition ),
  6117. m_shouldDebugBreak( false ),
  6118. m_shouldThrow( false )
  6119. {}
  6120. ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) {
  6121. m_data.resultType = result;
  6122. return *this;
  6123. }
  6124. ResultBuilder& ResultBuilder::setResultType( bool result ) {
  6125. m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed;
  6126. return *this;
  6127. }
  6128. ResultBuilder& ResultBuilder::setLhs( std::string const& lhs ) {
  6129. m_exprComponents.lhs = lhs;
  6130. return *this;
  6131. }
  6132. ResultBuilder& ResultBuilder::setRhs( std::string const& rhs ) {
  6133. m_exprComponents.rhs = rhs;
  6134. return *this;
  6135. }
  6136. ResultBuilder& ResultBuilder::setOp( std::string const& op ) {
  6137. m_exprComponents.op = op;
  6138. return *this;
  6139. }
  6140. void ResultBuilder::endExpression() {
  6141. m_exprComponents.testFalse = isFalseTest( m_assertionInfo.resultDisposition );
  6142. captureExpression();
  6143. }
  6144. void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) {
  6145. m_assertionInfo.resultDisposition = resultDisposition;
  6146. m_stream.oss << Catch::translateActiveException();
  6147. captureResult( ResultWas::ThrewException );
  6148. }
  6149. void ResultBuilder::captureResult( ResultWas::OfType resultType ) {
  6150. setResultType( resultType );
  6151. captureExpression();
  6152. }
  6153. void ResultBuilder::captureExpression() {
  6154. AssertionResult result = build();
  6155. getResultCapture().assertionEnded( result );
  6156. if( !result.isOk() ) {
  6157. if( getCurrentContext().getConfig()->shouldDebugBreak() )
  6158. m_shouldDebugBreak = true;
  6159. if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) )
  6160. m_shouldThrow = true;
  6161. }
  6162. }
  6163. void ResultBuilder::react() {
  6164. if( m_shouldThrow )
  6165. throw Catch::TestFailureException();
  6166. }
  6167. bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; }
  6168. bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); }
  6169. AssertionResult ResultBuilder::build() const
  6170. {
  6171. assert( m_data.resultType != ResultWas::Unknown );
  6172. AssertionResultData data = m_data;
  6173. // Flip bool results if testFalse is set
  6174. if( m_exprComponents.testFalse ) {
  6175. if( data.resultType == ResultWas::Ok )
  6176. data.resultType = ResultWas::ExpressionFailed;
  6177. else if( data.resultType == ResultWas::ExpressionFailed )
  6178. data.resultType = ResultWas::Ok;
  6179. }
  6180. data.message = m_stream.oss.str();
  6181. data.reconstructedExpression = reconstructExpression();
  6182. if( m_exprComponents.testFalse ) {
  6183. if( m_exprComponents.op == "" )
  6184. data.reconstructedExpression = "!" + data.reconstructedExpression;
  6185. else
  6186. data.reconstructedExpression = "!(" + data.reconstructedExpression + ")";
  6187. }
  6188. return AssertionResult( m_assertionInfo, data );
  6189. }
  6190. std::string ResultBuilder::reconstructExpression() const {
  6191. if( m_exprComponents.op == "" )
  6192. return m_exprComponents.lhs.empty() ? m_assertionInfo.capturedExpression : m_exprComponents.op + m_exprComponents.lhs;
  6193. else if( m_exprComponents.op == "matches" )
  6194. return m_exprComponents.lhs + " " + m_exprComponents.rhs;
  6195. else if( m_exprComponents.op != "!" ) {
  6196. if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 40 &&
  6197. m_exprComponents.lhs.find("\n") == std::string::npos &&
  6198. m_exprComponents.rhs.find("\n") == std::string::npos )
  6199. return m_exprComponents.lhs + " " + m_exprComponents.op + " " + m_exprComponents.rhs;
  6200. else
  6201. return m_exprComponents.lhs + "\n" + m_exprComponents.op + "\n" + m_exprComponents.rhs;
  6202. }
  6203. else
  6204. return "{can't expand - use " + m_assertionInfo.macroName + "_FALSE( " + m_assertionInfo.capturedExpression.substr(1) + " ) instead of " + m_assertionInfo.macroName + "( " + m_assertionInfo.capturedExpression + " ) for better diagnostics}";
  6205. }
  6206. } // end namespace Catch
  6207. // #included from: catch_tag_alias_registry.hpp
  6208. #define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED
  6209. // #included from: catch_tag_alias_registry.h
  6210. #define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED
  6211. #include <map>
  6212. namespace Catch {
  6213. class TagAliasRegistry : public ITagAliasRegistry {
  6214. public:
  6215. virtual ~TagAliasRegistry();
  6216. virtual Option<TagAlias> find( std::string const& alias ) const;
  6217. virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const;
  6218. void add( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
  6219. static TagAliasRegistry& get();
  6220. private:
  6221. std::map<std::string, TagAlias> m_registry;
  6222. };
  6223. } // end namespace Catch
  6224. #include <map>
  6225. #include <iostream>
  6226. namespace Catch {
  6227. TagAliasRegistry::~TagAliasRegistry() {}
  6228. Option<TagAlias> TagAliasRegistry::find( std::string const& alias ) const {
  6229. std::map<std::string, TagAlias>::const_iterator it = m_registry.find( alias );
  6230. if( it != m_registry.end() )
  6231. return it->second;
  6232. else
  6233. return Option<TagAlias>();
  6234. }
  6235. std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
  6236. std::string expandedTestSpec = unexpandedTestSpec;
  6237. for( std::map<std::string, TagAlias>::const_iterator it = m_registry.begin(), itEnd = m_registry.end();
  6238. it != itEnd;
  6239. ++it ) {
  6240. std::size_t pos = expandedTestSpec.find( it->first );
  6241. if( pos != std::string::npos ) {
  6242. expandedTestSpec = expandedTestSpec.substr( 0, pos ) +
  6243. it->second.tag +
  6244. expandedTestSpec.substr( pos + it->first.size() );
  6245. }
  6246. }
  6247. return expandedTestSpec;
  6248. }
  6249. void TagAliasRegistry::add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
  6250. if( !startsWith( alias, "[@" ) || !endsWith( alias, "]" ) ) {
  6251. std::ostringstream oss;
  6252. oss << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n" << lineInfo;
  6253. throw std::domain_error( oss.str().c_str() );
  6254. }
  6255. if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) {
  6256. std::ostringstream oss;
  6257. oss << "error: tag alias, \"" << alias << "\" already registered.\n"
  6258. << "\tFirst seen at " << find(alias)->lineInfo << "\n"
  6259. << "\tRedefined at " << lineInfo;
  6260. throw std::domain_error( oss.str().c_str() );
  6261. }
  6262. }
  6263. TagAliasRegistry& TagAliasRegistry::get() {
  6264. static TagAliasRegistry instance;
  6265. return instance;
  6266. }
  6267. ITagAliasRegistry::~ITagAliasRegistry() {}
  6268. ITagAliasRegistry const& ITagAliasRegistry::get() { return TagAliasRegistry::get(); }
  6269. RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
  6270. try {
  6271. TagAliasRegistry::get().add( alias, tag, lineInfo );
  6272. }
  6273. catch( std::exception& ex ) {
  6274. Colour colourGuard( Colour::Red );
  6275. Catch::cerr() << ex.what() << std::endl;
  6276. exit(1);
  6277. }
  6278. }
  6279. } // end namespace Catch
  6280. // #included from: ../reporters/catch_reporter_xml.hpp
  6281. #define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED
  6282. // #included from: catch_reporter_bases.hpp
  6283. #define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
  6284. #include <cstring>
  6285. namespace Catch {
  6286. struct StreamingReporterBase : SharedImpl<IStreamingReporter> {
  6287. StreamingReporterBase( ReporterConfig const& _config )
  6288. : m_config( _config.fullConfig() ),
  6289. stream( _config.stream() )
  6290. {}
  6291. virtual ~StreamingReporterBase();
  6292. virtual void noMatchingTestCases( std::string const& ) {}
  6293. virtual void testRunStarting( TestRunInfo const& _testRunInfo ) {
  6294. currentTestRunInfo = _testRunInfo;
  6295. }
  6296. virtual void testGroupStarting( GroupInfo const& _groupInfo ) {
  6297. currentGroupInfo = _groupInfo;
  6298. }
  6299. virtual void testCaseStarting( TestCaseInfo const& _testInfo ) {
  6300. currentTestCaseInfo = _testInfo;
  6301. }
  6302. virtual void sectionStarting( SectionInfo const& _sectionInfo ) {
  6303. m_sectionStack.push_back( _sectionInfo );
  6304. }
  6305. virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) {
  6306. m_sectionStack.pop_back();
  6307. }
  6308. virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) {
  6309. currentTestCaseInfo.reset();
  6310. }
  6311. virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) {
  6312. currentGroupInfo.reset();
  6313. }
  6314. virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) {
  6315. currentTestCaseInfo.reset();
  6316. currentGroupInfo.reset();
  6317. currentTestRunInfo.reset();
  6318. }
  6319. virtual void skipTest( TestCaseInfo const& ) {
  6320. // Don't do anything with this by default.
  6321. // It can optionally be overridden in the derived class.
  6322. }
  6323. Ptr<IConfig> m_config;
  6324. std::ostream& stream;
  6325. LazyStat<TestRunInfo> currentTestRunInfo;
  6326. LazyStat<GroupInfo> currentGroupInfo;
  6327. LazyStat<TestCaseInfo> currentTestCaseInfo;
  6328. std::vector<SectionInfo> m_sectionStack;
  6329. };
  6330. struct CumulativeReporterBase : SharedImpl<IStreamingReporter> {
  6331. template<typename T, typename ChildNodeT>
  6332. struct Node : SharedImpl<> {
  6333. explicit Node( T const& _value ) : value( _value ) {}
  6334. virtual ~Node() {}
  6335. typedef std::vector<Ptr<ChildNodeT> > ChildNodes;
  6336. T value;
  6337. ChildNodes children;
  6338. };
  6339. struct SectionNode : SharedImpl<> {
  6340. explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {}
  6341. virtual ~SectionNode();
  6342. bool operator == ( SectionNode const& other ) const {
  6343. return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
  6344. }
  6345. bool operator == ( Ptr<SectionNode> const& other ) const {
  6346. return operator==( *other );
  6347. }
  6348. SectionStats stats;
  6349. typedef std::vector<Ptr<SectionNode> > ChildSections;
  6350. typedef std::vector<AssertionStats> Assertions;
  6351. ChildSections childSections;
  6352. Assertions assertions;
  6353. std::string stdOut;
  6354. std::string stdErr;
  6355. };
  6356. struct BySectionInfo {
  6357. BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
  6358. BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
  6359. bool operator() ( Ptr<SectionNode> const& node ) const {
  6360. return node->stats.sectionInfo.lineInfo == m_other.lineInfo;
  6361. }
  6362. private:
  6363. void operator=( BySectionInfo const& );
  6364. SectionInfo const& m_other;
  6365. };
  6366. typedef Node<TestCaseStats, SectionNode> TestCaseNode;
  6367. typedef Node<TestGroupStats, TestCaseNode> TestGroupNode;
  6368. typedef Node<TestRunStats, TestGroupNode> TestRunNode;
  6369. CumulativeReporterBase( ReporterConfig const& _config )
  6370. : m_config( _config.fullConfig() ),
  6371. stream( _config.stream() )
  6372. {}
  6373. ~CumulativeReporterBase();
  6374. virtual void testRunStarting( TestRunInfo const& ) {}
  6375. virtual void testGroupStarting( GroupInfo const& ) {}
  6376. virtual void testCaseStarting( TestCaseInfo const& ) {}
  6377. virtual void sectionStarting( SectionInfo const& sectionInfo ) {
  6378. SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
  6379. Ptr<SectionNode> node;
  6380. if( m_sectionStack.empty() ) {
  6381. if( !m_rootSection )
  6382. m_rootSection = new SectionNode( incompleteStats );
  6383. node = m_rootSection;
  6384. }
  6385. else {
  6386. SectionNode& parentNode = *m_sectionStack.back();
  6387. SectionNode::ChildSections::const_iterator it =
  6388. std::find_if( parentNode.childSections.begin(),
  6389. parentNode.childSections.end(),
  6390. BySectionInfo( sectionInfo ) );
  6391. if( it == parentNode.childSections.end() ) {
  6392. node = new SectionNode( incompleteStats );
  6393. parentNode.childSections.push_back( node );
  6394. }
  6395. else
  6396. node = *it;
  6397. }
  6398. m_sectionStack.push_back( node );
  6399. m_deepestSection = node;
  6400. }
  6401. virtual void assertionStarting( AssertionInfo const& ) {}
  6402. virtual bool assertionEnded( AssertionStats const& assertionStats ) {
  6403. assert( !m_sectionStack.empty() );
  6404. SectionNode& sectionNode = *m_sectionStack.back();
  6405. sectionNode.assertions.push_back( assertionStats );
  6406. return true;
  6407. }
  6408. virtual void sectionEnded( SectionStats const& sectionStats ) {
  6409. assert( !m_sectionStack.empty() );
  6410. SectionNode& node = *m_sectionStack.back();
  6411. node.stats = sectionStats;
  6412. m_sectionStack.pop_back();
  6413. }
  6414. virtual void testCaseEnded( TestCaseStats const& testCaseStats ) {
  6415. Ptr<TestCaseNode> node = new TestCaseNode( testCaseStats );
  6416. assert( m_sectionStack.size() == 0 );
  6417. node->children.push_back( m_rootSection );
  6418. m_testCases.push_back( node );
  6419. m_rootSection.reset();
  6420. assert( m_deepestSection );
  6421. m_deepestSection->stdOut = testCaseStats.stdOut;
  6422. m_deepestSection->stdErr = testCaseStats.stdErr;
  6423. }
  6424. virtual void testGroupEnded( TestGroupStats const& testGroupStats ) {
  6425. Ptr<TestGroupNode> node = new TestGroupNode( testGroupStats );
  6426. node->children.swap( m_testCases );
  6427. m_testGroups.push_back( node );
  6428. }
  6429. virtual void testRunEnded( TestRunStats const& testRunStats ) {
  6430. Ptr<TestRunNode> node = new TestRunNode( testRunStats );
  6431. node->children.swap( m_testGroups );
  6432. m_testRuns.push_back( node );
  6433. testRunEndedCumulative();
  6434. }
  6435. virtual void testRunEndedCumulative() = 0;
  6436. virtual void skipTest( TestCaseInfo const& ) {}
  6437. Ptr<IConfig> m_config;
  6438. std::ostream& stream;
  6439. std::vector<AssertionStats> m_assertions;
  6440. std::vector<std::vector<Ptr<SectionNode> > > m_sections;
  6441. std::vector<Ptr<TestCaseNode> > m_testCases;
  6442. std::vector<Ptr<TestGroupNode> > m_testGroups;
  6443. std::vector<Ptr<TestRunNode> > m_testRuns;
  6444. Ptr<SectionNode> m_rootSection;
  6445. Ptr<SectionNode> m_deepestSection;
  6446. std::vector<Ptr<SectionNode> > m_sectionStack;
  6447. };
  6448. template<char C>
  6449. char const* getLineOfChars() {
  6450. static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
  6451. if( !*line ) {
  6452. memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
  6453. line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
  6454. }
  6455. return line;
  6456. }
  6457. } // end namespace Catch
  6458. // #included from: ../internal/catch_reporter_registrars.hpp
  6459. #define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
  6460. namespace Catch {
  6461. template<typename T>
  6462. class LegacyReporterRegistrar {
  6463. class ReporterFactory : public IReporterFactory {
  6464. virtual IStreamingReporter* create( ReporterConfig const& config ) const {
  6465. return new LegacyReporterAdapter( new T( config ) );
  6466. }
  6467. virtual std::string getDescription() const {
  6468. return T::getDescription();
  6469. }
  6470. };
  6471. public:
  6472. LegacyReporterRegistrar( std::string const& name ) {
  6473. getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
  6474. }
  6475. };
  6476. template<typename T>
  6477. class ReporterRegistrar {
  6478. class ReporterFactory : public IReporterFactory {
  6479. // *** Please Note ***:
  6480. // - If you end up here looking at a compiler error because it's trying to register
  6481. // your custom reporter class be aware that the native reporter interface has changed
  6482. // to IStreamingReporter. The "legacy" interface, IReporter, is still supported via
  6483. // an adapter. Just use REGISTER_LEGACY_REPORTER to take advantage of the adapter.
  6484. // However please consider updating to the new interface as the old one is now
  6485. // deprecated and will probably be removed quite soon!
  6486. // Please contact me via github if you have any questions at all about this.
  6487. // In fact, ideally, please contact me anyway to let me know you've hit this - as I have
  6488. // no idea who is actually using custom reporters at all (possibly no-one!).
  6489. // The new interface is designed to minimise exposure to interface changes in the future.
  6490. virtual IStreamingReporter* create( ReporterConfig const& config ) const {
  6491. return new T( config );
  6492. }
  6493. virtual std::string getDescription() const {
  6494. return T::getDescription();
  6495. }
  6496. };
  6497. public:
  6498. ReporterRegistrar( std::string const& name ) {
  6499. getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
  6500. }
  6501. };
  6502. }
  6503. #define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \
  6504. namespace{ Catch::LegacyReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
  6505. #define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \
  6506. namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
  6507. // #included from: ../internal/catch_xmlwriter.hpp
  6508. #define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED
  6509. #include <sstream>
  6510. #include <string>
  6511. #include <vector>
  6512. namespace Catch {
  6513. class XmlWriter {
  6514. public:
  6515. class ScopedElement {
  6516. public:
  6517. ScopedElement( XmlWriter* writer )
  6518. : m_writer( writer )
  6519. {}
  6520. ScopedElement( ScopedElement const& other )
  6521. : m_writer( other.m_writer ){
  6522. other.m_writer = NULL;
  6523. }
  6524. ~ScopedElement() {
  6525. if( m_writer )
  6526. m_writer->endElement();
  6527. }
  6528. ScopedElement& writeText( std::string const& text, bool indent = true ) {
  6529. m_writer->writeText( text, indent );
  6530. return *this;
  6531. }
  6532. template<typename T>
  6533. ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
  6534. m_writer->writeAttribute( name, attribute );
  6535. return *this;
  6536. }
  6537. private:
  6538. mutable XmlWriter* m_writer;
  6539. };
  6540. XmlWriter()
  6541. : m_tagIsOpen( false ),
  6542. m_needsNewline( false ),
  6543. m_os( &Catch::cout() )
  6544. {}
  6545. XmlWriter( std::ostream& os )
  6546. : m_tagIsOpen( false ),
  6547. m_needsNewline( false ),
  6548. m_os( &os )
  6549. {}
  6550. ~XmlWriter() {
  6551. while( !m_tags.empty() )
  6552. endElement();
  6553. }
  6554. XmlWriter& startElement( std::string const& name ) {
  6555. ensureTagClosed();
  6556. newlineIfNecessary();
  6557. stream() << m_indent << "<" << name;
  6558. m_tags.push_back( name );
  6559. m_indent += " ";
  6560. m_tagIsOpen = true;
  6561. return *this;
  6562. }
  6563. ScopedElement scopedElement( std::string const& name ) {
  6564. ScopedElement scoped( this );
  6565. startElement( name );
  6566. return scoped;
  6567. }
  6568. XmlWriter& endElement() {
  6569. newlineIfNecessary();
  6570. m_indent = m_indent.substr( 0, m_indent.size()-2 );
  6571. if( m_tagIsOpen ) {
  6572. stream() << "/>\n";
  6573. m_tagIsOpen = false;
  6574. }
  6575. else {
  6576. stream() << m_indent << "</" << m_tags.back() << ">\n";
  6577. }
  6578. m_tags.pop_back();
  6579. return *this;
  6580. }
  6581. XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) {
  6582. if( !name.empty() && !attribute.empty() ) {
  6583. stream() << " " << name << "=\"";
  6584. writeEncodedText( attribute );
  6585. stream() << "\"";
  6586. }
  6587. return *this;
  6588. }
  6589. XmlWriter& writeAttribute( std::string const& name, bool attribute ) {
  6590. stream() << " " << name << "=\"" << ( attribute ? "true" : "false" ) << "\"";
  6591. return *this;
  6592. }
  6593. template<typename T>
  6594. XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
  6595. if( !name.empty() )
  6596. stream() << " " << name << "=\"" << attribute << "\"";
  6597. return *this;
  6598. }
  6599. XmlWriter& writeText( std::string const& text, bool indent = true ) {
  6600. if( !text.empty() ){
  6601. bool tagWasOpen = m_tagIsOpen;
  6602. ensureTagClosed();
  6603. if( tagWasOpen && indent )
  6604. stream() << m_indent;
  6605. writeEncodedText( text );
  6606. m_needsNewline = true;
  6607. }
  6608. return *this;
  6609. }
  6610. XmlWriter& writeComment( std::string const& text ) {
  6611. ensureTagClosed();
  6612. stream() << m_indent << "<!--" << text << "-->";
  6613. m_needsNewline = true;
  6614. return *this;
  6615. }
  6616. XmlWriter& writeBlankLine() {
  6617. ensureTagClosed();
  6618. stream() << "\n";
  6619. return *this;
  6620. }
  6621. void setStream( std::ostream& os ) {
  6622. m_os = &os;
  6623. }
  6624. private:
  6625. XmlWriter( XmlWriter const& );
  6626. void operator=( XmlWriter const& );
  6627. std::ostream& stream() {
  6628. return *m_os;
  6629. }
  6630. void ensureTagClosed() {
  6631. if( m_tagIsOpen ) {
  6632. stream() << ">\n";
  6633. m_tagIsOpen = false;
  6634. }
  6635. }
  6636. void newlineIfNecessary() {
  6637. if( m_needsNewline ) {
  6638. stream() << "\n";
  6639. m_needsNewline = false;
  6640. }
  6641. }
  6642. void writeEncodedText( std::string const& text ) {
  6643. static const char* charsToEncode = "<&\"";
  6644. std::string mtext = text;
  6645. std::string::size_type pos = mtext.find_first_of( charsToEncode );
  6646. while( pos != std::string::npos ) {
  6647. stream() << mtext.substr( 0, pos );
  6648. switch( mtext[pos] ) {
  6649. case '<':
  6650. stream() << "&lt;";
  6651. break;
  6652. case '&':
  6653. stream() << "&amp;";
  6654. break;
  6655. case '\"':
  6656. stream() << "&quot;";
  6657. break;
  6658. }
  6659. mtext = mtext.substr( pos+1 );
  6660. pos = mtext.find_first_of( charsToEncode );
  6661. }
  6662. stream() << mtext;
  6663. }
  6664. bool m_tagIsOpen;
  6665. bool m_needsNewline;
  6666. std::vector<std::string> m_tags;
  6667. std::string m_indent;
  6668. std::ostream* m_os;
  6669. };
  6670. }
  6671. namespace Catch {
  6672. class XmlReporter : public StreamingReporterBase {
  6673. public:
  6674. XmlReporter( ReporterConfig const& _config )
  6675. : StreamingReporterBase( _config ),
  6676. m_sectionDepth( 0 )
  6677. {}
  6678. virtual ~XmlReporter();
  6679. static std::string getDescription() {
  6680. return "Reports test results as an XML document";
  6681. }
  6682. public: // StreamingReporterBase
  6683. virtual ReporterPreferences getPreferences() const {
  6684. ReporterPreferences prefs;
  6685. prefs.shouldRedirectStdOut = true;
  6686. return prefs;
  6687. }
  6688. virtual void noMatchingTestCases( std::string const& s ) {
  6689. StreamingReporterBase::noMatchingTestCases( s );
  6690. }
  6691. virtual void testRunStarting( TestRunInfo const& testInfo ) {
  6692. StreamingReporterBase::testRunStarting( testInfo );
  6693. m_xml.setStream( stream );
  6694. m_xml.startElement( "Catch" );
  6695. if( !m_config->name().empty() )
  6696. m_xml.writeAttribute( "name", m_config->name() );
  6697. }
  6698. virtual void testGroupStarting( GroupInfo const& groupInfo ) {
  6699. StreamingReporterBase::testGroupStarting( groupInfo );
  6700. m_xml.startElement( "Group" )
  6701. .writeAttribute( "name", groupInfo.name );
  6702. }
  6703. virtual void testCaseStarting( TestCaseInfo const& testInfo ) {
  6704. StreamingReporterBase::testCaseStarting(testInfo);
  6705. m_xml.startElement( "TestCase" ).writeAttribute( "name", trim( testInfo.name ) );
  6706. if ( m_config->showDurations() == ShowDurations::Always )
  6707. m_testCaseTimer.start();
  6708. }
  6709. virtual void sectionStarting( SectionInfo const& sectionInfo ) {
  6710. StreamingReporterBase::sectionStarting( sectionInfo );
  6711. if( m_sectionDepth++ > 0 ) {
  6712. m_xml.startElement( "Section" )
  6713. .writeAttribute( "name", trim( sectionInfo.name ) )
  6714. .writeAttribute( "description", sectionInfo.description );
  6715. }
  6716. }
  6717. virtual void assertionStarting( AssertionInfo const& ) { }
  6718. virtual bool assertionEnded( AssertionStats const& assertionStats ) {
  6719. const AssertionResult& assertionResult = assertionStats.assertionResult;
  6720. // Print any info messages in <Info> tags.
  6721. if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
  6722. for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
  6723. it != itEnd;
  6724. ++it ) {
  6725. if( it->type == ResultWas::Info ) {
  6726. m_xml.scopedElement( "Info" )
  6727. .writeText( it->message );
  6728. } else if ( it->type == ResultWas::Warning ) {
  6729. m_xml.scopedElement( "Warning" )
  6730. .writeText( it->message );
  6731. }
  6732. }
  6733. }
  6734. // Drop out if result was successful but we're not printing them.
  6735. if( !m_config->includeSuccessfulResults() && isOk(assertionResult.getResultType()) )
  6736. return true;
  6737. // Print the expression if there is one.
  6738. if( assertionResult.hasExpression() ) {
  6739. m_xml.startElement( "Expression" )
  6740. .writeAttribute( "success", assertionResult.succeeded() )
  6741. .writeAttribute( "type", assertionResult.getTestMacroName() )
  6742. .writeAttribute( "filename", assertionResult.getSourceInfo().file )
  6743. .writeAttribute( "line", assertionResult.getSourceInfo().line );
  6744. m_xml.scopedElement( "Original" )
  6745. .writeText( assertionResult.getExpression() );
  6746. m_xml.scopedElement( "Expanded" )
  6747. .writeText( assertionResult.getExpandedExpression() );
  6748. }
  6749. // And... Print a result applicable to each result type.
  6750. switch( assertionResult.getResultType() ) {
  6751. case ResultWas::ThrewException:
  6752. m_xml.scopedElement( "Exception" )
  6753. .writeAttribute( "filename", assertionResult.getSourceInfo().file )
  6754. .writeAttribute( "line", assertionResult.getSourceInfo().line )
  6755. .writeText( assertionResult.getMessage() );
  6756. break;
  6757. case ResultWas::FatalErrorCondition:
  6758. m_xml.scopedElement( "Fatal Error Condition" )
  6759. .writeAttribute( "filename", assertionResult.getSourceInfo().file )
  6760. .writeAttribute( "line", assertionResult.getSourceInfo().line )
  6761. .writeText( assertionResult.getMessage() );
  6762. break;
  6763. case ResultWas::Info:
  6764. m_xml.scopedElement( "Info" )
  6765. .writeText( assertionResult.getMessage() );
  6766. break;
  6767. case ResultWas::Warning:
  6768. // Warning will already have been written
  6769. break;
  6770. case ResultWas::ExplicitFailure:
  6771. m_xml.scopedElement( "Failure" )
  6772. .writeText( assertionResult.getMessage() );
  6773. break;
  6774. default:
  6775. break;
  6776. }
  6777. if( assertionResult.hasExpression() )
  6778. m_xml.endElement();
  6779. return true;
  6780. }
  6781. virtual void sectionEnded( SectionStats const& sectionStats ) {
  6782. StreamingReporterBase::sectionEnded( sectionStats );
  6783. if( --m_sectionDepth > 0 ) {
  6784. XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
  6785. e.writeAttribute( "successes", sectionStats.assertions.passed );
  6786. e.writeAttribute( "failures", sectionStats.assertions.failed );
  6787. e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
  6788. if ( m_config->showDurations() == ShowDurations::Always )
  6789. e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
  6790. m_xml.endElement();
  6791. }
  6792. }
  6793. virtual void testCaseEnded( TestCaseStats const& testCaseStats ) {
  6794. StreamingReporterBase::testCaseEnded( testCaseStats );
  6795. XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
  6796. e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
  6797. if ( m_config->showDurations() == ShowDurations::Always )
  6798. e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
  6799. m_xml.endElement();
  6800. }
  6801. virtual void testGroupEnded( TestGroupStats const& testGroupStats ) {
  6802. StreamingReporterBase::testGroupEnded( testGroupStats );
  6803. // TODO: Check testGroupStats.aborting and act accordingly.
  6804. m_xml.scopedElement( "OverallResults" )
  6805. .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
  6806. .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
  6807. .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
  6808. m_xml.endElement();
  6809. }
  6810. virtual void testRunEnded( TestRunStats const& testRunStats ) {
  6811. StreamingReporterBase::testRunEnded( testRunStats );
  6812. m_xml.scopedElement( "OverallResults" )
  6813. .writeAttribute( "successes", testRunStats.totals.assertions.passed )
  6814. .writeAttribute( "failures", testRunStats.totals.assertions.failed )
  6815. .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
  6816. m_xml.endElement();
  6817. }
  6818. private:
  6819. Timer m_testCaseTimer;
  6820. XmlWriter m_xml;
  6821. int m_sectionDepth;
  6822. };
  6823. INTERNAL_CATCH_REGISTER_REPORTER( "xml", XmlReporter )
  6824. } // end namespace Catch
  6825. // #included from: ../reporters/catch_reporter_junit.hpp
  6826. #define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED
  6827. #include <assert.h>
  6828. namespace Catch {
  6829. class JunitReporter : public CumulativeReporterBase {
  6830. public:
  6831. JunitReporter( ReporterConfig const& _config )
  6832. : CumulativeReporterBase( _config ),
  6833. xml( _config.stream() )
  6834. {}
  6835. ~JunitReporter();
  6836. static std::string getDescription() {
  6837. return "Reports test results in an XML format that looks like Ant's junitreport target";
  6838. }
  6839. virtual void noMatchingTestCases( std::string const& /*spec*/ ) {}
  6840. virtual ReporterPreferences getPreferences() const {
  6841. ReporterPreferences prefs;
  6842. prefs.shouldRedirectStdOut = true;
  6843. return prefs;
  6844. }
  6845. virtual void testRunStarting( TestRunInfo const& runInfo ) {
  6846. CumulativeReporterBase::testRunStarting( runInfo );
  6847. xml.startElement( "testsuites" );
  6848. }
  6849. virtual void testGroupStarting( GroupInfo const& groupInfo ) {
  6850. suiteTimer.start();
  6851. stdOutForSuite.str("");
  6852. stdErrForSuite.str("");
  6853. unexpectedExceptions = 0;
  6854. CumulativeReporterBase::testGroupStarting( groupInfo );
  6855. }
  6856. virtual bool assertionEnded( AssertionStats const& assertionStats ) {
  6857. if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException )
  6858. unexpectedExceptions++;
  6859. return CumulativeReporterBase::assertionEnded( assertionStats );
  6860. }
  6861. virtual void testCaseEnded( TestCaseStats const& testCaseStats ) {
  6862. stdOutForSuite << testCaseStats.stdOut;
  6863. stdErrForSuite << testCaseStats.stdErr;
  6864. CumulativeReporterBase::testCaseEnded( testCaseStats );
  6865. }
  6866. virtual void testGroupEnded( TestGroupStats const& testGroupStats ) {
  6867. double suiteTime = suiteTimer.getElapsedSeconds();
  6868. CumulativeReporterBase::testGroupEnded( testGroupStats );
  6869. writeGroup( *m_testGroups.back(), suiteTime );
  6870. }
  6871. virtual void testRunEndedCumulative() {
  6872. xml.endElement();
  6873. }
  6874. void writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
  6875. XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
  6876. TestGroupStats const& stats = groupNode.value;
  6877. xml.writeAttribute( "name", stats.groupInfo.name );
  6878. xml.writeAttribute( "errors", unexpectedExceptions );
  6879. xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
  6880. xml.writeAttribute( "tests", stats.totals.assertions.total() );
  6881. xml.writeAttribute( "hostname", "tbd" ); // !TBD
  6882. if( m_config->showDurations() == ShowDurations::Never )
  6883. xml.writeAttribute( "time", "" );
  6884. else
  6885. xml.writeAttribute( "time", suiteTime );
  6886. xml.writeAttribute( "timestamp", "tbd" ); // !TBD
  6887. // Write test cases
  6888. for( TestGroupNode::ChildNodes::const_iterator
  6889. it = groupNode.children.begin(), itEnd = groupNode.children.end();
  6890. it != itEnd;
  6891. ++it )
  6892. writeTestCase( **it );
  6893. xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite.str() ), false );
  6894. xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite.str() ), false );
  6895. }
  6896. void writeTestCase( TestCaseNode const& testCaseNode ) {
  6897. TestCaseStats const& stats = testCaseNode.value;
  6898. // All test cases have exactly one section - which represents the
  6899. // test case itself. That section may have 0-n nested sections
  6900. assert( testCaseNode.children.size() == 1 );
  6901. SectionNode const& rootSection = *testCaseNode.children.front();
  6902. std::string className = stats.testInfo.className;
  6903. if( className.empty() ) {
  6904. if( rootSection.childSections.empty() )
  6905. className = "global";
  6906. }
  6907. writeSection( className, "", rootSection );
  6908. }
  6909. void writeSection( std::string const& className,
  6910. std::string const& rootName,
  6911. SectionNode const& sectionNode ) {
  6912. std::string name = trim( sectionNode.stats.sectionInfo.name );
  6913. if( !rootName.empty() )
  6914. name = rootName + "/" + name;
  6915. if( !sectionNode.assertions.empty() ||
  6916. !sectionNode.stdOut.empty() ||
  6917. !sectionNode.stdErr.empty() ) {
  6918. XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
  6919. if( className.empty() ) {
  6920. xml.writeAttribute( "classname", name );
  6921. xml.writeAttribute( "name", "root" );
  6922. }
  6923. else {
  6924. xml.writeAttribute( "classname", className );
  6925. xml.writeAttribute( "name", name );
  6926. }
  6927. xml.writeAttribute( "time", Catch::toString( sectionNode.stats.durationInSeconds ) );
  6928. writeAssertions( sectionNode );
  6929. if( !sectionNode.stdOut.empty() )
  6930. xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false );
  6931. if( !sectionNode.stdErr.empty() )
  6932. xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false );
  6933. }
  6934. for( SectionNode::ChildSections::const_iterator
  6935. it = sectionNode.childSections.begin(),
  6936. itEnd = sectionNode.childSections.end();
  6937. it != itEnd;
  6938. ++it )
  6939. if( className.empty() )
  6940. writeSection( name, "", **it );
  6941. else
  6942. writeSection( className, name, **it );
  6943. }
  6944. void writeAssertions( SectionNode const& sectionNode ) {
  6945. for( SectionNode::Assertions::const_iterator
  6946. it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end();
  6947. it != itEnd;
  6948. ++it )
  6949. writeAssertion( *it );
  6950. }
  6951. void writeAssertion( AssertionStats const& stats ) {
  6952. AssertionResult const& result = stats.assertionResult;
  6953. if( !result.isOk() ) {
  6954. std::string elementName;
  6955. switch( result.getResultType() ) {
  6956. case ResultWas::ThrewException:
  6957. case ResultWas::FatalErrorCondition:
  6958. elementName = "error";
  6959. break;
  6960. case ResultWas::ExplicitFailure:
  6961. elementName = "failure";
  6962. break;
  6963. case ResultWas::ExpressionFailed:
  6964. elementName = "failure";
  6965. break;
  6966. case ResultWas::DidntThrowException:
  6967. elementName = "failure";
  6968. break;
  6969. // We should never see these here:
  6970. case ResultWas::Info:
  6971. case ResultWas::Warning:
  6972. case ResultWas::Ok:
  6973. case ResultWas::Unknown:
  6974. case ResultWas::FailureBit:
  6975. case ResultWas::Exception:
  6976. elementName = "internalError";
  6977. break;
  6978. }
  6979. XmlWriter::ScopedElement e = xml.scopedElement( elementName );
  6980. xml.writeAttribute( "message", result.getExpandedExpression() );
  6981. xml.writeAttribute( "type", result.getTestMacroName() );
  6982. std::ostringstream oss;
  6983. if( !result.getMessage().empty() )
  6984. oss << result.getMessage() << "\n";
  6985. for( std::vector<MessageInfo>::const_iterator
  6986. it = stats.infoMessages.begin(),
  6987. itEnd = stats.infoMessages.end();
  6988. it != itEnd;
  6989. ++it )
  6990. if( it->type == ResultWas::Info )
  6991. oss << it->message << "\n";
  6992. oss << "at " << result.getSourceInfo();
  6993. xml.writeText( oss.str(), false );
  6994. }
  6995. }
  6996. XmlWriter xml;
  6997. Timer suiteTimer;
  6998. std::ostringstream stdOutForSuite;
  6999. std::ostringstream stdErrForSuite;
  7000. unsigned int unexpectedExceptions;
  7001. };
  7002. INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter )
  7003. } // end namespace Catch
  7004. // #included from: ../reporters/catch_reporter_console.hpp
  7005. #define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED
  7006. namespace Catch {
  7007. struct ConsoleReporter : StreamingReporterBase {
  7008. ConsoleReporter( ReporterConfig const& _config )
  7009. : StreamingReporterBase( _config ),
  7010. m_headerPrinted( false )
  7011. {}
  7012. virtual ~ConsoleReporter();
  7013. static std::string getDescription() {
  7014. return "Reports test results as plain lines of text";
  7015. }
  7016. virtual ReporterPreferences getPreferences() const {
  7017. ReporterPreferences prefs;
  7018. prefs.shouldRedirectStdOut = false;
  7019. return prefs;
  7020. }
  7021. virtual void noMatchingTestCases( std::string const& spec ) {
  7022. stream << "No test cases matched '" << spec << "'" << std::endl;
  7023. }
  7024. virtual void assertionStarting( AssertionInfo const& ) {
  7025. }
  7026. virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
  7027. AssertionResult const& result = _assertionStats.assertionResult;
  7028. bool printInfoMessages = true;
  7029. // Drop out if result was successful and we're not printing those
  7030. if( !m_config->includeSuccessfulResults() && result.isOk() ) {
  7031. if( result.getResultType() != ResultWas::Warning )
  7032. return false;
  7033. printInfoMessages = false;
  7034. }
  7035. lazyPrint();
  7036. AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
  7037. printer.print();
  7038. stream << std::endl;
  7039. return true;
  7040. }
  7041. virtual void sectionStarting( SectionInfo const& _sectionInfo ) {
  7042. m_headerPrinted = false;
  7043. StreamingReporterBase::sectionStarting( _sectionInfo );
  7044. }
  7045. virtual void sectionEnded( SectionStats const& _sectionStats ) {
  7046. if( _sectionStats.missingAssertions ) {
  7047. lazyPrint();
  7048. Colour colour( Colour::ResultError );
  7049. if( m_sectionStack.size() > 1 )
  7050. stream << "\nNo assertions in section";
  7051. else
  7052. stream << "\nNo assertions in test case";
  7053. stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
  7054. }
  7055. if( m_headerPrinted ) {
  7056. if( m_config->showDurations() == ShowDurations::Always )
  7057. stream << "Completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
  7058. m_headerPrinted = false;
  7059. }
  7060. else {
  7061. if( m_config->showDurations() == ShowDurations::Always )
  7062. stream << _sectionStats.sectionInfo.name << " completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
  7063. }
  7064. StreamingReporterBase::sectionEnded( _sectionStats );
  7065. }
  7066. virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) {
  7067. StreamingReporterBase::testCaseEnded( _testCaseStats );
  7068. m_headerPrinted = false;
  7069. }
  7070. virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) {
  7071. if( currentGroupInfo.used ) {
  7072. printSummaryDivider();
  7073. stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
  7074. printTotals( _testGroupStats.totals );
  7075. stream << "\n" << std::endl;
  7076. }
  7077. StreamingReporterBase::testGroupEnded( _testGroupStats );
  7078. }
  7079. virtual void testRunEnded( TestRunStats const& _testRunStats ) {
  7080. printTotalsDivider( _testRunStats.totals );
  7081. printTotals( _testRunStats.totals );
  7082. stream << std::endl;
  7083. StreamingReporterBase::testRunEnded( _testRunStats );
  7084. }
  7085. private:
  7086. class AssertionPrinter {
  7087. void operator= ( AssertionPrinter const& );
  7088. public:
  7089. AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
  7090. : stream( _stream ),
  7091. stats( _stats ),
  7092. result( _stats.assertionResult ),
  7093. colour( Colour::None ),
  7094. message( result.getMessage() ),
  7095. messages( _stats.infoMessages ),
  7096. printInfoMessages( _printInfoMessages )
  7097. {
  7098. switch( result.getResultType() ) {
  7099. case ResultWas::Ok:
  7100. colour = Colour::Success;
  7101. passOrFail = "PASSED";
  7102. //if( result.hasMessage() )
  7103. if( _stats.infoMessages.size() == 1 )
  7104. messageLabel = "with message";
  7105. if( _stats.infoMessages.size() > 1 )
  7106. messageLabel = "with messages";
  7107. break;
  7108. case ResultWas::ExpressionFailed:
  7109. if( result.isOk() ) {
  7110. colour = Colour::Success;
  7111. passOrFail = "FAILED - but was ok";
  7112. }
  7113. else {
  7114. colour = Colour::Error;
  7115. passOrFail = "FAILED";
  7116. }
  7117. if( _stats.infoMessages.size() == 1 )
  7118. messageLabel = "with message";
  7119. if( _stats.infoMessages.size() > 1 )
  7120. messageLabel = "with messages";
  7121. break;
  7122. case ResultWas::ThrewException:
  7123. colour = Colour::Error;
  7124. passOrFail = "FAILED";
  7125. messageLabel = "due to unexpected exception with message";
  7126. break;
  7127. case ResultWas::FatalErrorCondition:
  7128. colour = Colour::Error;
  7129. passOrFail = "FAILED";
  7130. messageLabel = "due to a fatal error condition";
  7131. break;
  7132. case ResultWas::DidntThrowException:
  7133. colour = Colour::Error;
  7134. passOrFail = "FAILED";
  7135. messageLabel = "because no exception was thrown where one was expected";
  7136. break;
  7137. case ResultWas::Info:
  7138. messageLabel = "info";
  7139. break;
  7140. case ResultWas::Warning:
  7141. messageLabel = "warning";
  7142. break;
  7143. case ResultWas::ExplicitFailure:
  7144. passOrFail = "FAILED";
  7145. colour = Colour::Error;
  7146. if( _stats.infoMessages.size() == 1 )
  7147. messageLabel = "explicitly with message";
  7148. if( _stats.infoMessages.size() > 1 )
  7149. messageLabel = "explicitly with messages";
  7150. break;
  7151. // These cases are here to prevent compiler warnings
  7152. case ResultWas::Unknown:
  7153. case ResultWas::FailureBit:
  7154. case ResultWas::Exception:
  7155. passOrFail = "** internal error **";
  7156. colour = Colour::Error;
  7157. break;
  7158. }
  7159. }
  7160. void print() const {
  7161. printSourceInfo();
  7162. if( stats.totals.assertions.total() > 0 ) {
  7163. if( result.isOk() )
  7164. stream << "\n";
  7165. printResultType();
  7166. printOriginalExpression();
  7167. printReconstructedExpression();
  7168. }
  7169. else {
  7170. stream << "\n";
  7171. }
  7172. printMessage();
  7173. }
  7174. private:
  7175. void printResultType() const {
  7176. if( !passOrFail.empty() ) {
  7177. Colour colourGuard( colour );
  7178. stream << passOrFail << ":\n";
  7179. }
  7180. }
  7181. void printOriginalExpression() const {
  7182. if( result.hasExpression() ) {
  7183. Colour colourGuard( Colour::OriginalExpression );
  7184. stream << " ";
  7185. stream << result.getExpressionInMacro();
  7186. stream << "\n";
  7187. }
  7188. }
  7189. void printReconstructedExpression() const {
  7190. if( result.hasExpandedExpression() ) {
  7191. stream << "with expansion:\n";
  7192. Colour colourGuard( Colour::ReconstructedExpression );
  7193. stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << "\n";
  7194. }
  7195. }
  7196. void printMessage() const {
  7197. if( !messageLabel.empty() )
  7198. stream << messageLabel << ":" << "\n";
  7199. for( std::vector<MessageInfo>::const_iterator it = messages.begin(), itEnd = messages.end();
  7200. it != itEnd;
  7201. ++it ) {
  7202. // If this assertion is a warning ignore any INFO messages
  7203. if( printInfoMessages || it->type != ResultWas::Info )
  7204. stream << Text( it->message, TextAttributes().setIndent(2) ) << "\n";
  7205. }
  7206. }
  7207. void printSourceInfo() const {
  7208. Colour colourGuard( Colour::FileName );
  7209. stream << result.getSourceInfo() << ": ";
  7210. }
  7211. std::ostream& stream;
  7212. AssertionStats const& stats;
  7213. AssertionResult const& result;
  7214. Colour::Code colour;
  7215. std::string passOrFail;
  7216. std::string messageLabel;
  7217. std::string message;
  7218. std::vector<MessageInfo> messages;
  7219. bool printInfoMessages;
  7220. };
  7221. void lazyPrint() {
  7222. if( !currentTestRunInfo.used )
  7223. lazyPrintRunInfo();
  7224. if( !currentGroupInfo.used )
  7225. lazyPrintGroupInfo();
  7226. if( !m_headerPrinted ) {
  7227. printTestCaseAndSectionHeader();
  7228. m_headerPrinted = true;
  7229. }
  7230. }
  7231. void lazyPrintRunInfo() {
  7232. stream << "\n" << getLineOfChars<'~'>() << "\n";
  7233. Colour colour( Colour::SecondaryText );
  7234. stream << currentTestRunInfo->name
  7235. << " is a Catch v" << libraryVersion.majorVersion << "."
  7236. << libraryVersion.minorVersion << " b"
  7237. << libraryVersion.buildNumber;
  7238. if( libraryVersion.branchName != std::string( "master" ) )
  7239. stream << " (" << libraryVersion.branchName << ")";
  7240. stream << " host application.\n"
  7241. << "Run with -? for options\n\n";
  7242. if( m_config->rngSeed() != 0 )
  7243. stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
  7244. currentTestRunInfo.used = true;
  7245. }
  7246. void lazyPrintGroupInfo() {
  7247. if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) {
  7248. printClosedHeader( "Group: " + currentGroupInfo->name );
  7249. currentGroupInfo.used = true;
  7250. }
  7251. }
  7252. void printTestCaseAndSectionHeader() {
  7253. assert( !m_sectionStack.empty() );
  7254. printOpenHeader( currentTestCaseInfo->name );
  7255. if( m_sectionStack.size() > 1 ) {
  7256. Colour colourGuard( Colour::Headers );
  7257. std::vector<SectionInfo>::const_iterator
  7258. it = m_sectionStack.begin()+1, // Skip first section (test case)
  7259. itEnd = m_sectionStack.end();
  7260. for( ; it != itEnd; ++it )
  7261. printHeaderString( it->name, 2 );
  7262. }
  7263. SourceLineInfo lineInfo = m_sectionStack.front().lineInfo;
  7264. if( !lineInfo.empty() ){
  7265. stream << getLineOfChars<'-'>() << "\n";
  7266. Colour colourGuard( Colour::FileName );
  7267. stream << lineInfo << "\n";
  7268. }
  7269. stream << getLineOfChars<'.'>() << "\n" << std::endl;
  7270. }
  7271. void printClosedHeader( std::string const& _name ) {
  7272. printOpenHeader( _name );
  7273. stream << getLineOfChars<'.'>() << "\n";
  7274. }
  7275. void printOpenHeader( std::string const& _name ) {
  7276. stream << getLineOfChars<'-'>() << "\n";
  7277. {
  7278. Colour colourGuard( Colour::Headers );
  7279. printHeaderString( _name );
  7280. }
  7281. }
  7282. // if string has a : in first line will set indent to follow it on
  7283. // subsequent lines
  7284. void printHeaderString( std::string const& _string, std::size_t indent = 0 ) {
  7285. std::size_t i = _string.find( ": " );
  7286. if( i != std::string::npos )
  7287. i+=2;
  7288. else
  7289. i = 0;
  7290. stream << Text( _string, TextAttributes()
  7291. .setIndent( indent+i)
  7292. .setInitialIndent( indent ) ) << "\n";
  7293. }
  7294. struct SummaryColumn {
  7295. SummaryColumn( std::string const& _label, Colour::Code _colour )
  7296. : label( _label ),
  7297. colour( _colour )
  7298. {}
  7299. SummaryColumn addRow( std::size_t count ) {
  7300. std::ostringstream oss;
  7301. oss << count;
  7302. std::string row = oss.str();
  7303. for( std::vector<std::string>::iterator it = rows.begin(); it != rows.end(); ++it ) {
  7304. while( it->size() < row.size() )
  7305. *it = " " + *it;
  7306. while( it->size() > row.size() )
  7307. row = " " + row;
  7308. }
  7309. rows.push_back( row );
  7310. return *this;
  7311. }
  7312. std::string label;
  7313. Colour::Code colour;
  7314. std::vector<std::string> rows;
  7315. };
  7316. void printTotals( Totals const& totals ) {
  7317. if( totals.testCases.total() == 0 ) {
  7318. stream << Colour( Colour::Warning ) << "No tests ran\n";
  7319. }
  7320. else if( totals.assertions.total() > 0 && totals.assertions.allPassed() ) {
  7321. stream << Colour( Colour::ResultSuccess ) << "All tests passed";
  7322. stream << " ("
  7323. << pluralise( totals.assertions.passed, "assertion" ) << " in "
  7324. << pluralise( totals.testCases.passed, "test case" ) << ")"
  7325. << "\n";
  7326. }
  7327. else {
  7328. std::vector<SummaryColumn> columns;
  7329. columns.push_back( SummaryColumn( "", Colour::None )
  7330. .addRow( totals.testCases.total() )
  7331. .addRow( totals.assertions.total() ) );
  7332. columns.push_back( SummaryColumn( "passed", Colour::Success )
  7333. .addRow( totals.testCases.passed )
  7334. .addRow( totals.assertions.passed ) );
  7335. columns.push_back( SummaryColumn( "failed", Colour::ResultError )
  7336. .addRow( totals.testCases.failed )
  7337. .addRow( totals.assertions.failed ) );
  7338. columns.push_back( SummaryColumn( "failed as expected", Colour::ResultExpectedFailure )
  7339. .addRow( totals.testCases.failedButOk )
  7340. .addRow( totals.assertions.failedButOk ) );
  7341. printSummaryRow( "test cases", columns, 0 );
  7342. printSummaryRow( "assertions", columns, 1 );
  7343. }
  7344. }
  7345. void printSummaryRow( std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row ) {
  7346. for( std::vector<SummaryColumn>::const_iterator it = cols.begin(); it != cols.end(); ++it ) {
  7347. std::string value = it->rows[row];
  7348. if( it->label.empty() ) {
  7349. stream << label << ": ";
  7350. if( value != "0" )
  7351. stream << value;
  7352. else
  7353. stream << Colour( Colour::Warning ) << "- none -";
  7354. }
  7355. else if( value != "0" ) {
  7356. stream << Colour( Colour::LightGrey ) << " | ";
  7357. stream << Colour( it->colour )
  7358. << value << " " << it->label;
  7359. }
  7360. }
  7361. stream << "\n";
  7362. }
  7363. static std::size_t makeRatio( std::size_t number, std::size_t total ) {
  7364. std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0;
  7365. return ( ratio == 0 && number > 0 ) ? 1 : ratio;
  7366. }
  7367. static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) {
  7368. if( i > j && i > k )
  7369. return i;
  7370. else if( j > k )
  7371. return j;
  7372. else
  7373. return k;
  7374. }
  7375. void printTotalsDivider( Totals const& totals ) {
  7376. if( totals.testCases.total() > 0 ) {
  7377. std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() );
  7378. std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() );
  7379. std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() );
  7380. while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 )
  7381. findMax( failedRatio, failedButOkRatio, passedRatio )++;
  7382. while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 )
  7383. findMax( failedRatio, failedButOkRatio, passedRatio )--;
  7384. stream << Colour( Colour::Error ) << std::string( failedRatio, '=' );
  7385. stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio, '=' );
  7386. if( totals.testCases.allPassed() )
  7387. stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio, '=' );
  7388. else
  7389. stream << Colour( Colour::Success ) << std::string( passedRatio, '=' );
  7390. }
  7391. else {
  7392. stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' );
  7393. }
  7394. stream << "\n";
  7395. }
  7396. void printSummaryDivider() {
  7397. stream << getLineOfChars<'-'>() << "\n";
  7398. }
  7399. private:
  7400. bool m_headerPrinted;
  7401. };
  7402. INTERNAL_CATCH_REGISTER_REPORTER( "console", ConsoleReporter )
  7403. } // end namespace Catch
  7404. // #included from: ../reporters/catch_reporter_compact.hpp
  7405. #define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED
  7406. namespace Catch {
  7407. struct CompactReporter : StreamingReporterBase {
  7408. CompactReporter( ReporterConfig const& _config )
  7409. : StreamingReporterBase( _config )
  7410. {}
  7411. virtual ~CompactReporter();
  7412. static std::string getDescription() {
  7413. return "Reports test results on a single line, suitable for IDEs";
  7414. }
  7415. virtual ReporterPreferences getPreferences() const {
  7416. ReporterPreferences prefs;
  7417. prefs.shouldRedirectStdOut = false;
  7418. return prefs;
  7419. }
  7420. virtual void noMatchingTestCases( std::string const& spec ) {
  7421. stream << "No test cases matched '" << spec << "'" << std::endl;
  7422. }
  7423. virtual void assertionStarting( AssertionInfo const& ) {
  7424. }
  7425. virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
  7426. AssertionResult const& result = _assertionStats.assertionResult;
  7427. bool printInfoMessages = true;
  7428. // Drop out if result was successful and we're not printing those
  7429. if( !m_config->includeSuccessfulResults() && result.isOk() ) {
  7430. if( result.getResultType() != ResultWas::Warning )
  7431. return false;
  7432. printInfoMessages = false;
  7433. }
  7434. AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
  7435. printer.print();
  7436. stream << std::endl;
  7437. return true;
  7438. }
  7439. virtual void testRunEnded( TestRunStats const& _testRunStats ) {
  7440. printTotals( _testRunStats.totals );
  7441. stream << "\n" << std::endl;
  7442. StreamingReporterBase::testRunEnded( _testRunStats );
  7443. }
  7444. private:
  7445. class AssertionPrinter {
  7446. void operator= ( AssertionPrinter const& );
  7447. public:
  7448. AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
  7449. : stream( _stream )
  7450. , stats( _stats )
  7451. , result( _stats.assertionResult )
  7452. , messages( _stats.infoMessages )
  7453. , itMessage( _stats.infoMessages.begin() )
  7454. , printInfoMessages( _printInfoMessages )
  7455. {}
  7456. void print() {
  7457. printSourceInfo();
  7458. itMessage = messages.begin();
  7459. switch( result.getResultType() ) {
  7460. case ResultWas::Ok:
  7461. printResultType( Colour::ResultSuccess, passedString() );
  7462. printOriginalExpression();
  7463. printReconstructedExpression();
  7464. if ( ! result.hasExpression() )
  7465. printRemainingMessages( Colour::None );
  7466. else
  7467. printRemainingMessages();
  7468. break;
  7469. case ResultWas::ExpressionFailed:
  7470. if( result.isOk() )
  7471. printResultType( Colour::ResultSuccess, failedString() + std::string( " - but was ok" ) );
  7472. else
  7473. printResultType( Colour::Error, failedString() );
  7474. printOriginalExpression();
  7475. printReconstructedExpression();
  7476. printRemainingMessages();
  7477. break;
  7478. case ResultWas::ThrewException:
  7479. printResultType( Colour::Error, failedString() );
  7480. printIssue( "unexpected exception with message:" );
  7481. printMessage();
  7482. printExpressionWas();
  7483. printRemainingMessages();
  7484. break;
  7485. case ResultWas::FatalErrorCondition:
  7486. printResultType( Colour::Error, failedString() );
  7487. printIssue( "fatal error condition with message:" );
  7488. printMessage();
  7489. printExpressionWas();
  7490. printRemainingMessages();
  7491. break;
  7492. case ResultWas::DidntThrowException:
  7493. printResultType( Colour::Error, failedString() );
  7494. printIssue( "expected exception, got none" );
  7495. printExpressionWas();
  7496. printRemainingMessages();
  7497. break;
  7498. case ResultWas::Info:
  7499. printResultType( Colour::None, "info" );
  7500. printMessage();
  7501. printRemainingMessages();
  7502. break;
  7503. case ResultWas::Warning:
  7504. printResultType( Colour::None, "warning" );
  7505. printMessage();
  7506. printRemainingMessages();
  7507. break;
  7508. case ResultWas::ExplicitFailure:
  7509. printResultType( Colour::Error, failedString() );
  7510. printIssue( "explicitly" );
  7511. printRemainingMessages( Colour::None );
  7512. break;
  7513. // These cases are here to prevent compiler warnings
  7514. case ResultWas::Unknown:
  7515. case ResultWas::FailureBit:
  7516. case ResultWas::Exception:
  7517. printResultType( Colour::Error, "** internal error **" );
  7518. break;
  7519. }
  7520. }
  7521. private:
  7522. // Colour::LightGrey
  7523. static Colour::Code dimColour() { return Colour::FileName; }
  7524. #ifdef CATCH_PLATFORM_MAC
  7525. static const char* failedString() { return "FAILED"; }
  7526. static const char* passedString() { return "PASSED"; }
  7527. #else
  7528. static const char* failedString() { return "failed"; }
  7529. static const char* passedString() { return "passed"; }
  7530. #endif
  7531. void printSourceInfo() const {
  7532. Colour colourGuard( Colour::FileName );
  7533. stream << result.getSourceInfo() << ":";
  7534. }
  7535. void printResultType( Colour::Code colour, std::string passOrFail ) const {
  7536. if( !passOrFail.empty() ) {
  7537. {
  7538. Colour colourGuard( colour );
  7539. stream << " " << passOrFail;
  7540. }
  7541. stream << ":";
  7542. }
  7543. }
  7544. void printIssue( std::string issue ) const {
  7545. stream << " " << issue;
  7546. }
  7547. void printExpressionWas() {
  7548. if( result.hasExpression() ) {
  7549. stream << ";";
  7550. {
  7551. Colour colour( dimColour() );
  7552. stream << " expression was:";
  7553. }
  7554. printOriginalExpression();
  7555. }
  7556. }
  7557. void printOriginalExpression() const {
  7558. if( result.hasExpression() ) {
  7559. stream << " " << result.getExpression();
  7560. }
  7561. }
  7562. void printReconstructedExpression() const {
  7563. if( result.hasExpandedExpression() ) {
  7564. {
  7565. Colour colour( dimColour() );
  7566. stream << " for: ";
  7567. }
  7568. stream << result.getExpandedExpression();
  7569. }
  7570. }
  7571. void printMessage() {
  7572. if ( itMessage != messages.end() ) {
  7573. stream << " '" << itMessage->message << "'";
  7574. ++itMessage;
  7575. }
  7576. }
  7577. void printRemainingMessages( Colour::Code colour = dimColour() ) {
  7578. if ( itMessage == messages.end() )
  7579. return;
  7580. // using messages.end() directly yields compilation error:
  7581. std::vector<MessageInfo>::const_iterator itEnd = messages.end();
  7582. const std::size_t N = static_cast<std::size_t>( std::distance( itMessage, itEnd ) );
  7583. {
  7584. Colour colourGuard( colour );
  7585. stream << " with " << pluralise( N, "message" ) << ":";
  7586. }
  7587. for(; itMessage != itEnd; ) {
  7588. // If this assertion is a warning ignore any INFO messages
  7589. if( printInfoMessages || itMessage->type != ResultWas::Info ) {
  7590. stream << " '" << itMessage->message << "'";
  7591. if ( ++itMessage != itEnd ) {
  7592. Colour colourGuard( dimColour() );
  7593. stream << " and";
  7594. }
  7595. }
  7596. }
  7597. }
  7598. private:
  7599. std::ostream& stream;
  7600. AssertionStats const& stats;
  7601. AssertionResult const& result;
  7602. std::vector<MessageInfo> messages;
  7603. std::vector<MessageInfo>::const_iterator itMessage;
  7604. bool printInfoMessages;
  7605. };
  7606. // Colour, message variants:
  7607. // - white: No tests ran.
  7608. // - red: Failed [both/all] N test cases, failed [both/all] M assertions.
  7609. // - white: Passed [both/all] N test cases (no assertions).
  7610. // - red: Failed N tests cases, failed M assertions.
  7611. // - green: Passed [both/all] N tests cases with M assertions.
  7612. std::string bothOrAll( std::size_t count ) const {
  7613. return count == 1 ? "" : count == 2 ? "both " : "all " ;
  7614. }
  7615. void printTotals( const Totals& totals ) const {
  7616. if( totals.testCases.total() == 0 ) {
  7617. stream << "No tests ran.";
  7618. }
  7619. else if( totals.testCases.failed == totals.testCases.total() ) {
  7620. Colour colour( Colour::ResultError );
  7621. const std::string qualify_assertions_failed =
  7622. totals.assertions.failed == totals.assertions.total() ?
  7623. bothOrAll( totals.assertions.failed ) : "";
  7624. stream <<
  7625. "Failed " << bothOrAll( totals.testCases.failed )
  7626. << pluralise( totals.testCases.failed, "test case" ) << ", "
  7627. "failed " << qualify_assertions_failed <<
  7628. pluralise( totals.assertions.failed, "assertion" ) << ".";
  7629. }
  7630. else if( totals.assertions.total() == 0 ) {
  7631. stream <<
  7632. "Passed " << bothOrAll( totals.testCases.total() )
  7633. << pluralise( totals.testCases.total(), "test case" )
  7634. << " (no assertions).";
  7635. }
  7636. else if( totals.assertions.failed ) {
  7637. Colour colour( Colour::ResultError );
  7638. stream <<
  7639. "Failed " << pluralise( totals.testCases.failed, "test case" ) << ", "
  7640. "failed " << pluralise( totals.assertions.failed, "assertion" ) << ".";
  7641. }
  7642. else {
  7643. Colour colour( Colour::ResultSuccess );
  7644. stream <<
  7645. "Passed " << bothOrAll( totals.testCases.passed )
  7646. << pluralise( totals.testCases.passed, "test case" ) <<
  7647. " with " << pluralise( totals.assertions.passed, "assertion" ) << ".";
  7648. }
  7649. }
  7650. };
  7651. INTERNAL_CATCH_REGISTER_REPORTER( "compact", CompactReporter )
  7652. } // end namespace Catch
  7653. namespace Catch {
  7654. NonCopyable::~NonCopyable() {}
  7655. IShared::~IShared() {}
  7656. StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {}
  7657. IContext::~IContext() {}
  7658. IResultCapture::~IResultCapture() {}
  7659. ITestCase::~ITestCase() {}
  7660. ITestCaseRegistry::~ITestCaseRegistry() {}
  7661. IRegistryHub::~IRegistryHub() {}
  7662. IMutableRegistryHub::~IMutableRegistryHub() {}
  7663. IExceptionTranslator::~IExceptionTranslator() {}
  7664. IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {}
  7665. IReporter::~IReporter() {}
  7666. IReporterFactory::~IReporterFactory() {}
  7667. IReporterRegistry::~IReporterRegistry() {}
  7668. IStreamingReporter::~IStreamingReporter() {}
  7669. AssertionStats::~AssertionStats() {}
  7670. SectionStats::~SectionStats() {}
  7671. TestCaseStats::~TestCaseStats() {}
  7672. TestGroupStats::~TestGroupStats() {}
  7673. TestRunStats::~TestRunStats() {}
  7674. CumulativeReporterBase::SectionNode::~SectionNode() {}
  7675. CumulativeReporterBase::~CumulativeReporterBase() {}
  7676. StreamingReporterBase::~StreamingReporterBase() {}
  7677. ConsoleReporter::~ConsoleReporter() {}
  7678. CompactReporter::~CompactReporter() {}
  7679. IRunner::~IRunner() {}
  7680. IMutableContext::~IMutableContext() {}
  7681. IConfig::~IConfig() {}
  7682. XmlReporter::~XmlReporter() {}
  7683. JunitReporter::~JunitReporter() {}
  7684. TestRegistry::~TestRegistry() {}
  7685. FreeFunctionTestCase::~FreeFunctionTestCase() {}
  7686. IGeneratorInfo::~IGeneratorInfo() {}
  7687. IGeneratorsForTest::~IGeneratorsForTest() {}
  7688. TestSpec::Pattern::~Pattern() {}
  7689. TestSpec::NamePattern::~NamePattern() {}
  7690. TestSpec::TagPattern::~TagPattern() {}
  7691. TestSpec::ExcludedPattern::~ExcludedPattern() {}
  7692. Matchers::Impl::StdString::Equals::~Equals() {}
  7693. Matchers::Impl::StdString::Contains::~Contains() {}
  7694. Matchers::Impl::StdString::StartsWith::~StartsWith() {}
  7695. Matchers::Impl::StdString::EndsWith::~EndsWith() {}
  7696. void Config::dummy() {}
  7697. }
  7698. #ifdef __clang__
  7699. #pragma clang diagnostic pop
  7700. #endif
  7701. #endif
  7702. #ifdef CATCH_CONFIG_MAIN
  7703. // #included from: internal/catch_default_main.hpp
  7704. #define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED
  7705. #ifndef __OBJC__
  7706. // Standard C/C++ main entry point
  7707. int main (int argc, char * const argv[]) {
  7708. return Catch::Session().run( argc, argv );
  7709. }
  7710. #else // __OBJC__
  7711. // Objective-C entry point
  7712. int main (int argc, char * const argv[]) {
  7713. #if !CATCH_ARC_ENABLED
  7714. NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
  7715. #endif
  7716. Catch::registerTestMethods();
  7717. int result = Catch::Session().run( argc, (char* const*)argv );
  7718. #if !CATCH_ARC_ENABLED
  7719. [pool drain];
  7720. #endif
  7721. return result;
  7722. }
  7723. #endif // __OBJC__
  7724. #endif
  7725. #ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
  7726. # undef CLARA_CONFIG_MAIN
  7727. #endif
  7728. //////
  7729. // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
  7730. #ifdef CATCH_CONFIG_PREFIX_ALL
  7731. #define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE" )
  7732. #define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "CATCH_REQUIRE_FALSE" )
  7733. #define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS" )
  7734. #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS_AS" )
  7735. #define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_NOTHROW" )
  7736. #define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK" )
  7737. #define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CATCH_CHECK_FALSE" )
  7738. #define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_IF" )
  7739. #define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_ELSE" )
  7740. #define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CATCH_CHECK_NOFAIL" )
  7741. #define CATCH_CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS" )
  7742. #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS_AS" )
  7743. #define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_NOTHROW" )
  7744. #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" )
  7745. #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" )
  7746. #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
  7747. #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "CATCH_WARN", msg )
  7748. #define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
  7749. #define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
  7750. #define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
  7751. #ifdef CATCH_CONFIG_VARIADIC_MACROS
  7752. #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
  7753. #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
  7754. #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
  7755. #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
  7756. #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ )
  7757. #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", __VA_ARGS__ )
  7758. #else
  7759. #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
  7760. #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
  7761. #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
  7762. #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
  7763. #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", msg )
  7764. #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", msg )
  7765. #endif
  7766. #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
  7767. #define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
  7768. #define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
  7769. #define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
  7770. // "BDD-style" convenience wrappers
  7771. #ifdef CATCH_CONFIG_VARIADIC_MACROS
  7772. #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
  7773. #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
  7774. #else
  7775. #define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags )
  7776. #define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
  7777. #endif
  7778. #define CATCH_GIVEN( desc ) CATCH_SECTION( "Given: " desc, "" )
  7779. #define CATCH_WHEN( desc ) CATCH_SECTION( " When: " desc, "" )
  7780. #define CATCH_AND_WHEN( desc ) CATCH_SECTION( " And: " desc, "" )
  7781. #define CATCH_THEN( desc ) CATCH_SECTION( " Then: " desc, "" )
  7782. #define CATCH_AND_THEN( desc ) CATCH_SECTION( " And: " desc, "" )
  7783. // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
  7784. #else
  7785. #define REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "REQUIRE" )
  7786. #define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "REQUIRE_FALSE" )
  7787. #define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "REQUIRE_THROWS" )
  7788. #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "REQUIRE_THROWS_AS" )
  7789. #define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "REQUIRE_NOTHROW" )
  7790. #define CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK" )
  7791. #define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CHECK_FALSE" )
  7792. #define CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_IF" )
  7793. #define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_ELSE" )
  7794. #define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CHECK_NOFAIL" )
  7795. #define CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS" )
  7796. #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" )
  7797. #define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" )
  7798. #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THAT" )
  7799. #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "REQUIRE_THAT" )
  7800. #define INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
  7801. #define WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "WARN", msg )
  7802. #define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
  7803. #define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
  7804. #define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
  7805. #ifdef CATCH_CONFIG_VARIADIC_MACROS
  7806. #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
  7807. #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
  7808. #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
  7809. #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
  7810. #define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", __VA_ARGS__ )
  7811. #define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", __VA_ARGS__ )
  7812. #else
  7813. #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
  7814. #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
  7815. #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
  7816. #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
  7817. #define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", msg )
  7818. #define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", msg )
  7819. #endif
  7820. #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
  7821. #define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
  7822. #define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
  7823. #define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
  7824. #endif
  7825. #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
  7826. // "BDD-style" convenience wrappers
  7827. #ifdef CATCH_CONFIG_VARIADIC_MACROS
  7828. #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
  7829. #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
  7830. #else
  7831. #define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags )
  7832. #define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
  7833. #endif
  7834. #define GIVEN( desc ) SECTION( " Given: " desc, "" )
  7835. #define WHEN( desc ) SECTION( " When: " desc, "" )
  7836. #define AND_WHEN( desc ) SECTION( "And when: " desc, "" )
  7837. #define THEN( desc ) SECTION( " Then: " desc, "" )
  7838. #define AND_THEN( desc ) SECTION( " And: " desc, "" )
  7839. using Catch::Detail::Approx;
  7840. // #included from: internal/catch_reenable_warnings.h
  7841. #define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED
  7842. #ifdef __clang__
  7843. # ifdef __ICC // icpc defines the __clang__ macro
  7844. # pragma warning(pop)
  7845. # else
  7846. # pragma clang diagnostic pop
  7847. # endif
  7848. #elif defined __GNUC__
  7849. # pragma GCC diagnostic pop
  7850. #endif
  7851. #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED