Skip to main content
Module

x/chai/chai.js

BDD / TDD assertion framework for node.js and the browser that can be paired with any testing framework.
Go to Latest
File
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.chai = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){module.exports = require('./lib/chai');
},{"./lib/chai":2}],2:[function(require,module,exports){/*! * chai * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */var used = [];
/*! * Chai version */exports.version = '4.3.8';
/*! * Assertion Error */exports.AssertionError = require('assertion-error');
/*! * Utils for plugins (not exported) */var util = require('./chai/utils');
/** * # .use(function) * * Provides a way to extend the internals of Chai. * * @param {Function} * @returns {this} for chaining * @api public */exports.use = function (fn) { if (!~used.indexOf(fn)) { fn(exports, util); used.push(fn); } return exports;};
/*! * Utility Functions */exports.util = util;
/*! * Configuration */var config = require('./chai/config');exports.config = config;
/*! * Primary `Assertion` prototype */var assertion = require('./chai/assertion');exports.use(assertion);
/*! * Core Assertions */var core = require('./chai/core/assertions');exports.use(core);
/*! * Expect interface */var expect = require('./chai/interface/expect');exports.use(expect);
/*! * Should interface */var should = require('./chai/interface/should');exports.use(should);
/*! * Assert interface */var assert = require('./chai/interface/assert');exports.use(assert);
},{"./chai/assertion":3,"./chai/config":4,"./chai/core/assertions":5,"./chai/interface/assert":6,"./chai/interface/expect":7,"./chai/interface/should":8,"./chai/utils":22,"assertion-error":33}],3:[function(require,module,exports){/*! * chai * http://chaijs.com * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */var config = require('./config');
module.exports = function (_chai, util) { /*! * Module dependencies. */ var AssertionError = _chai.AssertionError , flag = util.flag; /*! * Module export. */ _chai.Assertion = Assertion; /*! * Assertion Constructor * * Creates object for chaining. * * `Assertion` objects contain metadata in the form of flags. Three flags can * be assigned during instantiation by passing arguments to this constructor: * * - `object`: This flag contains the target of the assertion. For example, in * the assertion `expect(numKittens).to.equal(7);`, the `object` flag will * contain `numKittens` so that the `equal` assertion can reference it when * needed. * * - `message`: This flag contains an optional custom error message to be * prepended to the error message that's generated by the assertion when it * fails. * * - `ssfi`: This flag stands for "start stack function indicator". It * contains a function reference that serves as the starting point for * removing frames from the stack trace of the error that's created by the * assertion when it fails. The goal is to provide a cleaner stack trace to * end users by removing Chai's internal functions. Note that it only works * in environments that support `Error.captureStackTrace`, and only when * `Chai.config.includeStack` hasn't been set to `false`. * * - `lockSsfi`: This flag controls whether or not the given `ssfi` flag * should retain its current value, even as assertions are chained off of * this object. This is usually set to `true` when creating a new assertion * from within another assertion. It's also temporarily set to `true` before * an overwritten assertion gets called by the overwriting assertion. * * @param {Mixed} obj target of the assertion * @param {String} msg (optional) custom error message * @param {Function} ssfi (optional) starting point for removing stack frames * @param {Boolean} lockSsfi (optional) whether or not the ssfi flag is locked * @api private */ function Assertion (obj, msg, ssfi, lockSsfi) { flag(this, 'ssfi', ssfi || Assertion); flag(this, 'lockSsfi', lockSsfi); flag(this, 'object', obj); flag(this, 'message', msg); return util.proxify(this); } Object.defineProperty(Assertion, 'includeStack', { get: function() { console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.'); return config.includeStack; }, set: function(value) { console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.'); config.includeStack = value; } }); Object.defineProperty(Assertion, 'showDiff', { get: function() { console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.'); return config.showDiff; }, set: function(value) { console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.'); config.showDiff = value; } }); Assertion.addProperty = function (name, fn) { util.addProperty(this.prototype, name, fn); }; Assertion.addMethod = function (name, fn) { util.addMethod(this.prototype, name, fn); }; Assertion.addChainableMethod = function (name, fn, chainingBehavior) { util.addChainableMethod(this.prototype, name, fn, chainingBehavior); }; Assertion.overwriteProperty = function (name, fn) { util.overwriteProperty(this.prototype, name, fn); }; Assertion.overwriteMethod = function (name, fn) { util.overwriteMethod(this.prototype, name, fn); }; Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) { util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior); }; /** * ### .assert(expression, message, negateMessage, expected, actual, showDiff) * * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass. * * @name assert * @param {Philosophical} expression to be tested * @param {String|Function} message or function that returns message to display if expression fails * @param {String|Function} negatedMessage or function that returns negatedMessage to display if negated expression fails * @param {Mixed} expected value (remember to check for negation) * @param {Mixed} actual (optional) will default to `this.obj` * @param {Boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails * @api private */ Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) { var ok = util.test(this, arguments); if (false !== showDiff) showDiff = true; if (undefined === expected && undefined === _actual) showDiff = false; if (true !== config.showDiff) showDiff = false; if (!ok) { msg = util.getMessage(this, arguments); var actual = util.getActual(this, arguments); var assertionErrorObjectProperties = { actual: actual , expected: expected , showDiff: showDiff }; var operator = util.getOperator(this, arguments); if (operator) { assertionErrorObjectProperties.operator = operator; } throw new AssertionError( msg, assertionErrorObjectProperties, (config.includeStack) ? this.assert : flag(this, 'ssfi')); } }; /*! * ### ._obj * * Quick reference to stored `actual` value for plugin developers. * * @api private */ Object.defineProperty(Assertion.prototype, '_obj', { get: function () { return flag(this, 'object'); } , set: function (val) { flag(this, 'object', val); } });};
},{"./config":4}],4:[function(require,module,exports){module.exports = {
/** * ### config.includeStack * * User configurable property, influences whether stack trace * is included in Assertion error message. Default of false * suppresses stack trace in the error message. * * chai.config.includeStack = true; // enable stack on error * * @param {Boolean} * @api public */ includeStack: false, /** * ### config.showDiff * * User configurable property, influences whether or not * the `showDiff` flag should be included in the thrown * AssertionErrors. `false` will always be `false`; `true` * will be true when the assertion has requested a diff * be shown. * * @param {Boolean} * @api public */ showDiff: true, /** * ### config.truncateThreshold * * User configurable property, sets length threshold for actual and * expected values in assertion errors. If this threshold is exceeded, for * example for large data structures, the value is replaced with something * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`. * * Set it to zero if you want to disable truncating altogether. * * This is especially userful when doing assertions on arrays: having this * set to a reasonable large value makes the failure messages readily * inspectable. * * chai.config.truncateThreshold = 0; // disable truncating * * @param {Number} * @api public */ truncateThreshold: 40, /** * ### config.useProxy * * User configurable property, defines if chai will use a Proxy to throw * an error when a non-existent property is read, which protects users * from typos when using property-based assertions. * * Set it to false if you want to disable this feature. * * chai.config.useProxy = false; // disable use of Proxy * * This feature is automatically disabled regardless of this config value * in environments that don't support proxies. * * @param {Boolean} * @api public */ useProxy: true, /** * ### config.proxyExcludedKeys * * User configurable property, defines which properties should be ignored * instead of throwing an error if they do not exist on the assertion. * This is only applied if the environment Chai is running in supports proxies and * if the `useProxy` configuration setting is enabled. * By default, `then` and `inspect` will not throw an error if they do not exist on the * assertion object because the `.inspect` property is read by `util.inspect` (for example, when * using `console.log` on the assertion object) and `.then` is necessary for promise type-checking. * * // By default these keys will not throw an error if they do not exist on the assertion object * chai.config.proxyExcludedKeys = ['then', 'inspect']; * * @param {Array} * @api public */ proxyExcludedKeys: ['then', 'catch', 'inspect', 'toJSON']};
},{}],5:[function(require,module,exports){/*! * chai * http://chaijs.com * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */module.exports = function (chai, _) { var Assertion = chai.Assertion , AssertionError = chai.AssertionError , flag = _.flag; /** * ### Language Chains * * The following are provided as chainable getters to improve the readability * of your assertions. * * **Chains** * * - to * - be * - been * - is * - that * - which * - and * - has * - have * - with * - at * - of * - same * - but * - does * - still * - also * * @name language chains * @namespace BDD * @api public */ [ 'to', 'be', 'been', 'is' , 'and', 'has', 'have', 'with' , 'that', 'which', 'at', 'of' , 'same', 'but', 'does', 'still', "also" ].forEach(function (chain) { Assertion.addProperty(chain); }); /** * ### .not * * Negates all assertions that follow in the chain. * * expect(function () {}).to.not.throw(); * expect({a: 1}).to.not.have.property('b'); * expect([1, 2]).to.be.an('array').that.does.not.include(3); * * Just because you can negate any assertion with `.not` doesn't mean you * should. With great power comes great responsibility. It's often best to * assert that the one expected output was produced, rather than asserting * that one of countless unexpected outputs wasn't produced. See individual * assertions for specific guidance. * * expect(2).to.equal(2); // Recommended * expect(2).to.not.equal(1); // Not recommended * * @name not * @namespace BDD * @api public */ Assertion.addProperty('not', function () { flag(this, 'negate', true); }); /** * ### .deep * * Causes all `.equal`, `.include`, `.members`, `.keys`, and `.property` * assertions that follow in the chain to use deep equality instead of strict * (`===`) equality. See the `deep-eql` project page for info on the deep * equality algorithm: https://github.com/chaijs/deep-eql. * * // Target object deeply (but not strictly) equals `{a: 1}` * expect({a: 1}).to.deep.equal({a: 1}); * expect({a: 1}).to.not.equal({a: 1}); * * // Target array deeply (but not strictly) includes `{a: 1}` * expect([{a: 1}]).to.deep.include({a: 1}); * expect([{a: 1}]).to.not.include({a: 1}); * * // Target object deeply (but not strictly) includes `x: {a: 1}` * expect({x: {a: 1}}).to.deep.include({x: {a: 1}}); * expect({x: {a: 1}}).to.not.include({x: {a: 1}}); * * // Target array deeply (but not strictly) has member `{a: 1}` * expect([{a: 1}]).to.have.deep.members([{a: 1}]); * expect([{a: 1}]).to.not.have.members([{a: 1}]); * * // Target set deeply (but not strictly) has key `{a: 1}` * expect(new Set([{a: 1}])).to.have.deep.keys([{a: 1}]); * expect(new Set([{a: 1}])).to.not.have.keys([{a: 1}]); * * // Target object deeply (but not strictly) has property `x: {a: 1}` * expect({x: {a: 1}}).to.have.deep.property('x', {a: 1}); * expect({x: {a: 1}}).to.not.have.property('x', {a: 1}); * * @name deep * @namespace BDD * @api public */ Assertion.addProperty('deep', function () { flag(this, 'deep', true); }); /** * ### .nested * * Enables dot- and bracket-notation in all `.property` and `.include` * assertions that follow in the chain. * * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]'); * expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'}); * * If `.` or `[]` are part of an actual property name, they can be escaped by * adding two backslashes before them. * * expect({'.a': {'[b]': 'x'}}).to.have.nested.property('\\.a.\\[b\\]'); * expect({'.a': {'[b]': 'x'}}).to.nested.include({'\\.a.\\[b\\]': 'x'}); * * `.nested` cannot be combined with `.own`. * * @name nested * @namespace BDD * @api public */ Assertion.addProperty('nested', function () { flag(this, 'nested', true); }); /** * ### .own * * Causes all `.property` and `.include` assertions that follow in the chain * to ignore inherited properties. * * Object.prototype.b = 2; * * expect({a: 1}).to.have.own.property('a'); * expect({a: 1}).to.have.property('b'); * expect({a: 1}).to.not.have.own.property('b'); * * expect({a: 1}).to.own.include({a: 1}); * expect({a: 1}).to.include({b: 2}).but.not.own.include({b: 2}); * * `.own` cannot be combined with `.nested`. * * @name own * @namespace BDD * @api public */ Assertion.addProperty('own', function () { flag(this, 'own', true); }); /** * ### .ordered * * Causes all `.members` assertions that follow in the chain to require that * members be in the same order. * * expect([1, 2]).to.have.ordered.members([1, 2]) * .but.not.have.ordered.members([2, 1]); * * When `.include` and `.ordered` are combined, the ordering begins at the * start of both arrays. * * expect([1, 2, 3]).to.include.ordered.members([1, 2]) * .but.not.include.ordered.members([2, 3]); * * @name ordered * @namespace BDD * @api public */ Assertion.addProperty('ordered', function () { flag(this, 'ordered', true); }); /** * ### .any * * Causes all `.keys` assertions that follow in the chain to only require that * the target have at least one of the given keys. This is the opposite of * `.all`, which requires that the target have all of the given keys. * * expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd'); * * See the `.keys` doc for guidance on when to use `.any` or `.all`. * * @name any * @namespace BDD * @api public */ Assertion.addProperty('any', function () { flag(this, 'any', true); flag(this, 'all', false); }); /** * ### .all * * Causes all `.keys` assertions that follow in the chain to require that the * target have all of the given keys. This is the opposite of `.any`, which * only requires that the target have at least one of the given keys. * * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); * * Note that `.all` is used by default when neither `.all` nor `.any` are * added earlier in the chain. However, it's often best to add `.all` anyway * because it improves readability. * * See the `.keys` doc for guidance on when to use `.any` or `.all`. * * @name all * @namespace BDD * @api public */ Assertion.addProperty('all', function () { flag(this, 'all', true); flag(this, 'any', false); }); /** * ### .a(type[, msg]) * * Asserts that the target's type is equal to the given string `type`. Types * are case insensitive. See the `type-detect` project page for info on the * type detection algorithm: https://github.com/chaijs/type-detect. * * expect('foo').to.be.a('string'); * expect({a: 1}).to.be.an('object'); * expect(null).to.be.a('null'); * expect(undefined).to.be.an('undefined'); * expect(new Error).to.be.an('error'); * expect(Promise.resolve()).to.be.a('promise'); * expect(new Float32Array).to.be.a('float32array'); * expect(Symbol()).to.be.a('symbol'); * * `.a` supports objects that have a custom type set via `Symbol.toStringTag`. * * var myObj = { * [Symbol.toStringTag]: 'myCustomType' * }; * * expect(myObj).to.be.a('myCustomType').but.not.an('object'); * * It's often best to use `.a` to check a target's type before making more * assertions on the same target. That way, you avoid unexpected behavior from * any assertion that does different things based on the target's type. * * expect([1, 2, 3]).to.be.an('array').that.includes(2); * expect([]).to.be.an('array').that.is.empty; * * Add `.not` earlier in the chain to negate `.a`. However, it's often best to * assert that the target is the expected type, rather than asserting that it * isn't one of many unexpected types. * * expect('foo').to.be.a('string'); // Recommended * expect('foo').to.not.be.an('array'); // Not recommended * * `.a` accepts an optional `msg` argument which is a custom error message to * show when the assertion fails. The message can also be given as the second * argument to `expect`. * * expect(1).to.be.a('string', 'nooo why fail??'); * expect(1, 'nooo why fail??').to.be.a('string'); * * `.a` can also be used as a language chain to improve the readability of * your assertions. * * expect({b: 2}).to.have.a.property('b'); * * The alias `.an` can be used interchangeably with `.a`. * * @name a * @alias an * @param {String} type * @param {String} msg _optional_ * @namespace BDD * @api public */ function an (type, msg) { if (msg) flag(this, 'message', msg); type = type.toLowerCase(); var obj = flag(this, 'object') , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a '; this.assert( type === _.type(obj).toLowerCase() , 'expected #{this} to be ' + article + type , 'expected #{this} not to be ' + article + type ); } Assertion.addChainableMethod('an', an); Assertion.addChainableMethod('a', an); /** * ### .include(val[, msg]) * * When the target is a string, `.include` asserts that the given string `val` * is a substring of the target. * * expect('foobar').to.include('foo'); * * When the target is an array, `.include` asserts that the given `val` is a * member of the target. * * expect([1, 2, 3]).to.include(2); * * When the target is an object, `.include` asserts that the given object * `val`'s properties are a subset of the target's properties. * * expect({a: 1, b: 2, c: 3}).to.include({a: 1, b: 2}); * * When the target is a Set or WeakSet, `.include` asserts that the given `val` is a * member of the target. SameValueZero equality algorithm is used. * * expect(new Set([1, 2])).to.include(2); * * When the target is a Map, `.include` asserts that the given `val` is one of * the values of the target. SameValueZero equality algorithm is used. * * expect(new Map([['a', 1], ['b', 2]])).to.include(2); * * Because `.include` does different things based on the target's type, it's * important to check the target's type before using `.include`. See the `.a` * doc for info on testing a target's type. * * expect([1, 2, 3]).to.be.an('array').that.includes(2); * * By default, strict (`===`) equality is used to compare array members and * object properties. Add `.deep` earlier in the chain to use deep equality * instead (WeakSet targets are not supported). See the `deep-eql` project * page for info on the deep equality algorithm: https://github.com/chaijs/deep-eql. * * // Target array deeply (but not strictly) includes `{a: 1}` * expect([{a: 1}]).to.deep.include({a: 1}); * expect([{a: 1}]).to.not.include({a: 1}); * * // Target object deeply (but not strictly) includes `x: {a: 1}` * expect({x: {a: 1}}).to.deep.include({x: {a: 1}}); * expect({x: {a: 1}}).to.not.include({x: {a: 1}}); * * By default, all of the target's properties are searched when working with * objects. This includes properties that are inherited and/or non-enumerable. * Add `.own` earlier in the chain to exclude the target's inherited * properties from the search. * * Object.prototype.b = 2; * * expect({a: 1}).to.own.include({a: 1}); * expect({a: 1}).to.include({b: 2}).but.not.own.include({b: 2}); * * Note that a target object is always only searched for `val`'s own * enumerable properties. * * `.deep` and `.own` can be combined. * * expect({a: {b: 2}}).to.deep.own.include({a: {b: 2}}); * * Add `.nested` earlier in the chain to enable dot- and bracket-notation when * referencing nested properties. * * expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'}); * * If `.` or `[]` are part of an actual property name, they can be escaped by * adding two backslashes before them. * * expect({'.a': {'[b]': 2}}).to.nested.include({'\\.a.\\[b\\]': 2}); * * `.deep` and `.nested` can be combined. * * expect({a: {b: [{c: 3}]}}).to.deep.nested.include({'a.b[0]': {c: 3}}); * * `.own` and `.nested` cannot be combined. * * Add `.not` earlier in the chain to negate `.include`. * * expect('foobar').to.not.include('taco'); * expect([1, 2, 3]).to.not.include(4); * * However, it's dangerous to negate `.include` when the target is an object. * The problem is that it creates uncertain expectations by asserting that the * target object doesn't have all of `val`'s key/value pairs but may or may * not have some of them. It's often best to identify the exact output that's * expected, and then write an assertion that only accepts that exact output. * * When the target object isn't even expected to have `val`'s keys, it's * often best to assert exactly that. * * expect({c: 3}).to.not.have.any.keys('a', 'b'); // Recommended * expect({c: 3}).to.not.include({a: 1, b: 2}); // Not recommended * * When the target object is expected to have `val`'s keys, it's often best to * assert that each of the properties has its expected value, rather than * asserting that each property doesn't have one of many unexpected values. * * expect({a: 3, b: 4}).to.include({a: 3, b: 4}); // Recommended * expect({a: 3, b: 4}).to.not.include({a: 1, b: 2}); // Not recommended * * `.include` accepts an optional `msg` argument which is a custom error * message to show when the assertion fails. The message can also be given as * the second argument to `expect`. * * expect([1, 2, 3]).to.include(4, 'nooo why fail??'); * expect([1, 2, 3], 'nooo why fail??').to.include(4); * * `.include` can also be used as a language chain, causing all `.members` and * `.keys` assertions that follow in the chain to require the target to be a * superset of the expected set, rather than an identical set. Note that * `.members` ignores duplicates in the subset when `.include` is added. * * // Target object's keys are a superset of ['a', 'b'] but not identical * expect({a: 1, b: 2, c: 3}).to.include.all.keys('a', 'b'); * expect({a: 1, b: 2, c: 3}).to.not.have.all.keys('a', 'b'); * * // Target array is a superset of [1, 2] but not identical * expect([1, 2, 3]).to.include.members([1, 2]); * expect([1, 2, 3]).to.not.have.members([1, 2]); * * // Duplicates in the subset are ignored * expect([1, 2, 3]).to.include.members([1, 2, 2, 2]); * * Note that adding `.any` earlier in the chain causes the `.keys` assertion * to ignore `.include`. * * // Both assertions are identical * expect({a: 1}).to.include.any.keys('a', 'b'); * expect({a: 1}).to.have.any.keys('a', 'b'); * * The aliases `.includes`, `.contain`, and `.contains` can be used * interchangeably with `.include`. * * @name include * @alias contain * @alias includes * @alias contains * @param {Mixed} val * @param {String} msg _optional_ * @namespace BDD * @api public */ function SameValueZero(a, b) { return (_.isNaN(a) && _.isNaN(b)) || a === b; } function includeChainingBehavior () { flag(this, 'contains', true); } function include (val, msg) { if (msg) flag(this, 'message', msg); var obj = flag(this, 'object') , objType = _.type(obj).toLowerCase() , flagMsg = flag(this, 'message') , negate = flag(this, 'negate') , ssfi = flag(this, 'ssfi') , isDeep = flag(this, 'deep') , descriptor = isDeep ? 'deep ' : ''; flagMsg = flagMsg ? flagMsg + ': ' : ''; var included = false; switch (objType) { case 'string': included = obj.indexOf(val) !== -1; break; case 'weakset': if (isDeep) { throw new AssertionError( flagMsg + 'unable to use .deep.include with WeakSet', undefined, ssfi ); } included = obj.has(val); break; case 'map': var isEql = isDeep ? _.eql : SameValueZero; obj.forEach(function (item) { included = included || isEql(item, val); }); break; case 'set': if (isDeep) { obj.forEach(function (item) { included = included || _.eql(item, val); }); } else { included = obj.has(val); } break; case 'array': if (isDeep) { included = obj.some(function (item) { return _.eql(item, val); }) } else { included = obj.indexOf(val) !== -1; } break; default: // This block is for asserting a subset of properties in an object. // `_.expectTypes` isn't used here because `.include` should work with // objects with a custom `@@toStringTag`. if (val !== Object(val)) { throw new AssertionError( flagMsg + 'the given combination of arguments (' + objType + ' and ' + _.type(val).toLowerCase() + ')' + ' is invalid for this assertion. ' + 'You can use an array, a map, an object, a set, a string, ' + 'or a weakset instead of a ' + _.type(val).toLowerCase(), undefined, ssfi ); } var props = Object.keys(val) , firstErr = null , numErrs = 0; props.forEach(function (prop) { var propAssertion = new Assertion(obj); _.transferFlags(this, propAssertion, true); flag(propAssertion, 'lockSsfi', true); if (!negate || props.length === 1) { propAssertion.property(prop, val[prop]); return; } try { propAssertion.property(prop, val[prop]); } catch (err) { if (!_.checkError.compatibleConstructor(err, AssertionError)) { throw err; } if (firstErr === null) firstErr = err; numErrs++; } }, this); // When validating .not.include with multiple properties, we only want // to throw an assertion error if all of the properties are included, // in which case we throw the first property assertion error that we // encountered. if (negate && props.length > 1 && numErrs === props.length) { throw firstErr; } return; } // Assert inclusion in collection or substring in a string. this.assert( included , 'expected #{this} to ' + descriptor + 'include ' + _.inspect(val) , 'expected #{this} to not ' + descriptor + 'include ' + _.inspect(val)); } Assertion.addChainableMethod('include', include, includeChainingBehavior); Assertion.addChainableMethod('contain', include, includeChainingBehavior); Assertion.addChainableMethod('contains', include, includeChainingBehavior); Assertion.addChainableMethod('includes', include, includeChainingBehavior); /** * ### .ok * * Asserts that the target is a truthy value (considered `true` in boolean context). * However, it's often best to assert that the target is strictly (`===`) or * deeply equal to its expected value. * * expect(1).to.equal(1); // Recommended * expect(1).to.be.ok; // Not recommended * * expect(true).to.be.true; // Recommended * expect(true).to.be.ok; // Not recommended * * Add `.not` earlier in the chain to negate `.ok`. * * expect(0).to.equal(0); // Recommended * expect(0).to.not.be.ok; // Not recommended * * expect(false).to.be.false; // Recommended * expect(false).to.not.be.ok; // Not recommended * * expect(null).to.be.null; // Recommended * expect(null).to.not.be.ok; // Not recommended * * expect(undefined).to.be.undefined; // Recommended * expect(undefined).to.not.be.ok; // Not recommended * * A custom error message can be given as the second argument to `expect`. * * expect(false, 'nooo why fail??').to.be.ok; * * @name ok * @namespace BDD * @api public */ Assertion.addProperty('ok', function () { this.assert( flag(this, 'object') , 'expected #{this} to be truthy' , 'expected #{this} to be falsy'); }); /** * ### .true * * Asserts that the target is strictly (`===`) equal to `true`. * * expect(true).to.be.true; * * Add `.not` earlier in the chain to negate `.true`. However, it's often best * to assert that the target is equal to its expected value, rather than not * equal to `true`. * * expect(false).to.be.false; // Recommended * expect(false).to.not.be.true; // Not recommended * * expect(1).to.equal(1); // Recommended * expect(1).to.not.be.true; // Not recommended * * A custom error message can be given as the second argument to `expect`. * * expect(false, 'nooo why fail??').to.be.true; * * @name true * @namespace BDD * @api public */ Assertion.addProperty('true', function () { this.assert( true === flag(this, 'object') , 'expected #{this} to be true' , 'expected #{this} to be false' , flag(this, 'negate') ? false : true ); }); /** * ### .false * * Asserts that the target is strictly (`===`) equal to `false`. * * expect(false).to.be.false; * * Add `.not` earlier in the chain to negate `.false`. However, it's often * best to assert that the target is equal to its expected value, rather than * not equal to `false`. * * expect(true).to.be.true; // Recommended * expect(true).to.not.be.false; // Not recommended * * expect(1).to.equal(1); // Recommended * expect(1).to.not.be.false; // Not recommended * * A custom error message can be given as the second argument to `expect`. * * expect(true, 'nooo why fail??').to.be.false; * * @name false * @namespace BDD * @api public */ Assertion.addProperty('false', function () { this.assert( false === flag(this, 'object') , 'expected #{this} to be false' , 'expected #{this} to be true' , flag(this, 'negate') ? true : false ); }); /** * ### .null * * Asserts that the target is strictly (`===`) equal to `null`. * * expect(null).to.be.null; * * Add `.not` earlier in the chain to negate `.null`. However, it's often best * to assert that the target is equal to its expected value, rather than not * equal to `null`. * * expect(1).to.equal(1); // Recommended * expect(1).to.not.be.null; // Not recommended * * A custom error message can be given as the second argument to `expect`. * * expect(42, 'nooo why fail??').to.be.null; * * @name null * @namespace BDD * @api public */ Assertion.addProperty('null', function () { this.assert( null === flag(this, 'object') , 'expected #{this} to be null' , 'expected #{this} not to be null' ); }); /** * ### .undefined * * Asserts that the target is strictly (`===`) equal to `undefined`. * * expect(undefined).to.be.undefined; * * Add `.not` earlier in the chain to negate `.undefined`. However, it's often * best to assert that the target is equal to its expected value, rather than * not equal to `undefined`. * * expect(1).to.equal(1); // Recommended * expect(1).to.not.be.undefined; // Not recommended * * A custom error message can be given as the second argument to `expect`. * * expect(42, 'nooo why fail??').to.be.undefined; * * @name undefined * @namespace BDD * @api public */ Assertion.addProperty('undefined', function () { this.assert( undefined === flag(this, 'object') , 'expected #{this} to be undefined' , 'expected #{this} not to be undefined' ); }); /** * ### .NaN * * Asserts that the target is exactly `NaN`. * * expect(NaN).to.be.NaN; * * Add `.not` earlier in the chain to negate `.NaN`. However, it's often best * to assert that the target is equal to its expected value, rather than not * equal to `NaN`. * * expect('foo').to.equal('foo'); // Recommended * expect('foo').to.not.be.NaN; // Not recommended * * A custom error message can be given as the second argument to `expect`. * * expect(42, 'nooo why fail??').to.be.NaN; * * @name NaN * @namespace BDD * @api public */ Assertion.addProperty('NaN', function () { this.assert( _.isNaN(flag(this, 'object')) , 'expected #{this} to be NaN' , 'expected #{this} not to be NaN' ); }); /** * ### .exist * * Asserts that the target is not strictly (`===`) equal to either `null` or * `undefined`. However, it's often best to assert that the target is equal to * its expected value. * * expect(1).to.equal(1); // Recommended * expect(1).to.exist; // Not recommended * * expect(0).to.equal(0); // Recommended * expect(0).to.exist; // Not recommended * * Add `.not` earlier in the chain to negate `.exist`. * * expect(null).to.be.null; // Recommended * expect(null).to.not.exist; // Not recommended * * expect(undefined).to.be.undefined; // Recommended * expect(undefined).to.not.exist; // Not recommended * * A custom error message can be given as the second argument to `expect`. * * expect(null, 'nooo why fail??').to.exist; * * The alias `.exists` can be used interchangeably with `.exist`. * * @name exist * @alias exists * @namespace BDD * @api public */ function assertExist () { var val = flag(this, 'object'); this.assert( val !== null && val !== undefined , 'expected #{this} to exist' , 'expected #{this} to not exist' ); } Assertion.addProperty('exist', assertExist); Assertion.addProperty('exists', assertExist); /** * ### .empty * * When the target is a string or array, `.empty` asserts that the target's * `length` property is strictly (`===`) equal to `0`. * * expect([]).to.be.empty; * expect('').to.be.empty; * * When the target is a map or set, `.empty` asserts that the target's `size` * property is strictly equal to `0`. * * expect(new Set()).to.be.empty; * expect(new Map()).to.be.empty; * * When the target is a non-function object, `.empty` asserts that the target * doesn't have any own enumerable properties. Properties with Symbol-based * keys are excluded from the count. * * expect({}).to.be.empty; * * Because `.empty` does different things based on the target's type, it's * important to check the target's type before using `.empty`. See the `.a` * doc for info on testing a target's type. * * expect([]).to.be.an('array').that.is.empty; * * Add `.not` earlier in the chain to negate `.empty`. However, it's often * best to assert that the target contains its expected number of values, * rather than asserting that it's not empty. * * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended * expect([1, 2, 3]).to.not.be.empty; // Not recommended * * expect(new Set([1, 2, 3])).to.have.property('size', 3); // Recommended * expect(new Set([1, 2, 3])).to.not.be.empty; // Not recommended * * expect(Object.keys({a: 1})).to.have.lengthOf(1); // Recommended * expect({a: 1}).to.not.be.empty; // Not recommended * * A custom error message can be given as the second argument to `expect`. * * expect([1, 2, 3], 'nooo why fail??').to.be.empty; * * @name empty * @namespace BDD * @api public */ Assertion.addProperty('empty', function () { var val = flag(this, 'object') , ssfi = flag(this, 'ssfi') , flagMsg = flag(this, 'message') , itemsCount; flagMsg = flagMsg ? flagMsg + ': ' : ''; switch (_.type(val).toLowerCase()) { case 'array': case 'string': itemsCount = val.length; break; case 'map': case 'set': itemsCount = val.size; break; case 'weakmap': case 'weakset': throw new AssertionError( flagMsg + '.empty was passed a weak collection', undefined, ssfi ); case 'function': var msg = flagMsg + '.empty was passed a function ' + _.getName(val); throw new AssertionError(msg.trim(), undefined, ssfi); default: if (val !== Object(val)) { throw new AssertionError( flagMsg + '.empty was passed non-string primitive ' + _.inspect(val), undefined, ssfi ); } itemsCount = Object.keys(val).length; } this.assert( 0 === itemsCount , 'expected #{this} to be empty' , 'expected #{this} not to be empty' ); }); /** * ### .arguments * * Asserts that the target is an `arguments` object. * * function test () { * expect(arguments).to.be.arguments; * } * * test(); * * Add `.not` earlier in the chain to negate `.arguments`. However, it's often * best to assert which type the target is expected to be, rather than * asserting that it’s not an `arguments` object. * * expect('foo').to.be.a('string'); // Recommended * expect('foo').to.not.be.arguments; // Not recommended * * A custom error message can be given as the second argument to `expect`. * * expect({}, 'nooo why fail??').to.be.arguments; * * The alias `.Arguments` can be used interchangeably with `.arguments`. * * @name arguments * @alias Arguments * @namespace BDD * @api public */ function checkArguments () { var obj = flag(this, 'object') , type = _.type(obj); this.assert( 'Arguments' === type , 'expected #{this} to be arguments but got ' + type , 'expected #{this} to not be arguments' ); } Assertion.addProperty('arguments', checkArguments); Assertion.addProperty('Arguments', checkArguments); /** * ### .equal(val[, msg]) * * Asserts that the target is strictly (`===`) equal to the given `val`. * * expect(1).to.equal(1); * expect('foo').to.equal('foo'); * * Add `.deep` earlier in the chain to use deep equality instead. See the * `deep-eql` project page for info on the deep equality algorithm: * https://github.com/chaijs/deep-eql. * * // Target object deeply (but not strictly) equals `{a: 1}` * expect({a: 1}).to.deep.equal({a: 1}); * expect({a: 1}).to.not.equal({a: 1}); * * // Target array deeply (but not strictly) equals `[1, 2]` * expect([1, 2]).to.deep.equal([1, 2]); * expect([1, 2]).to.not.equal([1, 2]); * * Add `.not` earlier in the chain to negate `.equal`. However, it's often * best to assert that the target is equal to its expected value, rather than * not equal to one of countless unexpected values. * * expect(1).to.equal(1); // Recommended * expect(1).to.not.equal(2); // Not recommended * * `.equal` accepts an optional `msg` argument which is a custom error message * to show when the assertion fails. The message can also be given as the * second argument to `expect`. * * expect(1).to.equal(2, 'nooo why fail??'); * expect(1, 'nooo why fail??').to.equal(2); * * The aliases `.equals` and `eq` can be used interchangeably with `.equal`. * * @name equal * @alias equals * @alias eq * @param {Mixed} val * @param {String} msg _optional_ * @namespace BDD * @api public */ function assertEqual (val, msg) { if (msg) flag(this, 'message', msg); var obj = flag(this, 'object'); if (flag(this, 'deep')) { var prevLockSsfi = flag(this, 'lockSsfi'); flag(this, 'lockSsfi', true); this.eql(val); flag(this, 'lockSsfi', prevLockSsfi); } else { this.assert( val === obj , 'expected #{this} to equal #{exp}' , 'expected #{this} to not equal #{exp}' , val , this._obj , true ); } } Assertion.addMethod('equal', assertEqual); Assertion.addMethod('equals', assertEqual); Assertion.addMethod('eq', assertEqual); /** * ### .eql(obj[, msg]) * * Asserts that the target is deeply equal to the given `obj`. See the * `deep-eql` project page for info on the deep equality algorithm: * https://github.com/chaijs/deep-eql. * * // Target object is deeply (but not strictly) equal to {a: 1} * expect({a: 1}).to.eql({a: 1}).but.not.equal({a: 1}); * * // Target array is deeply (but not strictly) equal to [1, 2] * expect([1, 2]).to.eql([1, 2]).but.not.equal([1, 2]); * * Add `.not` earlier in the chain to negate `.eql`. However, it's often best * to assert that the target is deeply equal to its expected value, rather * than not deeply equal to one of countless unexpected values. * * expect({a: 1}).to.eql({a: 1}); // Recommended * expect({a: 1}).to.not.eql({b: 2}); // Not recommended * * `.eql` accepts an optional `msg` argument which is a custom error message * to show when the assertion fails. The message can also be given as the * second argument to `expect`. * * expect({a: 1}).to.eql({b: 2}, 'nooo why fail??'); * expect({a: 1}, 'nooo why fail??').to.eql({b: 2}); * * The alias `.eqls` can be used interchangeably with `.eql`. * * The `.deep.equal` assertion is almost identical to `.eql` but with one * difference: `.deep.equal` causes deep equality comparisons to also be used * for any other assertions that follow in the chain. * * @name eql * @alias eqls * @param {Mixed} obj * @param {String} msg _optional_ * @namespace BDD * @api public */ function assertEql(obj, msg) { if (msg) flag(this, 'message', msg); this.assert( _.eql(obj, flag(this, 'object')) , 'expected #{this} to deeply equal #{exp}' , 'expected #{this} to not deeply equal #{exp}' , obj , this._obj , true ); } Assertion.addMethod('eql', assertEql); Assertion.addMethod('eqls', assertEql); /** * ### .above(n[, msg]) * * Asserts that the target is a number or a date greater than the given number or date `n` respectively. * However, it's often best to assert that the target is equal to its expected * value. * * expect(2).to.equal(2); // Recommended * expect(2).to.be.above(1); // Not recommended * * Add `.lengthOf` earlier in the chain to assert that the target's `length` * or `size` is greater than the given number `n`. * * expect('foo').to.have.lengthOf(3); // Recommended * expect('foo').to.have.lengthOf.above(2); // Not recommended * * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended * expect([1, 2, 3]).to.have.lengthOf.above(2); // Not recommended * * Add `.not` earlier in the chain to negate `.above`. * * expect(2).to.equal(2); // Recommended * expect(1).to.not.be.above(2); // Not recommended * * `.above` accepts an optional `msg` argument which is a custom error message * to show when the assertion fails. The message can also be given as the * second argument to `expect`. * * expect(1).to.be.above(2, 'nooo why fail??'); * expect(1, 'nooo why fail??').to.be.above(2); * * The aliases `.gt` and `.greaterThan` can be used interchangeably with * `.above`. * * @name above * @alias gt * @alias greaterThan * @param {Number} n * @param {String} msg _optional_ * @namespace BDD * @api public */ function assertAbove (n, msg) { if (msg) flag(this, 'message', msg); var obj = flag(this, 'object') , doLength = flag(this, 'doLength') , flagMsg = flag(this, 'message') , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') , ssfi = flag(this, 'ssfi') , objType = _.type(obj).toLowerCase() , nType = _.type(n).toLowerCase() , errorMessage , shouldThrow = true; if (doLength && objType !== 'map' && objType !== 'set') { new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); } if (!doLength && (objType === 'date' && nType !== 'date')) { errorMessage = msgPrefix + 'the argument to above must be a date'; } else if (nType !== 'number' && (doLength || objType === 'number')) { errorMessage = msgPrefix + 'the argument to above must be a number'; } else if (!doLength && (objType !== 'date' && objType !== 'number')) { var printObj = (objType === 'string') ? "'" + obj + "'" : obj; errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; } else { shouldThrow = false; } if (shouldThrow) { throw new AssertionError(errorMessage, undefined, ssfi); } if (doLength) { var descriptor = 'length' , itemsCount; if (objType === 'map' || objType === 'set') { descriptor = 'size'; itemsCount = obj.size; } else { itemsCount = obj.length; } this.assert( itemsCount > n , 'expected #{this} to have a ' + descriptor + ' above #{exp} but got #{act}' , 'expected #{this} to not have a ' + descriptor + ' above #{exp}' , n , itemsCount ); } else { this.assert( obj > n , 'expected #{this} to be above #{exp}' , 'expected #{this} to be at most #{exp}' , n ); } } Assertion.addMethod('above', assertAbove); Assertion.addMethod('gt', assertAbove); Assertion.addMethod('greaterThan', assertAbove); /** * ### .least(n[, msg]) * * Asserts that the target is a number or a date greater than or equal to the given * number or date `n` respectively. However, it's often best to assert that the target is equal to * its expected value. * * expect(2).to.equal(2); // Recommended * expect(2).to.be.at.least(1); // Not recommended * expect(2).to.be.at.least(2); // Not recommended * * Add `.lengthOf` earlier in the chain to assert that the target's `length` * or `size` is greater than or equal to the given number `n`. * * expect('foo').to.have.lengthOf(3); // Recommended * expect('foo').to.have.lengthOf.at.least(2); // Not recommended * * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended * expect([1, 2, 3]).to.have.lengthOf.at.least(2); // Not recommended * * Add `.not` earlier in the chain to negate `.least`. * * expect(1).to.equal(1); // Recommended * expect(1).to.not.be.at.least(2); // Not recommended * * `.least` accepts an optional `msg` argument which is a custom error message * to show when the assertion fails. The message can also be given as the * second argument to `expect`. * * expect(1).to.be.at.least(2, 'nooo why fail??'); * expect(1, 'nooo why fail??').to.be.at.least(2); * * The aliases `.gte` and `.greaterThanOrEqual` can be used interchangeably with * `.least`. * * @name least * @alias gte * @alias greaterThanOrEqual * @param {Number} n * @param {String} msg _optional_ * @namespace BDD * @api public */ function assertLeast (n, msg) { if (msg) flag(this, 'message', msg); var obj = flag(this, 'object') , doLength = flag(this, 'doLength') , flagMsg = flag(this, 'message') , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') , ssfi = flag(this, 'ssfi') , objType = _.type(obj).toLowerCase() , nType = _.type(n).toLowerCase() , errorMessage , shouldThrow = true; if (doLength && objType !== 'map' && objType !== 'set') { new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); } if (!doLength && (objType === 'date' && nType !== 'date')) { errorMessage = msgPrefix + 'the argument to least must be a date'; } else if (nType !== 'number' && (doLength || objType === 'number')) { errorMessage = msgPrefix + 'the argument to least must be a number'; } else if (!doLength && (objType !== 'date' && objType !== 'number')) { var printObj = (objType === 'string') ? "'" + obj + "'" : obj; errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; } else { shouldThrow = false; } if (shouldThrow) { throw new AssertionError(errorMessage, undefined, ssfi); } if (doLength) { var descriptor = 'length' , itemsCount; if (objType === 'map' || objType === 'set') { descriptor = 'size'; itemsCount = obj.size; } else { itemsCount = obj.length; } this.assert( itemsCount >= n , 'expected #{this} to have a ' + descriptor + ' at least #{exp} but got #{act}' , 'expected #{this} to have a ' + descriptor + ' below #{exp}' , n , itemsCount ); } else { this.assert( obj >= n , 'expected #{this} to be at least #{exp}' , 'expected #{this} to be below #{exp}' , n ); } } Assertion.addMethod('least', assertLeast); Assertion.addMethod('gte', assertLeast); Assertion.addMethod('greaterThanOrEqual', assertLeast); /** * ### .below(n[, msg]) * * Asserts that the target is a number or a date less than the given number or date `n` respectively. * However, it's often best to assert that the target is equal to its expected * value. * * expect(1).to.equal(1); // Recommended * expect(1).to.be.below(2); // Not recommended * * Add `.lengthOf` earlier in the chain to assert that the target's `length` * or `size` is less than the given number `n`. * * expect('foo').to.have.lengthOf(3); // Recommended * expect('foo').to.have.lengthOf.below(4); // Not recommended * * expect([1, 2, 3]).to.have.length(3); // Recommended * expect([1, 2, 3]).to.have.lengthOf.below(4); // Not recommended * * Add `.not` earlier in the chain to negate `.below`. * * expect(2).to.equal(2); // Recommended * expect(2).to.not.be.below(1); // Not recommended * * `.below` accepts an optional `msg` argument which is a custom error message * to show when the assertion fails. The message can also be given as the * second argument to `expect`. * * expect(2).to.be.below(1, 'nooo why fail??'); * expect(2, 'nooo why fail??').to.be.below(1); * * The aliases `.lt` and `.lessThan` can be used interchangeably with * `.below`. * * @name below * @alias lt * @alias lessThan * @param {Number} n * @param {String} msg _optional_ * @namespace BDD * @api public */ function assertBelow (n, msg) { if (msg) flag(this, 'message', msg); var obj = flag(this, 'object') , doLength = flag(this, 'doLength') , flagMsg = flag(this, 'message') , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') , ssfi = flag(this, 'ssfi') , objType = _.type(obj).toLowerCase() , nType = _.type(n).toLowerCase() , errorMessage , shouldThrow = true; if (doLength && objType !== 'map' && objType !== 'set') { new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); } if (!doLength && (objType === 'date' && nType !== 'date')) { errorMessage = msgPrefix + 'the argument to below must be a date'; } else if (nType !== 'number' && (doLength || objType === 'number')) { errorMessage = msgPrefix + 'the argument to below must be a number'; } else if (!doLength && (objType !== 'date' && objType !== 'number')) { var printObj = (objType === 'string') ? "'" + obj + "'" : obj; errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; } else { shouldThrow = false; } if (shouldThrow) { throw new AssertionError(errorMessage, undefined, ssfi); } if (doLength) { var descriptor = 'length' , itemsCount; if (objType === 'map' || objType === 'set') { descriptor = 'size'; itemsCount = obj.size; } else { itemsCount = obj.length; } this.assert( itemsCount < n , 'expected #{this} to have a ' + descriptor + ' below #{exp} but got #{act}' , 'expected #{this} to not have a ' + descriptor + ' below #{exp}' , n , itemsCount ); } else { this.assert( obj < n , 'expected #{this} to be below #{exp}' , 'expected #{this} to be at least #{exp}' , n ); } } Assertion.addMethod('below', assertBelow); Assertion.addMethod('lt', assertBelow); Assertion.addMethod('lessThan', assertBelow); /** * ### .most(n[, msg]) * * Asserts that the target is a number or a date less than or equal to the given number * or date `n` respectively. However, it's often best to assert that the target is equal to its * expected value. * * expect(1).to.equal(1); // Recommended * expect(1).to.be.at.most(2); // Not recommended * expect(1).to.be.at.most(1); // Not recommended * * Add `.lengthOf` earlier in the chain to assert that the target's `length` * or `size` is less than or equal to the given number `n`. * * expect('foo').to.have.lengthOf(3); // Recommended * expect('foo').to.have.lengthOf.at.most(4); // Not recommended * * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended * expect([1, 2, 3]).to.have.lengthOf.at.most(4); // Not recommended * * Add `.not` earlier in the chain to negate `.most`. * * expect(2).to.equal(2); // Recommended * expect(2).to.not.be.at.most(1); // Not recommended * * `.most` accepts an optional `msg` argument which is a custom error message * to show when the assertion fails. The message can also be given as the * second argument to `expect`. * * expect(2).to.be.at.most(1, 'nooo why fail??'); * expect(2, 'nooo why fail??').to.be.at.most(1); * * The aliases `.lte` and `.lessThanOrEqual` can be used interchangeably with * `.most`. * * @name most * @alias lte * @alias lessThanOrEqual * @param {Number} n * @param {String} msg _optional_ * @namespace BDD * @api public */ function assertMost (n, msg) { if (msg) flag(this, 'message', msg); var obj = flag(this, 'object') , doLength = flag(this, 'doLength') , flagMsg = flag(this, 'message') , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') , ssfi = flag(this, 'ssfi') , objType = _.type(obj).toLowerCase() , nType = _.type(n).toLowerCase() , errorMessage , shouldThrow = true; if (doLength && objType !== 'map' && objType !== 'set') { new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); } if (!doLength && (objType === 'date' && nType !== 'date')) { errorMessage = msgPrefix + 'the argument to most must be a date'; } else if (nType !== 'number' && (doLength || objType === 'number')) { errorMessage = msgPrefix + 'the argument to most must be a number'; } else if (!doLength && (objType !== 'date' && objType !== 'number')) { var printObj = (objType === 'string') ? "'" + obj + "'" : obj; errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; } else { shouldThrow = false; } if (shouldThrow) { throw new AssertionError(errorMessage, undefined, ssfi); } if (doLength) { var descriptor = 'length' , itemsCount; if (objType === 'map' || objType === 'set') { descriptor = 'size'; itemsCount = obj.size; } else { itemsCount = obj.length; } this.assert( itemsCount <= n , 'expected #{this} to have a ' + descriptor + ' at most #{exp} but got #{act}' , 'expected #{this} to have a ' + descriptor + ' above #{exp}' , n , itemsCount ); } else { this.assert( obj <= n , 'expected #{this} to be at most #{exp}' , 'expected #{this} to be above #{exp}' , n ); } } Assertion.addMethod('most', assertMost); Assertion.addMethod('lte', assertMost); Assertion.addMethod('lessThanOrEqual', assertMost); /** * ### .within(start, finish[, msg]) * * Asserts that the target is a number or a date greater than or equal to the given * number or date `start`, and less than or equal to the given number or date `finish` respectively. * However, it's often best to assert that the target is equal to its expected * value. * * expect(2).to.equal(2); // Recommended * expect(2).to.be.within(1, 3); // Not recommended * expect(2).to.be.within(2, 3); // Not recommended * expect(2).to.be.within(1, 2); // Not recommended * * Add `.lengthOf` earlier in the chain to assert that the target's `length` * or `size` is greater than or equal to the given number `start`, and less * than or equal to the given number `finish`. * * expect('foo').to.have.lengthOf(3); // Recommended * expect('foo').to.have.lengthOf.within(2, 4); // Not recommended * * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended * expect([1, 2, 3]).to.have.lengthOf.within(2, 4); // Not recommended * * Add `.not` earlier in the chain to negate `.within`. * * expect(1).to.equal(1); // Recommended * expect(1).to.not.be.within(2, 4); // Not recommended * * `.within` accepts an optional `msg` argument which is a custom error * message to show when the assertion fails. The message can also be given as * the second argument to `expect`. * * expect(4).to.be.within(1, 3, 'nooo why fail??'); * expect(4, 'nooo why fail??').to.be.within(1, 3); * * @name within * @param {Number} start lower bound inclusive * @param {Number} finish upper bound inclusive * @param {String} msg _optional_ * @namespace BDD * @api public */ Assertion.addMethod('within', function (start, finish, msg) { if (msg) flag(this, 'message', msg); var obj = flag(this, 'object') , doLength = flag(this, 'doLength') , flagMsg = flag(this, 'message') , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') , ssfi = flag(this, 'ssfi') , objType = _.type(obj).toLowerCase() , startType = _.type(start).toLowerCase() , finishType = _.type(finish).toLowerCase() , errorMessage , shouldThrow = true , range = (startType === 'date' && finishType === 'date') ? start.toISOString() + '..' + finish.toISOString() : start + '..' + finish; if (doLength && objType !== 'map' && objType !== 'set') { new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); } if (!doLength && (objType === 'date' && (startType !== 'date' || finishType !== 'date'))) { errorMessage = msgPrefix + 'the arguments to within must be dates'; } else if ((startType !== 'number' || finishType !== 'number') && (doLength || objType === 'number')) { errorMessage = msgPrefix + 'the arguments to within must be numbers'; } else if (!doLength && (objType !== 'date' && objType !== 'number')) { var printObj = (objType === 'string') ? "'" + obj + "'" : obj; errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; } else { shouldThrow = false; } if (shouldThrow) { throw new AssertionError(errorMessage, undefined, ssfi); } if (doLength) { var descriptor = 'length' , itemsCount; if (objType === 'map' || objType === 'set') { descriptor = 'size'; itemsCount = obj.size; } else { itemsCount = obj.length; } this.assert( itemsCount >= start && itemsCount <= finish , 'expected #{this} to have a ' + descriptor + ' within ' + range , 'expected #{this} to not have a ' + descriptor + ' within ' + range ); } else { this.assert( obj >= start && obj <= finish , 'expected #{this} to be within ' + range , 'expected #{this} to not be within ' + range ); } }); /** * ### .instanceof(constructor[, msg]) * * Asserts that the target is an instance of the given `constructor`. * * function Cat () { } * * expect(new Cat()).to.be.an.instanceof(Cat); * expect([1, 2]).to.be.an.instanceof(Array); * * Add `.not` earlier in the chain to negate `.instanceof`. * * expect({a: 1}).to.not.be.an.instanceof(Array); * * `.instanceof` accepts an optional `msg` argument which is a custom error * message to show when the assertion fails. The message can also be given as * the second argument to `expect`. * * expect(1).to.be.an.instanceof(Array, 'nooo why fail??'); * expect(1, 'nooo why fail??').to.be.an.instanceof(Array); * * Due to limitations in ES5, `.instanceof` may not always work as expected * when using a transpiler such as Babel or TypeScript. In particular, it may * produce unexpected results when subclassing built-in object such as * `Array`, `Error`, and `Map`. See your transpiler's docs for details: * * - ([Babel](https://babeljs.io/docs/usage/caveats/#classes)) * - ([TypeScript](https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work)) * * The alias `.instanceOf` can be used interchangeably with `.instanceof`. * * @name instanceof * @param {Constructor} constructor * @param {String} msg _optional_ * @alias instanceOf * @namespace BDD * @api public */ function assertInstanceOf (constructor, msg) { if (msg) flag(this, 'message', msg); var target = flag(this, 'object') var ssfi = flag(this, 'ssfi'); var flagMsg = flag(this, 'message'); try { var isInstanceOf = target instanceof constructor; } catch (err) { if (err instanceof TypeError) { flagMsg = flagMsg ? flagMsg + ': ' : ''; throw new AssertionError( flagMsg + 'The instanceof assertion needs a constructor but ' + _.type(constructor) + ' was given.', undefined, ssfi ); } throw err; } var name = _.getName(constructor); if (name === null) { name = 'an unnamed constructor'; } this.assert( isInstanceOf , 'expected #{this} to be an instance of ' + name , 'expected #{this} to not be an instance of ' + name ); }; Assertion.addMethod('instanceof', assertInstanceOf); Assertion.addMethod('instanceOf', assertInstanceOf); /** * ### .property(name[, val[, msg]]) * * Asserts that the target has a property with the given key `name`. * * expect({a: 1}).to.have.property('a'); * * When `val` is provided, `.property` also asserts that the property's value * is equal to the given `val`. * * expect({a: 1}).to.have.property('a', 1); * * By default, strict (`===`) equality is used. Add `.deep` earlier in the * chain to use deep equality instead. See the `deep-eql` project page for * info on the deep equality algorithm: https://github.com/chaijs/deep-eql. * * // Target object deeply (but not strictly) has property `x: {a: 1}` * expect({x: {a: 1}}).to.have.deep.property('x', {a: 1}); * expect({x: {a: 1}}).to.not.have.property('x', {a: 1}); * * The target's enumerable and non-enumerable properties are always included * in the search. By default, both own and inherited properties are included. * Add `.own` earlier in the chain to exclude inherited properties from the * search. * * Object.prototype.b = 2; * * expect({a: 1}).to.have.own.property('a'); * expect({a: 1}).to.have.own.property('a', 1); * expect({a: 1}).to.have.property('b'); * expect({a: 1}).to.not.have.own.property('b'); * * `.deep` and `.own` can be combined. * * expect({x: {a: 1}}).to.have.deep.own.property('x', {a: 1}); * * Add `.nested` earlier in the chain to enable dot- and bracket-notation when * referencing nested properties. * * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]'); * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]', 'y'); * * If `.` or `[]` are part of an actual property name, they can be escaped by * adding two backslashes before them. * * expect({'.a': {'[b]': 'x'}}).to.have.nested.property('\\.a.\\[b\\]'); * * `.deep` and `.nested` can be combined. * * expect({a: {b: [{c: 3}]}}) * .to.have.deep.nested.property('a.b[0]', {c: 3}); * * `.own` and `.nested` cannot be combined. * * Add `.not` earlier in the chain to negate `.property`. * * expect({a: 1}).to.not.have.property('b'); * * However, it's dangerous to negate `.property` when providing `val`. The * problem is that it creates uncertain expectations by asserting that the * target either doesn't have a property with the given key `name`, or that it * does have a property with the given key `name` but its value isn't equal to * the given `val`. It's often best to identify the exact output that's * expected, and then write an assertion that only accepts that exact output. * * When the target isn't expected to have a property with the given key * `name`, it's often best to assert exactly that. * * expect({b: 2}).to.not.have.property('a'); // Recommended * expect({b: 2}).to.not.have.property('a', 1); // Not recommended * * When the target is expected to have a property with the given key `name`, * it's often best to assert that the property has its expected value, rather * than asserting that it doesn't have one of many unexpected values. * * expect({a: 3}).to.have.property('a', 3); // Recommended * expect({a: 3}).to.not.have.property('a', 1); // Not recommended * * `.property` changes the target of any assertions that follow in the chain * to be the value of the property from the original target object. * * expect({a: 1}).to.have.property('a').that.is.a('number'); * * `.property` accepts an optional `msg` argument which is a custom error * message to show when the assertion fails. The message can also be given as * the second argument to `expect`. When not providing `val`, only use the * second form. * * // Recommended * expect({a: 1}).to.have.property('a', 2, 'nooo why fail??'); * expect({a: 1}, 'nooo why fail??').to.have.property('a', 2); * expect({a: 1}, 'nooo why fail??').to.have.property('b'); * * // Not recommended * expect({a: 1}).to.have.property('b', undefined, 'nooo why fail??'); * * The above assertion isn't the same thing as not providing `val`. Instead, * it's asserting that the target object has a `b` property that's equal to * `undefined`. * * The assertions `.ownProperty` and `.haveOwnProperty` can be used * interchangeably with `.own.property`. * * @name property * @param {String} name * @param {Mixed} val (optional) * @param {String} msg _optional_ * @returns value of property for chaining * @namespace BDD * @api public */ function assertProperty (name, val, msg) { if (msg) flag(this, 'message', msg); var isNested = flag(this, 'nested') , isOwn = flag(this, 'own') , flagMsg = flag(this, 'message') , obj = flag(this, 'object') , ssfi = flag(this, 'ssfi') , nameType = typeof name; flagMsg = flagMsg ? flagMsg + ': ' : ''; if (isNested) { if (nameType !== 'string') { throw new AssertionError( flagMsg + 'the argument to property must be a string when using nested syntax', undefined, ssfi ); } } else { if (nameType !== 'string' && nameType !== 'number' && nameType !== 'symbol') { throw new AssertionError( flagMsg + 'the argument to property must be a string, number, or symbol', undefined, ssfi ); } } if (isNested && isOwn) { throw new AssertionError( flagMsg + 'The "nested" and "own" flags cannot be combined.', undefined, ssfi ); } if (obj === null || obj === undefined) { throw new AssertionError( flagMsg + 'Target cannot be null or undefined.', undefined, ssfi ); } var isDeep = flag(this, 'deep') , negate = flag(this, 'negate') , pathInfo = isNested ? _.getPathInfo(obj, name) : null , value = isNested ? pathInfo.value : obj[name]; var descriptor = ''; if (isDeep) descriptor += 'deep '; if (isOwn) descriptor += 'own '; if (isNested) descriptor += 'nested '; descriptor += 'property '; var hasProperty; if (isOwn) hasProperty = Object.prototype.hasOwnProperty.call(obj, name); else if (isNested) hasProperty = pathInfo.exists; else hasProperty = _.hasProperty(obj, name); // When performing a negated assertion for both name and val, merely having // a property with the given name isn't enough to cause the assertion to // fail. It must both have a property with the given name, and the value of // that property must equal the given val. Therefore, skip this assertion in // favor of the next. if (!negate || arguments.length === 1) { this.assert( hasProperty , 'expected #{this} to have ' + descriptor + _.inspect(name) , 'expected #{this} to not have ' + descriptor + _.inspect(name)); } if (arguments.length > 1) { this.assert( hasProperty && (isDeep ? _.eql(val, value) : val === value) , 'expected #{this} to have ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}' , 'expected #{this} to not have ' + descriptor + _.inspect(name) + ' of #{act}' , val , value ); } flag(this, 'object', value); } Assertion.addMethod('property', assertProperty); function assertOwnProperty (name, value, msg) { flag(this, 'own', true); assertProperty.apply(this, arguments); } Assertion.addMethod('ownProperty', assertOwnProperty); Assertion.addMethod('haveOwnProperty', assertOwnProperty); /** * ### .ownPropertyDescriptor(name[, descriptor[, msg]]) * * Asserts that the target has its own property descriptor with the given key * `name`. Enumerable and non-enumerable properties are included in the * search. * * expect({a: 1}).to.have.ownPropertyDescriptor('a'); * * When `descriptor` is provided, `.ownPropertyDescriptor` also asserts that * the property's descriptor is deeply equal to the given `descriptor`. See * the `deep-eql` project page for info on the deep equality algorithm: * https://github.com/chaijs/deep-eql. * * expect({a: 1}).to.have.ownPropertyDescriptor('a', { * configurable: true, * enumerable: true, * writable: true, * value: 1, * }); * * Add `.not` earlier in the chain to negate `.ownPropertyDescriptor`. * * expect({a: 1}).to.not.have.ownPropertyDescriptor('b'); * * However, it's dangerous to negate `.ownPropertyDescriptor` when providing * a `descriptor`. The problem is that it creates uncertain expectations by * asserting that the target either doesn't have a property descriptor with * the given key `name`, or that it does have a property descriptor with the * given key `name` but it’s not deeply equal to the given `descriptor`. It's * often best to identify the exact output that's expected, and then write an * assertion that only accepts that exact output. * * When the target isn't expected to have a property descriptor with the given * key `name`, it's often best to assert exactly that. * * // Recommended * expect({b: 2}).to.not.have.ownPropertyDescriptor('a'); * * // Not recommended * expect({b: 2}).to.not.have.ownPropertyDescriptor('a', { * configurable: true, * enumerable: true, * writable: true, * value: 1, * }); * * When the target is expected to have a property descriptor with the given * key `name`, it's often best to assert that the property has its expected * descriptor, rather than asserting that it doesn't have one of many * unexpected descriptors. * * // Recommended * expect({a: 3}).to.have.ownPropertyDescriptor('a', { * configurable: true, * enumerable: true, * writable: true, * value: 3, * }); * * // Not recommended * expect({a: 3}).to.not.have.ownPropertyDescriptor('a', { * configurable: true, * enumerable: true, * writable: true, * value: 1, * }); * * `.ownPropertyDescriptor` changes the target of any assertions that follow * in the chain to be the value of the property descriptor from the original * target object. * * expect({a: 1}).to.have.ownPropertyDescriptor('a') * .that.has.property('enumerable', true); * * `.ownPropertyDescriptor` accepts an optional `msg` argument which is a * custom error message to show when the assertion fails. The message can also * be given as the second argument to `expect`. When not providing * `descriptor`, only use the second form. * * // Recommended * expect({a: 1}).to.have.ownPropertyDescriptor('a', { * configurable: true, * enumerable: true, * writable: true, * value: 2, * }, 'nooo why fail??'); * * // Recommended * expect({a: 1}, 'nooo why fail??').to.have.ownPropertyDescriptor('a', { * configurable: true, * enumerable: true, * writable: true, * value: 2, * }); * * // Recommended * expect({a: 1}, 'nooo why fail??').to.have.ownPropertyDescriptor('b'); * * // Not recommended * expect({a: 1}) * .to.have.ownPropertyDescriptor('b', undefined, 'nooo why fail??'); * * The above assertion isn't the same thing as not providing `descriptor`. * Instead, it's asserting that the target object has a `b` property * descriptor that's deeply equal to `undefined`. * * The alias `.haveOwnPropertyDescriptor` can be used interchangeably with * `.ownPropertyDescriptor`. * * @name ownPropertyDescriptor * @alias haveOwnPropertyDescriptor * @param {String} name * @param {Object} descriptor _optional_ * @param {String} msg _optional_ * @namespace BDD * @api public */ function assertOwnPropertyDescriptor (name, descriptor, msg) { if (typeof descriptor === 'string') { msg = descriptor; descriptor = null; } if (msg) flag(this, 'message', msg); var obj = flag(this, 'object'); var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name); if (actualDescriptor && descriptor) { this.assert( _.eql(descriptor, actualDescriptor) , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor) , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor) , descriptor , actualDescriptor , true ); } else { this.assert( actualDescriptor , 'expected #{this} to have an own property descriptor for ' + _.inspect(name) , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name) ); } flag(this, 'object', actualDescriptor); } Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor); Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor); /** * ### .lengthOf(n[, msg]) * * Asserts that the target's `length` or `size` is equal to the given number * `n`. * * expect([1, 2, 3]).to.have.lengthOf(3); * expect('foo').to.have.lengthOf(3); * expect(new Set([1, 2, 3])).to.have.lengthOf(3); * expect(new Map([['a', 1], ['b', 2], ['c', 3]])).to.have.lengthOf(3); * * Add `.not` earlier in the chain to negate `.lengthOf`. However, it's often * best to assert that the target's `length` property is equal to its expected * value, rather than not equal to one of many unexpected values. * * expect('foo').to.have.lengthOf(3); // Recommended * expect('foo').to.not.have.lengthOf(4); // Not recommended * * `.lengthOf` accepts an optional `msg` argument which is a custom error * message to show when the assertion fails. The message can also be given as * the second argument to `expect`. * * expect([1, 2, 3]).to.have.lengthOf(2, 'nooo why fail??'); * expect([1, 2, 3], 'nooo why fail??').to.have.lengthOf(2); * * `.lengthOf` can also be used as a language chain, causing all `.above`, * `.below`, `.least`, `.most`, and `.within` assertions that follow in the * chain to use the target's `length` property as the target. However, it's * often best to assert that the target's `length` property is equal to its * expected length, rather than asserting that its `length` property falls * within some range of values. * * // Recommended * expect([1, 2, 3]).to.have.lengthOf(3); * * // Not recommended * expect([1, 2, 3]).to.have.lengthOf.above(2); * expect([1, 2, 3]).to.have.lengthOf.below(4); * expect([1, 2, 3]).to.have.lengthOf.at.least(3); * expect([1, 2, 3]).to.have.lengthOf.at.most(3); * expect([1, 2, 3]).to.have.lengthOf.within(2,4); * * Due to a compatibility issue, the alias `.length` can't be chained directly * off of an uninvoked method such as `.a`. Therefore, `.length` can't be used * interchangeably with `.lengthOf` in every situation. It's recommended to * always use `.lengthOf` instead of `.length`. * * expect([1, 2, 3]).to.have.a.length(3); // incompatible; throws error * expect([1, 2, 3]).to.have.a.lengthOf(3); // passes as expected * * @name lengthOf * @alias length * @param {Number} n * @param {String} msg _optional_ * @namespace BDD * @api public */ function assertLengthChain () { flag(this, 'doLength', true); } function assertLength (n, msg) { if (msg) flag(this, 'message', msg); var obj = flag(this, 'object') , objType = _.type(obj).toLowerCase() , flagMsg = flag(this, 'message') , ssfi = flag(this, 'ssfi') , descriptor = 'length' , itemsCount; switch (objType) { case 'map': case 'set': descriptor = 'size'; itemsCount = obj.size; break; default: new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); itemsCount = obj.length; } this.assert( itemsCount == n , 'expected #{this} to have a ' + descriptor + ' of #{exp} but got #{act}' , 'expected #{this} to not have a ' + descriptor + ' of #{act}' , n , itemsCount ); } Assertion.addChainableMethod('length', assertLength, assertLengthChain); Assertion.addChainableMethod('lengthOf', assertLength, assertLengthChain); /** * ### .match(re[, msg]) * * Asserts that the target matches the given regular expression `re`. * * expect('foobar').to.match(/^foo/); * * Add `.not` earlier in the chain to negate `.match`. * * expect('foobar').to.not.match(/taco/); * * `.match` accepts an optional `msg` argument which is a custom error message * to show when the assertion fails. The message can also be given as the * second argument to `expect`. * * expect('foobar').to.match(/taco/, 'nooo why fail??'); * expect('foobar', 'nooo why fail??').to.match(/taco/); * * The alias `.matches` can be used interchangeably with `.match`. * * @name match * @alias matches * @param {RegExp} re * @param {String} msg _optional_ * @namespace BDD * @api public */ function assertMatch(re, msg) { if (msg) flag(this, 'message', msg); var obj = flag(this, 'object'); this.assert( re.exec(obj) , 'expected #{this} to match ' + re , 'expected #{this} not to match ' + re ); } Assertion.addMethod('match', assertMatch); Assertion.addMethod('matches', assertMatch); /** * ### .string(str[, msg]) * * Asserts that the target string contains the given substring `str`. * * expect('foobar').to.have.string('bar'); * * Add `.not` earlier in the chain to negate `.string`. * * expect('foobar').to.not.have.string('taco'); * * `.string` accepts an optional `msg` argument which is a custom error * message to show when the assertion fails. The message can also be given as * the second argument to `expect`. * * expect('foobar').to.have.string('taco', 'nooo why fail??'); * expect('foobar', 'nooo why fail??').to.have.string('taco'); * * @name string * @param {String} str * @param {String} msg _optional_ * @namespace BDD * @api public */ Assertion.addMethod('string', function (str, msg) { if (msg) flag(this, 'message', msg); var obj = flag(this, 'object') , flagMsg = flag(this, 'message') , ssfi = flag(this, 'ssfi'); new Assertion(obj, flagMsg, ssfi, true).is.a('string'); this.assert( ~obj.indexOf(str) , 'expected #{this} to contain ' + _.inspect(str) , 'expected #{this} to not contain ' + _.inspect(str) ); }); /** * ### .keys(key1[, key2[, ...]]) * * Asserts that the target object, array, map, or set has the given keys. Only * the target's own inherited properties are included in the search. * * When the target is an object or array, keys can be provided as one or more * string arguments, a single array argument, or a single object argument. In * the latter case, only the keys in the given object matter; the values are * ignored. * * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); * expect(['x', 'y']).to.have.all.keys(0, 1); * * expect({a: 1, b: 2}).to.have.all.keys(['a', 'b']); * expect(['x', 'y']).to.have.all.keys([0, 1]); * * expect({a: 1, b: 2}).to.have.all.keys({a: 4, b: 5}); // ignore 4 and 5 * expect(['x', 'y']).to.have.all.keys({0: 4, 1: 5}); // ignore 4 and 5 * * When the target is a map or set, each key must be provided as a separate * argument. * * expect(new Map([['a', 1], ['b', 2]])).to.have.all.keys('a', 'b'); * expect(new Set(['a', 'b'])).to.have.all.keys('a', 'b'); * * Because `.keys` does different things based on the target's type, it's * important to check the target's type before using `.keys`. See the `.a` doc * for info on testing a target's type. * * expect({a: 1, b: 2}).to.be.an('object').that.has.all.keys('a', 'b'); * * By default, strict (`===`) equality is used to compare keys of maps and * sets. Add `.deep` earlier in the chain to use deep equality instead. See * the `deep-eql` project page for info on the deep equality algorithm: * https://github.com/chaijs/deep-eql. * * // Target set deeply (but not strictly) has key `{a: 1}` * expect(new Set([{a: 1}])).to.have.all.deep.keys([{a: 1}]); * expect(new Set([{a: 1}])).to.not.have.all.keys([{a: 1}]); * * By default, the target must have all of the given keys and no more. Add * `.any` earlier in the chain to only require that the target have at least * one of the given keys. Also, add `.not` earlier in the chain to negate * `.keys`. It's often best to add `.any` when negating `.keys`, and to use * `.all` when asserting `.keys` without negation. * * When negating `.keys`, `.any` is preferred because `.not.any.keys` asserts * exactly what's expected of the output, whereas `.not.all.keys` creates * uncertain expectations. * * // Recommended; asserts that target doesn't have any of the given keys * expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd'); * * // Not recommended; asserts that target doesn't have all of the given * // keys but may or may not have some of them * expect({a: 1, b: 2}).to.not.have.all.keys('c', 'd'); * * When asserting `.keys` without negation, `.all` is preferred because * `.all.keys` asserts exactly what's expected of the output, whereas * `.any.keys` creates uncertain expectations. * * // Recommended; asserts that target has all the given keys * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); * * // Not recommended; asserts that target has at least one of the given * // keys but may or may not have more of them * expect({a: 1, b: 2}).to.have.any.keys('a', 'b'); * * Note that `.all` is used by default when neither `.all` nor `.any` appear * earlier in the chain. However, it's often best to add `.all` anyway because * it improves readability. * * // Both assertions are identical * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); // Recommended * expect({a: 1, b: 2}).to.have.keys('a', 'b'); // Not recommended * * Add `.include` earlier in the chain to require that the target's keys be a * superset of the expected keys, rather than identical sets. * * // Target object's keys are a superset of ['a', 'b'] but not identical * expect({a: 1, b: 2, c: 3}).to.include.all.keys('a', 'b'); * expect({a: 1, b: 2, c: 3}).to.not.have.all.keys('a', 'b'); * * However, if `.any` and `.include` are combined, only the `.any` takes * effect. The `.include` is ignored in this case. * * // Both assertions are identical * expect({a: 1}).to.have.any.keys('a', 'b'); * expect({a: 1}).to.include.any.keys('a', 'b'); * * A custom error message can be given as the second argument to `expect`. * * expect({a: 1}, 'nooo why fail??').to.have.key('b'); * * The alias `.key` can be used interchangeably with `.keys`. * * @name keys * @alias key * @param {...String|Array|Object} keys * @namespace BDD * @api public */ function assertKeys (keys) { var obj = flag(this, 'object') , objType = _.type(obj) , keysType = _.type(keys) , ssfi = flag(this, 'ssfi') , isDeep = flag(this, 'deep') , str , deepStr = '' , actual , ok = true , flagMsg = flag(this, 'message'); flagMsg = flagMsg ? flagMsg + ': ' : ''; var mixedArgsMsg = flagMsg + 'when testing keys against an object or an array you must give a single Array|Object|String argument or multiple String arguments'; if (objType === 'Map' || objType === 'Set') { deepStr = isDeep ? 'deeply ' : ''; actual = []; // Map and Set '.keys' aren't supported in IE 11. Therefore, use .forEach. obj.forEach(function (val, key) { actual.push(key) }); if (keysType !== 'Array') { keys = Array.prototype.slice.call(arguments); } } else { actual = _.getOwnEnumerableProperties(obj); switch (keysType) { case 'Array': if (arguments.length > 1) { throw new AssertionError(mixedArgsMsg, undefined, ssfi); } break; case 'Object': if (arguments.length > 1) { throw new AssertionError(mixedArgsMsg, undefined, ssfi); } keys = Object.keys(keys); break; default: keys = Array.prototype.slice.call(arguments); } // Only stringify non-Symbols because Symbols would become "Symbol()" keys = keys.map(function (val) { return typeof val === 'symbol' ? val : String(val); }); } if (!keys.length) { throw new AssertionError(flagMsg + 'keys required', undefined, ssfi); } var len = keys.length , any = flag(this, 'any') , all = flag(this, 'all') , expected = keys; if (!any && !all) { all = true; } // Has any if (any) { ok = expected.some(function(expectedKey) { return actual.some(function(actualKey) { if (isDeep) { return _.eql(expectedKey, actualKey); } else { return expectedKey === actualKey; } }); }); } // Has all if (all) { ok = expected.every(function(expectedKey) { return actual.some(function(actualKey) { if (isDeep) { return _.eql(expectedKey, actualKey); } else { return expectedKey === actualKey; } }); }); if (!flag(this, 'contains')) { ok = ok && keys.length == actual.length; } } // Key string if (len > 1) { keys = keys.map(function(key) { return _.inspect(key); }); var last = keys.pop(); if (all) { str = keys.join(', ') + ', and ' + last; } if (any) { str = keys.join(', ') + ', or ' + last; } } else { str = _.inspect(keys[0]); } // Form str = (len > 1 ? 'keys ' : 'key ') + str; // Have / include str = (flag(this, 'contains') ? 'contain ' : 'have ') + str; // Assertion this.assert( ok , 'expected #{this} to ' + deepStr + str , 'expected #{this} to not ' + deepStr + str , expected.slice(0).sort(_.compareByInspect) , actual.sort(_.compareByInspect) , true ); } Assertion.addMethod('keys', assertKeys); Assertion.addMethod('key', assertKeys); /** * ### .throw([errorLike], [errMsgMatcher], [msg]) * * When no arguments are provided, `.throw` invokes the target function and * asserts that an error is thrown. * * var badFn = function () { throw new TypeError('Illegal salmon!'); }; * * expect(badFn).to.throw(); * * When one argument is provided, and it's an error constructor, `.throw` * invokes the target function and asserts that an error is thrown that's an * instance of that error constructor. * * var badFn = function () { throw new TypeError('Illegal salmon!'); }; * * expect(badFn).to.throw(TypeError); * * When one argument is provided, and it's an error instance, `.throw` invokes * the target function and asserts that an error is thrown that's strictly * (`===`) equal to that error instance. * * var err = new TypeError('Illegal salmon!'); * var badFn = function () { throw err; }; * * expect(badFn).to.throw(err); * * When one argument is provided, and it's a string, `.throw` invokes the * target function and asserts that an error is thrown with a message that * contains that string. * * var badFn = function () { throw new TypeError('Illegal salmon!'); }; * * expect(badFn).to.throw('salmon'); * * When one argument is provided, and it's a regular expression, `.throw` * invokes the target function and asserts that an error is thrown with a * message that matches that regular expression. * * var badFn = function () { throw new TypeError('Illegal salmon!'); }; * * expect(badFn).to.throw(/salmon/); * * When two arguments are provided, and the first is an error instance or * constructor, and the second is a string or regular expression, `.throw` * invokes the function and asserts that an error is thrown that fulfills both * conditions as described above. * * var err = new TypeError('Illegal salmon!'); * var badFn = function () { throw err; }; * * expect(badFn).to.throw(TypeError, 'salmon'); * expect(badFn).to.throw(TypeError, /salmon/); * expect(badFn).to.throw(err, 'salmon'); * expect(badFn).to.throw(err, /salmon/); * * Add `.not` earlier in the chain to negate `.throw`. * * var goodFn = function () {}; * * expect(goodFn).to.not.throw(); * * However, it's dangerous to negate `.throw` when providing any arguments. * The problem is that it creates uncertain expectations by asserting that the * target either doesn't throw an error, or that it throws an error but of a * different type than the given type, or that it throws an error of the given * type but with a message that doesn't include the given string. It's often * best to identify the exact output that's expected, and then write an * assertion that only accepts that exact output. * * When the target isn't expected to throw an error, it's often best to assert * exactly that. * * var goodFn = function () {}; * * expect(goodFn).to.not.throw(); // Recommended * expect(goodFn).to.not.throw(ReferenceError, 'x'); // Not recommended * * When the target is expected to throw an error, it's often best to assert * that the error is of its expected type, and has a message that includes an * expected string, rather than asserting that it doesn't have one of many * unexpected types, and doesn't have a message that includes some string. * * var badFn = function () { throw new TypeError('Illegal salmon!'); }; * * expect(badFn).to.throw(TypeError, 'salmon'); // Recommended * expect(badFn).to.not.throw(ReferenceError, 'x'); // Not recommended * * `.throw` changes the target of any assertions that follow in the chain to * be the error object that's thrown. * * var err = new TypeError('Illegal salmon!'); * err.code = 42; * var badFn = function () { throw err; }; * * expect(badFn).to.throw(TypeError).with.property('code', 42); * * `.throw` accepts an optional `msg` argument which is a custom error message * to show when the assertion fails. The message can also be given as the * second argument to `expect`. When not providing two arguments, always use * the second form. * * var goodFn = function () {}; * * expect(goodFn).to.throw(TypeError, 'x', 'nooo why fail??'); * expect(goodFn, 'nooo why fail??').to.throw(); * * Due to limitations in ES5, `.throw` may not always work as expected when * using a transpiler such as Babel or TypeScript. In particular, it may * produce unexpected results when subclassing the built-in `Error` object and * then passing the subclassed constructor to `.throw`. See your transpiler's * docs for details: * * - ([Babel](https://babeljs.io/docs/usage/caveats/#classes)) * - ([TypeScript](https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work)) * * Beware of some common mistakes when using the `throw` assertion. One common * mistake is to accidentally invoke the function yourself instead of letting * the `throw` assertion invoke the function for you. For example, when * testing if a function named `fn` throws, provide `fn` instead of `fn()` as * the target for the assertion. * * expect(fn).to.throw(); // Good! Tests `fn` as desired * expect(fn()).to.throw(); // Bad! Tests result of `fn()`, not `fn` * * If you need to assert that your function `fn` throws when passed certain * arguments, then wrap a call to `fn` inside of another function. * * expect(function () { fn(42); }).to.throw(); // Function expression * expect(() => fn(42)).to.throw(); // ES6 arrow function * * Another common mistake is to provide an object method (or any stand-alone * function that relies on `this`) as the target of the assertion. Doing so is * problematic because the `this` context will be lost when the function is * invoked by `.throw`; there's no way for it to know what `this` is supposed * to be. There are two ways around this problem. One solution is to wrap the * method or function call inside of another function. Another solution is to * use `bind`. * * expect(function () { cat.meow(); }).to.throw(); // Function expression * expect(() => cat.meow()).to.throw(); // ES6 arrow function * expect(cat.meow.bind(cat)).to.throw(); // Bind * * Finally, it's worth mentioning that it's a best practice in JavaScript to * only throw `Error` and derivatives of `Error` such as `ReferenceError`, * `TypeError`, and user-defined objects that extend `Error`. No other type of * value will generate a stack trace when initialized. With that said, the * `throw` assertion does technically support any type of value being thrown, * not just `Error` and its derivatives. * * The aliases `.throws` and `.Throw` can be used interchangeably with * `.throw`. * * @name throw * @alias throws * @alias Throw * @param {Error|ErrorConstructor} errorLike * @param {String|RegExp} errMsgMatcher error message * @param {String} msg _optional_ * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types * @returns error for chaining (null if no error) * @namespace BDD * @api public */ function assertThrows (errorLike, errMsgMatcher, msg) { if (msg) flag(this, 'message', msg); var obj = flag(this, 'object') , ssfi = flag(this, 'ssfi') , flagMsg = flag(this, 'message') , negate = flag(this, 'negate') || false; new Assertion(obj, flagMsg, ssfi, true).is.a('function'); if (errorLike instanceof RegExp || typeof errorLike === 'string') { errMsgMatcher = errorLike; errorLike = null; } var caughtErr; try { obj(); } catch (err) { caughtErr = err; } // If we have the negate flag enabled and at least one valid argument it means we do expect an error // but we want it to match a given set of criteria var everyArgIsUndefined = errorLike === undefined && errMsgMatcher === undefined; // If we've got the negate flag enabled and both args, we should only fail if both aren't compatible // See Issue #551 and PR #683@GitHub var everyArgIsDefined = Boolean(errorLike && errMsgMatcher); var errorLikeFail = false; var errMsgMatcherFail = false; // Checking if error was thrown if (everyArgIsUndefined || !everyArgIsUndefined && !negate) { // We need this to display results correctly according to their types var errorLikeString = 'an error'; if (errorLike instanceof Error) { errorLikeString = '#{exp}'; } else if (errorLike) { errorLikeString = _.checkError.getConstructorName(errorLike); } this.assert( caughtErr , 'expected #{this} to throw ' + errorLikeString , 'expected #{this} to not throw an error but #{act} was thrown' , errorLike && errorLike.toString() , (caughtErr instanceof Error ? caughtErr.toString() : (typeof caughtErr === 'string' ? caughtErr : caughtErr && _.checkError.getConstructorName(caughtErr))) ); } if (errorLike && caughtErr) { // We should compare instances only if `errorLike` is an instance of `Error` if (errorLike instanceof Error) { var isCompatibleInstance = _.checkError.compatibleInstance(caughtErr, errorLike); if (isCompatibleInstance === negate) { // These checks were created to ensure we won't fail too soon when we've got both args and a negate // See Issue #551 and PR #683@GitHub if (everyArgIsDefined && negate) { errorLikeFail = true; } else { this.assert( negate , 'expected #{this} to throw #{exp} but #{act} was thrown' , 'expected #{this} to not throw #{exp}' + (caughtErr && !negate ? ' but #{act} was thrown' : '') , errorLike.toString() , caughtErr.toString() ); } } } var isCompatibleConstructor = _.checkError.compatibleConstructor(caughtErr, errorLike); if (isCompatibleConstructor === negate) { if (everyArgIsDefined && negate) { errorLikeFail = true; } else { this.assert( negate , 'expected #{this} to throw #{exp} but #{act} was thrown' , 'expected #{this} to not throw #{exp}' + (caughtErr ? ' but #{act} was thrown' : '') , (errorLike instanceof Error ? errorLike.toString() : errorLike && _.checkError.getConstructorName(errorLike)) , (caughtErr instanceof Error ? caughtErr.toString() : caughtErr && _.checkError.getConstructorName(caughtErr)) ); } } } if (caughtErr && errMsgMatcher !== undefined && errMsgMatcher !== null) { // Here we check compatible messages var placeholder = 'including'; if (errMsgMatcher instanceof RegExp) { placeholder = 'matching' } var isCompatibleMessage = _.checkError.compatibleMessage(caughtErr, errMsgMatcher); if (isCompatibleMessage === negate) { if (everyArgIsDefined && negate) { errMsgMatcherFail = true; } else { this.assert( negate , 'expected #{this} to throw error ' + placeholder + ' #{exp} but got #{act}' , 'expected #{this} to throw error not ' + placeholder + ' #{exp}' , errMsgMatcher , _.checkError.getMessage(caughtErr) ); } } } // If both assertions failed and both should've matched we throw an error if (errorLikeFail && errMsgMatcherFail) { this.assert( negate , 'expected #{this} to throw #{exp} but #{act} was thrown' , 'expected #{this} to not throw #{exp}' + (caughtErr ? ' but #{act} was thrown' : '') , (errorLike instanceof Error ? errorLike.toString() : errorLike && _.checkError.getConstructorName(errorLike)) , (caughtErr instanceof Error ? caughtErr.toString() : caughtErr && _.checkError.getConstructorName(caughtErr)) ); } flag(this, 'object', caughtErr); }; Assertion.addMethod('throw', assertThrows); Assertion.addMethod('throws', assertThrows); Assertion.addMethod('Throw', assertThrows); /** * ### .respondTo(method[, msg]) * * When the target is a non-function object, `.respondTo` asserts that the * target has a method with the given name `method`. The method can be own or * inherited, and it can be enumerable or non-enumerable. * * function Cat () {} * Cat.prototype.meow = function () {}; * * expect(new Cat()).to.respondTo('meow'); * * When the target is a function, `.respondTo` asserts that the target's * `prototype` property has a method with the given name `method`. Again, the * method can be own or inherited, and it can be enumerable or non-enumerable. * * function Cat () {} * Cat.prototype.meow = function () {}; * * expect(Cat).to.respondTo('meow'); * * Add `.itself` earlier in the chain to force `.respondTo` to treat the * target as a non-function object, even if it's a function. Thus, it asserts * that the target has a method with the given name `method`, rather than * asserting that the target's `prototype` property has a method with the * given name `method`. * * function Cat () {} * Cat.prototype.meow = function () {}; * Cat.hiss = function () {}; * * expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow'); * * When not adding `.itself`, it's important to check the target's type before * using `.respondTo`. See the `.a` doc for info on checking a target's type. * * function Cat () {} * Cat.prototype.meow = function () {}; * * expect(new Cat()).to.be.an('object').that.respondsTo('meow'); * * Add `.not` earlier in the chain to negate `.respondTo`. * * function Dog () {} * Dog.prototype.bark = function () {}; * * expect(new Dog()).to.not.respondTo('meow'); * * `.respondTo` accepts an optional `msg` argument which is a custom error * message to show when the assertion fails. The message can also be given as * the second argument to `expect`. * * expect({}).to.respondTo('meow', 'nooo why fail??'); * expect({}, 'nooo why fail??').to.respondTo('meow'); * * The alias `.respondsTo` can be used interchangeably with `.respondTo`. * * @name respondTo * @alias respondsTo * @param {String} method * @param {String} msg _optional_ * @namespace BDD * @api public */ function respondTo (method, msg) { if (msg) flag(this, 'message', msg); var obj = flag(this, 'object') , itself = flag(this, 'itself') , context = ('function' === typeof obj && !itself) ? obj.prototype[method] : obj[method]; this.assert( 'function' === typeof context , 'expected #{this} to respond to ' + _.inspect(method) , 'expected #{this} to not respond to ' + _.inspect(method) ); } Assertion.addMethod('respondTo', respondTo); Assertion.addMethod('respondsTo', respondTo); /** * ### .itself * * Forces all `.respondTo` assertions that follow in the chain to behave as if * the target is a non-function object, even if it's a function. Thus, it * causes `.respondTo` to assert that the target has a method with the given * name, rather than asserting that the target's `prototype` property has a * method with the given name. * * function Cat () {} * Cat.prototype.meow = function () {}; * Cat.hiss = function () {}; * * expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow'); * * @name itself * @namespace BDD * @api public */ Assertion.addProperty('itself', function () { flag(this, 'itself', true); }); /** * ### .satisfy(matcher[, msg]) * * Invokes the given `matcher` function with the target being passed as the * first argument, and asserts that the value returned is truthy. * * expect(1).to.satisfy(function(num) { * return num > 0; * }); * * Add `.not` earlier in the chain to negate `.satisfy`. * * expect(1).to.not.satisfy(function(num) { * return num > 2; * }); * * `.satisfy` accepts an optional `msg` argument which is a custom error * message to show when the assertion fails. The message can also be given as * the second argument to `expect`. * * expect(1).to.satisfy(function(num) { * return num > 2; * }, 'nooo why fail??'); * * expect(1, 'nooo why fail??').to.satisfy(function(num) { * return num > 2; * }); * * The alias `.satisfies` can be used interchangeably with `.satisfy`. * * @name satisfy * @alias satisfies * @param {Function} matcher * @param {String} msg _optional_ * @namespace BDD * @api public */ function satisfy (matcher, msg) { if (msg) flag(this, 'message', msg); var obj = flag(this, 'object'); var result = matcher(obj); this.assert( result , 'expected #{this} to satisfy ' + _.objDisplay(matcher) , 'expected #{this} to not satisfy' + _.objDisplay(matcher) , flag(this, 'negate') ? false : true , result ); } Assertion.addMethod('satisfy', satisfy); Assertion.addMethod('satisfies', satisfy); /** * ### .closeTo(expected, delta[, msg]) * * Asserts that the target is a number that's within a given +/- `delta` range * of the given number `expected`. However, it's often best to assert that the * target is equal to its expected value. * * // Recommended * expect(1.5).to.equal(1.5); * * // Not recommended * expect(1.5).to.be.closeTo(1, 0.5); * expect(1.5).to.be.closeTo(2, 0.5); * expect(1.5).to.be.closeTo(1, 1); * * Add `.not` earlier in the chain to negate `.closeTo`. * * expect(1.5).to.equal(1.5); // Recommended * expect(1.5).to.not.be.closeTo(3, 1); // Not recommended * * `.closeTo` accepts an optional `msg` argument which is a custom error * message to show when the assertion fails. The message can also be given as * the second argument to `expect`. * * expect(1.5).to.be.closeTo(3, 1, 'nooo why fail??'); * expect(1.5, 'nooo why fail??').to.be.closeTo(3, 1); * * The alias `.approximately` can be used interchangeably with `.closeTo`. * * @name closeTo * @alias approximately * @param {Number} expected * @param {Number} delta * @param {String} msg _optional_ * @namespace BDD * @api public */ function closeTo(expected, delta, msg) { if (msg) flag(this, 'message', msg); var obj = flag(this, 'object') , flagMsg = flag(this, 'message') , ssfi = flag(this, 'ssfi'); new Assertion(obj, flagMsg, ssfi, true).is.a('number'); if (typeof expected !== 'number' || typeof delta !== 'number') { flagMsg = flagMsg ? flagMsg + ': ' : ''; var deltaMessage = delta === undefined ? ", and a delta is required" : ""; throw new AssertionError( flagMsg + 'the arguments to closeTo or approximately must be numbers' + deltaMessage, undefined, ssfi ); } this.assert( Math.abs(obj - expected) <= delta , 'expected #{this} to be close to ' + expected + ' +/- ' + delta , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta ); } Assertion.addMethod('closeTo', closeTo); Assertion.addMethod('approximately', closeTo); // Note: Duplicates are ignored if testing for inclusion instead of sameness. function isSubsetOf(subset, superset, cmp, contains, ordered) { if (!contains) { if (subset.length !== superset.length) return false; superset = superset.slice(); } return subset.every(function(elem, idx) { if (ordered) return cmp ? cmp(elem, superset[idx]) : elem === superset[idx]; if (!cmp) { var matchIdx = superset.indexOf(elem); if (matchIdx === -1) return false; // Remove match from superset so not counted twice if duplicate in subset. if (!contains) superset.splice(matchIdx, 1); return true; } return superset.some(function(elem2, matchIdx) { if (!cmp(elem, elem2)) return false; // Remove match from superset so not counted twice if duplicate in subset. if (!contains) superset.splice(matchIdx, 1); return true; }); }); } /** * ### .members(set[, msg]) * * Asserts that the target array has the same members as the given array * `set`. * * expect([1, 2, 3]).to.have.members([2, 1, 3]); * expect([1, 2, 2]).to.have.members([2, 1, 2]); * * By default, members are compared using strict (`===`) equality. Add `.deep` * earlier in the chain to use deep equality instead. See the `deep-eql` * project page for info on the deep equality algorithm: * https://github.com/chaijs/deep-eql. * * // Target array deeply (but not strictly) has member `{a: 1}` * expect([{a: 1}]).to.have.deep.members([{a: 1}]); * expect([{a: 1}]).to.not.have.members([{a: 1}]); * * By default, order doesn't matter. Add `.ordered` earlier in the chain to * require that members appear in the same order. * * expect([1, 2, 3]).to.have.ordered.members([1, 2, 3]); * expect([1, 2, 3]).to.have.members([2, 1, 3]) * .but.not.ordered.members([2, 1, 3]); * * By default, both arrays must be the same size. Add `.include` earlier in * the chain to require that the target's members be a superset of the * expected members. Note that duplicates are ignored in the subset when * `.include` is added. * * // Target array is a superset of [1, 2] but not identical * expect([1, 2, 3]).to.include.members([1, 2]); * expect([1, 2, 3]).to.not.have.members([1, 2]); * * // Duplicates in the subset are ignored * expect([1, 2, 3]).to.include.members([1, 2, 2, 2]); * * `.deep`, `.ordered`, and `.include` can all be combined. However, if * `.include` and `.ordered` are combined, the ordering begins at the start of * both arrays. * * expect([{a: 1}, {b: 2}, {c: 3}]) * .to.include.deep.ordered.members([{a: 1}, {b: 2}]) * .but.not.include.deep.ordered.members([{b: 2}, {c: 3}]); * * Add `.not` earlier in the chain to negate `.members`. However, it's * dangerous to do so. The problem is that it creates uncertain expectations * by asserting that the target array doesn't have all of the same members as * the given array `set` but may or may not have some of them. It's often best * to identify the exact output that's expected, and then write an assertion * that only accepts that exact output. * * expect([1, 2]).to.not.include(3).and.not.include(4); // Recommended * expect([1, 2]).to.not.have.members([3, 4]); // Not recommended * * `.members` accepts an optional `msg` argument which is a custom error * message to show when the assertion fails. The message can also be given as * the second argument to `expect`. * * expect([1, 2]).to.have.members([1, 2, 3], 'nooo why fail??'); * expect([1, 2], 'nooo why fail??').to.have.members([1, 2, 3]); * * @name members * @param {Array} set * @param {String} msg _optional_ * @namespace BDD * @api public */ Assertion.addMethod('members', function (subset, msg) { if (msg) flag(this, 'message', msg); var obj = flag(this, 'object') , flagMsg = flag(this, 'message') , ssfi = flag(this, 'ssfi'); new Assertion(obj, flagMsg, ssfi, true).to.be.an('array'); new Assertion(subset, flagMsg, ssfi, true).to.be.an('array'); var contains = flag(this, 'contains'); var ordered = flag(this, 'ordered'); var subject, failMsg, failNegateMsg; if (contains) { subject = ordered ? 'an ordered superset' : 'a superset'; failMsg = 'expected #{this} to be ' + subject + ' of #{exp}'; failNegateMsg = 'expected #{this} to not be ' + subject + ' of #{exp}'; } else { subject = ordered ? 'ordered members' : 'members'; failMsg = 'expected #{this} to have the same ' + subject + ' as #{exp}'; failNegateMsg = 'expected #{this} to not have the same ' + subject + ' as #{exp}'; } var cmp = flag(this, 'deep') ? _.eql : undefined; this.assert( isSubsetOf(subset, obj, cmp, contains, ordered) , failMsg , failNegateMsg , subset , obj , true ); }); /** * ### .oneOf(list[, msg]) * * Asserts that the target is a member of the given array `list`. However, * it's often best to assert that the target is equal to its expected value. * * expect(1).to.equal(1); // Recommended * expect(1).to.be.oneOf([1, 2, 3]); // Not recommended * * Comparisons are performed using strict (`===`) equality. * * Add `.not` earlier in the chain to negate `.oneOf`. * * expect(1).to.equal(1); // Recommended * expect(1).to.not.be.oneOf([2, 3, 4]); // Not recommended * * It can also be chained with `.contain` or `.include`, which will work with * both arrays and strings: * * expect('Today is sunny').to.contain.oneOf(['sunny', 'cloudy']) * expect('Today is rainy').to.not.contain.oneOf(['sunny', 'cloudy']) * expect([1,2,3]).to.contain.oneOf([3,4,5]) * expect([1,2,3]).to.not.contain.oneOf([4,5,6]) * * `.oneOf` accepts an optional `msg` argument which is a custom error message * to show when the assertion fails. The message can also be given as the * second argument to `expect`. * * expect(1).to.be.oneOf([2, 3, 4], 'nooo why fail??'); * expect(1, 'nooo why fail??').to.be.oneOf([2, 3, 4]); * * @name oneOf * @param {Array<*>} list * @param {String} msg _optional_ * @namespace BDD * @api public */ function oneOf (list, msg) { if (msg) flag(this, 'message', msg); var expected = flag(this, 'object') , flagMsg = flag(this, 'message') , ssfi = flag(this, 'ssfi') , contains = flag(this, 'contains') , isDeep = flag(this, 'deep'); new Assertion(list, flagMsg, ssfi, true).to.be.an('array'); if (contains) { this.assert( list.some(function(possibility) { return expected.indexOf(possibility) > -1 }) , 'expected #{this} to contain one of #{exp}' , 'expected #{this} to not contain one of #{exp}' , list , expected ); } else { if (isDeep) { this.assert( list.some(function(possibility) { return _.eql(expected, possibility) }) , 'expected #{this} to deeply equal one of #{exp}' , 'expected #{this} to deeply equal one of #{exp}' , list , expected ); } else { this.assert( list.indexOf(expected) > -1 , 'expected #{this} to be one of #{exp}' , 'expected #{this} to not be one of #{exp}' , list , expected ); } } } Assertion.addMethod('oneOf', oneOf); /** * ### .change(subject[, prop[, msg]]) * * When one argument is provided, `.change` asserts that the given function * `subject` returns a different value when it's invoked before the target * function compared to when it's invoked afterward. However, it's often best * to assert that `subject` is equal to its expected value. * * var dots = '' * , addDot = function () { dots += '.'; } * , getDots = function () { return dots; }; * * // Recommended * expect(getDots()).to.equal(''); * addDot(); * expect(getDots()).to.equal('.'); * * // Not recommended * expect(addDot).to.change(getDots); * * When two arguments are provided, `.change` asserts that the value of the * given object `subject`'s `prop` property is different before invoking the * target function compared to afterward. * * var myObj = {dots: ''} * , addDot = function () { myObj.dots += '.'; }; * * // Recommended * expect(myObj).to.have.property('dots', ''); * addDot(); * expect(myObj).to.have.property('dots', '.'); * * // Not recommended * expect(addDot).to.change(myObj, 'dots'); * * Strict (`===`) equality is used to compare before and after values. * * Add `.not` earlier in the chain to negate `.change`. * * var dots = '' * , noop = function () {} * , getDots = function () { return dots; }; * * expect(noop).to.not.change(getDots); * * var myObj = {dots: ''} * , noop = function () {}; * * expect(noop).to.not.change(myObj, 'dots'); * * `.change` accepts an optional `msg` argument which is a custom error * message to show when the assertion fails. The message can also be given as * the second argument to `expect`. When not providing two arguments, always * use the second form. * * var myObj = {dots: ''} * , addDot = function () { myObj.dots += '.'; }; * * expect(addDot).to.not.change(myObj, 'dots', 'nooo why fail??'); * * var dots = '' * , addDot = function () { dots += '.'; } * , getDots = function () { return dots; }; * * expect(addDot, 'nooo why fail??').to.not.change(getDots); * * `.change` also causes all `.by` assertions that follow in the chain to * assert how much a numeric subject was increased or decreased by. However, * it's dangerous to use `.change.by`. The problem is that it creates * uncertain expectations by asserting that the subject either increases by * the given delta, or that it decreases by the given delta. It's often best * to identify the exact output that's expected, and then write an assertion * that only accepts that exact output. * * var myObj = {val: 1} * , addTwo = function () { myObj.val += 2; } * , subtractTwo = function () { myObj.val -= 2; }; * * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended * expect(addTwo).to.change(myObj, 'val').by(2); // Not recommended * * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended * expect(subtractTwo).to.change(myObj, 'val').by(2); // Not recommended * * The alias `.changes` can be used interchangeably with `.change`. * * @name change * @alias changes * @param {String} subject * @param {String} prop name _optional_ * @param {String} msg _optional_ * @namespace BDD * @api public */ function assertChanges (subject, prop, msg) { if (msg) flag(this, 'message', msg); var fn = flag(this, 'object') , flagMsg = flag(this, 'message') , ssfi = flag(this, 'ssfi'); new Assertion(fn, flagMsg, ssfi, true).is.a('function'); var initial; if (!prop) { new Assertion(subject, flagMsg, ssfi, true).is.a('function'); initial = subject(); } else { new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop); initial = subject[prop]; } fn(); var final = prop === undefined || prop === null ? subject() : subject[prop]; var msgObj = prop === undefined || prop === null ? initial : '.' + prop; // This gets flagged because of the .by(delta) assertion flag(this, 'deltaMsgObj', msgObj); flag(this, 'initialDeltaValue', initial); flag(this, 'finalDeltaValue', final); flag(this, 'deltaBehavior', 'change'); flag(this, 'realDelta', final !== initial); this.assert( initial !== final , 'expected ' + msgObj + ' to change' , 'expected ' + msgObj + ' to not change' ); } Assertion.addMethod('change', assertChanges); Assertion.addMethod('changes', assertChanges); /** * ### .increase(subject[, prop[, msg]]) * * When one argument is provided, `.increase` asserts that the given function * `subject` returns a greater number when it's invoked after invoking the * target function compared to when it's invoked beforehand. `.increase` also * causes all `.by` assertions that follow in the chain to assert how much * greater of a number is returned. It's often best to assert that the return * value increased by the expected amount, rather than asserting it increased * by any amount. * * var val = 1 * , addTwo = function () { val += 2; } * , getVal = function () { return val; }; * * expect(addTwo).to.increase(getVal).by(2); // Recommended * expect(addTwo).to.increase(getVal); // Not recommended * * When two arguments are provided, `.increase` asserts that the value of the * given object `subject`'s `prop` property is greater after invoking the * target function compared to beforehand. * * var myObj = {val: 1} * , addTwo = function () { myObj.val += 2; }; * * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended * expect(addTwo).to.increase(myObj, 'val'); // Not recommended * * Add `.not` earlier in the chain to negate `.increase`. However, it's * dangerous to do so. The problem is that it creates uncertain expectations * by asserting that the subject either decreases, or that it stays the same. * It's often best to identify the exact output that's expected, and then * write an assertion that only accepts that exact output. * * When the subject is expected to decrease, it's often best to assert that it * decreased by the expected amount. * * var myObj = {val: 1} * , subtractTwo = function () { myObj.val -= 2; }; * * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended * expect(subtractTwo).to.not.increase(myObj, 'val'); // Not recommended * * When the subject is expected to stay the same, it's often best to assert * exactly that. * * var myObj = {val: 1} * , noop = function () {}; * * expect(noop).to.not.change(myObj, 'val'); // Recommended * expect(noop).to.not.increase(myObj, 'val'); // Not recommended * * `.increase` accepts an optional `msg` argument which is a custom error * message to show when the assertion fails. The message can also be given as * the second argument to `expect`. When not providing two arguments, always * use the second form. * * var myObj = {val: 1} * , noop = function () {}; * * expect(noop).to.increase(myObj, 'val', 'nooo why fail??'); * * var val = 1 * , noop = function () {} * , getVal = function () { return val; }; * * expect(noop, 'nooo why fail??').to.increase(getVal); * * The alias `.increases` can be used interchangeably with `.increase`. * * @name increase * @alias increases * @param {String|Function} subject * @param {String} prop name _optional_ * @param {String} msg _optional_ * @namespace BDD * @api public */ function assertIncreases (subject, prop, msg) { if (msg) flag(this, 'message', msg); var fn = flag(this, 'object') , flagMsg = flag(this, 'message') , ssfi = flag(this, 'ssfi'); new Assertion(fn, flagMsg, ssfi, true).is.a('function'); var initial; if (!prop) { new Assertion(subject, flagMsg, ssfi, true).is.a('function'); initial = subject(); } else { new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop); initial = subject[prop]; } // Make sure that the target is a number new Assertion(initial, flagMsg, ssfi, true).is.a('number'); fn(); var final = prop === undefined || prop === null ? subject() : subject[prop]; var msgObj = prop === undefined || prop === null ? initial : '.' + prop; flag(this, 'deltaMsgObj', msgObj); flag(this, 'initialDeltaValue', initial); flag(this, 'finalDeltaValue', final); flag(this, 'deltaBehavior', 'increase'); flag(this, 'realDelta', final - initial); this.assert( final - initial > 0 , 'expected ' + msgObj + ' to increase' , 'expected ' + msgObj + ' to not increase' ); } Assertion.addMethod('increase', assertIncreases); Assertion.addMethod('increases', assertIncreases); /** * ### .decrease(subject[, prop[, msg]]) * * When one argument is provided, `.decrease` asserts that the given function * `subject` returns a lesser number when it's invoked after invoking the * target function compared to when it's invoked beforehand. `.decrease` also * causes all `.by` assertions that follow in the chain to assert how much * lesser of a number is returned. It's often best to assert that the return * value decreased by the expected amount, rather than asserting it decreased * by any amount. * * var val = 1 * , subtractTwo = function () { val -= 2; } * , getVal = function () { return val; }; * * expect(subtractTwo).to.decrease(getVal).by(2); // Recommended * expect(subtractTwo).to.decrease(getVal); // Not recommended * * When two arguments are provided, `.decrease` asserts that the value of the * given object `subject`'s `prop` property is lesser after invoking the * target function compared to beforehand. * * var myObj = {val: 1} * , subtractTwo = function () { myObj.val -= 2; }; * * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended * expect(subtractTwo).to.decrease(myObj, 'val'); // Not recommended * * Add `.not` earlier in the chain to negate `.decrease`. However, it's * dangerous to do so. The problem is that it creates uncertain expectations * by asserting that the subject either increases, or that it stays the same. * It's often best to identify the exact output that's expected, and then * write an assertion that only accepts that exact output. * * When the subject is expected to increase, it's often best to assert that it * increased by the expected amount. * * var myObj = {val: 1} * , addTwo = function () { myObj.val += 2; }; * * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended * expect(addTwo).to.not.decrease(myObj, 'val'); // Not recommended * * When the subject is expected to stay the same, it's often best to assert * exactly that. * * var myObj = {val: 1} * , noop = function () {}; * * expect(noop).to.not.change(myObj, 'val'); // Recommended * expect(noop).to.not.decrease(myObj, 'val'); // Not recommended * * `.decrease` accepts an optional `msg` argument which is a custom error * message to show when the assertion fails. The message can also be given as * the second argument to `expect`. When not providing two arguments, always * use the second form. * * var myObj = {val: 1} * , noop = function () {}; * * expect(noop).to.decrease(myObj, 'val', 'nooo why fail??'); * * var val = 1 * , noop = function () {} * , getVal = function () { return val; }; * * expect(noop, 'nooo why fail??').to.decrease(getVal); * * The alias `.decreases` can be used interchangeably with `.decrease`. * * @name decrease * @alias decreases * @param {String|Function} subject * @param {String} prop name _optional_ * @param {String} msg _optional_ * @namespace BDD * @api public */ function assertDecreases (subject, prop, msg) { if (msg) flag(this, 'message', msg); var fn = flag(this, 'object') , flagMsg = flag(this, 'message') , ssfi = flag(this, 'ssfi'); new Assertion(fn, flagMsg, ssfi, true).is.a('function'); var initial; if (!prop) { new Assertion(subject, flagMsg, ssfi, true).is.a('function'); initial = subject(); } else { new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop); initial = subject[prop]; } // Make sure that the target is a number new Assertion(initial, flagMsg, ssfi, true).is.a('number'); fn(); var final = prop === undefined || prop === null ? subject() : subject[prop]; var msgObj = prop === undefined || prop === null ? initial : '.' + prop; flag(this, 'deltaMsgObj', msgObj); flag(this, 'initialDeltaValue', initial); flag(this, 'finalDeltaValue', final); flag(this, 'deltaBehavior', 'decrease'); flag(this, 'realDelta', initial - final); this.assert( final - initial < 0 , 'expected ' + msgObj + ' to decrease' , 'expected ' + msgObj + ' to not decrease' ); } Assertion.addMethod('decrease', assertDecreases); Assertion.addMethod('decreases', assertDecreases); /** * ### .by(delta[, msg]) * * When following an `.increase` assertion in the chain, `.by` asserts that * the subject of the `.increase` assertion increased by the given `delta`. * * var myObj = {val: 1} * , addTwo = function () { myObj.val += 2; }; * * expect(addTwo).to.increase(myObj, 'val').by(2); * * When following a `.decrease` assertion in the chain, `.by` asserts that the * subject of the `.decrease` assertion decreased by the given `delta`. * * var myObj = {val: 1} * , subtractTwo = function () { myObj.val -= 2; }; * * expect(subtractTwo).to.decrease(myObj, 'val').by(2); * * When following a `.change` assertion in the chain, `.by` asserts that the * subject of the `.change` assertion either increased or decreased by the * given `delta`. However, it's dangerous to use `.change.by`. The problem is * that it creates uncertain expectations. It's often best to identify the * exact output that's expected, and then write an assertion that only accepts * that exact output. * * var myObj = {val: 1} * , addTwo = function () { myObj.val += 2; } * , subtractTwo = function () { myObj.val -= 2; }; * * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended * expect(addTwo).to.change(myObj, 'val').by(2); // Not recommended * * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended * expect(subtractTwo).to.change(myObj, 'val').by(2); // Not recommended * * Add `.not` earlier in the chain to negate `.by`. However, it's often best * to assert that the subject changed by its expected delta, rather than * asserting that it didn't change by one of countless unexpected deltas. * * var myObj = {val: 1} * , addTwo = function () { myObj.val += 2; }; * * // Recommended * expect(addTwo).to.increase(myObj, 'val').by(2); * * // Not recommended * expect(addTwo).to.increase(myObj, 'val').but.not.by(3); * * `.by` accepts an optional `msg` argument which is a custom error message to * show when the assertion fails. The message can also be given as the second * argument to `expect`. * * var myObj = {val: 1} * , addTwo = function () { myObj.val += 2; }; * * expect(addTwo).to.increase(myObj, 'val').by(3, 'nooo why fail??'); * expect(addTwo, 'nooo why fail??').to.increase(myObj, 'val').by(3); * * @name by * @param {Number} delta * @param {String} msg _optional_ * @namespace BDD * @api public */ function assertDelta(delta, msg) { if (msg) flag(this, 'message', msg); var msgObj = flag(this, 'deltaMsgObj'); var initial = flag(this, 'initialDeltaValue'); var final = flag(this, 'finalDeltaValue'); var behavior = flag(this, 'deltaBehavior'); var realDelta = flag(this, 'realDelta'); var expression; if (behavior === 'change') { expression = Math.abs(final - initial) === Math.abs(delta); } else { expression = realDelta === Math.abs(delta); } this.assert( expression , 'expected ' + msgObj + ' to ' + behavior + ' by ' + delta , 'expected ' + msgObj + ' to not ' + behavior + ' by ' + delta ); } Assertion.addMethod('by', assertDelta); /** * ### .extensible * * Asserts that the target is extensible, which means that new properties can * be added to it. Primitives are never extensible. * * expect({a: 1}).to.be.extensible; * * Add `.not` earlier in the chain to negate `.extensible`. * * var nonExtensibleObject = Object.preventExtensions({}) * , sealedObject = Object.seal({}) * , frozenObject = Object.freeze({}); * * expect(nonExtensibleObject).to.not.be.extensible; * expect(sealedObject).to.not.be.extensible; * expect(frozenObject).to.not.be.extensible; * expect(1).to.not.be.extensible; * * A custom error message can be given as the second argument to `expect`. * * expect(1, 'nooo why fail??').to.be.extensible; * * @name extensible * @namespace BDD * @api public */ Assertion.addProperty('extensible', function() { var obj = flag(this, 'object'); // In ES5, if the argument to this method is a primitive, then it will cause a TypeError. // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible // The following provides ES6 behavior for ES5 environments. var isExtensible = obj === Object(obj) && Object.isExtensible(obj); this.assert( isExtensible , 'expected #{this} to be extensible' , 'expected #{this} to not be extensible' ); }); /** * ### .sealed * * Asserts that the target is sealed, which means that new properties can't be * added to it, and its existing properties can't be reconfigured or deleted. * However, it's possible that its existing properties can still be reassigned * to different values. Primitives are always sealed. * * var sealedObject = Object.seal({}); * var frozenObject = Object.freeze({}); * * expect(sealedObject).to.be.sealed; * expect(frozenObject).to.be.sealed; * expect(1).to.be.sealed; * * Add `.not` earlier in the chain to negate `.sealed`. * * expect({a: 1}).to.not.be.sealed; * * A custom error message can be given as the second argument to `expect`. * * expect({a: 1}, 'nooo why fail??').to.be.sealed; * * @name sealed * @namespace BDD * @api public */ Assertion.addProperty('sealed', function() { var obj = flag(this, 'object'); // In ES5, if the argument to this method is a primitive, then it will cause a TypeError. // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true. // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed // The following provides ES6 behavior for ES5 environments. var isSealed = obj === Object(obj) ? Object.isSealed(obj) : true; this.assert( isSealed , 'expected #{this} to be sealed' , 'expected #{this} to not be sealed' ); }); /** * ### .frozen * * Asserts that the target is frozen, which means that new properties can't be * added to it, and its existing properties can't be reassigned to different * values, reconfigured, or deleted. Primitives are always frozen. * * var frozenObject = Object.freeze({}); * * expect(frozenObject).to.be.frozen; * expect(1).to.be.frozen; * * Add `.not` earlier in the chain to negate `.frozen`. * * expect({a: 1}).to.not.be.frozen; * * A custom error message can be given as the second argument to `expect`. * * expect({a: 1}, 'nooo why fail??').to.be.frozen; * * @name frozen * @namespace BDD * @api public */ Assertion.addProperty('frozen', function() { var obj = flag(this, 'object'); // In ES5, if the argument to this method is a primitive, then it will cause a TypeError. // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true. // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen // The following provides ES6 behavior for ES5 environments. var isFrozen = obj === Object(obj) ? Object.isFrozen(obj) : true; this.assert( isFrozen , 'expected #{this} to be frozen' , 'expected #{this} to not be frozen' ); }); /** * ### .finite * * Asserts that the target is a number, and isn't `NaN` or positive/negative * `Infinity`. * * expect(1).to.be.finite; * * Add `.not` earlier in the chain to negate `.finite`. However, it's * dangerous to do so. The problem is that it creates uncertain expectations * by asserting that the subject either isn't a number, or that it's `NaN`, or * that it's positive `Infinity`, or that it's negative `Infinity`. It's often * best to identify the exact output that's expected, and then write an * assertion that only accepts that exact output. * * When the target isn't expected to be a number, it's often best to assert * that it's the expected type, rather than asserting that it isn't one of * many unexpected types. * * expect('foo').to.be.a('string'); // Recommended * expect('foo').to.not.be.finite; // Not recommended * * When the target is expected to be `NaN`, it's often best to assert exactly * that. * * expect(NaN).to.be.NaN; // Recommended * expect(NaN).to.not.be.finite; // Not recommended * * When the target is expected to be positive infinity, it's often best to * assert exactly that. * * expect(Infinity).to.equal(Infinity); // Recommended * expect(Infinity).to.not.be.finite; // Not recommended * * When the target is expected to be negative infinity, it's often best to * assert exactly that. * * expect(-Infinity).to.equal(-Infinity); // Recommended * expect(-Infinity).to.not.be.finite; // Not recommended * * A custom error message can be given as the second argument to `expect`. * * expect('foo', 'nooo why fail??').to.be.finite; * * @name finite * @namespace BDD * @api public */ Assertion.addProperty('finite', function(msg) { var obj = flag(this, 'object'); this.assert( typeof obj === 'number' && isFinite(obj) , 'expected #{this} to be a finite number' , 'expected #{this} to not be a finite number' ); });};
},{}],6:[function(require,module,exports){/*! * chai * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */module.exports = function (chai, util) { /*! * Chai dependencies. */ var Assertion = chai.Assertion , flag = util.flag; /*! * Module export. */ /** * ### assert(expression, message) * * Write your own test expressions. * * assert('foo' !== 'bar', 'foo is not bar'); * assert(Array.isArray([]), 'empty arrays are arrays'); * * @param {Mixed} expression to test for truthiness * @param {String} message to display on error * @name assert * @namespace Assert * @api public */ var assert = chai.assert = function (express, errmsg) { var test = new Assertion(null, null, chai.assert, true); test.assert( express , errmsg , '[ negation message unavailable ]' ); }; /** * ### .fail([message]) * ### .fail(actual, expected, [message], [operator]) * * Throw a failure. Node.js `assert` module-compatible. * * assert.fail(); * assert.fail("custom error message"); * assert.fail(1, 2); * assert.fail(1, 2, "custom error message"); * assert.fail(1, 2, "custom error message", ">"); * assert.fail(1, 2, undefined, ">"); * * @name fail * @param {Mixed} actual * @param {Mixed} expected * @param {String} message * @param {String} operator * @namespace Assert * @api public */ assert.fail = function (actual, expected, message, operator) { if (arguments.length < 2) { // Comply with Node's fail([message]) interface message = actual; actual = undefined; } message = message || 'assert.fail()'; throw new chai.AssertionError(message, { actual: actual , expected: expected , operator: operator }, assert.fail); }; /** * ### .isOk(object, [message]) * * Asserts that `object` is truthy. * * assert.isOk('everything', 'everything is ok'); * assert.isOk(false, 'this will fail'); * * @name isOk * @alias ok * @param {Mixed} object to test * @param {String} message * @namespace Assert * @api public */ assert.isOk = function (val, msg) { new Assertion(val, msg, assert.isOk, true).is.ok; }; /** * ### .isNotOk(object, [message]) * * Asserts that `object` is falsy. * * assert.isNotOk('everything', 'this will fail'); * assert.isNotOk(false, 'this will pass'); * * @name isNotOk * @alias notOk * @param {Mixed} object to test * @param {String} message * @namespace Assert * @api public */ assert.isNotOk = function (val, msg) { new Assertion(val, msg, assert.isNotOk, true).is.not.ok; }; /** * ### .equal(actual, expected, [message]) * * Asserts non-strict equality (`==`) of `actual` and `expected`. * * assert.equal(3, '3', '== coerces values to strings'); * * @name equal * @param {Mixed} actual * @param {Mixed} expected * @param {String} message * @namespace Assert * @api public */ assert.equal = function (act, exp, msg) { var test = new Assertion(act, msg, assert.equal, true); test.assert( exp == flag(test, 'object') , 'expected #{this} to equal #{exp}' , 'expected #{this} to not equal #{act}' , exp , act , true ); }; /** * ### .notEqual(actual, expected, [message]) * * Asserts non-strict inequality (`!=`) of `actual` and `expected`. * * assert.notEqual(3, 4, 'these numbers are not equal'); * * @name notEqual * @param {Mixed} actual * @param {Mixed} expected * @param {String} message * @namespace Assert * @api public */ assert.notEqual = function (act, exp, msg) { var test = new Assertion(act, msg, assert.notEqual, true); test.assert( exp != flag(test, 'object') , 'expected #{this} to not equal #{exp}' , 'expected #{this} to equal #{act}' , exp , act , true ); }; /** * ### .strictEqual(actual, expected, [message]) * * Asserts strict equality (`===`) of `actual` and `expected`. * * assert.strictEqual(true, true, 'these booleans are strictly equal'); * * @name strictEqual * @param {Mixed} actual * @param {Mixed} expected * @param {String} message * @namespace Assert * @api public */ assert.strictEqual = function (act, exp, msg) { new Assertion(act, msg, assert.strictEqual, true).to.equal(exp); }; /** * ### .notStrictEqual(actual, expected, [message]) * * Asserts strict inequality (`!==`) of `actual` and `expected`. * * assert.notStrictEqual(3, '3', 'no coercion for strict equality'); * * @name notStrictEqual * @param {Mixed} actual * @param {Mixed} expected * @param {String} message * @namespace Assert * @api public */ assert.notStrictEqual = function (act, exp, msg) { new Assertion(act, msg, assert.notStrictEqual, true).to.not.equal(exp); }; /** * ### .deepEqual(actual, expected, [message]) * * Asserts that `actual` is deeply equal to `expected`. * * assert.deepEqual({ tea: 'green' }, { tea: 'green' }); * * @name deepEqual * @param {Mixed} actual * @param {Mixed} expected * @param {String} message * @alias deepStrictEqual * @namespace Assert * @api public */ assert.deepEqual = assert.deepStrictEqual = function (act, exp, msg) { new Assertion(act, msg, assert.deepEqual, true).to.eql(exp); }; /** * ### .notDeepEqual(actual, expected, [message]) * * Assert that `actual` is not deeply equal to `expected`. * * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' }); * * @name notDeepEqual * @param {Mixed} actual * @param {Mixed} expected * @param {String} message * @namespace Assert * @api public */ assert.notDeepEqual = function (act, exp, msg) { new Assertion(act, msg, assert.notDeepEqual, true).to.not.eql(exp); }; /** * ### .isAbove(valueToCheck, valueToBeAbove, [message]) * * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove`. * * assert.isAbove(5, 2, '5 is strictly greater than 2'); * * @name isAbove * @param {Mixed} valueToCheck * @param {Mixed} valueToBeAbove * @param {String} message * @namespace Assert * @api public */ assert.isAbove = function (val, abv, msg) { new Assertion(val, msg, assert.isAbove, true).to.be.above(abv); }; /** * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message]) * * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast`. * * assert.isAtLeast(5, 2, '5 is greater or equal to 2'); * assert.isAtLeast(3, 3, '3 is greater or equal to 3'); * * @name isAtLeast * @param {Mixed} valueToCheck * @param {Mixed} valueToBeAtLeast * @param {String} message * @namespace Assert * @api public */ assert.isAtLeast = function (val, atlst, msg) { new Assertion(val, msg, assert.isAtLeast, true).to.be.least(atlst); }; /** * ### .isBelow(valueToCheck, valueToBeBelow, [message]) * * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow`. * * assert.isBelow(3, 6, '3 is strictly less than 6'); * * @name isBelow * @param {Mixed} valueToCheck * @param {Mixed} valueToBeBelow * @param {String} message * @namespace Assert * @api public */ assert.isBelow = function (val, blw, msg) { new Assertion(val, msg, assert.isBelow, true).to.be.below(blw); }; /** * ### .isAtMost(valueToCheck, valueToBeAtMost, [message]) * * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost`. * * assert.isAtMost(3, 6, '3 is less than or equal to 6'); * assert.isAtMost(4, 4, '4 is less than or equal to 4'); * * @name isAtMost * @param {Mixed} valueToCheck * @param {Mixed} valueToBeAtMost * @param {String} message * @namespace Assert * @api public */ assert.isAtMost = function (val, atmst, msg) { new Assertion(val, msg, assert.isAtMost, true).to.be.most(atmst); }; /** * ### .isTrue(value, [message]) * * Asserts that `value` is true. * * var teaServed = true; * assert.isTrue(teaServed, 'the tea has been served'); * * @name isTrue * @param {Mixed} value * @param {String} message * @namespace Assert * @api public */ assert.isTrue = function (val, msg) { new Assertion(val, msg, assert.isTrue, true).is['true']; }; /** * ### .isNotTrue(value, [message]) * * Asserts that `value` is not true. * * var tea = 'tasty chai'; * assert.isNotTrue(tea, 'great, time for tea!'); * * @name isNotTrue * @param {Mixed} value * @param {String} message * @namespace Assert * @api public */ assert.isNotTrue = function (val, msg) { new Assertion(val, msg, assert.isNotTrue, true).to.not.equal(true); }; /** * ### .isFalse(value, [message]) * * Asserts that `value` is false. * * var teaServed = false; * assert.isFalse(teaServed, 'no tea yet? hmm...'); * * @name isFalse * @param {Mixed} value * @param {String} message * @namespace Assert * @api public */ assert.isFalse = function (val, msg) { new Assertion(val, msg, assert.isFalse, true).is['false']; }; /** * ### .isNotFalse(value, [message]) * * Asserts that `value` is not false. * * var tea = 'tasty chai'; * assert.isNotFalse(tea, 'great, time for tea!'); * * @name isNotFalse * @param {Mixed} value * @param {String} message * @namespace Assert * @api public */ assert.isNotFalse = function (val, msg) { new Assertion(val, msg, assert.isNotFalse, true).to.not.equal(false); }; /** * ### .isNull(value, [message]) * * Asserts that `value` is null. * * assert.isNull(err, 'there was no error'); * * @name isNull * @param {Mixed} value * @param {String} message * @namespace Assert * @api public */ assert.isNull = function (val, msg) { new Assertion(val, msg, assert.isNull, true).to.equal(null); }; /** * ### .isNotNull(value, [message]) * * Asserts that `value` is not null. * * var tea = 'tasty chai'; * assert.isNotNull(tea, 'great, time for tea!'); * * @name isNotNull * @param {Mixed} value * @param {String} message * @namespace Assert * @api public */ assert.isNotNull = function (val, msg) { new Assertion(val, msg, assert.isNotNull, true).to.not.equal(null); }; /** * ### .isNaN * * Asserts that value is NaN. * * assert.isNaN(NaN, 'NaN is NaN'); * * @name isNaN * @param {Mixed} value * @param {String} message * @namespace Assert * @api public */ assert.isNaN = function (val, msg) { new Assertion(val, msg, assert.isNaN, true).to.be.NaN; }; /** * ### .isNotNaN * * Asserts that value is not NaN. * * assert.isNotNaN(4, '4 is not NaN'); * * @name isNotNaN * @param {Mixed} value * @param {String} message * @namespace Assert * @api public */ assert.isNotNaN = function (val, msg) { new Assertion(val, msg, assert.isNotNaN, true).not.to.be.NaN; }; /** * ### .exists * * Asserts that the target is neither `null` nor `undefined`. * * var foo = 'hi'; * * assert.exists(foo, 'foo is neither `null` nor `undefined`'); * * @name exists * @param {Mixed} value * @param {String} message * @namespace Assert * @api public */ assert.exists = function (val, msg) { new Assertion(val, msg, assert.exists, true).to.exist; }; /** * ### .notExists * * Asserts that the target is either `null` or `undefined`. * * var bar = null * , baz; * * assert.notExists(bar); * assert.notExists(baz, 'baz is either null or undefined'); * * @name notExists * @param {Mixed} value * @param {String} message * @namespace Assert * @api public */ assert.notExists = function (val, msg) { new Assertion(val, msg, assert.notExists, true).to.not.exist; }; /** * ### .isUndefined(value, [message]) * * Asserts that `value` is `undefined`. * * var tea; * assert.isUndefined(tea, 'no tea defined'); * * @name isUndefined * @param {Mixed} value * @param {String} message * @namespace Assert * @api public */ assert.isUndefined = function (val, msg) { new Assertion(val, msg, assert.isUndefined, true).to.equal(undefined); }; /** * ### .isDefined(value, [message]) * * Asserts that `value` is not `undefined`. * * var tea = 'cup of chai'; * assert.isDefined(tea, 'tea has been defined'); * * @name isDefined * @param {Mixed} value * @param {String} message * @namespace Assert * @api public */ assert.isDefined = function (val, msg) { new Assertion(val, msg, assert.isDefined, true).to.not.equal(undefined); }; /** * ### .isFunction(value, [message]) * * Asserts that `value` is a function. * * function serveTea() { return 'cup of tea'; }; * assert.isFunction(serveTea, 'great, we can have tea now'); * * @name isFunction * @param {Mixed} value * @param {String} message * @namespace Assert * @api public */ assert.isFunction = function (val, msg) { new Assertion(val, msg, assert.isFunction, true).to.be.a('function'); }; /** * ### .isNotFunction(value, [message]) * * Asserts that `value` is _not_ a function. * * var serveTea = [ 'heat', 'pour', 'sip' ]; * assert.isNotFunction(serveTea, 'great, we have listed the steps'); * * @name isNotFunction * @param {Mixed} value * @param {String} message * @namespace Assert * @api public */ assert.isNotFunction = function (val, msg) { new Assertion(val, msg, assert.isNotFunction, true).to.not.be.a('function'); }; /** * ### .isObject(value, [message]) * * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`). * _The assertion does not match subclassed objects._ * * var selection = { name: 'Chai', serve: 'with spices' }; * assert.isObject(selection, 'tea selection is an object'); * * @name isObject * @param {Mixed} value * @param {String} message * @namespace Assert * @api public */ assert.isObject = function (val, msg) { new Assertion(val, msg, assert.isObject, true).to.be.a('object'); }; /** * ### .isNotObject(value, [message]) * * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`). * * var selection = 'chai' * assert.isNotObject(selection, 'tea selection is not an object'); * assert.isNotObject(null, 'null is not an object'); * * @name isNotObject * @param {Mixed} value * @param {String} message * @namespace Assert * @api public */ assert.isNotObject = function (val, msg) { new Assertion(val, msg, assert.isNotObject, true).to.not.be.a('object'); }; /** * ### .isArray(value, [message]) * * Asserts that `value` is an array. * * var menu = [ 'green', 'chai', 'oolong' ]; * assert.isArray(menu, 'what kind of tea do we want?'); * * @name isArray * @param {Mixed} value * @param {String} message * @namespace Assert * @api public */ assert.isArray = function (val, msg) { new Assertion(val, msg, assert.isArray, true).to.be.an('array'); }; /** * ### .isNotArray(value, [message]) * * Asserts that `value` is _not_ an array. * * var menu = 'green|chai|oolong'; * assert.isNotArray(menu, 'what kind of tea do we want?'); * * @name isNotArray * @param {Mixed} value * @param {String} message * @namespace Assert * @api public */ assert.isNotArray = function (val, msg) { new Assertion(val, msg, assert.isNotArray, true).to.not.be.an('array'); }; /** * ### .isString(value, [message]) * * Asserts that `value` is a string. * * var teaOrder = 'chai'; * assert.isString(teaOrder, 'order placed'); * * @name isString * @param {Mixed} value * @param {String} message * @namespace Assert * @api public */ assert.isString = function (val, msg) { new Assertion(val, msg, assert.isString, true).to.be.a('string'); }; /** * ### .isNotString(value, [message]) * * Asserts that `value` is _not_ a string. * * var teaOrder = 4; * assert.isNotString(teaOrder, 'order placed'); * * @name isNotString * @param {Mixed} value * @param {String} message * @namespace Assert * @api public */ assert.isNotString = function (val, msg) { new Assertion(val, msg, assert.isNotString, true).to.not.be.a('string'); }; /** * ### .isNumber(value, [message]) * * Asserts that `value` is a number. * * var cups = 2; * assert.isNumber(cups, 'how many cups'); * * @name isNumber * @param {Number} value * @param {String} message * @namespace Assert * @api public */ assert.isNumber = function (val, msg) { new Assertion(val, msg, assert.isNumber, true).to.be.a('number'); }; /** * ### .isNotNumber(value, [message]) * * Asserts that `value` is _not_ a number. * * var cups = '2 cups please'; * assert.isNotNumber(cups, 'how many cups'); * * @name isNotNumber * @param {Mixed} value * @param {String} message * @namespace Assert * @api public */ assert.isNotNumber = function (val, msg) { new Assertion(val, msg, assert.isNotNumber, true).to.not.be.a('number'); }; /** * ### .isFinite(value, [message]) * * Asserts that `value` is a finite number. Unlike `.isNumber`, this will fail for `NaN` and `Infinity`. * * var cups = 2; * assert.isFinite(cups, 'how many cups'); * * assert.isFinite(NaN); // throws * * @name isFinite * @param {Number} value * @param {String} message * @namespace Assert * @api public */ assert.isFinite = function (val, msg) { new Assertion(val, msg, assert.isFinite, true).to.be.finite; }; /** * ### .isBoolean(value, [message]) * * Asserts that `value` is a boolean. * * var teaReady = true * , teaServed = false; * * assert.isBoolean(teaReady, 'is the tea ready'); * assert.isBoolean(teaServed, 'has tea been served'); * * @name isBoolean * @param {Mixed} value * @param {String} message * @namespace Assert * @api public */ assert.isBoolean = function (val, msg) { new Assertion(val, msg, assert.isBoolean, true).to.be.a('boolean'); }; /** * ### .isNotBoolean(value, [message]) * * Asserts that `value` is _not_ a boolean. * * var teaReady = 'yep' * , teaServed = 'nope'; * * assert.isNotBoolean(teaReady, 'is the tea ready'); * assert.isNotBoolean(teaServed, 'has tea been served'); * * @name isNotBoolean * @param {Mixed} value * @param {String} message * @namespace Assert * @api public */ assert.isNotBoolean = function (val, msg) { new Assertion(val, msg, assert.isNotBoolean, true).to.not.be.a('boolean'); }; /** * ### .typeOf(value, name, [message]) * * Asserts that `value`'s type is `name`, as determined by * `Object.prototype.toString`. * * assert.typeOf({ tea: 'chai' }, 'object', 'we have an object'); * assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array'); * assert.typeOf('tea', 'string', 'we have a string'); * assert.typeOf(/tea/, 'regexp', 'we have a regular expression'); * assert.typeOf(null, 'null', 'we have a null'); * assert.typeOf(undefined, 'undefined', 'we have an undefined'); * * @name typeOf * @param {Mixed} value * @param {String} name * @param {String} message * @namespace Assert * @api public */ assert.typeOf = function (val, type, msg) { new Assertion(val, msg, assert.typeOf, true).to.be.a(type); }; /** * ### .notTypeOf(value, name, [message]) * * Asserts that `value`'s type is _not_ `name`, as determined by * `Object.prototype.toString`. * * assert.notTypeOf('tea', 'number', 'strings are not numbers'); * * @name notTypeOf * @param {Mixed} value * @param {String} typeof name * @param {String} message * @namespace Assert * @api public */ assert.notTypeOf = function (val, type, msg) { new Assertion(val, msg, assert.notTypeOf, true).to.not.be.a(type); }; /** * ### .instanceOf(object, constructor, [message]) * * Asserts that `value` is an instance of `constructor`. * * var Tea = function (name) { this.name = name; } * , chai = new Tea('chai'); * * assert.instanceOf(chai, Tea, 'chai is an instance of tea'); * * @name instanceOf * @param {Object} object * @param {Constructor} constructor * @param {String} message * @namespace Assert * @api public */ assert.instanceOf = function (val, type, msg) { new Assertion(val, msg, assert.instanceOf, true).to.be.instanceOf(type); }; /** * ### .notInstanceOf(object, constructor, [message]) * * Asserts `value` is not an instance of `constructor`. * * var Tea = function (name) { this.name = name; } * , chai = new String('chai'); * * assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea'); * * @name notInstanceOf * @param {Object} object * @param {Constructor} constructor * @param {String} message * @namespace Assert * @api public */ assert.notInstanceOf = function (val, type, msg) { new Assertion(val, msg, assert.notInstanceOf, true) .to.not.be.instanceOf(type); }; /** * ### .include(haystack, needle, [message]) * * Asserts that `haystack` includes `needle`. Can be used to assert the * inclusion of a value in an array, a substring in a string, or a subset of * properties in an object. * * assert.include([1,2,3], 2, 'array contains value'); * assert.include('foobar', 'foo', 'string contains substring'); * assert.include({ foo: 'bar', hello: 'universe' }, { foo: 'bar' }, 'object contains property'); * * Strict equality (===) is used. When asserting the inclusion of a value in * an array, the array is searched for an element that's strictly equal to the * given value. When asserting a subset of properties in an object, the object * is searched for the given property keys, checking that each one is present * and strictly equal to the given property value. For instance: * * var obj1 = {a: 1} * , obj2 = {b: 2}; * assert.include([obj1, obj2], obj1); * assert.include({foo: obj1, bar: obj2}, {foo: obj1}); * assert.include({foo: obj1, bar: obj2}, {foo: obj1, bar: obj2}); * * @name include * @param {Array|String} haystack * @param {Mixed} needle * @param {String} message * @namespace Assert * @api public */ assert.include = function (exp, inc, msg) { new Assertion(exp, msg, assert.include, true).include(inc); }; /** * ### .notInclude(haystack, needle, [message]) * * Asserts that `haystack` does not include `needle`. Can be used to assert * the absence of a value in an array, a substring in a string, or a subset of * properties in an object. * * assert.notInclude([1,2,3], 4, "array doesn't contain value"); * assert.notInclude('foobar', 'baz', "string doesn't contain substring"); * assert.notInclude({ foo: 'bar', hello: 'universe' }, { foo: 'baz' }, 'object doesn't contain property'); * * Strict equality (===) is used. When asserting the absence of a value in an * array, the array is searched to confirm the absence of an element that's * strictly equal to the given value. When asserting a subset of properties in * an object, the object is searched to confirm that at least one of the given * property keys is either not present or not strictly equal to the given * property value. For instance: * * var obj1 = {a: 1} * , obj2 = {b: 2}; * assert.notInclude([obj1, obj2], {a: 1}); * assert.notInclude({foo: obj1, bar: obj2}, {foo: {a: 1}}); * assert.notInclude({foo: obj1, bar: obj2}, {foo: obj1, bar: {b: 2}}); * * @name notInclude * @param {Array|String} haystack * @param {Mixed} needle * @param {String} message * @namespace Assert * @api public */ assert.notInclude = function (exp, inc, msg) { new Assertion(exp, msg, assert.notInclude, true).not.include(inc); }; /** * ### .deepInclude(haystack, needle, [message]) * * Asserts that `haystack` includes `needle`. Can be used to assert the * inclusion of a value in an array or a subset of properties in an object. * Deep equality is used. * * var obj1 = {a: 1} * , obj2 = {b: 2}; * assert.deepInclude([obj1, obj2], {a: 1}); * assert.deepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}}); * assert.deepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}, bar: {b: 2}}); * * @name deepInclude * @param {Array|String} haystack * @param {Mixed} needle * @param {String} message * @namespace Assert * @api public */ assert.deepInclude = function (exp, inc, msg) { new Assertion(exp, msg, assert.deepInclude, true).deep.include(inc); }; /** * ### .notDeepInclude(haystack, needle, [message]) * * Asserts that `haystack` does not include `needle`. Can be used to assert * the absence of a value in an array or a subset of properties in an object. * Deep equality is used. * * var obj1 = {a: 1} * , obj2 = {b: 2}; * assert.notDeepInclude([obj1, obj2], {a: 9}); * assert.notDeepInclude({foo: obj1, bar: obj2}, {foo: {a: 9}}); * assert.notDeepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}, bar: {b: 9}}); * * @name notDeepInclude * @param {Array|String} haystack * @param {Mixed} needle * @param {String} message * @namespace Assert * @api public */ assert.notDeepInclude = function (exp, inc, msg) { new Assertion(exp, msg, assert.notDeepInclude, true).not.deep.include(inc); }; /** * ### .nestedInclude(haystack, needle, [message]) * * Asserts that 'haystack' includes 'needle'. * Can be used to assert the inclusion of a subset of properties in an * object. * Enables the use of dot- and bracket-notation for referencing nested * properties. * '[]' and '.' in property names can be escaped using double backslashes. * * assert.nestedInclude({'.a': {'b': 'x'}}, {'\\.a.[b]': 'x'}); * assert.nestedInclude({'a': {'[b]': 'x'}}, {'a.\\[b\\]': 'x'}); * * @name nestedInclude * @param {Object} haystack * @param {Object} needle * @param {String} message * @namespace Assert * @api public */ assert.nestedInclude = function (exp, inc, msg) { new Assertion(exp, msg, assert.nestedInclude, true).nested.include(inc); }; /** * ### .notNestedInclude(haystack, needle, [message]) * * Asserts that 'haystack' does not include 'needle'. * Can be used to assert the absence of a subset of properties in an * object. * Enables the use of dot- and bracket-notation for referencing nested * properties. * '[]' and '.' in property names can be escaped using double backslashes. * * assert.notNestedInclude({'.a': {'b': 'x'}}, {'\\.a.b': 'y'}); * assert.notNestedInclude({'a': {'[b]': 'x'}}, {'a.\\[b\\]': 'y'}); * * @name notNestedInclude * @param {Object} haystack * @param {Object} needle * @param {String} message * @namespace Assert * @api public */ assert.notNestedInclude = function (exp, inc, msg) { new Assertion(exp, msg, assert.notNestedInclude, true) .not.nested.include(inc); }; /** * ### .deepNestedInclude(haystack, needle, [message]) * * Asserts that 'haystack' includes 'needle'. * Can be used to assert the inclusion of a subset of properties in an * object while checking for deep equality. * Enables the use of dot- and bracket-notation for referencing nested * properties. * '[]' and '.' in property names can be escaped using double backslashes. * * assert.deepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {x: 1}}); * assert.deepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {x: 1}}); * * @name deepNestedInclude * @param {Object} haystack * @param {Object} needle * @param {String} message * @namespace Assert * @api public */ assert.deepNestedInclude = function(exp, inc, msg) { new Assertion(exp, msg, assert.deepNestedInclude, true) .deep.nested.include(inc); }; /** * ### .notDeepNestedInclude(haystack, needle, [message]) * * Asserts that 'haystack' does not include 'needle'. * Can be used to assert the absence of a subset of properties in an * object while checking for deep equality. * Enables the use of dot- and bracket-notation for referencing nested * properties. * '[]' and '.' in property names can be escaped using double backslashes. * * assert.notDeepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {y: 1}}) * assert.notDeepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {y: 2}}); * * @name notDeepNestedInclude * @param {Object} haystack * @param {Object} needle * @param {String} message * @namespace Assert * @api public */ assert.notDeepNestedInclude = function(exp, inc, msg) { new Assertion(exp, msg, assert.notDeepNestedInclude, true) .not.deep.nested.include(inc); }; /** * ### .ownInclude(haystack, needle, [message]) * * Asserts that 'haystack' includes 'needle'. * Can be used to assert the inclusion of a subset of properties in an * object while ignoring inherited properties. * * assert.ownInclude({ a: 1 }, { a: 1 }); * * @name ownInclude * @param {Object} haystack * @param {Object} needle * @param {String} message * @namespace Assert * @api public */ assert.ownInclude = function(exp, inc, msg) { new Assertion(exp, msg, assert.ownInclude, true).own.include(inc); }; /** * ### .notOwnInclude(haystack, needle, [message]) * * Asserts that 'haystack' includes 'needle'. * Can be used to assert the absence of a subset of properties in an * object while ignoring inherited properties. * * Object.prototype.b = 2; * * assert.notOwnInclude({ a: 1 }, { b: 2 }); * * @name notOwnInclude * @param {Object} haystack * @param {Object} needle * @param {String} message * @namespace Assert * @api public */ assert.notOwnInclude = function(exp, inc, msg) { new Assertion(exp, msg, assert.notOwnInclude, true).not.own.include(inc); }; /** * ### .deepOwnInclude(haystack, needle, [message]) * * Asserts that 'haystack' includes 'needle'. * Can be used to assert the inclusion of a subset of properties in an * object while ignoring inherited properties and checking for deep equality. * * assert.deepOwnInclude({a: {b: 2}}, {a: {b: 2}}); * * @name deepOwnInclude * @param {Object} haystack * @param {Object} needle * @param {String} message * @namespace Assert * @api public */ assert.deepOwnInclude = function(exp, inc, msg) { new Assertion(exp, msg, assert.deepOwnInclude, true) .deep.own.include(inc); }; /** * ### .notDeepOwnInclude(haystack, needle, [message]) * * Asserts that 'haystack' includes 'needle'. * Can be used to assert the absence of a subset of properties in an * object while ignoring inherited properties and checking for deep equality. * * assert.notDeepOwnInclude({a: {b: 2}}, {a: {c: 3}}); * * @name notDeepOwnInclude * @param {Object} haystack * @param {Object} needle * @param {String} message * @namespace Assert * @api public */ assert.notDeepOwnInclude = function(exp, inc, msg) { new Assertion(exp, msg, assert.notDeepOwnInclude, true) .not.deep.own.include(inc); }; /** * ### .match(value, regexp, [message]) * * Asserts that `value` matches the regular expression `regexp`. * * assert.match('foobar', /^foo/, 'regexp matches'); * * @name match * @param {Mixed} value * @param {RegExp} regexp * @param {String} message * @namespace Assert * @api public */ assert.match = function (exp, re, msg) { new Assertion(exp, msg, assert.match, true).to.match(re); }; /** * ### .notMatch(value, regexp, [message]) * * Asserts that `value` does not match the regular expression `regexp`. * * assert.notMatch('foobar', /^foo/, 'regexp does not match'); * * @name notMatch * @param {Mixed} value * @param {RegExp} regexp * @param {String} message * @namespace Assert * @api public */ assert.notMatch = function (exp, re, msg) { new Assertion(exp, msg, assert.notMatch, true).to.not.match(re); }; /** * ### .property(object, property, [message]) * * Asserts that `object` has a direct or inherited property named by * `property`. * * assert.property({ tea: { green: 'matcha' }}, 'tea'); * assert.property({ tea: { green: 'matcha' }}, 'toString'); * * @name property * @param {Object} object * @param {String} property * @param {String} message * @namespace Assert * @api public */ assert.property = function (obj, prop, msg) { new Assertion(obj, msg, assert.property, true).to.have.property(prop); }; /** * ### .notProperty(object, property, [message]) * * Asserts that `object` does _not_ have a direct or inherited property named * by `property`. * * assert.notProperty({ tea: { green: 'matcha' }}, 'coffee'); * * @name notProperty * @param {Object} object * @param {String} property * @param {String} message * @namespace Assert * @api public */ assert.notProperty = function (obj, prop, msg) { new Assertion(obj, msg, assert.notProperty, true) .to.not.have.property(prop); }; /** * ### .propertyVal(object, property, value, [message]) * * Asserts that `object` has a direct or inherited property named by * `property` with a value given by `value`. Uses a strict equality check * (===). * * assert.propertyVal({ tea: 'is good' }, 'tea', 'is good'); * * @name propertyVal * @param {Object} object * @param {String} property * @param {Mixed} value * @param {String} message * @namespace Assert * @api public */ assert.propertyVal = function (obj, prop, val, msg) { new Assertion(obj, msg, assert.propertyVal, true) .to.have.property(prop, val); }; /** * ### .notPropertyVal(object, property, value, [message]) * * Asserts that `object` does _not_ have a direct or inherited property named * by `property` with value given by `value`. Uses a strict equality check * (===). * * assert.notPropertyVal({ tea: 'is good' }, 'tea', 'is bad'); * assert.notPropertyVal({ tea: 'is good' }, 'coffee', 'is good'); * * @name notPropertyVal * @param {Object} object * @param {String} property * @param {Mixed} value * @param {String} message * @namespace Assert * @api public */ assert.notPropertyVal = function (obj, prop, val, msg) { new Assertion(obj, msg, assert.notPropertyVal, true) .to.not.have.property(prop, val); }; /** * ### .deepPropertyVal(object, property, value, [message]) * * Asserts that `object` has a direct or inherited property named by * `property` with a value given by `value`. Uses a deep equality check. * * assert.deepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'matcha' }); * * @name deepPropertyVal * @param {Object} object * @param {String} property * @param {Mixed} value * @param {String} message * @namespace Assert * @api public */ assert.deepPropertyVal = function (obj, prop, val, msg) { new Assertion(obj, msg, assert.deepPropertyVal, true) .to.have.deep.property(prop, val); }; /** * ### .notDeepPropertyVal(object, property, value, [message]) * * Asserts that `object` does _not_ have a direct or inherited property named * by `property` with value given by `value`. Uses a deep equality check. * * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { black: 'matcha' }); * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'oolong' }); * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'coffee', { green: 'matcha' }); * * @name notDeepPropertyVal * @param {Object} object * @param {String} property * @param {Mixed} value * @param {String} message * @namespace Assert * @api public */ assert.notDeepPropertyVal = function (obj, prop, val, msg) { new Assertion(obj, msg, assert.notDeepPropertyVal, true) .to.not.have.deep.property(prop, val); }; /** * ### .ownProperty(object, property, [message]) * * Asserts that `object` has a direct property named by `property`. Inherited * properties aren't checked. * * assert.ownProperty({ tea: { green: 'matcha' }}, 'tea'); * * @name ownProperty * @param {Object} object * @param {String} property * @param {String} message * @api public */ assert.ownProperty = function (obj, prop, msg) { new Assertion(obj, msg, assert.ownProperty, true) .to.have.own.property(prop); }; /** * ### .notOwnProperty(object, property, [message]) * * Asserts that `object` does _not_ have a direct property named by * `property`. Inherited properties aren't checked. * * assert.notOwnProperty({ tea: { green: 'matcha' }}, 'coffee'); * assert.notOwnProperty({}, 'toString'); * * @name notOwnProperty * @param {Object} object * @param {String} property * @param {String} message * @api public */ assert.notOwnProperty = function (obj, prop, msg) { new Assertion(obj, msg, assert.notOwnProperty, true) .to.not.have.own.property(prop); }; /** * ### .ownPropertyVal(object, property, value, [message]) * * Asserts that `object` has a direct property named by `property` and a value * equal to the provided `value`. Uses a strict equality check (===). * Inherited properties aren't checked. * * assert.ownPropertyVal({ coffee: 'is good'}, 'coffee', 'is good'); * * @name ownPropertyVal * @param {Object} object * @param {String} property * @param {Mixed} value * @param {String} message * @api public */ assert.ownPropertyVal = function (obj, prop, value, msg) { new Assertion(obj, msg, assert.ownPropertyVal, true) .to.have.own.property(prop, value); }; /** * ### .notOwnPropertyVal(object, property, value, [message]) * * Asserts that `object` does _not_ have a direct property named by `property` * with a value equal to the provided `value`. Uses a strict equality check * (===). Inherited properties aren't checked. * * assert.notOwnPropertyVal({ tea: 'is better'}, 'tea', 'is worse'); * assert.notOwnPropertyVal({}, 'toString', Object.prototype.toString); * * @name notOwnPropertyVal * @param {Object} object * @param {String} property * @param {Mixed} value * @param {String} message * @api public */ assert.notOwnPropertyVal = function (obj, prop, value, msg) { new Assertion(obj, msg, assert.notOwnPropertyVal, true) .to.not.have.own.property(prop, value); }; /** * ### .deepOwnPropertyVal(object, property, value, [message]) * * Asserts that `object` has a direct property named by `property` and a value * equal to the provided `value`. Uses a deep equality check. Inherited * properties aren't checked. * * assert.deepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'matcha' }); * * @name deepOwnPropertyVal * @param {Object} object * @param {String} property * @param {Mixed} value * @param {String} message * @api public */ assert.deepOwnPropertyVal = function (obj, prop, value, msg) { new Assertion(obj, msg, assert.deepOwnPropertyVal, true) .to.have.deep.own.property(prop, value); }; /** * ### .notDeepOwnPropertyVal(object, property, value, [message]) * * Asserts that `object` does _not_ have a direct property named by `property` * with a value equal to the provided `value`. Uses a deep equality check. * Inherited properties aren't checked. * * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { black: 'matcha' }); * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'oolong' }); * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'coffee', { green: 'matcha' }); * assert.notDeepOwnPropertyVal({}, 'toString', Object.prototype.toString); * * @name notDeepOwnPropertyVal * @param {Object} object * @param {String} property * @param {Mixed} value * @param {String} message * @api public */ assert.notDeepOwnPropertyVal = function (obj, prop, value, msg) { new Assertion(obj, msg, assert.notDeepOwnPropertyVal, true) .to.not.have.deep.own.property(prop, value); }; /** * ### .nestedProperty(object, property, [message]) * * Asserts that `object` has a direct or inherited property named by * `property`, which can be a string using dot- and bracket-notation for * nested reference. * * assert.nestedProperty({ tea: { green: 'matcha' }}, 'tea.green'); * * @name nestedProperty * @param {Object} object * @param {String} property * @param {String} message * @namespace Assert * @api public */ assert.nestedProperty = function (obj, prop, msg) { new Assertion(obj, msg, assert.nestedProperty, true) .to.have.nested.property(prop); }; /** * ### .notNestedProperty(object, property, [message]) * * Asserts that `object` does _not_ have a property named by `property`, which * can be a string using dot- and bracket-notation for nested reference. The * property cannot exist on the object nor anywhere in its prototype chain. * * assert.notNestedProperty({ tea: { green: 'matcha' }}, 'tea.oolong'); * * @name notNestedProperty * @param {Object} object * @param {String} property * @param {String} message * @namespace Assert * @api public */ assert.notNestedProperty = function (obj, prop, msg) { new Assertion(obj, msg, assert.notNestedProperty, true) .to.not.have.nested.property(prop); }; /** * ### .nestedPropertyVal(object, property, value, [message]) * * Asserts that `object` has a property named by `property` with value given * by `value`. `property` can use dot- and bracket-notation for nested * reference. Uses a strict equality check (===). * * assert.nestedPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha'); * * @name nestedPropertyVal * @param {Object} object * @param {String} property * @param {Mixed} value * @param {String} message * @namespace Assert * @api public */ assert.nestedPropertyVal = function (obj, prop, val, msg) { new Assertion(obj, msg, assert.nestedPropertyVal, true) .to.have.nested.property(prop, val); }; /** * ### .notNestedPropertyVal(object, property, value, [message]) * * Asserts that `object` does _not_ have a property named by `property` with * value given by `value`. `property` can use dot- and bracket-notation for * nested reference. Uses a strict equality check (===). * * assert.notNestedPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha'); * assert.notNestedPropertyVal({ tea: { green: 'matcha' }}, 'coffee.green', 'matcha'); * * @name notNestedPropertyVal * @param {Object} object * @param {String} property * @param {Mixed} value * @param {String} message * @namespace Assert * @api public */ assert.notNestedPropertyVal = function (obj, prop, val, msg) { new Assertion(obj, msg, assert.notNestedPropertyVal, true) .to.not.have.nested.property(prop, val); }; /** * ### .deepNestedPropertyVal(object, property, value, [message]) * * Asserts that `object` has a property named by `property` with a value given * by `value`. `property` can use dot- and bracket-notation for nested * reference. Uses a deep equality check. * * assert.deepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { matcha: 'yum' }); * * @name deepNestedPropertyVal * @param {Object} object * @param {String} property * @param {Mixed} value * @param {String} message * @namespace Assert * @api public */ assert.deepNestedPropertyVal = function (obj, prop, val, msg) { new Assertion(obj, msg, assert.deepNestedPropertyVal, true) .to.have.deep.nested.property(prop, val); }; /** * ### .notDeepNestedPropertyVal(object, property, value, [message]) * * Asserts that `object` does _not_ have a property named by `property` with * value given by `value`. `property` can use dot- and bracket-notation for * nested reference. Uses a deep equality check. * * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { oolong: 'yum' }); * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { matcha: 'yuck' }); * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.black', { matcha: 'yum' }); * * @name notDeepNestedPropertyVal * @param {Object} object * @param {String} property * @param {Mixed} value * @param {String} message * @namespace Assert * @api public */ assert.notDeepNestedPropertyVal = function (obj, prop, val, msg) { new Assertion(obj, msg, assert.notDeepNestedPropertyVal, true) .to.not.have.deep.nested.property(prop, val); } /** * ### .lengthOf(object, length, [message]) * * Asserts that `object` has a `length` or `size` with the expected value. * * assert.lengthOf([1,2,3], 3, 'array has length of 3'); * assert.lengthOf('foobar', 6, 'string has length of 6'); * assert.lengthOf(new Set([1,2,3]), 3, 'set has size of 3'); * assert.lengthOf(new Map([['a',1],['b',2],['c',3]]), 3, 'map has size of 3'); * * @name lengthOf * @param {Mixed} object * @param {Number} length * @param {String} message * @namespace Assert * @api public */ assert.lengthOf = function (exp, len, msg) { new Assertion(exp, msg, assert.lengthOf, true).to.have.lengthOf(len); }; /** * ### .hasAnyKeys(object, [keys], [message]) * * Asserts that `object` has at least one of the `keys` provided. * You can also provide a single object instead of a `keys` array and its keys * will be used as the expected set of keys. * * assert.hasAnyKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'iDontExist', 'baz']); * assert.hasAnyKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, iDontExist: 99, baz: 1337}); * assert.hasAnyKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']); * assert.hasAnyKeys(new Set([{foo: 'bar'}, 'anotherKey']), [{foo: 'bar'}, 'anotherKey']); * * @name hasAnyKeys * @param {Mixed} object * @param {Array|Object} keys * @param {String} message * @namespace Assert * @api public */ assert.hasAnyKeys = function (obj, keys, msg) { new Assertion(obj, msg, assert.hasAnyKeys, true).to.have.any.keys(keys); } /** * ### .hasAllKeys(object, [keys], [message]) * * Asserts that `object` has all and only all of the `keys` provided. * You can also provide a single object instead of a `keys` array and its keys * will be used as the expected set of keys. * * assert.hasAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'bar', 'baz']); * assert.hasAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, bar: 99, baz: 1337]); * assert.hasAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']); * assert.hasAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}, 'anotherKey']); * * @name hasAllKeys * @param {Mixed} object * @param {String[]} keys * @param {String} message * @namespace Assert * @api public */ assert.hasAllKeys = function (obj, keys, msg) { new Assertion(obj, msg, assert.hasAllKeys, true).to.have.all.keys(keys); } /** * ### .containsAllKeys(object, [keys], [message]) * * Asserts that `object` has all of the `keys` provided but may have more keys not listed. * You can also provide a single object instead of a `keys` array and its keys * will be used as the expected set of keys. * * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'baz']); * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'bar', 'baz']); * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, baz: 1337}); * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, bar: 99, baz: 1337}); * assert.containsAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}]); * assert.containsAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']); * assert.containsAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}]); * assert.containsAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}, 'anotherKey']); * * @name containsAllKeys * @param {Mixed} object * @param {String[]} keys * @param {String} message * @namespace Assert * @api public */ assert.containsAllKeys = function (obj, keys, msg) { new Assertion(obj, msg, assert.containsAllKeys, true) .to.contain.all.keys(keys); } /** * ### .doesNotHaveAnyKeys(object, [keys], [message]) * * Asserts that `object` has none of the `keys` provided. * You can also provide a single object instead of a `keys` array and its keys * will be used as the expected set of keys. * * assert.doesNotHaveAnyKeys({foo: 1, bar: 2, baz: 3}, ['one', 'two', 'example']); * assert.doesNotHaveAnyKeys({foo: 1, bar: 2, baz: 3}, {one: 1, two: 2, example: 'foo'}); * assert.doesNotHaveAnyKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{one: 'two'}, 'example']); * assert.doesNotHaveAnyKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{one: 'two'}, 'example']); * * @name doesNotHaveAnyKeys * @param {Mixed} object * @param {String[]} keys * @param {String} message * @namespace Assert * @api public */ assert.doesNotHaveAnyKeys = function (obj, keys, msg) { new Assertion(obj, msg, assert.doesNotHaveAnyKeys, true) .to.not.have.any.keys(keys); } /** * ### .doesNotHaveAllKeys(object, [keys], [message]) * * Asserts that `object` does not have at least one of the `keys` provided. * You can also provide a single object instead of a `keys` array and its keys * will be used as the expected set of keys. * * assert.doesNotHaveAllKeys({foo: 1, bar: 2, baz: 3}, ['one', 'two', 'example']); * assert.doesNotHaveAllKeys({foo: 1, bar: 2, baz: 3}, {one: 1, two: 2, example: 'foo'}); * assert.doesNotHaveAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{one: 'two'}, 'example']); * assert.doesNotHaveAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{one: 'two'}, 'example']); * * @name doesNotHaveAllKeys * @param {Mixed} object * @param {String[]} keys * @param {String} message * @namespace Assert * @api public */ assert.doesNotHaveAllKeys = function (obj, keys, msg) { new Assertion(obj, msg, assert.doesNotHaveAllKeys, true) .to.not.have.all.keys(keys); } /** * ### .hasAnyDeepKeys(object, [keys], [message]) * * Asserts that `object` has at least one of the `keys` provided. * Since Sets and Maps can have objects as keys you can use this assertion to perform * a deep comparison. * You can also provide a single object instead of a `keys` array and its keys * will be used as the expected set of keys. * * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {one: 'one'}); * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), [{one: 'one'}, {two: 'two'}]); * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]); * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {one: 'one'}); * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {three: 'three'}]); * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]); * * @name hasAnyDeepKeys * @param {Mixed} object * @param {Array|Object} keys * @param {String} message * @namespace Assert * @api public */ assert.hasAnyDeepKeys = function (obj, keys, msg) { new Assertion(obj, msg, assert.hasAnyDeepKeys, true) .to.have.any.deep.keys(keys); } /** * ### .hasAllDeepKeys(object, [keys], [message]) * * Asserts that `object` has all and only all of the `keys` provided. * Since Sets and Maps can have objects as keys you can use this assertion to perform * a deep comparison. * You can also provide a single object instead of a `keys` array and its keys * will be used as the expected set of keys. * * assert.hasAllDeepKeys(new Map([[{one: 'one'}, 'valueOne']]), {one: 'one'}); * assert.hasAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]); * assert.hasAllDeepKeys(new Set([{one: 'one'}]), {one: 'one'}); * assert.hasAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]); * * @name hasAllDeepKeys * @param {Mixed} object * @param {Array|Object} keys * @param {String} message * @namespace Assert * @api public */ assert.hasAllDeepKeys = function (obj, keys, msg) { new Assertion(obj, msg, assert.hasAllDeepKeys, true) .to.have.all.deep.keys(keys); } /** * ### .containsAllDeepKeys(object, [keys], [message]) * * Asserts that `object` contains all of the `keys` provided. * Since Sets and Maps can have objects as keys you can use this assertion to perform * a deep comparison. * You can also provide a single object instead of a `keys` array and its keys * will be used as the expected set of keys. * * assert.containsAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {one: 'one'}); * assert.containsAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]); * assert.containsAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {one: 'one'}); * assert.containsAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]); * * @name containsAllDeepKeys * @param {Mixed} object * @param {Array|Object} keys * @param {String} message * @namespace Assert * @api public */ assert.containsAllDeepKeys = function (obj, keys, msg) { new Assertion(obj, msg, assert.containsAllDeepKeys, true) .to.contain.all.deep.keys(keys); } /** * ### .doesNotHaveAnyDeepKeys(object, [keys], [message]) * * Asserts that `object` has none of the `keys` provided. * Since Sets and Maps can have objects as keys you can use this assertion to perform * a deep comparison. * You can also provide a single object instead of a `keys` array and its keys * will be used as the expected set of keys. * * assert.doesNotHaveAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {thisDoesNot: 'exist'}); * assert.doesNotHaveAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{twenty: 'twenty'}, {fifty: 'fifty'}]); * assert.doesNotHaveAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {twenty: 'twenty'}); * assert.doesNotHaveAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{twenty: 'twenty'}, {fifty: 'fifty'}]); * * @name doesNotHaveAnyDeepKeys * @param {Mixed} object * @param {Array|Object} keys * @param {String} message * @namespace Assert * @api public */ assert.doesNotHaveAnyDeepKeys = function (obj, keys, msg) { new Assertion(obj, msg, assert.doesNotHaveAnyDeepKeys, true) .to.not.have.any.deep.keys(keys); } /** * ### .doesNotHaveAllDeepKeys(object, [keys], [message]) * * Asserts that `object` does not have at least one of the `keys` provided. * Since Sets and Maps can have objects as keys you can use this assertion to perform * a deep comparison. * You can also provide a single object instead of a `keys` array and its keys * will be used as the expected set of keys. * * assert.doesNotHaveAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {thisDoesNot: 'exist'}); * assert.doesNotHaveAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{twenty: 'twenty'}, {one: 'one'}]); * assert.doesNotHaveAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {twenty: 'twenty'}); * assert.doesNotHaveAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {fifty: 'fifty'}]); * * @name doesNotHaveAllDeepKeys * @param {Mixed} object * @param {Array|Object} keys * @param {String} message * @namespace Assert * @api public */ assert.doesNotHaveAllDeepKeys = function (obj, keys, msg) { new Assertion(obj, msg, assert.doesNotHaveAllDeepKeys, true) .to.not.have.all.deep.keys(keys); } /** * ### .throws(fn, [errorLike/string/regexp], [string/regexp], [message]) * * If `errorLike` is an `Error` constructor, asserts that `fn` will throw an error that is an * instance of `errorLike`. * If `errorLike` is an `Error` instance, asserts that the error thrown is the same * instance as `errorLike`. * If `errMsgMatcher` is provided, it also asserts that the error thrown will have a * message matching `errMsgMatcher`. * * assert.throws(fn, 'Error thrown must have this msg'); * assert.throws(fn, /Error thrown must have a msg that matches this/); * assert.throws(fn, ReferenceError); * assert.throws(fn, errorInstance); * assert.throws(fn, ReferenceError, 'Error thrown must be a ReferenceError and have this msg'); * assert.throws(fn, errorInstance, 'Error thrown must be the same errorInstance and have this msg'); * assert.throws(fn, ReferenceError, /Error thrown must be a ReferenceError and match this/); * assert.throws(fn, errorInstance, /Error thrown must be the same errorInstance and match this/); * * @name throws * @alias throw * @alias Throw * @param {Function} fn * @param {ErrorConstructor|Error} errorLike * @param {RegExp|String} errMsgMatcher * @param {String} message * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types * @namespace Assert * @api public */ assert.throws = function (fn, errorLike, errMsgMatcher, msg) { if ('string' === typeof errorLike || errorLike instanceof RegExp) { errMsgMatcher = errorLike; errorLike = null; } var assertErr = new Assertion(fn, msg, assert.throws, true) .to.throw(errorLike, errMsgMatcher); return flag(assertErr, 'object'); }; /** * ### .doesNotThrow(fn, [errorLike/string/regexp], [string/regexp], [message]) * * If `errorLike` is an `Error` constructor, asserts that `fn` will _not_ throw an error that is an * instance of `errorLike`. * If `errorLike` is an `Error` instance, asserts that the error thrown is _not_ the same * instance as `errorLike`. * If `errMsgMatcher` is provided, it also asserts that the error thrown will _not_ have a * message matching `errMsgMatcher`. * * assert.doesNotThrow(fn, 'Any Error thrown must not have this message'); * assert.doesNotThrow(fn, /Any Error thrown must not match this/); * assert.doesNotThrow(fn, Error); * assert.doesNotThrow(fn, errorInstance); * assert.doesNotThrow(fn, Error, 'Error must not have this message'); * assert.doesNotThrow(fn, errorInstance, 'Error must not have this message'); * assert.doesNotThrow(fn, Error, /Error must not match this/); * assert.doesNotThrow(fn, errorInstance, /Error must not match this/); * * @name doesNotThrow * @param {Function} fn * @param {ErrorConstructor} errorLike * @param {RegExp|String} errMsgMatcher * @param {String} message * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types * @namespace Assert * @api public */ assert.doesNotThrow = function (fn, errorLike, errMsgMatcher, msg) { if ('string' === typeof errorLike || errorLike instanceof RegExp) { errMsgMatcher = errorLike; errorLike = null; } new Assertion(fn, msg, assert.doesNotThrow, true) .to.not.throw(errorLike, errMsgMatcher); }; /** * ### .operator(val1, operator, val2, [message]) * * Compares two values using `operator`. * * assert.operator(1, '<', 2, 'everything is ok'); * assert.operator(1, '>', 2, 'this will fail'); * * @name operator * @param {Mixed} val1 * @param {String} operator * @param {Mixed} val2 * @param {String} message * @namespace Assert * @api public */ assert.operator = function (val, operator, val2, msg) { var ok; switch(operator) { case '==': ok = val == val2; break; case '===': ok = val === val2; break; case '>': ok = val > val2; break; case '>=': ok = val >= val2; break; case '<': ok = val < val2; break; case '<=': ok = val <= val2; break; case '!=': ok = val != val2; break; case '!==': ok = val !== val2; break; default: msg = msg ? msg + ': ' : msg; throw new chai.AssertionError( msg + 'Invalid operator "' + operator + '"', undefined, assert.operator ); } var test = new Assertion(ok, msg, assert.operator, true); test.assert( true === flag(test, 'object') , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2) , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) ); }; /** * ### .closeTo(actual, expected, delta, [message]) * * Asserts that the target is equal `expected`, to within a +/- `delta` range. * * assert.closeTo(1.5, 1, 0.5, 'numbers are close'); * * @name closeTo * @param {Number} actual * @param {Number} expected * @param {Number} delta * @param {String} message * @namespace Assert * @api public */ assert.closeTo = function (act, exp, delta, msg) { new Assertion(act, msg, assert.closeTo, true).to.be.closeTo(exp, delta); }; /** * ### .approximately(actual, expected, delta, [message]) * * Asserts that the target is equal `expected`, to within a +/- `delta` range. * * assert.approximately(1.5, 1, 0.5, 'numbers are close'); * * @name approximately * @param {Number} actual * @param {Number} expected * @param {Number} delta * @param {String} message * @namespace Assert * @api public */ assert.approximately = function (act, exp, delta, msg) { new Assertion(act, msg, assert.approximately, true) .to.be.approximately(exp, delta); }; /** * ### .sameMembers(set1, set2, [message]) * * Asserts that `set1` and `set2` have the same members in any order. Uses a * strict equality check (===). * * assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members'); * * @name sameMembers * @param {Array} set1 * @param {Array} set2 * @param {String} message * @namespace Assert * @api public */ assert.sameMembers = function (set1, set2, msg) { new Assertion(set1, msg, assert.sameMembers, true) .to.have.same.members(set2); } /** * ### .notSameMembers(set1, set2, [message]) * * Asserts that `set1` and `set2` don't have the same members in any order. * Uses a strict equality check (===). * * assert.notSameMembers([ 1, 2, 3 ], [ 5, 1, 3 ], 'not same members'); * * @name notSameMembers * @param {Array} set1 * @param {Array} set2 * @param {String} message * @namespace Assert * @api public */ assert.notSameMembers = function (set1, set2, msg) { new Assertion(set1, msg, assert.notSameMembers, true) .to.not.have.same.members(set2); } /** * ### .sameDeepMembers(set1, set2, [message]) * * Asserts that `set1` and `set2` have the same members in any order. Uses a * deep equality check. * * assert.sameDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [{ b: 2 }, { a: 1 }, { c: 3 }], 'same deep members'); * * @name sameDeepMembers * @param {Array} set1 * @param {Array} set2 * @param {String} message * @namespace Assert * @api public */ assert.sameDeepMembers = function (set1, set2, msg) { new Assertion(set1, msg, assert.sameDeepMembers, true) .to.have.same.deep.members(set2); } /** * ### .notSameDeepMembers(set1, set2, [message]) * * Asserts that `set1` and `set2` don't have the same members in any order. * Uses a deep equality check. * * assert.notSameDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [{ b: 2 }, { a: 1 }, { f: 5 }], 'not same deep members'); * * @name notSameDeepMembers * @param {Array} set1 * @param {Array} set2 * @param {String} message * @namespace Assert * @api public */ assert.notSameDeepMembers = function (set1, set2, msg) { new Assertion(set1, msg, assert.notSameDeepMembers, true) .to.not.have.same.deep.members(set2); } /** * ### .sameOrderedMembers(set1, set2, [message]) * * Asserts that `set1` and `set2` have the same members in the same order. * Uses a strict equality check (===). * * assert.sameOrderedMembers([ 1, 2, 3 ], [ 1, 2, 3 ], 'same ordered members'); * * @name sameOrderedMembers * @param {Array} set1 * @param {Array} set2 * @param {String} message * @namespace Assert * @api public */ assert.sameOrderedMembers = function (set1, set2, msg) { new Assertion(set1, msg, assert.sameOrderedMembers, true) .to.have.same.ordered.members(set2); } /** * ### .notSameOrderedMembers(set1, set2, [message]) * * Asserts that `set1` and `set2` don't have the same members in the same * order. Uses a strict equality check (===). * * assert.notSameOrderedMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'not same ordered members'); * * @name notSameOrderedMembers * @param {Array} set1 * @param {Array} set2 * @param {String} message * @namespace Assert * @api public */ assert.notSameOrderedMembers = function (set1, set2, msg) { new Assertion(set1, msg, assert.notSameOrderedMembers, true) .to.not.have.same.ordered.members(set2); } /** * ### .sameDeepOrderedMembers(set1, set2, [message]) * * Asserts that `set1` and `set2` have the same members in the same order. * Uses a deep equality check. * * assert.sameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 }, { c: 3 } ], 'same deep ordered members'); * * @name sameDeepOrderedMembers * @param {Array} set1 * @param {Array} set2 * @param {String} message * @namespace Assert * @api public */ assert.sameDeepOrderedMembers = function (set1, set2, msg) { new Assertion(set1, msg, assert.sameDeepOrderedMembers, true) .to.have.same.deep.ordered.members(set2); } /** * ### .notSameDeepOrderedMembers(set1, set2, [message]) * * Asserts that `set1` and `set2` don't have the same members in the same * order. Uses a deep equality check. * * assert.notSameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 }, { z: 5 } ], 'not same deep ordered members'); * assert.notSameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 }, { c: 3 } ], 'not same deep ordered members'); * * @name notSameDeepOrderedMembers * @param {Array} set1 * @param {Array} set2 * @param {String} message * @namespace Assert * @api public */ assert.notSameDeepOrderedMembers = function (set1, set2, msg) { new Assertion(set1, msg, assert.notSameDeepOrderedMembers, true) .to.not.have.same.deep.ordered.members(set2); } /** * ### .includeMembers(superset, subset, [message]) * * Asserts that `subset` is included in `superset` in any order. Uses a * strict equality check (===). Duplicates are ignored. * * assert.includeMembers([ 1, 2, 3 ], [ 2, 1, 2 ], 'include members'); * * @name includeMembers * @param {Array} superset * @param {Array} subset * @param {String} message * @namespace Assert * @api public */ assert.includeMembers = function (superset, subset, msg) { new Assertion(superset, msg, assert.includeMembers, true) .to.include.members(subset); } /** * ### .notIncludeMembers(superset, subset, [message]) * * Asserts that `subset` isn't included in `superset` in any order. Uses a * strict equality check (===). Duplicates are ignored. * * assert.notIncludeMembers([ 1, 2, 3 ], [ 5, 1 ], 'not include members'); * * @name notIncludeMembers * @param {Array} superset * @param {Array} subset * @param {String} message * @namespace Assert * @api public */ assert.notIncludeMembers = function (superset, subset, msg) { new Assertion(superset, msg, assert.notIncludeMembers, true) .to.not.include.members(subset); } /** * ### .includeDeepMembers(superset, subset, [message]) * * Asserts that `subset` is included in `superset` in any order. Uses a deep * equality check. Duplicates are ignored. * * assert.includeDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 }, { b: 2 } ], 'include deep members'); * * @name includeDeepMembers * @param {Array} superset * @param {Array} subset * @param {String} message * @namespace Assert * @api public */ assert.includeDeepMembers = function (superset, subset, msg) { new Assertion(superset, msg, assert.includeDeepMembers, true) .to.include.deep.members(subset); } /** * ### .notIncludeDeepMembers(superset, subset, [message]) * * Asserts that `subset` isn't included in `superset` in any order. Uses a * deep equality check. Duplicates are ignored. * * assert.notIncludeDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { f: 5 } ], 'not include deep members'); * * @name notIncludeDeepMembers * @param {Array} superset * @param {Array} subset * @param {String} message * @namespace Assert * @api public */ assert.notIncludeDeepMembers = function (superset, subset, msg) { new Assertion(superset, msg, assert.notIncludeDeepMembers, true) .to.not.include.deep.members(subset); } /** * ### .includeOrderedMembers(superset, subset, [message]) * * Asserts that `subset` is included in `superset` in the same order * beginning with the first element in `superset`. Uses a strict equality * check (===). * * assert.includeOrderedMembers([ 1, 2, 3 ], [ 1, 2 ], 'include ordered members'); * * @name includeOrderedMembers * @param {Array} superset * @param {Array} subset * @param {String} message * @namespace Assert * @api public */ assert.includeOrderedMembers = function (superset, subset, msg) { new Assertion(superset, msg, assert.includeOrderedMembers, true) .to.include.ordered.members(subset); } /** * ### .notIncludeOrderedMembers(superset, subset, [message]) * * Asserts that `subset` isn't included in `superset` in the same order * beginning with the first element in `superset`. Uses a strict equality * check (===). * * assert.notIncludeOrderedMembers([ 1, 2, 3 ], [ 2, 1 ], 'not include ordered members'); * assert.notIncludeOrderedMembers([ 1, 2, 3 ], [ 2, 3 ], 'not include ordered members'); * * @name notIncludeOrderedMembers * @param {Array} superset * @param {Array} subset * @param {String} message * @namespace Assert * @api public */ assert.notIncludeOrderedMembers = function (superset, subset, msg) { new Assertion(superset, msg, assert.notIncludeOrderedMembers, true) .to.not.include.ordered.members(subset); } /** * ### .includeDeepOrderedMembers(superset, subset, [message]) * * Asserts that `subset` is included in `superset` in the same order * beginning with the first element in `superset`. Uses a deep equality * check. * * assert.includeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 } ], 'include deep ordered members'); * * @name includeDeepOrderedMembers * @param {Array} superset * @param {Array} subset * @param {String} message * @namespace Assert * @api public */ assert.includeDeepOrderedMembers = function (superset, subset, msg) { new Assertion(superset, msg, assert.includeDeepOrderedMembers, true) .to.include.deep.ordered.members(subset); } /** * ### .notIncludeDeepOrderedMembers(superset, subset, [message]) * * Asserts that `subset` isn't included in `superset` in the same order * beginning with the first element in `superset`. Uses a deep equality * check. * * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { f: 5 } ], 'not include deep ordered members'); * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 } ], 'not include deep ordered members'); * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { c: 3 } ], 'not include deep ordered members'); * * @name notIncludeDeepOrderedMembers * @param {Array} superset * @param {Array} subset * @param {String} message * @namespace Assert * @api public */ assert.notIncludeDeepOrderedMembers = function (superset, subset, msg) { new Assertion(superset, msg, assert.notIncludeDeepOrderedMembers, true) .to.not.include.deep.ordered.members(subset); } /** * ### .oneOf(inList, list, [message]) * * Asserts that non-object, non-array value `inList` appears in the flat array `list`. * * assert.oneOf(1, [ 2, 1 ], 'Not found in list'); * * @name oneOf * @param {*} inList * @param {Array<*>} list * @param {String} message * @namespace Assert * @api public */ assert.oneOf = function (inList, list, msg) { new Assertion(inList, msg, assert.oneOf, true).to.be.oneOf(list); } /** * ### .changes(function, object, property, [message]) * * Asserts that a function changes the value of a property. * * var obj = { val: 10 }; * var fn = function() { obj.val = 22 }; * assert.changes(fn, obj, 'val'); * * @name changes * @param {Function} modifier function * @param {Object} object or getter function * @param {String} property name _optional_ * @param {String} message _optional_ * @namespace Assert * @api public */ assert.changes = function (fn, obj, prop, msg) { if (arguments.length === 3 && typeof obj === 'function') { msg = prop; prop = null; } new Assertion(fn, msg, assert.changes, true).to.change(obj, prop); } /** * ### .changesBy(function, object, property, delta, [message]) * * Asserts that a function changes the value of a property by an amount (delta). * * var obj = { val: 10 }; * var fn = function() { obj.val += 2 }; * assert.changesBy(fn, obj, 'val', 2); * * @name changesBy * @param {Function} modifier function * @param {Object} object or getter function * @param {String} property name _optional_ * @param {Number} change amount (delta) * @param {String} message _optional_ * @namespace Assert * @api public */ assert.changesBy = function (fn, obj, prop, delta, msg) { if (arguments.length === 4 && typeof obj === 'function') { var tmpMsg = delta; delta = prop; msg = tmpMsg; } else if (arguments.length === 3) { delta = prop; prop = null; } new Assertion(fn, msg, assert.changesBy, true) .to.change(obj, prop).by(delta); } /** * ### .doesNotChange(function, object, property, [message]) * * Asserts that a function does not change the value of a property. * * var obj = { val: 10 }; * var fn = function() { console.log('foo'); }; * assert.doesNotChange(fn, obj, 'val'); * * @name doesNotChange * @param {Function} modifier function * @param {Object} object or getter function * @param {String} property name _optional_ * @param {String} message _optional_ * @namespace Assert * @api public */ assert.doesNotChange = function (fn, obj, prop, msg) { if (arguments.length === 3 && typeof obj === 'function') { msg = prop; prop = null; } return new Assertion(fn, msg, assert.doesNotChange, true) .to.not.change(obj, prop); } /** * ### .changesButNotBy(function, object, property, delta, [message]) * * Asserts that a function does not change the value of a property or of a function's return value by an amount (delta) * * var obj = { val: 10 }; * var fn = function() { obj.val += 10 }; * assert.changesButNotBy(fn, obj, 'val', 5); * * @name changesButNotBy * @param {Function} modifier function * @param {Object} object or getter function * @param {String} property name _optional_ * @param {Number} change amount (delta) * @param {String} message _optional_ * @namespace Assert * @api public */ assert.changesButNotBy = function (fn, obj, prop, delta, msg) { if (arguments.length === 4 && typeof obj === 'function') { var tmpMsg = delta; delta = prop; msg = tmpMsg; } else if (arguments.length === 3) { delta = prop; prop = null; } new Assertion(fn, msg, assert.changesButNotBy, true) .to.change(obj, prop).but.not.by(delta); } /** * ### .increases(function, object, property, [message]) * * Asserts that a function increases a numeric object property. * * var obj = { val: 10 }; * var fn = function() { obj.val = 13 }; * assert.increases(fn, obj, 'val'); * * @name increases * @param {Function} modifier function * @param {Object} object or getter function * @param {String} property name _optional_ * @param {String} message _optional_ * @namespace Assert * @api public */ assert.increases = function (fn, obj, prop, msg) { if (arguments.length === 3 && typeof obj === 'function') { msg = prop; prop = null; } return new Assertion(fn, msg, assert.increases, true) .to.increase(obj, prop); } /** * ### .increasesBy(function, object, property, delta, [message]) * * Asserts that a function increases a numeric object property or a function's return value by an amount (delta). * * var obj = { val: 10 }; * var fn = function() { obj.val += 10 }; * assert.increasesBy(fn, obj, 'val', 10); * * @name increasesBy * @param {Function} modifier function * @param {Object} object or getter function * @param {String} property name _optional_ * @param {Number} change amount (delta) * @param {String} message _optional_ * @namespace Assert * @api public */ assert.increasesBy = function (fn, obj, prop, delta, msg) { if (arguments.length === 4 && typeof obj === 'function') { var tmpMsg = delta; delta = prop; msg = tmpMsg; } else if (arguments.length === 3) { delta = prop; prop = null; } new Assertion(fn, msg, assert.increasesBy, true) .to.increase(obj, prop).by(delta); } /** * ### .doesNotIncrease(function, object, property, [message]) * * Asserts that a function does not increase a numeric object property. * * var obj = { val: 10 }; * var fn = function() { obj.val = 8 }; * assert.doesNotIncrease(fn, obj, 'val'); * * @name doesNotIncrease * @param {Function} modifier function * @param {Object} object or getter function * @param {String} property name _optional_ * @param {String} message _optional_ * @namespace Assert * @api public */ assert.doesNotIncrease = function (fn, obj, prop, msg) { if (arguments.length === 3 && typeof obj === 'function') { msg = prop; prop = null; } return new Assertion(fn, msg, assert.doesNotIncrease, true) .to.not.increase(obj, prop); } /** * ### .increasesButNotBy(function, object, property, delta, [message]) * * Asserts that a function does not increase a numeric object property or function's return value by an amount (delta). * * var obj = { val: 10 }; * var fn = function() { obj.val = 15 }; * assert.increasesButNotBy(fn, obj, 'val', 10); * * @name increasesButNotBy * @param {Function} modifier function * @param {Object} object or getter function * @param {String} property name _optional_ * @param {Number} change amount (delta) * @param {String} message _optional_ * @namespace Assert * @api public */ assert.increasesButNotBy = function (fn, obj, prop, delta, msg) { if (arguments.length === 4 && typeof obj === 'function') { var tmpMsg = delta; delta = prop; msg = tmpMsg; } else if (arguments.length === 3) { delta = prop; prop = null; } new Assertion(fn, msg, assert.increasesButNotBy, true) .to.increase(obj, prop).but.not.by(delta); } /** * ### .decreases(function, object, property, [message]) * * Asserts that a function decreases a numeric object property. * * var obj = { val: 10 }; * var fn = function() { obj.val = 5 }; * assert.decreases(fn, obj, 'val'); * * @name decreases * @param {Function} modifier function * @param {Object} object or getter function * @param {String} property name _optional_ * @param {String} message _optional_ * @namespace Assert * @api public */ assert.decreases = function (fn, obj, prop, msg) { if (arguments.length === 3 && typeof obj === 'function') { msg = prop; prop = null; } return new Assertion(fn, msg, assert.decreases, true) .to.decrease(obj, prop); } /** * ### .decreasesBy(function, object, property, delta, [message]) * * Asserts that a function decreases a numeric object property or a function's return value by an amount (delta) * * var obj = { val: 10 }; * var fn = function() { obj.val -= 5 }; * assert.decreasesBy(fn, obj, 'val', 5); * * @name decreasesBy * @param {Function} modifier function * @param {Object} object or getter function * @param {String} property name _optional_ * @param {Number} change amount (delta) * @param {String} message _optional_ * @namespace Assert * @api public */ assert.decreasesBy = function (fn, obj, prop, delta, msg) { if (arguments.length === 4 && typeof obj === 'function') { var tmpMsg = delta; delta = prop; msg = tmpMsg; } else if (arguments.length === 3) { delta = prop; prop = null; } new Assertion(fn, msg, assert.decreasesBy, true) .to.decrease(obj, prop).by(delta); } /** * ### .doesNotDecrease(function, object, property, [message]) * * Asserts that a function does not decreases a numeric object property. * * var obj = { val: 10 }; * var fn = function() { obj.val = 15 }; * assert.doesNotDecrease(fn, obj, 'val'); * * @name doesNotDecrease * @param {Function} modifier function * @param {Object} object or getter function * @param {String} property name _optional_ * @param {String} message _optional_ * @namespace Assert * @api public */ assert.doesNotDecrease = function (fn, obj, prop, msg) { if (arguments.length === 3 && typeof obj === 'function') { msg = prop; prop = null; } return new Assertion(fn, msg, assert.doesNotDecrease, true) .to.not.decrease(obj, prop); } /** * ### .doesNotDecreaseBy(function, object, property, delta, [message]) * * Asserts that a function does not decreases a numeric object property or a function's return value by an amount (delta) * * var obj = { val: 10 }; * var fn = function() { obj.val = 5 }; * assert.doesNotDecreaseBy(fn, obj, 'val', 1); * * @name doesNotDecreaseBy * @param {Function} modifier function * @param {Object} object or getter function * @param {String} property name _optional_ * @param {Number} change amount (delta) * @param {String} message _optional_ * @namespace Assert * @api public */ assert.doesNotDecreaseBy = function (fn, obj, prop, delta, msg) { if (arguments.length === 4 && typeof obj === 'function') { var tmpMsg = delta; delta = prop; msg = tmpMsg; } else if (arguments.length === 3) { delta = prop; prop = null; } return new Assertion(fn, msg, assert.doesNotDecreaseBy, true) .to.not.decrease(obj, prop).by(delta); } /** * ### .decreasesButNotBy(function, object, property, delta, [message]) * * Asserts that a function does not decreases a numeric object property or a function's return value by an amount (delta) * * var obj = { val: 10 }; * var fn = function() { obj.val = 5 }; * assert.decreasesButNotBy(fn, obj, 'val', 1); * * @name decreasesButNotBy * @param {Function} modifier function * @param {Object} object or getter function * @param {String} property name _optional_ * @param {Number} change amount (delta) * @param {String} message _optional_ * @namespace Assert * @api public */ assert.decreasesButNotBy = function (fn, obj, prop, delta, msg) { if (arguments.length === 4 && typeof obj === 'function') { var tmpMsg = delta; delta = prop; msg = tmpMsg; } else if (arguments.length === 3) { delta = prop; prop = null; } new Assertion(fn, msg, assert.decreasesButNotBy, true) .to.decrease(obj, prop).but.not.by(delta); } /*! * ### .ifError(object) * * Asserts if value is not a false value, and throws if it is a true value. * This is added to allow for chai to be a drop-in replacement for Node's * assert class. * * var err = new Error('I am a custom error'); * assert.ifError(err); // Rethrows err! * * @name ifError * @param {Object} object * @namespace Assert * @api public */ assert.ifError = function (val) { if (val) { throw(val); } }; /** * ### .isExtensible(object) * * Asserts that `object` is extensible (can have new properties added to it). * * assert.isExtensible({}); * * @name isExtensible * @alias extensible * @param {Object} object * @param {String} message _optional_ * @namespace Assert * @api public */ assert.isExtensible = function (obj, msg) { new Assertion(obj, msg, assert.isExtensible, true).to.be.extensible; }; /** * ### .isNotExtensible(object) * * Asserts that `object` is _not_ extensible. * * var nonExtensibleObject = Object.preventExtensions({}); * var sealedObject = Object.seal({}); * var frozenObject = Object.freeze({}); * * assert.isNotExtensible(nonExtensibleObject); * assert.isNotExtensible(sealedObject); * assert.isNotExtensible(frozenObject); * * @name isNotExtensible * @alias notExtensible * @param {Object} object * @param {String} message _optional_ * @namespace Assert * @api public */ assert.isNotExtensible = function (obj, msg) { new Assertion(obj, msg, assert.isNotExtensible, true).to.not.be.extensible; }; /** * ### .isSealed(object) * * Asserts that `object` is sealed (cannot have new properties added to it * and its existing properties cannot be removed). * * var sealedObject = Object.seal({}); * var frozenObject = Object.seal({}); * * assert.isSealed(sealedObject); * assert.isSealed(frozenObject); * * @name isSealed * @alias sealed * @param {Object} object * @param {String} message _optional_ * @namespace Assert * @api public */ assert.isSealed = function (obj, msg) { new Assertion(obj, msg, assert.isSealed, true).to.be.sealed; }; /** * ### .isNotSealed(object) * * Asserts that `object` is _not_ sealed. * * assert.isNotSealed({}); * * @name isNotSealed * @alias notSealed * @param {Object} object * @param {String} message _optional_ * @namespace Assert * @api public */ assert.isNotSealed = function (obj, msg) { new Assertion(obj, msg, assert.isNotSealed, true).to.not.be.sealed; }; /** * ### .isFrozen(object) * * Asserts that `object` is frozen (cannot have new properties added to it * and its existing properties cannot be modified). * * var frozenObject = Object.freeze({}); * assert.frozen(frozenObject); * * @name isFrozen * @alias frozen * @param {Object} object * @param {String} message _optional_ * @namespace Assert * @api public */ assert.isFrozen = function (obj, msg) { new Assertion(obj, msg, assert.isFrozen, true).to.be.frozen; }; /** * ### .isNotFrozen(object) * * Asserts that `object` is _not_ frozen. * * assert.isNotFrozen({}); * * @name isNotFrozen * @alias notFrozen * @param {Object} object * @param {String} message _optional_ * @namespace Assert * @api public */ assert.isNotFrozen = function (obj, msg) { new Assertion(obj, msg, assert.isNotFrozen, true).to.not.be.frozen; }; /** * ### .isEmpty(target) * * Asserts that the target does not contain any values. * For arrays and strings, it checks the `length` property. * For `Map` and `Set` instances, it checks the `size` property. * For non-function objects, it gets the count of own * enumerable string keys. * * assert.isEmpty([]); * assert.isEmpty(''); * assert.isEmpty(new Map); * assert.isEmpty({}); * * @name isEmpty * @alias empty * @param {Object|Array|String|Map|Set} target * @param {String} message _optional_ * @namespace Assert * @api public */ assert.isEmpty = function(val, msg) { new Assertion(val, msg, assert.isEmpty, true).to.be.empty; }; /** * ### .isNotEmpty(target) * * Asserts that the target contains values. * For arrays and strings, it checks the `length` property. * For `Map` and `Set` instances, it checks the `size` property. * For non-function objects, it gets the count of own * enumerable string keys. * * assert.isNotEmpty([1, 2]); * assert.isNotEmpty('34'); * assert.isNotEmpty(new Set([5, 6])); * assert.isNotEmpty({ key: 7 }); * * @name isNotEmpty * @alias notEmpty * @param {Object|Array|String|Map|Set} target * @param {String} message _optional_ * @namespace Assert * @api public */ assert.isNotEmpty = function(val, msg) { new Assertion(val, msg, assert.isNotEmpty, true).to.not.be.empty; }; /*! * Aliases. */ (function alias(name, as){ assert[as] = assert[name]; return alias; }) ('isOk', 'ok') ('isNotOk', 'notOk') ('throws', 'throw') ('throws', 'Throw') ('isExtensible', 'extensible') ('isNotExtensible', 'notExtensible') ('isSealed', 'sealed') ('isNotSealed', 'notSealed') ('isFrozen', 'frozen') ('isNotFrozen', 'notFrozen') ('isEmpty', 'empty') ('isNotEmpty', 'notEmpty');};
},{}],7:[function(require,module,exports){/*! * chai * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */module.exports = function (chai, util) { chai.expect = function (val, message) { return new chai.Assertion(val, message); }; /** * ### .fail([message]) * ### .fail(actual, expected, [message], [operator]) * * Throw a failure. * * expect.fail(); * expect.fail("custom error message"); * expect.fail(1, 2); * expect.fail(1, 2, "custom error message"); * expect.fail(1, 2, "custom error message", ">"); * expect.fail(1, 2, undefined, ">"); * * @name fail * @param {Mixed} actual * @param {Mixed} expected * @param {String} message * @param {String} operator * @namespace BDD * @api public */ chai.expect.fail = function (actual, expected, message, operator) { if (arguments.length < 2) { message = actual; actual = undefined; } message = message || 'expect.fail()'; throw new chai.AssertionError(message, { actual: actual , expected: expected , operator: operator }, chai.expect.fail); };};
},{}],8:[function(require,module,exports){/*! * chai * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */module.exports = function (chai, util) { var Assertion = chai.Assertion; function loadShould () { // explicitly define this method as function as to have it's name to include as `ssfi` function shouldGetter() { if (this instanceof String || this instanceof Number || this instanceof Boolean || typeof Symbol === 'function' && this instanceof Symbol || typeof BigInt === 'function' && this instanceof BigInt) { return new Assertion(this.valueOf(), null, shouldGetter); } return new Assertion(this, null, shouldGetter); } function shouldSetter(value) { // See https://github.com/chaijs/chai/issues/86: this makes // `whatever.should = someValue` actually set `someValue`, which is // especially useful for `global.should = require('chai').should()`. // // Note that we have to use [[DefineProperty]] instead of [[Put]] // since otherwise we would trigger this very setter! Object.defineProperty(this, 'should', { value: value, enumerable: true, configurable: true, writable: true }); } // modify Object.prototype to have `should` Object.defineProperty(Object.prototype, 'should', { set: shouldSetter , get: shouldGetter , configurable: true }); var should = {}; /** * ### .fail([message]) * ### .fail(actual, expected, [message], [operator]) * * Throw a failure. * * should.fail(); * should.fail("custom error message"); * should.fail(1, 2); * should.fail(1, 2, "custom error message"); * should.fail(1, 2, "custom error message", ">"); * should.fail(1, 2, undefined, ">"); * * * @name fail * @param {Mixed} actual * @param {Mixed} expected * @param {String} message * @param {String} operator * @namespace BDD * @api public */ should.fail = function (actual, expected, message, operator) { if (arguments.length < 2) { message = actual; actual = undefined; } message = message || 'should.fail()'; throw new chai.AssertionError(message, { actual: actual , expected: expected , operator: operator }, should.fail); }; /** * ### .equal(actual, expected, [message]) * * Asserts non-strict equality (`==`) of `actual` and `expected`. * * should.equal(3, '3', '== coerces values to strings'); * * @name equal * @param {Mixed} actual * @param {Mixed} expected * @param {String} message * @namespace Should * @api public */ should.equal = function (val1, val2, msg) { new Assertion(val1, msg).to.equal(val2); }; /** * ### .throw(function, [constructor/string/regexp], [string/regexp], [message]) * * Asserts that `function` will throw an error that is an instance of * `constructor`, or alternately that it will throw an error with message * matching `regexp`. * * should.throw(fn, 'function throws a reference error'); * should.throw(fn, /function throws a reference error/); * should.throw(fn, ReferenceError); * should.throw(fn, ReferenceError, 'function throws a reference error'); * should.throw(fn, ReferenceError, /function throws a reference error/); * * @name throw * @alias Throw * @param {Function} function * @param {ErrorConstructor} constructor * @param {RegExp} regexp * @param {String} message * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types * @namespace Should * @api public */ should.Throw = function (fn, errt, errs, msg) { new Assertion(fn, msg).to.Throw(errt, errs); }; /** * ### .exist * * Asserts that the target is neither `null` nor `undefined`. * * var foo = 'hi'; * * should.exist(foo, 'foo exists'); * * @name exist * @namespace Should * @api public */ should.exist = function (val, msg) { new Assertion(val, msg).to.exist; } // negation should.not = {} /** * ### .not.equal(actual, expected, [message]) * * Asserts non-strict inequality (`!=`) of `actual` and `expected`. * * should.not.equal(3, 4, 'these numbers are not equal'); * * @name not.equal * @param {Mixed} actual * @param {Mixed} expected * @param {String} message * @namespace Should * @api public */ should.not.equal = function (val1, val2, msg) { new Assertion(val1, msg).to.not.equal(val2); }; /** * ### .throw(function, [constructor/regexp], [message]) * * Asserts that `function` will _not_ throw an error that is an instance of * `constructor`, or alternately that it will not throw an error with message * matching `regexp`. * * should.not.throw(fn, Error, 'function does not throw'); * * @name not.throw * @alias not.Throw * @param {Function} function * @param {ErrorConstructor} constructor * @param {RegExp} regexp * @param {String} message * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types * @namespace Should * @api public */ should.not.Throw = function (fn, errt, errs, msg) { new Assertion(fn, msg).to.not.Throw(errt, errs); }; /** * ### .not.exist * * Asserts that the target is neither `null` nor `undefined`. * * var bar = null; * * should.not.exist(bar, 'bar does not exist'); * * @name not.exist * @namespace Should * @api public */ should.not.exist = function (val, msg) { new Assertion(val, msg).to.not.exist; } should['throw'] = should['Throw']; should.not['throw'] = should.not['Throw']; return should; }; chai.should = loadShould; chai.Should = loadShould;};
},{}],9:[function(require,module,exports){/*! * Chai - addChainingMethod utility * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> * MIT Licensed *//*! * Module dependencies */var addLengthGuard = require('./addLengthGuard');var chai = require('../../chai');var flag = require('./flag');var proxify = require('./proxify');var transferFlags = require('./transferFlags');
/*! * Module variables */// Check whether `Object.setPrototypeOf` is supportedvar canSetPrototype = typeof Object.setPrototypeOf === 'function';
// Without `Object.setPrototypeOf` support, this module will need to add properties to a function.// However, some of functions' own props are not configurable and should be skipped.var testFn = function() {};var excludeNames = Object.getOwnPropertyNames(testFn).filter(function(name) { var propDesc = Object.getOwnPropertyDescriptor(testFn, name); // Note: PhantomJS 1.x includes `callee` as one of `testFn`'s own properties, // but then returns `undefined` as the property descriptor for `callee`. As a // workaround, we perform an otherwise unnecessary type-check for `propDesc`, // and then filter it out if it's not an object as it should be. if (typeof propDesc !== 'object') return true; return !propDesc.configurable;});
// Cache `Function` propertiesvar call = Function.prototype.call, apply = Function.prototype.apply;/** * ### .addChainableMethod(ctx, name, method, chainingBehavior) * * Adds a method to an object, such that the method can also be chained. * * utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) { * var obj = utils.flag(this, 'object'); * new chai.Assertion(obj).to.be.equal(str); * }); * * Can also be accessed directly from `chai.Assertion`. * * chai.Assertion.addChainableMethod('foo', fn, chainingBehavior); * * The result can then be used as both a method assertion, executing both `method` and * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`. * * expect(fooStr).to.be.foo('bar'); * expect(fooStr).to.be.foo.equal('foo'); * * @param {Object} ctx object to which the method is added * @param {String} name of method to add * @param {Function} method function to be used for `name`, when called * @param {Function} chainingBehavior function to be called every time the property is accessed * @namespace Utils * @name addChainableMethod * @api public */module.exports = function addChainableMethod(ctx, name, method, chainingBehavior) { if (typeof chainingBehavior !== 'function') { chainingBehavior = function () { }; } var chainableBehavior = { method: method , chainingBehavior: chainingBehavior }; // save the methods so we can overwrite them later, if we need to. if (!ctx.__methods) { ctx.__methods = {}; } ctx.__methods[name] = chainableBehavior; Object.defineProperty(ctx, name, { get: function chainableMethodGetter() { chainableBehavior.chainingBehavior.call(this); var chainableMethodWrapper = function () { // Setting the `ssfi` flag to `chainableMethodWrapper` causes this // function to be the starting point for removing implementation // frames from the stack trace of a failed assertion. // // However, we only want to use this function as the starting point if // the `lockSsfi` flag isn't set. // // If the `lockSsfi` flag is set, then this assertion is being // invoked from inside of another assertion. In this case, the `ssfi` // flag has already been set by the outer assertion. // // Note that overwriting a chainable method merely replaces the saved // methods in `ctx.__methods` instead of completely replacing the // overwritten assertion. Therefore, an overwriting assertion won't // set the `ssfi` or `lockSsfi` flags. if (!flag(this, 'lockSsfi')) { flag(this, 'ssfi', chainableMethodWrapper); } var result = chainableBehavior.method.apply(this, arguments); if (result !== undefined) { return result; } var newAssertion = new chai.Assertion(); transferFlags(this, newAssertion); return newAssertion; }; addLengthGuard(chainableMethodWrapper, name, true); // Use `Object.setPrototypeOf` if available if (canSetPrototype) { // Inherit all properties from the object by replacing the `Function` prototype var prototype = Object.create(this); // Restore the `call` and `apply` methods from `Function` prototype.call = call; prototype.apply = apply; Object.setPrototypeOf(chainableMethodWrapper, prototype); } // Otherwise, redefine all properties (slow!) else { var asserterNames = Object.getOwnPropertyNames(ctx); asserterNames.forEach(function (asserterName) { if (excludeNames.indexOf(asserterName) !== -1) { return; } var pd = Object.getOwnPropertyDescriptor(ctx, asserterName); Object.defineProperty(chainableMethodWrapper, asserterName, pd); }); } transferFlags(this, chainableMethodWrapper); return proxify(chainableMethodWrapper); } , configurable: true });};
},{"../../chai":2,"./addLengthGuard":10,"./flag":15,"./proxify":30,"./transferFlags":32}],10:[function(require,module,exports){var fnLengthDesc = Object.getOwnPropertyDescriptor(function () {}, 'length');
/*! * Chai - addLengthGuard utility * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> * MIT Licensed *//** * ### .addLengthGuard(fn, assertionName, isChainable) * * Define `length` as a getter on the given uninvoked method assertion. The * getter acts as a guard against chaining `length` directly off of an uninvoked * method assertion, which is a problem because it references `function`'s * built-in `length` property instead of Chai's `length` assertion. When the * getter catches the user making this mistake, it throws an error with a * helpful message. * * There are two ways in which this mistake can be made. The first way is by * chaining the `length` assertion directly off of an uninvoked chainable * method. In this case, Chai suggests that the user use `lengthOf` instead. The * second way is by chaining the `length` assertion directly off of an uninvoked * non-chainable method. Non-chainable methods must be invoked prior to * chaining. In this case, Chai suggests that the user consult the docs for the * given assertion. * * If the `length` property of functions is unconfigurable, then return `fn` * without modification. * * Note that in ES6, the function's `length` property is configurable, so once * support for legacy environments is dropped, Chai's `length` property can * replace the built-in function's `length` property, and this length guard will * no longer be necessary. In the mean time, maintaining consistency across all * environments is the priority. * * @param {Function} fn * @param {String} assertionName * @param {Boolean} isChainable * @namespace Utils * @name addLengthGuard */module.exports = function addLengthGuard (fn, assertionName, isChainable) { if (!fnLengthDesc.configurable) return fn; Object.defineProperty(fn, 'length', { get: function () { if (isChainable) { throw Error('Invalid Chai property: ' + assertionName + '.length. Due' + ' to a compatibility issue, "length" cannot directly follow "' + assertionName + '". Use "' + assertionName + '.lengthOf" instead.'); } throw Error('Invalid Chai property: ' + assertionName + '.length. See' + ' docs for proper usage of "' + assertionName + '".'); } }); return fn;};
},{}],11:[function(require,module,exports){/*! * Chai - addMethod utility * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */var addLengthGuard = require('./addLengthGuard');var chai = require('../../chai');var flag = require('./flag');var proxify = require('./proxify');var transferFlags = require('./transferFlags');
/** * ### .addMethod(ctx, name, method) * * Adds a method to the prototype of an object. * * utils.addMethod(chai.Assertion.prototype, 'foo', function (str) { * var obj = utils.flag(this, 'object'); * new chai.Assertion(obj).to.be.equal(str); * }); * * Can also be accessed directly from `chai.Assertion`. * * chai.Assertion.addMethod('foo', fn); * * Then can be used as any other assertion. * * expect(fooStr).to.be.foo('bar'); * * @param {Object} ctx object to which the method is added * @param {String} name of method to add * @param {Function} method function to be used for name * @namespace Utils * @name addMethod * @api public */module.exports = function addMethod(ctx, name, method) { var methodWrapper = function () { // Setting the `ssfi` flag to `methodWrapper` causes this function to be the // starting point for removing implementation frames from the stack trace of // a failed assertion. // // However, we only want to use this function as the starting point if the // `lockSsfi` flag isn't set. // // If the `lockSsfi` flag is set, then either this assertion has been // overwritten by another assertion, or this assertion is being invoked from // inside of another assertion. In the first case, the `ssfi` flag has // already been set by the overwriting assertion. In the second case, the // `ssfi` flag has already been set by the outer assertion. if (!flag(this, 'lockSsfi')) { flag(this, 'ssfi', methodWrapper); } var result = method.apply(this, arguments); if (result !== undefined) return result; var newAssertion = new chai.Assertion(); transferFlags(this, newAssertion); return newAssertion; }; addLengthGuard(methodWrapper, name, false); ctx[name] = proxify(methodWrapper, name);};
},{"../../chai":2,"./addLengthGuard":10,"./flag":15,"./proxify":30,"./transferFlags":32}],12:[function(require,module,exports){/*! * Chai - addProperty utility * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */var chai = require('../../chai');var flag = require('./flag');var isProxyEnabled = require('./isProxyEnabled');var transferFlags = require('./transferFlags');
/** * ### .addProperty(ctx, name, getter) * * Adds a property to the prototype of an object. * * utils.addProperty(chai.Assertion.prototype, 'foo', function () { * var obj = utils.flag(this, 'object'); * new chai.Assertion(obj).to.be.instanceof(Foo); * }); * * Can also be accessed directly from `chai.Assertion`. * * chai.Assertion.addProperty('foo', fn); * * Then can be used as any other assertion. * * expect(myFoo).to.be.foo; * * @param {Object} ctx object to which the property is added * @param {String} name of property to add * @param {Function} getter function to be used for name * @namespace Utils * @name addProperty * @api public */module.exports = function addProperty(ctx, name, getter) { getter = getter === undefined ? function () {} : getter; Object.defineProperty(ctx, name, { get: function propertyGetter() { // Setting the `ssfi` flag to `propertyGetter` causes this function to // be the starting point for removing implementation frames from the // stack trace of a failed assertion. // // However, we only want to use this function as the starting point if // the `lockSsfi` flag isn't set and proxy protection is disabled. // // If the `lockSsfi` flag is set, then either this assertion has been // overwritten by another assertion, or this assertion is being invoked // from inside of another assertion. In the first case, the `ssfi` flag // has already been set by the overwriting assertion. In the second // case, the `ssfi` flag has already been set by the outer assertion. // // If proxy protection is enabled, then the `ssfi` flag has already been // set by the proxy getter. if (!isProxyEnabled() && !flag(this, 'lockSsfi')) { flag(this, 'ssfi', propertyGetter); } var result = getter.call(this); if (result !== undefined) return result; var newAssertion = new chai.Assertion(); transferFlags(this, newAssertion); return newAssertion; } , configurable: true });};
},{"../../chai":2,"./flag":15,"./isProxyEnabled":25,"./transferFlags":32}],13:[function(require,module,exports){/*! * Chai - compareByInspect utility * Copyright(c) 2011-2016 Jake Luer <jake@alogicalparadox.com> * MIT Licensed *//*! * Module dependencies */var inspect = require('./inspect');
/** * ### .compareByInspect(mixed, mixed) * * To be used as a compareFunction with Array.prototype.sort. Compares elements * using inspect instead of default behavior of using toString so that Symbols * and objects with irregular/missing toString can still be sorted without a * TypeError. * * @param {Mixed} first element to compare * @param {Mixed} second element to compare * @returns {Number} -1 if 'a' should come before 'b'; otherwise 1 * @name compareByInspect * @namespace Utils * @api public */module.exports = function compareByInspect(a, b) { return inspect(a) < inspect(b) ? -1 : 1;};
},{"./inspect":23}],14:[function(require,module,exports){/*! * Chai - expectTypes utility * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> * MIT Licensed *//** * ### .expectTypes(obj, types) * * Ensures that the object being tested against is of a valid type. * * utils.expectTypes(this, ['array', 'object', 'string']); * * @param {Mixed} obj constructed Assertion * @param {Array} type A list of allowed types for this assertion * @namespace Utils * @name expectTypes * @api public */var AssertionError = require('assertion-error');var flag = require('./flag');var type = require('type-detect');
module.exports = function expectTypes(obj, types) { var flagMsg = flag(obj, 'message'); var ssfi = flag(obj, 'ssfi'); flagMsg = flagMsg ? flagMsg + ': ' : ''; obj = flag(obj, 'object'); types = types.map(function (t) { return t.toLowerCase(); }); types.sort(); // Transforms ['lorem', 'ipsum'] into 'a lorem, or an ipsum' var str = types.map(function (t, index) { var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a'; var or = types.length > 1 && index === types.length - 1 ? 'or ' : ''; return or + art + ' ' + t; }).join(', '); var objType = type(obj).toLowerCase(); if (!types.some(function (expected) { return objType === expected; })) { throw new AssertionError( flagMsg + 'object tested must be ' + str + ', but ' + objType + ' given', undefined, ssfi ); }};
},{"./flag":15,"assertion-error":33,"type-detect":39}],15:[function(require,module,exports){/*! * Chai - flag utility * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> * MIT Licensed *//** * ### .flag(object, key, [value]) * * Get or set a flag value on an object. If a * value is provided it will be set, else it will * return the currently set value or `undefined` if * the value is not set. * * utils.flag(this, 'foo', 'bar'); // setter * utils.flag(this, 'foo'); // getter, returns `bar` * * @param {Object} object constructed Assertion * @param {String} key * @param {Mixed} value (optional) * @namespace Utils * @name flag * @api private */module.exports = function flag(obj, key, value) { var flags = obj.__flags || (obj.__flags = Object.create(null)); if (arguments.length === 3) { flags[key] = value; } else { return flags[key]; }};
},{}],16:[function(require,module,exports){/*! * Chai - getActual utility * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> * MIT Licensed *//** * ### .getActual(object, [actual]) * * Returns the `actual` value for an Assertion. * * @param {Object} object (constructed Assertion) * @param {Arguments} chai.Assertion.prototype.assert arguments * @namespace Utils * @name getActual */module.exports = function getActual(obj, args) { return args.length > 4 ? args[4] : obj._obj;};
},{}],17:[function(require,module,exports){/*! * Chai - message composition utility * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> * MIT Licensed *//*! * Module dependencies */var flag = require('./flag') , getActual = require('./getActual') , objDisplay = require('./objDisplay');/** * ### .getMessage(object, message, negateMessage) * * Construct the error message based on flags * and template tags. Template tags will return * a stringified inspection of the object referenced. * * Message template tags: * - `#{this}` current asserted object * - `#{act}` actual value * - `#{exp}` expected value * * @param {Object} object (constructed Assertion) * @param {Arguments} chai.Assertion.prototype.assert arguments * @namespace Utils * @name getMessage * @api public */module.exports = function getMessage(obj, args) { var negate = flag(obj, 'negate') , val = flag(obj, 'object') , expected = args[3] , actual = getActual(obj, args) , msg = negate ? args[2] : args[1] , flagMsg = flag(obj, 'message'); if(typeof msg === "function") msg = msg(); msg = msg || ''; msg = msg .replace(/#\{this\}/g, function () { return objDisplay(val); }) .replace(/#\{act\}/g, function () { return objDisplay(actual); }) .replace(/#\{exp\}/g, function () { return objDisplay(expected); }); return flagMsg ? flagMsg + ': ' + msg : msg;};
},{"./flag":15,"./getActual":16,"./objDisplay":26}],18:[function(require,module,exports){var type = require('type-detect');
var flag = require('./flag');
function isObjectType(obj) { var objectType = type(obj); var objectTypes = ['Array', 'Object', 'function']; return objectTypes.indexOf(objectType) !== -1;}
/** * ### .getOperator(message) * * Extract the operator from error message. * Operator defined is based on below link * https://nodejs.org/api/assert.html#assert_assert. * * Returns the `operator` or `undefined` value for an Assertion. * * @param {Object} object (constructed Assertion) * @param {Arguments} chai.Assertion.prototype.assert arguments * @namespace Utils * @name getOperator * @api public */module.exports = function getOperator(obj, args) { var operator = flag(obj, 'operator'); var negate = flag(obj, 'negate'); var expected = args[3]; var msg = negate ? args[2] : args[1]; if (operator) { return operator; } if (typeof msg === 'function') msg = msg(); msg = msg || ''; if (!msg) { return undefined; } if (/\shave\s/.test(msg)) { return undefined; } var isObject = isObjectType(expected); if (/\snot\s/.test(msg)) { return isObject ? 'notDeepStrictEqual' : 'notStrictEqual'; } return isObject ? 'deepStrictEqual' : 'strictEqual';};
},{"./flag":15,"type-detect":39}],19:[function(require,module,exports){/*! * Chai - getOwnEnumerableProperties utility * Copyright(c) 2011-2016 Jake Luer <jake@alogicalparadox.com> * MIT Licensed *//*! * Module dependencies */var getOwnEnumerablePropertySymbols = require('./getOwnEnumerablePropertySymbols');
/** * ### .getOwnEnumerableProperties(object) * * This allows the retrieval of directly-owned enumerable property names and * symbols of an object. This function is necessary because Object.keys only * returns enumerable property names, not enumerable property symbols. * * @param {Object} object * @returns {Array} * @namespace Utils * @name getOwnEnumerableProperties * @api public */module.exports = function getOwnEnumerableProperties(obj) { return Object.keys(obj).concat(getOwnEnumerablePropertySymbols(obj));};
},{"./getOwnEnumerablePropertySymbols":20}],20:[function(require,module,exports){/*! * Chai - getOwnEnumerablePropertySymbols utility * Copyright(c) 2011-2016 Jake Luer <jake@alogicalparadox.com> * MIT Licensed *//** * ### .getOwnEnumerablePropertySymbols(object) * * This allows the retrieval of directly-owned enumerable property symbols of an * object. This function is necessary because Object.getOwnPropertySymbols * returns both enumerable and non-enumerable property symbols. * * @param {Object} object * @returns {Array} * @namespace Utils * @name getOwnEnumerablePropertySymbols * @api public */module.exports = function getOwnEnumerablePropertySymbols(obj) { if (typeof Object.getOwnPropertySymbols !== 'function') return []; return Object.getOwnPropertySymbols(obj).filter(function (sym) { return Object.getOwnPropertyDescriptor(obj, sym).enumerable; });};
},{}],21:[function(require,module,exports){/*! * Chai - getProperties utility * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> * MIT Licensed *//** * ### .getProperties(object) * * This allows the retrieval of property names of an object, enumerable or not, * inherited or not. * * @param {Object} object * @returns {Array} * @namespace Utils * @name getProperties * @api public */module.exports = function getProperties(object) { var result = Object.getOwnPropertyNames(object); function addProperty(property) { if (result.indexOf(property) === -1) { result.push(property); } } var proto = Object.getPrototypeOf(object); while (proto !== null) { Object.getOwnPropertyNames(proto).forEach(addProperty); proto = Object.getPrototypeOf(proto); } return result;};
},{}],22:[function(require,module,exports){/*! * chai * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com> * MIT Licensed *//*! * Dependencies that are used for multiple exports are required here only once */var pathval = require('pathval');
/*! * test utility */exports.test = require('./test');
/*! * type utility */exports.type = require('type-detect');
/*! * expectTypes utility */exports.expectTypes = require('./expectTypes');
/*! * message utility */exports.getMessage = require('./getMessage');
/*! * actual utility */exports.getActual = require('./getActual');
/*! * Inspect util */exports.inspect = require('./inspect');
/*! * Object Display util */exports.objDisplay = require('./objDisplay');
/*! * Flag utility */exports.flag = require('./flag');
/*! * Flag transferring utility */exports.transferFlags = require('./transferFlags');
/*! * Deep equal utility */exports.eql = require('deep-eql');
/*! * Deep path info */exports.getPathInfo = pathval.getPathInfo;
/*! * Check if a property exists */exports.hasProperty = pathval.hasProperty;
/*! * Function name */exports.getName = require('get-func-name');
/*! * add Property */exports.addProperty = require('./addProperty');
/*! * add Method */exports.addMethod = require('./addMethod');
/*! * overwrite Property */exports.overwriteProperty = require('./overwriteProperty');
/*! * overwrite Method */exports.overwriteMethod = require('./overwriteMethod');
/*! * Add a chainable method */exports.addChainableMethod = require('./addChainableMethod');
/*! * Overwrite chainable method */exports.overwriteChainableMethod = require('./overwriteChainableMethod');
/*! * Compare by inspect method */exports.compareByInspect = require('./compareByInspect');
/*! * Get own enumerable property symbols method */exports.getOwnEnumerablePropertySymbols = require('./getOwnEnumerablePropertySymbols');
/*! * Get own enumerable properties method */exports.getOwnEnumerableProperties = require('./getOwnEnumerableProperties');
/*! * Checks error against a given set of criteria */exports.checkError = require('check-error');
/*! * Proxify util */exports.proxify = require('./proxify');
/*! * addLengthGuard util */exports.addLengthGuard = require('./addLengthGuard');
/*! * isProxyEnabled helper */exports.isProxyEnabled = require('./isProxyEnabled');
/*! * isNaN method */exports.isNaN = require('./isNaN');
/*! * getOperator method */exports.getOperator = require('./getOperator');},{"./addChainableMethod":9,"./addLengthGuard":10,"./addMethod":11,"./addProperty":12,"./compareByInspect":13,"./expectTypes":14,"./flag":15,"./getActual":16,"./getMessage":17,"./getOperator":18,"./getOwnEnumerableProperties":19,"./getOwnEnumerablePropertySymbols":20,"./inspect":23,"./isNaN":24,"./isProxyEnabled":25,"./objDisplay":26,"./overwriteChainableMethod":27,"./overwriteMethod":28,"./overwriteProperty":29,"./proxify":30,"./test":31,"./transferFlags":32,"check-error":34,"deep-eql":35,"get-func-name":36,"pathval":38,"type-detect":39}],23:[function(require,module,exports){// This is (almost) directly from Node.js utils// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js
var getName = require('get-func-name');var loupe = require('loupe');var config = require('../config');
module.exports = inspect;
/** * ### .inspect(obj, [showHidden], [depth], [colors]) * * Echoes the value of a value. Tries to print the value out * in the best way possible given the different types. * * @param {Object} obj The object to print out. * @param {Boolean} showHidden Flag that shows hidden (not enumerable) * properties of objects. Default is false. * @param {Number} depth Depth in which to descend in object. Default is 2. * @param {Boolean} colors Flag to turn on ANSI escape codes to color the * output. Default is false (no coloring). * @namespace Utils * @name inspect */function inspect(obj, showHidden, depth, colors) { var options = { colors: colors, depth: (typeof depth === 'undefined' ? 2 : depth), showHidden: showHidden, truncate: config.truncateThreshold ? config.truncateThreshold : Infinity, }; return loupe.inspect(obj, options);}
},{"../config":4,"get-func-name":36,"loupe":37}],24:[function(require,module,exports){/*! * Chai - isNaN utility * Copyright(c) 2012-2015 Sakthipriyan Vairamani <thechargingvolcano@gmail.com> * MIT Licensed *//** * ### .isNaN(value) * * Checks if the given value is NaN or not. * * utils.isNaN(NaN); // true * * @param {Value} The value which has to be checked if it is NaN * @name isNaN * @api private */function isNaN(value) { // Refer http://www.ecma-international.org/ecma-262/6.0/#sec-isnan-number // section's NOTE. return value !== value;}
// If ECMAScript 6's Number.isNaN is present, prefer that.module.exports = Number.isNaN || isNaN;
},{}],25:[function(require,module,exports){var config = require('../config');
/*! * Chai - isProxyEnabled helper * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> * MIT Licensed *//** * ### .isProxyEnabled() * * Helper function to check if Chai's proxy protection feature is enabled. If * proxies are unsupported or disabled via the user's Chai config, then return * false. Otherwise, return true. * * @namespace Utils * @name isProxyEnabled */module.exports = function isProxyEnabled() { return config.useProxy && typeof Proxy !== 'undefined' && typeof Reflect !== 'undefined';};
},{"../config":4}],26:[function(require,module,exports){/*! * Chai - flag utility * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> * MIT Licensed *//*! * Module dependencies */var inspect = require('./inspect');var config = require('../config');
/** * ### .objDisplay(object) * * Determines if an object or an array matches * criteria to be inspected in-line for error * messages or should be truncated. * * @param {Mixed} javascript object to inspect * @returns {string} stringified object * @name objDisplay * @namespace Utils * @api public */module.exports = function objDisplay(obj) { var str = inspect(obj) , type = Object.prototype.toString.call(obj); if (config.truncateThreshold && str.length >= config.truncateThreshold) { if (type === '[object Function]') { return !obj.name || obj.name === '' ? '[Function]' : '[Function: ' + obj.name + ']'; } else if (type === '[object Array]') { return '[ Array(' + obj.length + ') ]'; } else if (type === '[object Object]') { var keys = Object.keys(obj) , kstr = keys.length > 2 ? keys.splice(0, 2).join(', ') + ', ...' : keys.join(', '); return '{ Object (' + kstr + ') }'; } else { return str; } } else { return str; }};
},{"../config":4,"./inspect":23}],27:[function(require,module,exports){/*! * Chai - overwriteChainableMethod utility * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */var chai = require('../../chai');var transferFlags = require('./transferFlags');
/** * ### .overwriteChainableMethod(ctx, name, method, chainingBehavior) * * Overwrites an already existing chainable method * and provides access to the previous function or * property. Must return functions to be used for * name. * * utils.overwriteChainableMethod(chai.Assertion.prototype, 'lengthOf', * function (_super) { * } * , function (_super) { * } * ); * * Can also be accessed directly from `chai.Assertion`. * * chai.Assertion.overwriteChainableMethod('foo', fn, fn); * * Then can be used as any other assertion. * * expect(myFoo).to.have.lengthOf(3); * expect(myFoo).to.have.lengthOf.above(3); * * @param {Object} ctx object whose method / property is to be overwritten * @param {String} name of method / property to overwrite * @param {Function} method function that returns a function to be used for name * @param {Function} chainingBehavior function that returns a function to be used for property * @namespace Utils * @name overwriteChainableMethod * @api public */module.exports = function overwriteChainableMethod(ctx, name, method, chainingBehavior) { var chainableBehavior = ctx.__methods[name]; var _chainingBehavior = chainableBehavior.chainingBehavior; chainableBehavior.chainingBehavior = function overwritingChainableMethodGetter() { var result = chainingBehavior(_chainingBehavior).call(this); if (result !== undefined) { return result; } var newAssertion = new chai.Assertion(); transferFlags(this, newAssertion); return newAssertion; }; var _method = chainableBehavior.method; chainableBehavior.method = function overwritingChainableMethodWrapper() { var result = method(_method).apply(this, arguments); if (result !== undefined) { return result; } var newAssertion = new chai.Assertion(); transferFlags(this, newAssertion); return newAssertion; };};
},{"../../chai":2,"./transferFlags":32}],28:[function(require,module,exports){/*! * Chai - overwriteMethod utility * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */var addLengthGuard = require('./addLengthGuard');var chai = require('../../chai');var flag = require('./flag');var proxify = require('./proxify');var transferFlags = require('./transferFlags');
/** * ### .overwriteMethod(ctx, name, fn) * * Overwrites an already existing method and provides * access to previous function. Must return function * to be used for name. * * utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) { * return function (str) { * var obj = utils.flag(this, 'object'); * if (obj instanceof Foo) { * new chai.Assertion(obj.value).to.equal(str); * } else { * _super.apply(this, arguments); * } * } * }); * * Can also be accessed directly from `chai.Assertion`. * * chai.Assertion.overwriteMethod('foo', fn); * * Then can be used as any other assertion. * * expect(myFoo).to.equal('bar'); * * @param {Object} ctx object whose method is to be overwritten * @param {String} name of method to overwrite * @param {Function} method function that returns a function to be used for name * @namespace Utils * @name overwriteMethod * @api public */module.exports = function overwriteMethod(ctx, name, method) { var _method = ctx[name] , _super = function () { throw new Error(name + ' is not a function'); }; if (_method && 'function' === typeof _method) _super = _method; var overwritingMethodWrapper = function () { // Setting the `ssfi` flag to `overwritingMethodWrapper` causes this // function to be the starting point for removing implementation frames from // the stack trace of a failed assertion. // // However, we only want to use this function as the starting point if the // `lockSsfi` flag isn't set. // // If the `lockSsfi` flag is set, then either this assertion has been // overwritten by another assertion, or this assertion is being invoked from // inside of another assertion. In the first case, the `ssfi` flag has // already been set by the overwriting assertion. In the second case, the // `ssfi` flag has already been set by the outer assertion. if (!flag(this, 'lockSsfi')) { flag(this, 'ssfi', overwritingMethodWrapper); } // Setting the `lockSsfi` flag to `true` prevents the overwritten assertion // from changing the `ssfi` flag. By this point, the `ssfi` flag is already // set to the correct starting point for this assertion. var origLockSsfi = flag(this, 'lockSsfi'); flag(this, 'lockSsfi', true); var result = method(_super).apply(this, arguments); flag(this, 'lockSsfi', origLockSsfi); if (result !== undefined) { return result; } var newAssertion = new chai.Assertion(); transferFlags(this, newAssertion); return newAssertion; } addLengthGuard(overwritingMethodWrapper, name, false); ctx[name] = proxify(overwritingMethodWrapper, name);};
},{"../../chai":2,"./addLengthGuard":10,"./flag":15,"./proxify":30,"./transferFlags":32}],29:[function(require,module,exports){/*! * Chai - overwriteProperty utility * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */var chai = require('../../chai');var flag = require('./flag');var isProxyEnabled = require('./isProxyEnabled');var transferFlags = require('./transferFlags');
/** * ### .overwriteProperty(ctx, name, fn) * * Overwrites an already existing property getter and provides * access to previous value. Must return function to use as getter. * * utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) { * return function () { * var obj = utils.flag(this, 'object'); * if (obj instanceof Foo) { * new chai.Assertion(obj.name).to.equal('bar'); * } else { * _super.call(this); * } * } * }); * * * Can also be accessed directly from `chai.Assertion`. * * chai.Assertion.overwriteProperty('foo', fn); * * Then can be used as any other assertion. * * expect(myFoo).to.be.ok; * * @param {Object} ctx object whose property is to be overwritten * @param {String} name of property to overwrite * @param {Function} getter function that returns a getter function to be used for name * @namespace Utils * @name overwriteProperty * @api public */module.exports = function overwriteProperty(ctx, name, getter) { var _get = Object.getOwnPropertyDescriptor(ctx, name) , _super = function () {}; if (_get && 'function' === typeof _get.get) _super = _get.get Object.defineProperty(ctx, name, { get: function overwritingPropertyGetter() { // Setting the `ssfi` flag to `overwritingPropertyGetter` causes this // function to be the starting point for removing implementation frames // from the stack trace of a failed assertion. // // However, we only want to use this function as the starting point if // the `lockSsfi` flag isn't set and proxy protection is disabled. // // If the `lockSsfi` flag is set, then either this assertion has been // overwritten by another assertion, or this assertion is being invoked // from inside of another assertion. In the first case, the `ssfi` flag // has already been set by the overwriting assertion. In the second // case, the `ssfi` flag has already been set by the outer assertion. // // If proxy protection is enabled, then the `ssfi` flag has already been // set by the proxy getter. if (!isProxyEnabled() && !flag(this, 'lockSsfi')) { flag(this, 'ssfi', overwritingPropertyGetter); } // Setting the `lockSsfi` flag to `true` prevents the overwritten // assertion from changing the `ssfi` flag. By this point, the `ssfi` // flag is already set to the correct starting point for this assertion. var origLockSsfi = flag(this, 'lockSsfi'); flag(this, 'lockSsfi', true); var result = getter(_super).call(this); flag(this, 'lockSsfi', origLockSsfi); if (result !== undefined) { return result; } var newAssertion = new chai.Assertion(); transferFlags(this, newAssertion); return newAssertion; } , configurable: true });};
},{"../../chai":2,"./flag":15,"./isProxyEnabled":25,"./transferFlags":32}],30:[function(require,module,exports){var config = require('../config');var flag = require('./flag');var getProperties = require('./getProperties');var isProxyEnabled = require('./isProxyEnabled');
/*! * Chai - proxify utility * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> * MIT Licensed *//** * ### .proxify(object) * * Return a proxy of given object that throws an error when a non-existent * property is read. By default, the root cause is assumed to be a misspelled * property, and thus an attempt is made to offer a reasonable suggestion from * the list of existing properties. However, if a nonChainableMethodName is * provided, then the root cause is instead a failure to invoke a non-chainable * method prior to reading the non-existent property. * * If proxies are unsupported or disabled via the user's Chai config, then * return object without modification. * * @param {Object} obj * @param {String} nonChainableMethodName * @namespace Utils * @name proxify */var builtins = ['__flags', '__methods', '_obj', 'assert'];
module.exports = function proxify(obj, nonChainableMethodName) { if (!isProxyEnabled()) return obj; return new Proxy(obj, { get: function proxyGetter(target, property) { // This check is here because we should not throw errors on Symbol properties // such as `Symbol.toStringTag`. // The values for which an error should be thrown can be configured using // the `config.proxyExcludedKeys` setting. if (typeof property === 'string' && config.proxyExcludedKeys.indexOf(property) === -1 && !Reflect.has(target, property)) { // Special message for invalid property access of non-chainable methods. if (nonChainableMethodName) { throw Error('Invalid Chai property: ' + nonChainableMethodName + '.' + property + '. See docs for proper usage of "' + nonChainableMethodName + '".'); } // If the property is reasonably close to an existing Chai property, // suggest that property to the user. Only suggest properties with a // distance less than 4. var suggestion = null; var suggestionDistance = 4; getProperties(target).forEach(function(prop) { if ( !Object.prototype.hasOwnProperty(prop) && builtins.indexOf(prop) === -1 ) { var dist = stringDistanceCapped( property, prop, suggestionDistance ); if (dist < suggestionDistance) { suggestion = prop; suggestionDistance = dist; } } }); if (suggestion !== null) { throw Error('Invalid Chai property: ' + property + '. Did you mean "' + suggestion + '"?'); } else { throw Error('Invalid Chai property: ' + property); } } // Use this proxy getter as the starting point for removing implementation // frames from the stack trace of a failed assertion. For property // assertions, this prevents the proxy getter from showing up in the stack // trace since it's invoked before the property getter. For method and // chainable method assertions, this flag will end up getting changed to // the method wrapper, which is good since this frame will no longer be in // the stack once the method is invoked. Note that Chai builtin assertion // properties such as `__flags` are skipped since this is only meant to // capture the starting point of an assertion. This step is also skipped // if the `lockSsfi` flag is set, thus indicating that this assertion is // being called from within another assertion. In that case, the `ssfi` // flag is already set to the outer assertion's starting point. if (builtins.indexOf(property) === -1 && !flag(target, 'lockSsfi')) { flag(target, 'ssfi', proxyGetter); } return Reflect.get(target, property); } });};
/** * # stringDistanceCapped(strA, strB, cap) * Return the Levenshtein distance between two strings, but no more than cap. * @param {string} strA * @param {string} strB * @param {number} number * @return {number} min(string distance between strA and strB, cap) * @api private */function stringDistanceCapped(strA, strB, cap) { if (Math.abs(strA.length - strB.length) >= cap) { return cap; } var memo = []; // `memo` is a two-dimensional array containing distances. // memo[i][j] is the distance between strA.slice(0, i) and // strB.slice(0, j). for (var i = 0; i <= strA.length; i++) { memo[i] = Array(strB.length + 1).fill(0); memo[i][0] = i; } for (var j = 0; j < strB.length; j++) { memo[0][j] = j; } for (var i = 1; i <= strA.length; i++) { var ch = strA.charCodeAt(i - 1); for (var j = 1; j <= strB.length; j++) { if (Math.abs(i - j) >= cap) { memo[i][j] = cap; continue; } memo[i][j] = Math.min( memo[i - 1][j] + 1, memo[i][j - 1] + 1, memo[i - 1][j - 1] + (ch === strB.charCodeAt(j - 1) ? 0 : 1) ); } } return memo[strA.length][strB.length];}
},{"../config":4,"./flag":15,"./getProperties":21,"./isProxyEnabled":25}],31:[function(require,module,exports){/*! * Chai - test utility * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> * MIT Licensed *//*! * Module dependencies */var flag = require('./flag');
/** * ### .test(object, expression) * * Test an object for expression. * * @param {Object} object (constructed Assertion) * @param {Arguments} chai.Assertion.prototype.assert arguments * @namespace Utils * @name test */module.exports = function test(obj, args) { var negate = flag(obj, 'negate') , expr = args[0]; return negate ? !expr : expr;};
},{"./flag":15}],32:[function(require,module,exports){/*! * Chai - transferFlags utility * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> * MIT Licensed *//** * ### .transferFlags(assertion, object, includeAll = true) * * Transfer all the flags for `assertion` to `object`. If * `includeAll` is set to `false`, then the base Chai * assertion flags (namely `object`, `ssfi`, `lockSsfi`, * and `message`) will not be transferred. * * * var newAssertion = new Assertion(); * utils.transferFlags(assertion, newAssertion); * * var anotherAssertion = new Assertion(myObj); * utils.transferFlags(assertion, anotherAssertion, false); * * @param {Assertion} assertion the assertion to transfer the flags from * @param {Object} object the object to transfer the flags to; usually a new assertion * @param {Boolean} includeAll * @namespace Utils * @name transferFlags * @api private */module.exports = function transferFlags(assertion, object, includeAll) { var flags = assertion.__flags || (assertion.__flags = Object.create(null)); if (!object.__flags) { object.__flags = Object.create(null); } includeAll = arguments.length === 3 ? includeAll : true; for (var flag in flags) { if (includeAll || (flag !== 'object' && flag !== 'ssfi' && flag !== 'lockSsfi' && flag != 'message')) { object.__flags[flag] = flags[flag]; } }};
},{}],33:[function(require,module,exports){/*! * assertion-error * Copyright(c) 2013 Jake Luer <jake@qualiancy.com> * MIT Licensed *//*! * Return a function that will copy properties from * one object to another excluding any originally * listed. Returned function will create a new `{}`. * * @param {String} excluded properties ... * @return {Function} */function exclude () { var excludes = [].slice.call(arguments); function excludeProps (res, obj) { Object.keys(obj).forEach(function (key) { if (!~excludes.indexOf(key)) res[key] = obj[key]; }); } return function extendExclude () { var args = [].slice.call(arguments) , i = 0 , res = {}; for (; i < args.length; i++) { excludeProps(res, args[i]); } return res; };};
/*! * Primary Exports */module.exports = AssertionError;
/** * ### AssertionError * * An extension of the JavaScript `Error` constructor for * assertion and validation scenarios. * * @param {String} message * @param {Object} properties to include (optional) * @param {callee} start stack function (optional) */function AssertionError (message, _props, ssf) { var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON') , props = extend(_props || {}); // default values this.message = message || 'Unspecified AssertionError'; this.showDiff = false; // copy from properties for (var key in props) { this[key] = props[key]; } // capture stack trace ssf = ssf || AssertionError; if (Error.captureStackTrace) { Error.captureStackTrace(this, ssf); } else { try { throw new Error(); } catch(e) { this.stack = e.stack; } }}
/*! * Inherit from Error.prototype */AssertionError.prototype = Object.create(Error.prototype);
/*! * Statically set name */AssertionError.prototype.name = 'AssertionError';
/*! * Ensure correct constructor */AssertionError.prototype.constructor = AssertionError;
/** * Allow errors to be converted to JSON for static transfer. * * @param {Boolean} include stack (default: `true`) * @return {Object} object that can be `JSON.stringify` */AssertionError.prototype.toJSON = function (stack) { var extend = exclude('constructor', 'toJSON', 'stack') , props = extend({ name: this.name }, this); // include stack if exists and not turned off if (false !== stack && this.stack) { props.stack = this.stack; } return props;};
},{}],34:[function(require,module,exports){'use strict';
/* ! * Chai - checkError utility * Copyright(c) 2012-2016 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */var getFunctionName = require('get-func-name');/** * ### .checkError * * Checks that an error conforms to a given set of criteria and/or retrieves information about it. * * @api public *//** * ### .compatibleInstance(thrown, errorLike) * * Checks if two instances are compatible (strict equal). * Returns false if errorLike is not an instance of Error, because instances * can only be compatible if they're both error instances. * * @name compatibleInstance * @param {Error} thrown error * @param {Error|ErrorConstructor} errorLike object to compare against * @namespace Utils * @api public */function compatibleInstance(thrown, errorLike) { return errorLike instanceof Error && thrown === errorLike;}
/** * ### .compatibleConstructor(thrown, errorLike) * * Checks if two constructors are compatible. * This function can receive either an error constructor or * an error instance as the `errorLike` argument. * Constructors are compatible if they're the same or if one is * an instance of another. * * @name compatibleConstructor * @param {Error} thrown error * @param {Error|ErrorConstructor} errorLike object to compare against * @namespace Utils * @api public */function compatibleConstructor(thrown, errorLike) { if (errorLike instanceof Error) { // If `errorLike` is an instance of any error we compare their constructors return thrown.constructor === errorLike.constructor || thrown instanceof errorLike.constructor; } else if (errorLike.prototype instanceof Error || errorLike === Error) { // If `errorLike` is a constructor that inherits from Error, we compare `thrown` to `errorLike` directly return thrown.constructor === errorLike || thrown instanceof errorLike; } return false;}
/** * ### .compatibleMessage(thrown, errMatcher) * * Checks if an error's message is compatible with a matcher (String or RegExp). * If the message contains the String or passes the RegExp test, * it is considered compatible. * * @name compatibleMessage * @param {Error} thrown error * @param {String|RegExp} errMatcher to look for into the message * @namespace Utils * @api public */function compatibleMessage(thrown, errMatcher) { var comparisonString = typeof thrown === 'string' ? thrown : thrown.message; if (errMatcher instanceof RegExp) { return errMatcher.test(comparisonString); } else if (typeof errMatcher === 'string') { return comparisonString.indexOf(errMatcher) !== -1; // eslint-disable-line no-magic-numbers } return false;}
/** * ### .getConstructorName(errorLike) * * Gets the constructor name for an Error instance or constructor itself. * * @name getConstructorName * @param {Error|ErrorConstructor} errorLike * @namespace Utils * @api public */function getConstructorName(errorLike) { var constructorName = errorLike; if (errorLike instanceof Error) { constructorName = getFunctionName(errorLike.constructor); } else if (typeof errorLike === 'function') { // If `err` is not an instance of Error it is an error constructor itself or another function. // If we've got a common function we get its name, otherwise we may need to create a new instance // of the error just in case it's a poorly-constructed error. Please see chaijs/chai/issues/45 to know more. constructorName = getFunctionName(errorLike); if (constructorName === '') { var newConstructorName = getFunctionName(new errorLike()); // eslint-disable-line new-cap constructorName = newConstructorName || constructorName; } } return constructorName;}
/** * ### .getMessage(errorLike) * * Gets the error message from an error. * If `err` is a String itself, we return it. * If the error has no message, we return an empty string. * * @name getMessage * @param {Error|String} errorLike * @namespace Utils * @api public */function getMessage(errorLike) { var msg = ''; if (errorLike && errorLike.message) { msg = errorLike.message; } else if (typeof errorLike === 'string') { msg = errorLike; } return msg;}
module.exports = { compatibleInstance: compatibleInstance, compatibleConstructor: compatibleConstructor, compatibleMessage: compatibleMessage, getMessage: getMessage, getConstructorName: getConstructorName,};
},{"get-func-name":36}],35:[function(require,module,exports){'use strict';/* globals Symbol: false, Uint8Array: false, WeakMap: false *//*! * deep-eql * Copyright(c) 2013 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */var type = require('type-detect');function FakeMap() { this._key = 'chai/deep-eql__' + Math.random() + Date.now();}
FakeMap.prototype = { get: function get(key) { return key[this._key]; }, set: function set(key, value) { if (Object.isExtensible(key)) { Object.defineProperty(key, this._key, { value: value, configurable: true, }); } },};
var MemoizeMap = typeof WeakMap === 'function' ? WeakMap : FakeMap;/*! * Check to see if the MemoizeMap has recorded a result of the two operands * * @param {Mixed} leftHandOperand * @param {Mixed} rightHandOperand * @param {MemoizeMap} memoizeMap * @returns {Boolean|null} result*/function memoizeCompare(leftHandOperand, rightHandOperand, memoizeMap) { // Technically, WeakMap keys can *only* be objects, not primitives. if (!memoizeMap || isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) { return null; } var leftHandMap = memoizeMap.get(leftHandOperand); if (leftHandMap) { var result = leftHandMap.get(rightHandOperand); if (typeof result === 'boolean') { return result; } } return null;}
/*! * Set the result of the equality into the MemoizeMap * * @param {Mixed} leftHandOperand * @param {Mixed} rightHandOperand * @param {MemoizeMap} memoizeMap * @param {Boolean} result*/function memoizeSet(leftHandOperand, rightHandOperand, memoizeMap, result) { // Technically, WeakMap keys can *only* be objects, not primitives. if (!memoizeMap || isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) { return; } var leftHandMap = memoizeMap.get(leftHandOperand); if (leftHandMap) { leftHandMap.set(rightHandOperand, result); } else { leftHandMap = new MemoizeMap(); leftHandMap.set(rightHandOperand, result); memoizeMap.set(leftHandOperand, leftHandMap); }}
/*! * Primary Export */module.exports = deepEqual;module.exports.MemoizeMap = MemoizeMap;
/** * Assert deeply nested sameValue equality between two objects of any type. * * @param {Mixed} leftHandOperand * @param {Mixed} rightHandOperand * @param {Object} [options] (optional) Additional options * @param {Array} [options.comparator] (optional) Override default algorithm, determining custom equality. * @param {Array} [options.memoize] (optional) Provide a custom memoization object which will cache the results of complex objects for a speed boost. By passing `false` you can disable memoization, but this will cause circular references to blow the stack. * @return {Boolean} equal match */function deepEqual(leftHandOperand, rightHandOperand, options) { // If we have a comparator, we can't assume anything; so bail to its check first. if (options && options.comparator) { return extensiveDeepEqual(leftHandOperand, rightHandOperand, options); } var simpleResult = simpleEqual(leftHandOperand, rightHandOperand); if (simpleResult !== null) { return simpleResult; } // Deeper comparisons are pushed through to a larger function return extensiveDeepEqual(leftHandOperand, rightHandOperand, options);}
/** * Many comparisons can be canceled out early via simple equality or primitive checks. * @param {Mixed} leftHandOperand * @param {Mixed} rightHandOperand * @return {Boolean|null} equal match */function simpleEqual(leftHandOperand, rightHandOperand) { // Equal references (except for Numbers) can be returned early if (leftHandOperand === rightHandOperand) { // Handle +-0 cases return leftHandOperand !== 0 || 1 / leftHandOperand === 1 / rightHandOperand; } // handle NaN cases if ( leftHandOperand !== leftHandOperand && // eslint-disable-line no-self-compare rightHandOperand !== rightHandOperand // eslint-disable-line no-self-compare ) { return true; } // Anything that is not an 'object', i.e. symbols, functions, booleans, numbers, // strings, and undefined, can be compared by reference. if (isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) { // Easy out b/c it would have passed the first equality check return false; } return null;}
/*! * The main logic of the `deepEqual` function. * * @param {Mixed} leftHandOperand * @param {Mixed} rightHandOperand * @param {Object} [options] (optional) Additional options * @param {Array} [options.comparator] (optional) Override default algorithm, determining custom equality. * @param {Array} [options.memoize] (optional) Provide a custom memoization object which will cache the results of complex objects for a speed boost. By passing `false` you can disable memoization, but this will cause circular references to blow the stack. * @return {Boolean} equal match*/function extensiveDeepEqual(leftHandOperand, rightHandOperand, options) { options = options || {}; options.memoize = options.memoize === false ? false : options.memoize || new MemoizeMap(); var comparator = options && options.comparator; // Check if a memoized result exists. var memoizeResultLeft = memoizeCompare(leftHandOperand, rightHandOperand, options.memoize); if (memoizeResultLeft !== null) { return memoizeResultLeft; } var memoizeResultRight = memoizeCompare(rightHandOperand, leftHandOperand, options.memoize); if (memoizeResultRight !== null) { return memoizeResultRight; } // If a comparator is present, use it. if (comparator) { var comparatorResult = comparator(leftHandOperand, rightHandOperand); // Comparators may return null, in which case we want to go back to default behavior. if (comparatorResult === false || comparatorResult === true) { memoizeSet(leftHandOperand, rightHandOperand, options.memoize, comparatorResult); return comparatorResult; } // To allow comparators to override *any* behavior, we ran them first. Since it didn't decide // what to do, we need to make sure to return the basic tests first before we move on. var simpleResult = simpleEqual(leftHandOperand, rightHandOperand); if (simpleResult !== null) { // Don't memoize this, it takes longer to set/retrieve than to just compare. return simpleResult; } } var leftHandType = type(leftHandOperand); if (leftHandType !== type(rightHandOperand)) { memoizeSet(leftHandOperand, rightHandOperand, options.memoize, false); return false; } // Temporarily set the operands in the memoize object to prevent blowing the stack memoizeSet(leftHandOperand, rightHandOperand, options.memoize, true); var result = extensiveDeepEqualByType(leftHandOperand, rightHandOperand, leftHandType, options); memoizeSet(leftHandOperand, rightHandOperand, options.memoize, result); return result;}
function extensiveDeepEqualByType(leftHandOperand, rightHandOperand, leftHandType, options) { switch (leftHandType) { case 'String': case 'Number': case 'Boolean': case 'Date': // If these types are their instance types (e.g. `new Number`) then re-deepEqual against their values return deepEqual(leftHandOperand.valueOf(), rightHandOperand.valueOf()); case 'Promise': case 'Symbol': case 'function': case 'WeakMap': case 'WeakSet': return leftHandOperand === rightHandOperand; case 'Error': return keysEqual(leftHandOperand, rightHandOperand, [ 'name', 'message', 'code' ], options); case 'Arguments': case 'Int8Array': case 'Uint8Array': case 'Uint8ClampedArray': case 'Int16Array': case 'Uint16Array': case 'Int32Array': case 'Uint32Array': case 'Float32Array': case 'Float64Array': case 'Array': return iterableEqual(leftHandOperand, rightHandOperand, options); case 'RegExp': return regexpEqual(leftHandOperand, rightHandOperand); case 'Generator': return generatorEqual(leftHandOperand, rightHandOperand, options); case 'DataView': return iterableEqual(new Uint8Array(leftHandOperand.buffer), new Uint8Array(rightHandOperand.buffer), options); case 'ArrayBuffer': return iterableEqual(new Uint8Array(leftHandOperand), new Uint8Array(rightHandOperand), options); case 'Set': return entriesEqual(leftHandOperand, rightHandOperand, options); case 'Map': return entriesEqual(leftHandOperand, rightHandOperand, options); case 'Temporal.PlainDate': case 'Temporal.PlainTime': case 'Temporal.PlainDateTime': case 'Temporal.Instant': case 'Temporal.ZonedDateTime': case 'Temporal.PlainYearMonth': case 'Temporal.PlainMonthDay': return leftHandOperand.equals(rightHandOperand); case 'Temporal.Duration': return leftHandOperand.total('nanoseconds') === rightHandOperand.total('nanoseconds'); case 'Temporal.TimeZone': case 'Temporal.Calendar': return leftHandOperand.toString() === rightHandOperand.toString(); default: return objectEqual(leftHandOperand, rightHandOperand, options); }}
/*! * Compare two Regular Expressions for equality. * * @param {RegExp} leftHandOperand * @param {RegExp} rightHandOperand * @return {Boolean} result */function regexpEqual(leftHandOperand, rightHandOperand) { return leftHandOperand.toString() === rightHandOperand.toString();}
/*! * Compare two Sets/Maps for equality. Faster than other equality functions. * * @param {Set} leftHandOperand * @param {Set} rightHandOperand * @param {Object} [options] (Optional) * @return {Boolean} result */function entriesEqual(leftHandOperand, rightHandOperand, options) { // IE11 doesn't support Set#entries or Set#@@iterator, so we need manually populate using Set#forEach if (leftHandOperand.size !== rightHandOperand.size) { return false; } if (leftHandOperand.size === 0) { return true; } var leftHandItems = []; var rightHandItems = []; leftHandOperand.forEach(function gatherEntries(key, value) { leftHandItems.push([ key, value ]); }); rightHandOperand.forEach(function gatherEntries(key, value) { rightHandItems.push([ key, value ]); }); return iterableEqual(leftHandItems.sort(), rightHandItems.sort(), options);}
/*! * Simple equality for flat iterable objects such as Arrays, TypedArrays or Node.js buffers. * * @param {Iterable} leftHandOperand * @param {Iterable} rightHandOperand * @param {Object} [options] (Optional) * @return {Boolean} result */function iterableEqual(leftHandOperand, rightHandOperand, options) { var length = leftHandOperand.length; if (length !== rightHandOperand.length) { return false; } if (length === 0) { return true; } var index = -1; while (++index < length) { if (deepEqual(leftHandOperand[index], rightHandOperand[index], options) === false) { return false; } } return true;}
/*! * Simple equality for generator objects such as those returned by generator functions. * * @param {Iterable} leftHandOperand * @param {Iterable} rightHandOperand * @param {Object} [options] (Optional) * @return {Boolean} result */function generatorEqual(leftHandOperand, rightHandOperand, options) { return iterableEqual(getGeneratorEntries(leftHandOperand), getGeneratorEntries(rightHandOperand), options);}
/*! * Determine if the given object has an @@iterator function. * * @param {Object} target * @return {Boolean} `true` if the object has an @@iterator function. */function hasIteratorFunction(target) { return typeof Symbol !== 'undefined' && typeof target === 'object' && typeof Symbol.iterator !== 'undefined' && typeof target[Symbol.iterator] === 'function';}
/*! * Gets all iterator entries from the given Object. If the Object has no @@iterator function, returns an empty array. * This will consume the iterator - which could have side effects depending on the @@iterator implementation. * * @param {Object} target * @returns {Array} an array of entries from the @@iterator function */function getIteratorEntries(target) { if (hasIteratorFunction(target)) { try { return getGeneratorEntries(target[Symbol.iterator]()); } catch (iteratorError) { return []; } } return [];}
/*! * Gets all entries from a Generator. This will consume the generator - which could have side effects. * * @param {Generator} target * @returns {Array} an array of entries from the Generator. */function getGeneratorEntries(generator) { var generatorResult = generator.next(); var accumulator = [ generatorResult.value ]; while (generatorResult.done === false) { generatorResult = generator.next(); accumulator.push(generatorResult.value); } return accumulator;}
/*! * Gets all own and inherited enumerable keys from a target. * * @param {Object} target * @returns {Array} an array of own and inherited enumerable keys from the target. */function getEnumerableKeys(target) { var keys = []; for (var key in target) { keys.push(key); } return keys;}
function getEnumerableSymbols(target) { var keys = []; var allKeys = Object.getOwnPropertySymbols(target); for (var i = 0; i < allKeys.length; i += 1) { var key = allKeys[i]; if (Object.getOwnPropertyDescriptor(target, key).enumerable) { keys.push(key); } } return keys;}
/*! * Determines if two objects have matching values, given a set of keys. Defers to deepEqual for the equality check of * each key. If any value of the given key is not equal, the function will return false (early). * * @param {Mixed} leftHandOperand * @param {Mixed} rightHandOperand * @param {Array} keys An array of keys to compare the values of leftHandOperand and rightHandOperand against * @param {Object} [options] (Optional) * @return {Boolean} result */function keysEqual(leftHandOperand, rightHandOperand, keys, options) { var length = keys.length; if (length === 0) { return true; } for (var i = 0; i < length; i += 1) { if (deepEqual(leftHandOperand[keys[i]], rightHandOperand[keys[i]], options) === false) { return false; } } return true;}
/*! * Recursively check the equality of two Objects. Once basic sameness has been established it will defer to `deepEqual` * for each enumerable key in the object. * * @param {Mixed} leftHandOperand * @param {Mixed} rightHandOperand * @param {Object} [options] (Optional) * @return {Boolean} result */function objectEqual(leftHandOperand, rightHandOperand, options) { var leftHandKeys = getEnumerableKeys(leftHandOperand); var rightHandKeys = getEnumerableKeys(rightHandOperand); var leftHandSymbols = getEnumerableSymbols(leftHandOperand); var rightHandSymbols = getEnumerableSymbols(rightHandOperand); leftHandKeys = leftHandKeys.concat(leftHandSymbols); rightHandKeys = rightHandKeys.concat(rightHandSymbols); if (leftHandKeys.length && leftHandKeys.length === rightHandKeys.length) { if (iterableEqual(mapSymbols(leftHandKeys).sort(), mapSymbols(rightHandKeys).sort()) === false) { return false; } return keysEqual(leftHandOperand, rightHandOperand, leftHandKeys, options); } var leftHandEntries = getIteratorEntries(leftHandOperand); var rightHandEntries = getIteratorEntries(rightHandOperand); if (leftHandEntries.length && leftHandEntries.length === rightHandEntries.length) { leftHandEntries.sort(); rightHandEntries.sort(); return iterableEqual(leftHandEntries, rightHandEntries, options); } if (leftHandKeys.length === 0 && leftHandEntries.length === 0 && rightHandKeys.length === 0 && rightHandEntries.length === 0) { return true; } return false;}
/*! * Returns true if the argument is a primitive. * * This intentionally returns true for all objects that can be compared by reference, * including functions and symbols. * * @param {Mixed} value * @return {Boolean} result */function isPrimitive(value) { return value === null || typeof value !== 'object';}
function mapSymbols(arr) { return arr.map(function mapSymbol(entry) { if (typeof entry === 'symbol') { return entry.toString(); } return entry; });}
},{"type-detect":39}],36:[function(require,module,exports){'use strict';
/* ! * Chai - getFuncName utility * Copyright(c) 2012-2016 Jake Luer <jake@alogicalparadox.com> * MIT Licensed *//** * ### .getFuncName(constructorFn) * * Returns the name of a function. * When a non-function instance is passed, returns `null`. * This also includes a polyfill function if `aFunc.name` is not defined. * * @name getFuncName * @param {Function} funct * @namespace Utils * @api public */var toString = Function.prototype.toString;var functionNameMatch = /\s*function(?:\s|\s*\/\*[^(?:*\/)]+\*\/\s*)*([^\s\(\/]+)/;var maxFunctionSourceLength = 512;function getFuncName(aFunc) { if (typeof aFunc !== 'function') { return null; } var name = ''; if (typeof Function.prototype.name === 'undefined' && typeof aFunc.name === 'undefined') { // eslint-disable-next-line prefer-reflect var functionSource = toString.call(aFunc); // To avoid unconstrained resource consumption due to pathalogically large function names, // we limit the available return value to be less than 512 characters. if (functionSource.indexOf('(') > maxFunctionSourceLength) { return name; } // Here we run a polyfill if Function does not support the `name` property and if aFunc.name is not defined var match = functionSource.match(functionNameMatch); if (match) { name = match[1]; } } else { // If we've got a `name` property we just use it name = aFunc.name; } return name;}
module.exports = getFuncName;
},{}],37:[function(require,module,exports){(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.loupe = {}));}(this, (function (exports) { 'use strict';
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function (obj) { return typeof obj; }; } else { _typeof = function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var ansiColors = { bold: ['1', '22'], dim: ['2', '22'], italic: ['3', '23'], underline: ['4', '24'], // 5 & 6 are blinking inverse: ['7', '27'], hidden: ['8', '28'], strike: ['9', '29'], // 10-20 are fonts // 21-29 are resets for 1-9 black: ['30', '39'], red: ['31', '39'], green: ['32', '39'], yellow: ['33', '39'], blue: ['34', '39'], magenta: ['35', '39'], cyan: ['36', '39'], white: ['37', '39'], brightblack: ['30;1', '39'], brightred: ['31;1', '39'], brightgreen: ['32;1', '39'], brightyellow: ['33;1', '39'], brightblue: ['34;1', '39'], brightmagenta: ['35;1', '39'], brightcyan: ['36;1', '39'], brightwhite: ['37;1', '39'], grey: ['90', '39'] }; var styles = { special: 'cyan', number: 'yellow', bigint: 'yellow', boolean: 'yellow', undefined: 'grey', null: 'bold', string: 'green', symbol: 'green', date: 'magenta', regexp: 'red' }; var truncator = '…'; function colorise(value, styleType) { var color = ansiColors[styles[styleType]] || ansiColors[styleType]; if (!color) { return String(value); } return "\x1B[".concat(color[0], "m").concat(String(value), "\x1B[").concat(color[1], "m"); } function normaliseOptions() { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref$showHidden = _ref.showHidden, showHidden = _ref$showHidden === void 0 ? false : _ref$showHidden, _ref$depth = _ref.depth, depth = _ref$depth === void 0 ? 2 : _ref$depth, _ref$colors = _ref.colors, colors = _ref$colors === void 0 ? false : _ref$colors, _ref$customInspect = _ref.customInspect, customInspect = _ref$customInspect === void 0 ? true : _ref$customInspect, _ref$showProxy = _ref.showProxy, showProxy = _ref$showProxy === void 0 ? false : _ref$showProxy, _ref$maxArrayLength = _ref.maxArrayLength, maxArrayLength = _ref$maxArrayLength === void 0 ? Infinity : _ref$maxArrayLength, _ref$breakLength = _ref.breakLength, breakLength = _ref$breakLength === void 0 ? Infinity : _ref$breakLength, _ref$seen = _ref.seen, seen = _ref$seen === void 0 ? [] : _ref$seen, _ref$truncate = _ref.truncate, truncate = _ref$truncate === void 0 ? Infinity : _ref$truncate, _ref$stylize = _ref.stylize, stylize = _ref$stylize === void 0 ? String : _ref$stylize; var options = { showHidden: Boolean(showHidden), depth: Number(depth), colors: Boolean(colors), customInspect: Boolean(customInspect), showProxy: Boolean(showProxy), maxArrayLength: Number(maxArrayLength), breakLength: Number(breakLength), truncate: Number(truncate), seen: seen, stylize: stylize }; if (options.colors) { options.stylize = colorise; } return options; } function truncate(string, length) { var tail = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : truncator; string = String(string); var tailLength = tail.length; var stringLength = string.length; if (tailLength > length && stringLength > tailLength) { return tail; } if (stringLength > length && stringLength > tailLength) { return "".concat(string.slice(0, length - tailLength)).concat(tail); } return string; } // eslint-disable-next-line complexity function inspectList(list, options, inspectItem) { var separator = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : ', '; inspectItem = inspectItem || options.inspect; var size = list.length; if (size === 0) return ''; var originalLength = options.truncate; var output = ''; var peek = ''; var truncated = ''; for (var i = 0; i < size; i += 1) { var last = i + 1 === list.length; var secondToLast = i + 2 === list.length; truncated = "".concat(truncator, "(").concat(list.length - i, ")"); var value = list[i]; // If there is more than one remaining we need to account for a separator of `, ` options.truncate = originalLength - output.length - (last ? 0 : separator.length); var string = peek || inspectItem(value, options) + (last ? '' : separator); var nextLength = output.length + string.length; var truncatedLength = nextLength + truncated.length; // If this is the last element, and adding it would // take us over length, but adding the truncator wouldn't - then break now if (last && nextLength > originalLength && output.length + truncated.length <= originalLength) { break; } // If this isn't the last or second to last element to scan, // but the string is already over length then break here
if (!last && !secondToLast && truncatedLength > originalLength) { break; } // Peek at the next string to determine if we should // break early before adding this item to the output
peek = last ? '' : inspectItem(list[i + 1], options) + (secondToLast ? '' : separator); // If we have one element left, but this element and // the next takes over length, the break early if (!last && secondToLast && truncatedLength > originalLength && nextLength + peek.length > originalLength) { break; } output += string; // If the next element takes us to length - // but there are more after that, then we should truncate now if (!last && !secondToLast && nextLength + peek.length >= originalLength) { truncated = "".concat(truncator, "(").concat(list.length - i - 1, ")"); break; } truncated = ''; } return "".concat(output).concat(truncated); } function quoteComplexKey(key) { if (key.match(/^[a-zA-Z_][a-zA-Z_0-9]*$/)) { return key; } return JSON.stringify(key).replace(/'/g, "\\'").replace(/\\"/g, '"').replace(/(^"|"$)/g, "'"); } function inspectProperty(_ref2, options) { var _ref3 = _slicedToArray(_ref2, 2), key = _ref3[0], value = _ref3[1]; options.truncate -= 2; if (typeof key === 'string') { key = quoteComplexKey(key); } else if (typeof key !== 'number') { key = "[".concat(options.inspect(key, options), "]"); } options.truncate -= key.length; value = options.inspect(value, options); return "".concat(key, ": ").concat(value); } function inspectArray(array, options) { // Object.keys will always output the Array indices first, so we can slice by // `array.length` to get non-index properties var nonIndexProperties = Object.keys(array).slice(array.length); if (!array.length && !nonIndexProperties.length) return '[]'; options.truncate -= 4; var listContents = inspectList(array, options); options.truncate -= listContents.length; var propertyContents = ''; if (nonIndexProperties.length) { propertyContents = inspectList(nonIndexProperties.map(function (key) { return [key, array[key]]; }), options, inspectProperty); } return "[ ".concat(listContents).concat(propertyContents ? ", ".concat(propertyContents) : '', " ]"); } /* ! * Chai - getFuncName utility * Copyright(c) 2012-2016 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */ /** * ### .getFuncName(constructorFn) * * Returns the name of a function. * When a non-function instance is passed, returns `null`. * This also includes a polyfill function if `aFunc.name` is not defined. * * @name getFuncName * @param {Function} funct * @namespace Utils * @api public */ var toString = Function.prototype.toString; var functionNameMatch = /\s*function(?:\s|\s*\/\*[^(?:*\/)]+\*\/\s*)*([^\s\(\/]+)/; function getFuncName(aFunc) { if (typeof aFunc !== 'function') { return null; } var name = ''; if (typeof Function.prototype.name === 'undefined' && typeof aFunc.name === 'undefined') { // Here we run a polyfill if Function does not support the `name` property and if aFunc.name is not defined var match = toString.call(aFunc).match(functionNameMatch); if (match) { name = match[1]; } } else { // If we've got a `name` property we just use it name = aFunc.name; } return name; } var getFuncName_1 = getFuncName; var getArrayName = function getArrayName(array) { // We need to special case Node.js' Buffers, which report to be Uint8Array if (typeof Buffer === 'function' && array instanceof Buffer) { return 'Buffer'; } if (array[Symbol.toStringTag]) { return array[Symbol.toStringTag]; } return getFuncName_1(array.constructor); }; function inspectTypedArray(array, options) { var name = getArrayName(array); options.truncate -= name.length + 4; // Object.keys will always output the Array indices first, so we can slice by // `array.length` to get non-index properties var nonIndexProperties = Object.keys(array).slice(array.length); if (!array.length && !nonIndexProperties.length) return "".concat(name, "[]"); // As we know TypedArrays only contain Unsigned Integers, we can skip inspecting each one and simply // stylise the toString() value of them var output = ''; for (var i = 0; i < array.length; i++) { var string = "".concat(options.stylize(truncate(array[i], options.truncate), 'number')).concat(i === array.length - 1 ? '' : ', '); options.truncate -= string.length; if (array[i] !== array.length && options.truncate <= 3) { output += "".concat(truncator, "(").concat(array.length - array[i] + 1, ")"); break; } output += string; } var propertyContents = ''; if (nonIndexProperties.length) { propertyContents = inspectList(nonIndexProperties.map(function (key) { return [key, array[key]]; }), options, inspectProperty); } return "".concat(name, "[ ").concat(output).concat(propertyContents ? ", ".concat(propertyContents) : '', " ]"); } function inspectDate(dateObject, options) { var stringRepresentation = dateObject.toJSON(); if (stringRepresentation === null) { return 'Invalid Date'; } var split = stringRepresentation.split('T'); var date = split[0]; // If we need to - truncate the time portion, but never the date return options.stylize("".concat(date, "T").concat(truncate(split[1], options.truncate - date.length - 1)), 'date'); } function inspectFunction(func, options) { var name = getFuncName_1(func); if (!name) { return options.stylize('[Function]', 'special'); } return options.stylize("[Function ".concat(truncate(name, options.truncate - 11), "]"), 'special'); } function inspectMapEntry(_ref, options) { var _ref2 = _slicedToArray(_ref, 2), key = _ref2[0], value = _ref2[1]; options.truncate -= 4; key = options.inspect(key, options); options.truncate -= key.length; value = options.inspect(value, options); return "".concat(key, " => ").concat(value); } // IE11 doesn't support `map.entries()`
function mapToEntries(map) { var entries = []; map.forEach(function (value, key) { entries.push([key, value]); }); return entries; } function inspectMap(map, options) { var size = map.size - 1; if (size <= 0) { return 'Map{}'; } options.truncate -= 7; return "Map{ ".concat(inspectList(mapToEntries(map), options, inspectMapEntry), " }"); } var isNaN = Number.isNaN || function (i) { return i !== i; }; // eslint-disable-line no-self-compare
function inspectNumber(number, options) { if (isNaN(number)) { return options.stylize('NaN', 'number'); } if (number === Infinity) { return options.stylize('Infinity', 'number'); } if (number === -Infinity) { return options.stylize('-Infinity', 'number'); } if (number === 0) { return options.stylize(1 / number === Infinity ? '+0' : '-0', 'number'); } return options.stylize(truncate(number, options.truncate), 'number'); } function inspectBigInt(number, options) { var nums = truncate(number.toString(), options.truncate - 1); if (nums !== truncator) nums += 'n'; return options.stylize(nums, 'bigint'); } function inspectRegExp(value, options) { var flags = value.toString().split('/')[2]; var sourceLength = options.truncate - (2 + flags.length); var source = value.source; return options.stylize("/".concat(truncate(source, sourceLength), "/").concat(flags), 'regexp'); } function arrayFromSet(set) { var values = []; set.forEach(function (value) { values.push(value); }); return values; } function inspectSet(set, options) { if (set.size === 0) return 'Set{}'; options.truncate -= 7; return "Set{ ".concat(inspectList(arrayFromSet(set), options), " }"); } var stringEscapeChars = new RegExp("['\\u0000-\\u001f\\u007f-\\u009f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5" + "\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]", 'g'); var escapeCharacters = { '\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', "'": "\\'", '\\': '\\\\' }; var hex = 16; var unicodeLength = 4; function escape(char) { return escapeCharacters[char] || "\\u".concat("0000".concat(char.charCodeAt(0).toString(hex)).slice(-unicodeLength)); } function inspectString(string, options) { if (stringEscapeChars.test(string)) { string = string.replace(stringEscapeChars, escape); } return options.stylize("'".concat(truncate(string, options.truncate - 2), "'"), 'string'); } function inspectSymbol(value) { if ('description' in Symbol.prototype) { return value.description ? "Symbol(".concat(value.description, ")") : 'Symbol()'; } return value.toString(); } var getPromiseValue = function getPromiseValue() { return 'Promise{…}'; }; try { var _process$binding = process.binding('util'), getPromiseDetails = _process$binding.getPromiseDetails, kPending = _process$binding.kPending, kRejected = _process$binding.kRejected; if (Array.isArray(getPromiseDetails(Promise.resolve()))) { getPromiseValue = function getPromiseValue(value, options) { var _getPromiseDetails = getPromiseDetails(value), _getPromiseDetails2 = _slicedToArray(_getPromiseDetails, 2), state = _getPromiseDetails2[0], innerValue = _getPromiseDetails2[1]; if (state === kPending) { return 'Promise{<pending>}'; } return "Promise".concat(state === kRejected ? '!' : '', "{").concat(options.inspect(innerValue, options), "}"); }; } } catch (notNode) { /* ignore */ } var inspectPromise = getPromiseValue; function inspectObject(object, options) { var properties = Object.getOwnPropertyNames(object); var symbols = Object.getOwnPropertySymbols ? Object.getOwnPropertySymbols(object) : []; if (properties.length === 0 && symbols.length === 0) { return '{}'; } options.truncate -= 4; options.seen = options.seen || []; if (options.seen.indexOf(object) >= 0) { return '[Circular]'; } options.seen.push(object); var propertyContents = inspectList(properties.map(function (key) { return [key, object[key]]; }), options, inspectProperty); var symbolContents = inspectList(symbols.map(function (key) { return [key, object[key]]; }), options, inspectProperty); options.seen.pop(); var sep = ''; if (propertyContents && symbolContents) { sep = ', '; } return "{ ".concat(propertyContents).concat(sep).concat(symbolContents, " }"); } var toStringTag = typeof Symbol !== 'undefined' && Symbol.toStringTag ? Symbol.toStringTag : false; function inspectClass(value, options) { var name = ''; if (toStringTag && toStringTag in value) { name = value[toStringTag]; } name = name || getFuncName_1(value.constructor); // Babel transforms anonymous classes to the name `_class` if (!name || name === '_class') { name = '<Anonymous Class>'; } options.truncate -= name.length; return "".concat(name).concat(inspectObject(value, options)); } function inspectArguments(args, options) { if (args.length === 0) return 'Arguments[]'; options.truncate -= 13; return "Arguments[ ".concat(inspectList(args, options), " ]"); } var errorKeys = ['stack', 'line', 'column', 'name', 'message', 'fileName', 'lineNumber', 'columnNumber', 'number', 'description']; function inspectObject$1(error, options) { var properties = Object.getOwnPropertyNames(error).filter(function (key) { return errorKeys.indexOf(key) === -1; }); var name = error.name; options.truncate -= name.length; var message = ''; if (typeof error.message === 'string') { message = truncate(error.message, options.truncate); } else { properties.unshift('message'); } message = message ? ": ".concat(message) : ''; options.truncate -= message.length + 5; var propertyContents = inspectList(properties.map(function (key) { return [key, error[key]]; }), options, inspectProperty); return "".concat(name).concat(message).concat(propertyContents ? " { ".concat(propertyContents, " }") : ''); } function inspectAttribute(_ref, options) { var _ref2 = _slicedToArray(_ref, 2), key = _ref2[0], value = _ref2[1]; options.truncate -= 3; if (!value) { return "".concat(options.stylize(key, 'yellow')); } return "".concat(options.stylize(key, 'yellow'), "=").concat(options.stylize("\"".concat(value, "\""), 'string')); } function inspectHTMLCollection(collection, options) { // eslint-disable-next-line no-use-before-define return inspectList(collection, options, inspectHTML, '\n'); } function inspectHTML(element, options) { var properties = element.getAttributeNames(); var name = element.tagName.toLowerCase(); var head = options.stylize("<".concat(name), 'special'); var headClose = options.stylize(">", 'special'); var tail = options.stylize("</".concat(name, ">"), 'special'); options.truncate -= name.length * 2 + 5; var propertyContents = ''; if (properties.length > 0) { propertyContents += ' '; propertyContents += inspectList(properties.map(function (key) { return [key, element.getAttribute(key)]; }), options, inspectAttribute, ' '); } options.truncate -= propertyContents.length; var truncate = options.truncate; var children = inspectHTMLCollection(element.children, options); if (children && children.length > truncate) { children = "".concat(truncator, "(").concat(element.children.length, ")"); } return "".concat(head).concat(propertyContents).concat(headClose).concat(children).concat(tail); } var symbolsSupported = typeof Symbol === 'function' && typeof Symbol.for === 'function'; var chaiInspect = symbolsSupported ? Symbol.for('chai/inspect') : '@@chai/inspect'; var nodeInspect = false; try { // eslint-disable-next-line global-require var nodeUtil = require('util'); nodeInspect = nodeUtil.inspect ? nodeUtil.inspect.custom : false; } catch (noNodeInspect) { nodeInspect = false; } function FakeMap() { // eslint-disable-next-line prefer-template this.key = 'chai/loupe__' + Math.random() + Date.now(); } FakeMap.prototype = { // eslint-disable-next-line object-shorthand get: function get(key) { return key[this.key]; }, // eslint-disable-next-line object-shorthand has: function has(key) { return this.key in key; }, // eslint-disable-next-line object-shorthand set: function set(key, value) { if (Object.isExtensible(key)) { Object.defineProperty(key, this.key, { // eslint-disable-next-line object-shorthand value: value, configurable: true }); } } }; var constructorMap = new (typeof WeakMap === 'function' ? WeakMap : FakeMap)(); var stringTagMap = {}; var baseTypesMap = { undefined: function undefined$1(value, options) { return options.stylize('undefined', 'undefined'); }, null: function _null(value, options) { return options.stylize(null, 'null'); }, boolean: function boolean(value, options) { return options.stylize(value, 'boolean'); }, Boolean: function Boolean(value, options) { return options.stylize(value, 'boolean'); }, number: inspectNumber, Number: inspectNumber, bigint: inspectBigInt, BigInt: inspectBigInt, string: inspectString, String: inspectString, function: inspectFunction, Function: inspectFunction, symbol: inspectSymbol, // A Symbol polyfill will return `Symbol` not `symbol` from typedetect Symbol: inspectSymbol, Array: inspectArray, Date: inspectDate, Map: inspectMap, Set: inspectSet, RegExp: inspectRegExp, Promise: inspectPromise, // WeakSet, WeakMap are totally opaque to us WeakSet: function WeakSet(value, options) { return options.stylize('WeakSet{…}', 'special'); }, WeakMap: function WeakMap(value, options) { return options.stylize('WeakMap{…}', 'special'); }, Arguments: inspectArguments, Int8Array: inspectTypedArray, Uint8Array: inspectTypedArray, Uint8ClampedArray: inspectTypedArray, Int16Array: inspectTypedArray, Uint16Array: inspectTypedArray, Int32Array: inspectTypedArray, Uint32Array: inspectTypedArray, Float32Array: inspectTypedArray, Float64Array: inspectTypedArray, Generator: function Generator() { return ''; }, DataView: function DataView() { return ''; }, ArrayBuffer: function ArrayBuffer() { return ''; }, Error: inspectObject$1, HTMLCollection: inspectHTMLCollection, NodeList: inspectHTMLCollection }; // eslint-disable-next-line complexity var inspectCustom = function inspectCustom(value, options, type) { if (chaiInspect in value && typeof value[chaiInspect] === 'function') { return value[chaiInspect](options); } if (nodeInspect && nodeInspect in value && typeof value[nodeInspect] === 'function') { return value[nodeInspect](options.depth, options); } if ('inspect' in value && typeof value.inspect === 'function') { return value.inspect(options.depth, options); } if ('constructor' in value && constructorMap.has(value.constructor)) { return constructorMap.get(value.constructor)(value, options); } if (stringTagMap[type]) { return stringTagMap[type](value, options); } return ''; }; var toString$1 = Object.prototype.toString; // eslint-disable-next-line complexity function inspect(value, options) { options = normaliseOptions(options); options.inspect = inspect; var _options = options, customInspect = _options.customInspect; var type = value === null ? 'null' : _typeof(value); if (type === 'object') { type = toString$1.call(value).slice(8, -1); } // If it is a base value that we already support, then use Loupe's inspector
if (baseTypesMap[type]) { return baseTypesMap[type](value, options); } // If `options.customInspect` is set to true then try to use the custom inspector
if (customInspect && value) { var output = inspectCustom(value, options, type); if (output) { if (typeof output === 'string') return output; return inspect(output, options); } } var proto = value ? Object.getPrototypeOf(value) : false; // If it's a plain Object then use Loupe's inspector if (proto === Object.prototype || proto === null) { return inspectObject(value, options); } // Specifically account for HTMLElements // eslint-disable-next-line no-undef
if (value && typeof HTMLElement === 'function' && value instanceof HTMLElement) { return inspectHTML(value, options); } if ('constructor' in value) { // If it is a class, inspect it like an object but add the constructor name if (value.constructor !== Object) { return inspectClass(value, options); } // If it is an object with an anonymous prototype, display it as an object.
return inspectObject(value, options); } // last chance to check if it's an object
if (value === Object(value)) { return inspectObject(value, options); } // We have run out of options! Just stringify the value
return options.stylize(String(value), type); } function registerConstructor(constructor, inspector) { if (constructorMap.has(constructor)) { return false; } constructorMap.set(constructor, inspector); return true; } function registerStringTag(stringTag, inspector) { if (stringTag in stringTagMap) { return false; } stringTagMap[stringTag] = inspector; return true; } var custom = chaiInspect; exports.custom = custom; exports.default = inspect; exports.inspect = inspect; exports.registerConstructor = registerConstructor; exports.registerStringTag = registerStringTag; Object.defineProperty(exports, '__esModule', { value: true });})));
},{"util":undefined}],38:[function(require,module,exports){'use strict';
/* ! * Chai - pathval utility * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> * @see https://github.com/logicalparadox/filtr * MIT Licensed *//** * ### .hasProperty(object, name) * * This allows checking whether an object has own * or inherited from prototype chain named property. * * Basically does the same thing as the `in` * operator but works properly with null/undefined values * and other primitives. * * var obj = { * arr: ['a', 'b', 'c'] * , str: 'Hello' * } * * The following would be the results. * * hasProperty(obj, 'str'); // true * hasProperty(obj, 'constructor'); // true * hasProperty(obj, 'bar'); // false * * hasProperty(obj.str, 'length'); // true * hasProperty(obj.str, 1); // true * hasProperty(obj.str, 5); // false * * hasProperty(obj.arr, 'length'); // true * hasProperty(obj.arr, 2); // true * hasProperty(obj.arr, 3); // false * * @param {Object} object * @param {String|Symbol} name * @returns {Boolean} whether it exists * @namespace Utils * @name hasProperty * @api public */function hasProperty(obj, name) { if (typeof obj === 'undefined' || obj === null) { return false; } // The `in` operator does not work with primitives. return name in Object(obj);}
/* ! * ## parsePath(path) * * Helper function used to parse string object * paths. Use in conjunction with `internalGetPathValue`. * * var parsed = parsePath('myobject.property.subprop'); * * ### Paths: * * * Can be infinitely deep and nested. * * Arrays are also valid using the formal `myobject.document[3].property`. * * Literal dots and brackets (not delimiter) must be backslash-escaped. * * @param {String} path * @returns {Object} parsed * @api private */function parsePath(path) { var str = path.replace(/([^\\])\[/g, '$1.['); var parts = str.match(/(\\\.|[^.]+?)+/g); return parts.map(function mapMatches(value) { if ( value === 'constructor' || value === '__proto__' || value === 'prototype' ) { return {}; } var regexp = /^\[(\d+)\]$/; var mArr = regexp.exec(value); var parsed = null; if (mArr) { parsed = { i: parseFloat(mArr[1]) }; } else { parsed = { p: value.replace(/\\([.[\]])/g, '$1') }; } return parsed; });}
/* ! * ## internalGetPathValue(obj, parsed[, pathDepth]) * * Helper companion function for `.parsePath` that returns * the value located at the parsed address. * * var value = getPathValue(obj, parsed); * * @param {Object} object to search against * @param {Object} parsed definition from `parsePath`. * @param {Number} depth (nesting level) of the property we want to retrieve * @returns {Object|Undefined} value * @api private */function internalGetPathValue(obj, parsed, pathDepth) { var temporaryValue = obj; var res = null; pathDepth = typeof pathDepth === 'undefined' ? parsed.length : pathDepth; for (var i = 0; i < pathDepth; i++) { var part = parsed[i]; if (temporaryValue) { if (typeof part.p === 'undefined') { temporaryValue = temporaryValue[part.i]; } else { temporaryValue = temporaryValue[part.p]; } if (i === pathDepth - 1) { res = temporaryValue; } } } return res;}
/* ! * ## internalSetPathValue(obj, value, parsed) * * Companion function for `parsePath` that sets * the value located at a parsed address. * * internalSetPathValue(obj, 'value', parsed); * * @param {Object} object to search and define on * @param {*} value to use upon set * @param {Object} parsed definition from `parsePath` * @api private */function internalSetPathValue(obj, val, parsed) { var tempObj = obj; var pathDepth = parsed.length; var part = null; // Here we iterate through every part of the path for (var i = 0; i < pathDepth; i++) { var propName = null; var propVal = null; part = parsed[i]; // If it's the last part of the path, we set the 'propName' value with the property name if (i === pathDepth - 1) { propName = typeof part.p === 'undefined' ? part.i : part.p; // Now we set the property with the name held by 'propName' on object with the desired val tempObj[propName] = val; } else if (typeof part.p !== 'undefined' && tempObj[part.p]) { tempObj = tempObj[part.p]; } else if (typeof part.i !== 'undefined' && tempObj[part.i]) { tempObj = tempObj[part.i]; } else { // If the obj doesn't have the property we create one with that name to define it var next = parsed[i + 1]; // Here we set the name of the property which will be defined propName = typeof part.p === 'undefined' ? part.i : part.p; // Here we decide if this property will be an array or a new object propVal = typeof next.p === 'undefined' ? [] : {}; tempObj[propName] = propVal; tempObj = tempObj[propName]; } }}
/** * ### .getPathInfo(object, path) * * This allows the retrieval of property info in an * object given a string path. * * The path info consists of an object with the * following properties: * * * parent - The parent object of the property referenced by `path` * * name - The name of the final property, a number if it was an array indexer * * value - The value of the property, if it exists, otherwise `undefined` * * exists - Whether the property exists or not * * @param {Object} object * @param {String} path * @returns {Object} info * @namespace Utils * @name getPathInfo * @api public */function getPathInfo(obj, path) { var parsed = parsePath(path); var last = parsed[parsed.length - 1]; var info = { parent: parsed.length > 1 ? internalGetPathValue(obj, parsed, parsed.length - 1) : obj, name: last.p || last.i, value: internalGetPathValue(obj, parsed), }; info.exists = hasProperty(info.parent, info.name); return info;}
/** * ### .getPathValue(object, path) * * This allows the retrieval of values in an * object given a string path. * * var obj = { * prop1: { * arr: ['a', 'b', 'c'] * , str: 'Hello' * } * , prop2: { * arr: [ { nested: 'Universe' } ] * , str: 'Hello again!' * } * } * * The following would be the results. * * getPathValue(obj, 'prop1.str'); // Hello * getPathValue(obj, 'prop1.att[2]'); // b * getPathValue(obj, 'prop2.arr[0].nested'); // Universe * * @param {Object} object * @param {String} path * @returns {Object} value or `undefined` * @namespace Utils * @name getPathValue * @api public */function getPathValue(obj, path) { var info = getPathInfo(obj, path); return info.value;}
/** * ### .setPathValue(object, path, value) * * Define the value in an object at a given string path. * * ```js * var obj = { * prop1: { * arr: ['a', 'b', 'c'] * , str: 'Hello' * } * , prop2: { * arr: [ { nested: 'Universe' } ] * , str: 'Hello again!' * } * }; * ``` * * The following would be acceptable. * * ```js * var properties = require('tea-properties'); * properties.set(obj, 'prop1.str', 'Hello Universe!'); * properties.set(obj, 'prop1.arr[2]', 'B'); * properties.set(obj, 'prop2.arr[0].nested.value', { hello: 'universe' }); * ``` * * @param {Object} object * @param {String} path * @param {Mixed} value * @api private */function setPathValue(obj, path, val) { var parsed = parsePath(path); internalSetPathValue(obj, val, parsed); return obj;}
module.exports = { hasProperty: hasProperty, getPathInfo: getPathInfo, getPathValue: getPathValue, setPathValue: setPathValue,};
},{}],39:[function(require,module,exports){(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.typeDetect = factory());}(this, (function () { 'use strict';
/* ! * type-detect * Copyright(c) 2013 jake luer <jake@alogicalparadox.com> * MIT Licensed */var promiseExists = typeof Promise === 'function';
/* eslint-disable no-undef */var globalObject = typeof self === 'object' ? self : global; // eslint-disable-line id-blacklist
var symbolExists = typeof Symbol !== 'undefined';var mapExists = typeof Map !== 'undefined';var setExists = typeof Set !== 'undefined';var weakMapExists = typeof WeakMap !== 'undefined';var weakSetExists = typeof WeakSet !== 'undefined';var dataViewExists = typeof DataView !== 'undefined';var symbolIteratorExists = symbolExists && typeof Symbol.iterator !== 'undefined';var symbolToStringTagExists = symbolExists && typeof Symbol.toStringTag !== 'undefined';var setEntriesExists = setExists && typeof Set.prototype.entries === 'function';var mapEntriesExists = mapExists && typeof Map.prototype.entries === 'function';var setIteratorPrototype = setEntriesExists && Object.getPrototypeOf(new Set().entries());var mapIteratorPrototype = mapEntriesExists && Object.getPrototypeOf(new Map().entries());var arrayIteratorExists = symbolIteratorExists && typeof Array.prototype[Symbol.iterator] === 'function';var arrayIteratorPrototype = arrayIteratorExists && Object.getPrototypeOf([][Symbol.iterator]());var stringIteratorExists = symbolIteratorExists && typeof String.prototype[Symbol.iterator] === 'function';var stringIteratorPrototype = stringIteratorExists && Object.getPrototypeOf(''[Symbol.iterator]());var toStringLeftSliceLength = 8;var toStringRightSliceLength = -1;/** * ### typeOf (obj) * * Uses `Object.prototype.toString` to determine the type of an object, * normalising behaviour across engine versions & well optimised. * * @param {Mixed} object * @return {String} object type * @api public */function typeDetect(obj) { /* ! Speed optimisation * Pre: * string literal x 3,039,035 ops/sec ±1.62% (78 runs sampled) * boolean literal x 1,424,138 ops/sec ±4.54% (75 runs sampled) * number literal x 1,653,153 ops/sec ±1.91% (82 runs sampled) * undefined x 9,978,660 ops/sec ±1.92% (75 runs sampled) * function x 2,556,769 ops/sec ±1.73% (77 runs sampled) * Post: * string literal x 38,564,796 ops/sec ±1.15% (79 runs sampled) * boolean literal x 31,148,940 ops/sec ±1.10% (79 runs sampled) * number literal x 32,679,330 ops/sec ±1.90% (78 runs sampled) * undefined x 32,363,368 ops/sec ±1.07% (82 runs sampled) * function x 31,296,870 ops/sec ±0.96% (83 runs sampled) */ var typeofObj = typeof obj; if (typeofObj !== 'object') { return typeofObj; } /* ! Speed optimisation * Pre: * null x 28,645,765 ops/sec ±1.17% (82 runs sampled) * Post: * null x 36,428,962 ops/sec ±1.37% (84 runs sampled) */ if (obj === null) { return 'null'; } /* ! Spec Conformance * Test: `Object.prototype.toString.call(window)`` * - Node === "[object global]" * - Chrome === "[object global]" * - Firefox === "[object Window]" * - PhantomJS === "[object Window]" * - Safari === "[object Window]" * - IE 11 === "[object Window]" * - IE Edge === "[object Window]" * Test: `Object.prototype.toString.call(this)`` * - Chrome Worker === "[object global]" * - Firefox Worker === "[object DedicatedWorkerGlobalScope]" * - Safari Worker === "[object DedicatedWorkerGlobalScope]" * - IE 11 Worker === "[object WorkerGlobalScope]" * - IE Edge Worker === "[object WorkerGlobalScope]" */ if (obj === globalObject) { return 'global'; } /* ! Speed optimisation * Pre: * array literal x 2,888,352 ops/sec ±0.67% (82 runs sampled) * Post: * array literal x 22,479,650 ops/sec ±0.96% (81 runs sampled) */ if ( Array.isArray(obj) && (symbolToStringTagExists === false || !(Symbol.toStringTag in obj)) ) { return 'Array'; } // Not caching existence of `window` and related properties due to potential // for `window` to be unset before tests in quasi-browser environments. if (typeof window === 'object' && window !== null) { /* ! Spec Conformance * (https://html.spec.whatwg.org/multipage/browsers.html#location) * WhatWG HTML$7.7.3 - The `Location` interface * Test: `Object.prototype.toString.call(window.location)`` * - IE <=11 === "[object Object]" * - IE Edge <=13 === "[object Object]" */ if (typeof window.location === 'object' && obj === window.location) { return 'Location'; } /* ! Spec Conformance * (https://html.spec.whatwg.org/#document) * WhatWG HTML$3.1.1 - The `Document` object * Note: Most browsers currently adher to the W3C DOM Level 2 spec * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-26809268) * which suggests that browsers should use HTMLTableCellElement for * both TD and TH elements. WhatWG separates these. * WhatWG HTML states: * > For historical reasons, Window objects must also have a * > writable, configurable, non-enumerable property named * > HTMLDocument whose value is the Document interface object. * Test: `Object.prototype.toString.call(document)`` * - Chrome === "[object HTMLDocument]" * - Firefox === "[object HTMLDocument]" * - Safari === "[object HTMLDocument]" * - IE <=10 === "[object Document]" * - IE 11 === "[object HTMLDocument]" * - IE Edge <=13 === "[object HTMLDocument]" */ if (typeof window.document === 'object' && obj === window.document) { return 'Document'; } if (typeof window.navigator === 'object') { /* ! Spec Conformance * (https://html.spec.whatwg.org/multipage/webappapis.html#mimetypearray) * WhatWG HTML$8.6.1.5 - Plugins - Interface MimeTypeArray * Test: `Object.prototype.toString.call(navigator.mimeTypes)`` * - IE <=10 === "[object MSMimeTypesCollection]" */ if (typeof window.navigator.mimeTypes === 'object' && obj === window.navigator.mimeTypes) { return 'MimeTypeArray'; } /* ! Spec Conformance * (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray) * WhatWG HTML$8.6.1.5 - Plugins - Interface PluginArray * Test: `Object.prototype.toString.call(navigator.plugins)`` * - IE <=10 === "[object MSPluginsCollection]" */ if (typeof window.navigator.plugins === 'object' && obj === window.navigator.plugins) { return 'PluginArray'; } } if ((typeof window.HTMLElement === 'function' || typeof window.HTMLElement === 'object') && obj instanceof window.HTMLElement) { /* ! Spec Conformance * (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray) * WhatWG HTML$4.4.4 - The `blockquote` element - Interface `HTMLQuoteElement` * Test: `Object.prototype.toString.call(document.createElement('blockquote'))`` * - IE <=10 === "[object HTMLBlockElement]" */ if (obj.tagName === 'BLOCKQUOTE') { return 'HTMLQuoteElement'; } /* ! Spec Conformance * (https://html.spec.whatwg.org/#htmltabledatacellelement) * WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableDataCellElement` * Note: Most browsers currently adher to the W3C DOM Level 2 spec * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075) * which suggests that browsers should use HTMLTableCellElement for * both TD and TH elements. WhatWG separates these. * Test: Object.prototype.toString.call(document.createElement('td')) * - Chrome === "[object HTMLTableCellElement]" * - Firefox === "[object HTMLTableCellElement]" * - Safari === "[object HTMLTableCellElement]" */ if (obj.tagName === 'TD') { return 'HTMLTableDataCellElement'; } /* ! Spec Conformance * (https://html.spec.whatwg.org/#htmltableheadercellelement) * WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableHeaderCellElement` * Note: Most browsers currently adher to the W3C DOM Level 2 spec * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075) * which suggests that browsers should use HTMLTableCellElement for * both TD and TH elements. WhatWG separates these. * Test: Object.prototype.toString.call(document.createElement('th')) * - Chrome === "[object HTMLTableCellElement]" * - Firefox === "[object HTMLTableCellElement]" * - Safari === "[object HTMLTableCellElement]" */ if (obj.tagName === 'TH') { return 'HTMLTableHeaderCellElement'; } } } /* ! Speed optimisation * Pre: * Float64Array x 625,644 ops/sec ±1.58% (80 runs sampled) * Float32Array x 1,279,852 ops/sec ±2.91% (77 runs sampled) * Uint32Array x 1,178,185 ops/sec ±1.95% (83 runs sampled) * Uint16Array x 1,008,380 ops/sec ±2.25% (80 runs sampled) * Uint8Array x 1,128,040 ops/sec ±2.11% (81 runs sampled) * Int32Array x 1,170,119 ops/sec ±2.88% (80 runs sampled) * Int16Array x 1,176,348 ops/sec ±5.79% (86 runs sampled) * Int8Array x 1,058,707 ops/sec ±4.94% (77 runs sampled) * Uint8ClampedArray x 1,110,633 ops/sec ±4.20% (80 runs sampled) * Post: * Float64Array x 7,105,671 ops/sec ±13.47% (64 runs sampled) * Float32Array x 5,887,912 ops/sec ±1.46% (82 runs sampled) * Uint32Array x 6,491,661 ops/sec ±1.76% (79 runs sampled) * Uint16Array x 6,559,795 ops/sec ±1.67% (82 runs sampled) * Uint8Array x 6,463,966 ops/sec ±1.43% (85 runs sampled) * Int32Array x 5,641,841 ops/sec ±3.49% (81 runs sampled) * Int16Array x 6,583,511 ops/sec ±1.98% (80 runs sampled) * Int8Array x 6,606,078 ops/sec ±1.74% (81 runs sampled) * Uint8ClampedArray x 6,602,224 ops/sec ±1.77% (83 runs sampled) */ var stringTag = (symbolToStringTagExists && obj[Symbol.toStringTag]); if (typeof stringTag === 'string') { return stringTag; } var objPrototype = Object.getPrototypeOf(obj); /* ! Speed optimisation * Pre: * regex literal x 1,772,385 ops/sec ±1.85% (77 runs sampled) * regex constructor x 2,143,634 ops/sec ±2.46% (78 runs sampled) * Post: * regex literal x 3,928,009 ops/sec ±0.65% (78 runs sampled) * regex constructor x 3,931,108 ops/sec ±0.58% (84 runs sampled) */ if (objPrototype === RegExp.prototype) { return 'RegExp'; } /* ! Speed optimisation * Pre: * date x 2,130,074 ops/sec ±4.42% (68 runs sampled) * Post: * date x 3,953,779 ops/sec ±1.35% (77 runs sampled) */ if (objPrototype === Date.prototype) { return 'Date'; } /* ! Spec Conformance * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-promise.prototype-@@tostringtag) * ES6$25.4.5.4 - Promise.prototype[@@toStringTag] should be "Promise": * Test: `Object.prototype.toString.call(Promise.resolve())`` * - Chrome <=47 === "[object Object]" * - Edge <=20 === "[object Object]" * - Firefox 29-Latest === "[object Promise]" * - Safari 7.1-Latest === "[object Promise]" */ if (promiseExists && objPrototype === Promise.prototype) { return 'Promise'; } /* ! Speed optimisation * Pre: * set x 2,222,186 ops/sec ±1.31% (82 runs sampled) * Post: * set x 4,545,879 ops/sec ±1.13% (83 runs sampled) */ if (setExists && objPrototype === Set.prototype) { return 'Set'; } /* ! Speed optimisation * Pre: * map x 2,396,842 ops/sec ±1.59% (81 runs sampled) * Post: * map x 4,183,945 ops/sec ±6.59% (82 runs sampled) */ if (mapExists && objPrototype === Map.prototype) { return 'Map'; } /* ! Speed optimisation * Pre: * weakset x 1,323,220 ops/sec ±2.17% (76 runs sampled) * Post: * weakset x 4,237,510 ops/sec ±2.01% (77 runs sampled) */ if (weakSetExists && objPrototype === WeakSet.prototype) { return 'WeakSet'; } /* ! Speed optimisation * Pre: * weakmap x 1,500,260 ops/sec ±2.02% (78 runs sampled) * Post: * weakmap x 3,881,384 ops/sec ±1.45% (82 runs sampled) */ if (weakMapExists && objPrototype === WeakMap.prototype) { return 'WeakMap'; } /* ! Spec Conformance * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-dataview.prototype-@@tostringtag) * ES6$24.2.4.21 - DataView.prototype[@@toStringTag] should be "DataView": * Test: `Object.prototype.toString.call(new DataView(new ArrayBuffer(1)))`` * - Edge <=13 === "[object Object]" */ if (dataViewExists && objPrototype === DataView.prototype) { return 'DataView'; } /* ! Spec Conformance * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%mapiteratorprototype%-@@tostringtag) * ES6$23.1.5.2.2 - %MapIteratorPrototype%[@@toStringTag] should be "Map Iterator": * Test: `Object.prototype.toString.call(new Map().entries())`` * - Edge <=13 === "[object Object]" */ if (mapExists && objPrototype === mapIteratorPrototype) { return 'Map Iterator'; } /* ! Spec Conformance * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%setiteratorprototype%-@@tostringtag) * ES6$23.2.5.2.2 - %SetIteratorPrototype%[@@toStringTag] should be "Set Iterator": * Test: `Object.prototype.toString.call(new Set().entries())`` * - Edge <=13 === "[object Object]" */ if (setExists && objPrototype === setIteratorPrototype) { return 'Set Iterator'; } /* ! Spec Conformance * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%arrayiteratorprototype%-@@tostringtag) * ES6$22.1.5.2.2 - %ArrayIteratorPrototype%[@@toStringTag] should be "Array Iterator": * Test: `Object.prototype.toString.call([][Symbol.iterator]())`` * - Edge <=13 === "[object Object]" */ if (arrayIteratorExists && objPrototype === arrayIteratorPrototype) { return 'Array Iterator'; } /* ! Spec Conformance * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%stringiteratorprototype%-@@tostringtag) * ES6$21.1.5.2.2 - %StringIteratorPrototype%[@@toStringTag] should be "String Iterator": * Test: `Object.prototype.toString.call(''[Symbol.iterator]())`` * - Edge <=13 === "[object Object]" */ if (stringIteratorExists && objPrototype === stringIteratorPrototype) { return 'String Iterator'; } /* ! Speed optimisation * Pre: * object from null x 2,424,320 ops/sec ±1.67% (76 runs sampled) * Post: * object from null x 5,838,000 ops/sec ±0.99% (84 runs sampled) */ if (objPrototype === null) { return 'Object'; } return Object .prototype .toString .call(obj) .slice(toStringLeftSliceLength, toStringRightSliceLength);}
return typeDetect;
})));
},{}]},{},[1])(1)});