Dieses Repository beinhaltet HTML- und Javascript Code zur einer NotizenWebApp auf Basis von Web Storage. Zudem sind Mocha/Chai Tests im Browser enthalten. https://meinenotizen.netlify.app/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

chai.js 338KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854
  1. (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){
  2. module.exports = require('./lib/chai');
  3. },{"./lib/chai":2}],2:[function(require,module,exports){
  4. /*!
  5. * chai
  6. * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
  7. * MIT Licensed
  8. */
  9. var used = [];
  10. /*!
  11. * Chai version
  12. */
  13. exports.version = '4.2.0';
  14. /*!
  15. * Assertion Error
  16. */
  17. exports.AssertionError = require('assertion-error');
  18. /*!
  19. * Utils for plugins (not exported)
  20. */
  21. var util = require('./chai/utils');
  22. /**
  23. * # .use(function)
  24. *
  25. * Provides a way to extend the internals of Chai.
  26. *
  27. * @param {Function}
  28. * @returns {this} for chaining
  29. * @api public
  30. */
  31. exports.use = function (fn) {
  32. if (!~used.indexOf(fn)) {
  33. fn(exports, util);
  34. used.push(fn);
  35. }
  36. return exports;
  37. };
  38. /*!
  39. * Utility Functions
  40. */
  41. exports.util = util;
  42. /*!
  43. * Configuration
  44. */
  45. var config = require('./chai/config');
  46. exports.config = config;
  47. /*!
  48. * Primary `Assertion` prototype
  49. */
  50. var assertion = require('./chai/assertion');
  51. exports.use(assertion);
  52. /*!
  53. * Core Assertions
  54. */
  55. var core = require('./chai/core/assertions');
  56. exports.use(core);
  57. /*!
  58. * Expect interface
  59. */
  60. var expect = require('./chai/interface/expect');
  61. exports.use(expect);
  62. /*!
  63. * Should interface
  64. */
  65. var should = require('./chai/interface/should');
  66. exports.use(should);
  67. /*!
  68. * Assert interface
  69. */
  70. var assert = require('./chai/interface/assert');
  71. exports.use(assert);
  72. },{"./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){
  73. /*!
  74. * chai
  75. * http://chaijs.com
  76. * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
  77. * MIT Licensed
  78. */
  79. var config = require('./config');
  80. module.exports = function (_chai, util) {
  81. /*!
  82. * Module dependencies.
  83. */
  84. var AssertionError = _chai.AssertionError
  85. , flag = util.flag;
  86. /*!
  87. * Module export.
  88. */
  89. _chai.Assertion = Assertion;
  90. /*!
  91. * Assertion Constructor
  92. *
  93. * Creates object for chaining.
  94. *
  95. * `Assertion` objects contain metadata in the form of flags. Three flags can
  96. * be assigned during instantiation by passing arguments to this constructor:
  97. *
  98. * - `object`: This flag contains the target of the assertion. For example, in
  99. * the assertion `expect(numKittens).to.equal(7);`, the `object` flag will
  100. * contain `numKittens` so that the `equal` assertion can reference it when
  101. * needed.
  102. *
  103. * - `message`: This flag contains an optional custom error message to be
  104. * prepended to the error message that's generated by the assertion when it
  105. * fails.
  106. *
  107. * - `ssfi`: This flag stands for "start stack function indicator". It
  108. * contains a function reference that serves as the starting point for
  109. * removing frames from the stack trace of the error that's created by the
  110. * assertion when it fails. The goal is to provide a cleaner stack trace to
  111. * end users by removing Chai's internal functions. Note that it only works
  112. * in environments that support `Error.captureStackTrace`, and only when
  113. * `Chai.config.includeStack` hasn't been set to `false`.
  114. *
  115. * - `lockSsfi`: This flag controls whether or not the given `ssfi` flag
  116. * should retain its current value, even as assertions are chained off of
  117. * this object. This is usually set to `true` when creating a new assertion
  118. * from within another assertion. It's also temporarily set to `true` before
  119. * an overwritten assertion gets called by the overwriting assertion.
  120. *
  121. * @param {Mixed} obj target of the assertion
  122. * @param {String} msg (optional) custom error message
  123. * @param {Function} ssfi (optional) starting point for removing stack frames
  124. * @param {Boolean} lockSsfi (optional) whether or not the ssfi flag is locked
  125. * @api private
  126. */
  127. function Assertion (obj, msg, ssfi, lockSsfi) {
  128. flag(this, 'ssfi', ssfi || Assertion);
  129. flag(this, 'lockSsfi', lockSsfi);
  130. flag(this, 'object', obj);
  131. flag(this, 'message', msg);
  132. return util.proxify(this);
  133. }
  134. Object.defineProperty(Assertion, 'includeStack', {
  135. get: function() {
  136. console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');
  137. return config.includeStack;
  138. },
  139. set: function(value) {
  140. console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');
  141. config.includeStack = value;
  142. }
  143. });
  144. Object.defineProperty(Assertion, 'showDiff', {
  145. get: function() {
  146. console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');
  147. return config.showDiff;
  148. },
  149. set: function(value) {
  150. console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');
  151. config.showDiff = value;
  152. }
  153. });
  154. Assertion.addProperty = function (name, fn) {
  155. util.addProperty(this.prototype, name, fn);
  156. };
  157. Assertion.addMethod = function (name, fn) {
  158. util.addMethod(this.prototype, name, fn);
  159. };
  160. Assertion.addChainableMethod = function (name, fn, chainingBehavior) {
  161. util.addChainableMethod(this.prototype, name, fn, chainingBehavior);
  162. };
  163. Assertion.overwriteProperty = function (name, fn) {
  164. util.overwriteProperty(this.prototype, name, fn);
  165. };
  166. Assertion.overwriteMethod = function (name, fn) {
  167. util.overwriteMethod(this.prototype, name, fn);
  168. };
  169. Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) {
  170. util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior);
  171. };
  172. /**
  173. * ### .assert(expression, message, negateMessage, expected, actual, showDiff)
  174. *
  175. * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.
  176. *
  177. * @name assert
  178. * @param {Philosophical} expression to be tested
  179. * @param {String|Function} message or function that returns message to display if expression fails
  180. * @param {String|Function} negatedMessage or function that returns negatedMessage to display if negated expression fails
  181. * @param {Mixed} expected value (remember to check for negation)
  182. * @param {Mixed} actual (optional) will default to `this.obj`
  183. * @param {Boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails
  184. * @api private
  185. */
  186. Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) {
  187. var ok = util.test(this, arguments);
  188. if (false !== showDiff) showDiff = true;
  189. if (undefined === expected && undefined === _actual) showDiff = false;
  190. if (true !== config.showDiff) showDiff = false;
  191. if (!ok) {
  192. msg = util.getMessage(this, arguments);
  193. var actual = util.getActual(this, arguments);
  194. throw new AssertionError(msg, {
  195. actual: actual
  196. , expected: expected
  197. , showDiff: showDiff
  198. }, (config.includeStack) ? this.assert : flag(this, 'ssfi'));
  199. }
  200. };
  201. /*!
  202. * ### ._obj
  203. *
  204. * Quick reference to stored `actual` value for plugin developers.
  205. *
  206. * @api private
  207. */
  208. Object.defineProperty(Assertion.prototype, '_obj',
  209. { get: function () {
  210. return flag(this, 'object');
  211. }
  212. , set: function (val) {
  213. flag(this, 'object', val);
  214. }
  215. });
  216. };
  217. },{"./config":4}],4:[function(require,module,exports){
  218. module.exports = {
  219. /**
  220. * ### config.includeStack
  221. *
  222. * User configurable property, influences whether stack trace
  223. * is included in Assertion error message. Default of false
  224. * suppresses stack trace in the error message.
  225. *
  226. * chai.config.includeStack = true; // enable stack on error
  227. *
  228. * @param {Boolean}
  229. * @api public
  230. */
  231. includeStack: false,
  232. /**
  233. * ### config.showDiff
  234. *
  235. * User configurable property, influences whether or not
  236. * the `showDiff` flag should be included in the thrown
  237. * AssertionErrors. `false` will always be `false`; `true`
  238. * will be true when the assertion has requested a diff
  239. * be shown.
  240. *
  241. * @param {Boolean}
  242. * @api public
  243. */
  244. showDiff: true,
  245. /**
  246. * ### config.truncateThreshold
  247. *
  248. * User configurable property, sets length threshold for actual and
  249. * expected values in assertion errors. If this threshold is exceeded, for
  250. * example for large data structures, the value is replaced with something
  251. * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`.
  252. *
  253. * Set it to zero if you want to disable truncating altogether.
  254. *
  255. * This is especially userful when doing assertions on arrays: having this
  256. * set to a reasonable large value makes the failure messages readily
  257. * inspectable.
  258. *
  259. * chai.config.truncateThreshold = 0; // disable truncating
  260. *
  261. * @param {Number}
  262. * @api public
  263. */
  264. truncateThreshold: 40,
  265. /**
  266. * ### config.useProxy
  267. *
  268. * User configurable property, defines if chai will use a Proxy to throw
  269. * an error when a non-existent property is read, which protects users
  270. * from typos when using property-based assertions.
  271. *
  272. * Set it to false if you want to disable this feature.
  273. *
  274. * chai.config.useProxy = false; // disable use of Proxy
  275. *
  276. * This feature is automatically disabled regardless of this config value
  277. * in environments that don't support proxies.
  278. *
  279. * @param {Boolean}
  280. * @api public
  281. */
  282. useProxy: true,
  283. /**
  284. * ### config.proxyExcludedKeys
  285. *
  286. * User configurable property, defines which properties should be ignored
  287. * instead of throwing an error if they do not exist on the assertion.
  288. * This is only applied if the environment Chai is running in supports proxies and
  289. * if the `useProxy` configuration setting is enabled.
  290. * By default, `then` and `inspect` will not throw an error if they do not exist on the
  291. * assertion object because the `.inspect` property is read by `util.inspect` (for example, when
  292. * using `console.log` on the assertion object) and `.then` is necessary for promise type-checking.
  293. *
  294. * // By default these keys will not throw an error if they do not exist on the assertion object
  295. * chai.config.proxyExcludedKeys = ['then', 'inspect'];
  296. *
  297. * @param {Array}
  298. * @api public
  299. */
  300. proxyExcludedKeys: ['then', 'catch', 'inspect', 'toJSON']
  301. };
  302. },{}],5:[function(require,module,exports){
  303. /*!
  304. * chai
  305. * http://chaijs.com
  306. * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
  307. * MIT Licensed
  308. */
  309. module.exports = function (chai, _) {
  310. var Assertion = chai.Assertion
  311. , AssertionError = chai.AssertionError
  312. , flag = _.flag;
  313. /**
  314. * ### Language Chains
  315. *
  316. * The following are provided as chainable getters to improve the readability
  317. * of your assertions.
  318. *
  319. * **Chains**
  320. *
  321. * - to
  322. * - be
  323. * - been
  324. * - is
  325. * - that
  326. * - which
  327. * - and
  328. * - has
  329. * - have
  330. * - with
  331. * - at
  332. * - of
  333. * - same
  334. * - but
  335. * - does
  336. * - still
  337. *
  338. * @name language chains
  339. * @namespace BDD
  340. * @api public
  341. */
  342. [ 'to', 'be', 'been', 'is'
  343. , 'and', 'has', 'have', 'with'
  344. , 'that', 'which', 'at', 'of'
  345. , 'same', 'but', 'does', 'still' ].forEach(function (chain) {
  346. Assertion.addProperty(chain);
  347. });
  348. /**
  349. * ### .not
  350. *
  351. * Negates all assertions that follow in the chain.
  352. *
  353. * expect(function () {}).to.not.throw();
  354. * expect({a: 1}).to.not.have.property('b');
  355. * expect([1, 2]).to.be.an('array').that.does.not.include(3);
  356. *
  357. * Just because you can negate any assertion with `.not` doesn't mean you
  358. * should. With great power comes great responsibility. It's often best to
  359. * assert that the one expected output was produced, rather than asserting
  360. * that one of countless unexpected outputs wasn't produced. See individual
  361. * assertions for specific guidance.
  362. *
  363. * expect(2).to.equal(2); // Recommended
  364. * expect(2).to.not.equal(1); // Not recommended
  365. *
  366. * @name not
  367. * @namespace BDD
  368. * @api public
  369. */
  370. Assertion.addProperty('not', function () {
  371. flag(this, 'negate', true);
  372. });
  373. /**
  374. * ### .deep
  375. *
  376. * Causes all `.equal`, `.include`, `.members`, `.keys`, and `.property`
  377. * assertions that follow in the chain to use deep equality instead of strict
  378. * (`===`) equality. See the `deep-eql` project page for info on the deep
  379. * equality algorithm: https://github.com/chaijs/deep-eql.
  380. *
  381. * // Target object deeply (but not strictly) equals `{a: 1}`
  382. * expect({a: 1}).to.deep.equal({a: 1});
  383. * expect({a: 1}).to.not.equal({a: 1});
  384. *
  385. * // Target array deeply (but not strictly) includes `{a: 1}`
  386. * expect([{a: 1}]).to.deep.include({a: 1});
  387. * expect([{a: 1}]).to.not.include({a: 1});
  388. *
  389. * // Target object deeply (but not strictly) includes `x: {a: 1}`
  390. * expect({x: {a: 1}}).to.deep.include({x: {a: 1}});
  391. * expect({x: {a: 1}}).to.not.include({x: {a: 1}});
  392. *
  393. * // Target array deeply (but not strictly) has member `{a: 1}`
  394. * expect([{a: 1}]).to.have.deep.members([{a: 1}]);
  395. * expect([{a: 1}]).to.not.have.members([{a: 1}]);
  396. *
  397. * // Target set deeply (but not strictly) has key `{a: 1}`
  398. * expect(new Set([{a: 1}])).to.have.deep.keys([{a: 1}]);
  399. * expect(new Set([{a: 1}])).to.not.have.keys([{a: 1}]);
  400. *
  401. * // Target object deeply (but not strictly) has property `x: {a: 1}`
  402. * expect({x: {a: 1}}).to.have.deep.property('x', {a: 1});
  403. * expect({x: {a: 1}}).to.not.have.property('x', {a: 1});
  404. *
  405. * @name deep
  406. * @namespace BDD
  407. * @api public
  408. */
  409. Assertion.addProperty('deep', function () {
  410. flag(this, 'deep', true);
  411. });
  412. /**
  413. * ### .nested
  414. *
  415. * Enables dot- and bracket-notation in all `.property` and `.include`
  416. * assertions that follow in the chain.
  417. *
  418. * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]');
  419. * expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'});
  420. *
  421. * If `.` or `[]` are part of an actual property name, they can be escaped by
  422. * adding two backslashes before them.
  423. *
  424. * expect({'.a': {'[b]': 'x'}}).to.have.nested.property('\\.a.\\[b\\]');
  425. * expect({'.a': {'[b]': 'x'}}).to.nested.include({'\\.a.\\[b\\]': 'x'});
  426. *
  427. * `.nested` cannot be combined with `.own`.
  428. *
  429. * @name nested
  430. * @namespace BDD
  431. * @api public
  432. */
  433. Assertion.addProperty('nested', function () {
  434. flag(this, 'nested', true);
  435. });
  436. /**
  437. * ### .own
  438. *
  439. * Causes all `.property` and `.include` assertions that follow in the chain
  440. * to ignore inherited properties.
  441. *
  442. * Object.prototype.b = 2;
  443. *
  444. * expect({a: 1}).to.have.own.property('a');
  445. * expect({a: 1}).to.have.property('b');
  446. * expect({a: 1}).to.not.have.own.property('b');
  447. *
  448. * expect({a: 1}).to.own.include({a: 1});
  449. * expect({a: 1}).to.include({b: 2}).but.not.own.include({b: 2});
  450. *
  451. * `.own` cannot be combined with `.nested`.
  452. *
  453. * @name own
  454. * @namespace BDD
  455. * @api public
  456. */
  457. Assertion.addProperty('own', function () {
  458. flag(this, 'own', true);
  459. });
  460. /**
  461. * ### .ordered
  462. *
  463. * Causes all `.members` assertions that follow in the chain to require that
  464. * members be in the same order.
  465. *
  466. * expect([1, 2]).to.have.ordered.members([1, 2])
  467. * .but.not.have.ordered.members([2, 1]);
  468. *
  469. * When `.include` and `.ordered` are combined, the ordering begins at the
  470. * start of both arrays.
  471. *
  472. * expect([1, 2, 3]).to.include.ordered.members([1, 2])
  473. * .but.not.include.ordered.members([2, 3]);
  474. *
  475. * @name ordered
  476. * @namespace BDD
  477. * @api public
  478. */
  479. Assertion.addProperty('ordered', function () {
  480. flag(this, 'ordered', true);
  481. });
  482. /**
  483. * ### .any
  484. *
  485. * Causes all `.keys` assertions that follow in the chain to only require that
  486. * the target have at least one of the given keys. This is the opposite of
  487. * `.all`, which requires that the target have all of the given keys.
  488. *
  489. * expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd');
  490. *
  491. * See the `.keys` doc for guidance on when to use `.any` or `.all`.
  492. *
  493. * @name any
  494. * @namespace BDD
  495. * @api public
  496. */
  497. Assertion.addProperty('any', function () {
  498. flag(this, 'any', true);
  499. flag(this, 'all', false);
  500. });
  501. /**
  502. * ### .all
  503. *
  504. * Causes all `.keys` assertions that follow in the chain to require that the
  505. * target have all of the given keys. This is the opposite of `.any`, which
  506. * only requires that the target have at least one of the given keys.
  507. *
  508. * expect({a: 1, b: 2}).to.have.all.keys('a', 'b');
  509. *
  510. * Note that `.all` is used by default when neither `.all` nor `.any` are
  511. * added earlier in the chain. However, it's often best to add `.all` anyway
  512. * because it improves readability.
  513. *
  514. * See the `.keys` doc for guidance on when to use `.any` or `.all`.
  515. *
  516. * @name all
  517. * @namespace BDD
  518. * @api public
  519. */
  520. Assertion.addProperty('all', function () {
  521. flag(this, 'all', true);
  522. flag(this, 'any', false);
  523. });
  524. /**
  525. * ### .a(type[, msg])
  526. *
  527. * Asserts that the target's type is equal to the given string `type`. Types
  528. * are case insensitive. See the `type-detect` project page for info on the
  529. * type detection algorithm: https://github.com/chaijs/type-detect.
  530. *
  531. * expect('foo').to.be.a('string');
  532. * expect({a: 1}).to.be.an('object');
  533. * expect(null).to.be.a('null');
  534. * expect(undefined).to.be.an('undefined');
  535. * expect(new Error).to.be.an('error');
  536. * expect(Promise.resolve()).to.be.a('promise');
  537. * expect(new Float32Array).to.be.a('float32array');
  538. * expect(Symbol()).to.be.a('symbol');
  539. *
  540. * `.a` supports objects that have a custom type set via `Symbol.toStringTag`.
  541. *
  542. * var myObj = {
  543. * [Symbol.toStringTag]: 'myCustomType'
  544. * };
  545. *
  546. * expect(myObj).to.be.a('myCustomType').but.not.an('object');
  547. *
  548. * It's often best to use `.a` to check a target's type before making more
  549. * assertions on the same target. That way, you avoid unexpected behavior from
  550. * any assertion that does different things based on the target's type.
  551. *
  552. * expect([1, 2, 3]).to.be.an('array').that.includes(2);
  553. * expect([]).to.be.an('array').that.is.empty;
  554. *
  555. * Add `.not` earlier in the chain to negate `.a`. However, it's often best to
  556. * assert that the target is the expected type, rather than asserting that it
  557. * isn't one of many unexpected types.
  558. *
  559. * expect('foo').to.be.a('string'); // Recommended
  560. * expect('foo').to.not.be.an('array'); // Not recommended
  561. *
  562. * `.a` accepts an optional `msg` argument which is a custom error message to
  563. * show when the assertion fails. The message can also be given as the second
  564. * argument to `expect`.
  565. *
  566. * expect(1).to.be.a('string', 'nooo why fail??');
  567. * expect(1, 'nooo why fail??').to.be.a('string');
  568. *
  569. * `.a` can also be used as a language chain to improve the readability of
  570. * your assertions.
  571. *
  572. * expect({b: 2}).to.have.a.property('b');
  573. *
  574. * The alias `.an` can be used interchangeably with `.a`.
  575. *
  576. * @name a
  577. * @alias an
  578. * @param {String} type
  579. * @param {String} msg _optional_
  580. * @namespace BDD
  581. * @api public
  582. */
  583. function an (type, msg) {
  584. if (msg) flag(this, 'message', msg);
  585. type = type.toLowerCase();
  586. var obj = flag(this, 'object')
  587. , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a ';
  588. this.assert(
  589. type === _.type(obj).toLowerCase()
  590. , 'expected #{this} to be ' + article + type
  591. , 'expected #{this} not to be ' + article + type
  592. );
  593. }
  594. Assertion.addChainableMethod('an', an);
  595. Assertion.addChainableMethod('a', an);
  596. /**
  597. * ### .include(val[, msg])
  598. *
  599. * When the target is a string, `.include` asserts that the given string `val`
  600. * is a substring of the target.
  601. *
  602. * expect('foobar').to.include('foo');
  603. *
  604. * When the target is an array, `.include` asserts that the given `val` is a
  605. * member of the target.
  606. *
  607. * expect([1, 2, 3]).to.include(2);
  608. *
  609. * When the target is an object, `.include` asserts that the given object
  610. * `val`'s properties are a subset of the target's properties.
  611. *
  612. * expect({a: 1, b: 2, c: 3}).to.include({a: 1, b: 2});
  613. *
  614. * When the target is a Set or WeakSet, `.include` asserts that the given `val` is a
  615. * member of the target. SameValueZero equality algorithm is used.
  616. *
  617. * expect(new Set([1, 2])).to.include(2);
  618. *
  619. * When the target is a Map, `.include` asserts that the given `val` is one of
  620. * the values of the target. SameValueZero equality algorithm is used.
  621. *
  622. * expect(new Map([['a', 1], ['b', 2]])).to.include(2);
  623. *
  624. * Because `.include` does different things based on the target's type, it's
  625. * important to check the target's type before using `.include`. See the `.a`
  626. * doc for info on testing a target's type.
  627. *
  628. * expect([1, 2, 3]).to.be.an('array').that.includes(2);
  629. *
  630. * By default, strict (`===`) equality is used to compare array members and
  631. * object properties. Add `.deep` earlier in the chain to use deep equality
  632. * instead (WeakSet targets are not supported). See the `deep-eql` project
  633. * page for info on the deep equality algorithm: https://github.com/chaijs/deep-eql.
  634. *
  635. * // Target array deeply (but not strictly) includes `{a: 1}`
  636. * expect([{a: 1}]).to.deep.include({a: 1});
  637. * expect([{a: 1}]).to.not.include({a: 1});
  638. *
  639. * // Target object deeply (but not strictly) includes `x: {a: 1}`
  640. * expect({x: {a: 1}}).to.deep.include({x: {a: 1}});
  641. * expect({x: {a: 1}}).to.not.include({x: {a: 1}});
  642. *
  643. * By default, all of the target's properties are searched when working with
  644. * objects. This includes properties that are inherited and/or non-enumerable.
  645. * Add `.own` earlier in the chain to exclude the target's inherited
  646. * properties from the search.
  647. *
  648. * Object.prototype.b = 2;
  649. *
  650. * expect({a: 1}).to.own.include({a: 1});
  651. * expect({a: 1}).to.include({b: 2}).but.not.own.include({b: 2});
  652. *
  653. * Note that a target object is always only searched for `val`'s own
  654. * enumerable properties.
  655. *
  656. * `.deep` and `.own` can be combined.
  657. *
  658. * expect({a: {b: 2}}).to.deep.own.include({a: {b: 2}});
  659. *
  660. * Add `.nested` earlier in the chain to enable dot- and bracket-notation when
  661. * referencing nested properties.
  662. *
  663. * expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'});
  664. *
  665. * If `.` or `[]` are part of an actual property name, they can be escaped by
  666. * adding two backslashes before them.
  667. *
  668. * expect({'.a': {'[b]': 2}}).to.nested.include({'\\.a.\\[b\\]': 2});
  669. *
  670. * `.deep` and `.nested` can be combined.
  671. *
  672. * expect({a: {b: [{c: 3}]}}).to.deep.nested.include({'a.b[0]': {c: 3}});
  673. *
  674. * `.own` and `.nested` cannot be combined.
  675. *
  676. * Add `.not` earlier in the chain to negate `.include`.
  677. *
  678. * expect('foobar').to.not.include('taco');
  679. * expect([1, 2, 3]).to.not.include(4);
  680. *
  681. * However, it's dangerous to negate `.include` when the target is an object.
  682. * The problem is that it creates uncertain expectations by asserting that the
  683. * target object doesn't have all of `val`'s key/value pairs but may or may
  684. * not have some of them. It's often best to identify the exact output that's
  685. * expected, and then write an assertion that only accepts that exact output.
  686. *
  687. * When the target object isn't even expected to have `val`'s keys, it's
  688. * often best to assert exactly that.
  689. *
  690. * expect({c: 3}).to.not.have.any.keys('a', 'b'); // Recommended
  691. * expect({c: 3}).to.not.include({a: 1, b: 2}); // Not recommended
  692. *
  693. * When the target object is expected to have `val`'s keys, it's often best to
  694. * assert that each of the properties has its expected value, rather than
  695. * asserting that each property doesn't have one of many unexpected values.
  696. *
  697. * expect({a: 3, b: 4}).to.include({a: 3, b: 4}); // Recommended
  698. * expect({a: 3, b: 4}).to.not.include({a: 1, b: 2}); // Not recommended
  699. *
  700. * `.include` accepts an optional `msg` argument which is a custom error
  701. * message to show when the assertion fails. The message can also be given as
  702. * the second argument to `expect`.
  703. *
  704. * expect([1, 2, 3]).to.include(4, 'nooo why fail??');
  705. * expect([1, 2, 3], 'nooo why fail??').to.include(4);
  706. *
  707. * `.include` can also be used as a language chain, causing all `.members` and
  708. * `.keys` assertions that follow in the chain to require the target to be a
  709. * superset of the expected set, rather than an identical set. Note that
  710. * `.members` ignores duplicates in the subset when `.include` is added.
  711. *
  712. * // Target object's keys are a superset of ['a', 'b'] but not identical
  713. * expect({a: 1, b: 2, c: 3}).to.include.all.keys('a', 'b');
  714. * expect({a: 1, b: 2, c: 3}).to.not.have.all.keys('a', 'b');
  715. *
  716. * // Target array is a superset of [1, 2] but not identical
  717. * expect([1, 2, 3]).to.include.members([1, 2]);
  718. * expect([1, 2, 3]).to.not.have.members([1, 2]);
  719. *
  720. * // Duplicates in the subset are ignored
  721. * expect([1, 2, 3]).to.include.members([1, 2, 2, 2]);
  722. *
  723. * Note that adding `.any` earlier in the chain causes the `.keys` assertion
  724. * to ignore `.include`.
  725. *
  726. * // Both assertions are identical
  727. * expect({a: 1}).to.include.any.keys('a', 'b');
  728. * expect({a: 1}).to.have.any.keys('a', 'b');
  729. *
  730. * The aliases `.includes`, `.contain`, and `.contains` can be used
  731. * interchangeably with `.include`.
  732. *
  733. * @name include
  734. * @alias contain
  735. * @alias includes
  736. * @alias contains
  737. * @param {Mixed} val
  738. * @param {String} msg _optional_
  739. * @namespace BDD
  740. * @api public
  741. */
  742. function SameValueZero(a, b) {
  743. return (_.isNaN(a) && _.isNaN(b)) || a === b;
  744. }
  745. function includeChainingBehavior () {
  746. flag(this, 'contains', true);
  747. }
  748. function include (val, msg) {
  749. if (msg) flag(this, 'message', msg);
  750. var obj = flag(this, 'object')
  751. , objType = _.type(obj).toLowerCase()
  752. , flagMsg = flag(this, 'message')
  753. , negate = flag(this, 'negate')
  754. , ssfi = flag(this, 'ssfi')
  755. , isDeep = flag(this, 'deep')
  756. , descriptor = isDeep ? 'deep ' : '';
  757. flagMsg = flagMsg ? flagMsg + ': ' : '';
  758. var included = false;
  759. switch (objType) {
  760. case 'string':
  761. included = obj.indexOf(val) !== -1;
  762. break;
  763. case 'weakset':
  764. if (isDeep) {
  765. throw new AssertionError(
  766. flagMsg + 'unable to use .deep.include with WeakSet',
  767. undefined,
  768. ssfi
  769. );
  770. }
  771. included = obj.has(val);
  772. break;
  773. case 'map':
  774. var isEql = isDeep ? _.eql : SameValueZero;
  775. obj.forEach(function (item) {
  776. included = included || isEql(item, val);
  777. });
  778. break;
  779. case 'set':
  780. if (isDeep) {
  781. obj.forEach(function (item) {
  782. included = included || _.eql(item, val);
  783. });
  784. } else {
  785. included = obj.has(val);
  786. }
  787. break;
  788. case 'array':
  789. if (isDeep) {
  790. included = obj.some(function (item) {
  791. return _.eql(item, val);
  792. })
  793. } else {
  794. included = obj.indexOf(val) !== -1;
  795. }
  796. break;
  797. default:
  798. // This block is for asserting a subset of properties in an object.
  799. // `_.expectTypes` isn't used here because `.include` should work with
  800. // objects with a custom `@@toStringTag`.
  801. if (val !== Object(val)) {
  802. throw new AssertionError(
  803. flagMsg + 'object tested must be an array, a map, an object,'
  804. + ' a set, a string, or a weakset, but ' + objType + ' given',
  805. undefined,
  806. ssfi
  807. );
  808. }
  809. var props = Object.keys(val)
  810. , firstErr = null
  811. , numErrs = 0;
  812. props.forEach(function (prop) {
  813. var propAssertion = new Assertion(obj);
  814. _.transferFlags(this, propAssertion, true);
  815. flag(propAssertion, 'lockSsfi', true);
  816. if (!negate || props.length === 1) {
  817. propAssertion.property(prop, val[prop]);
  818. return;
  819. }
  820. try {
  821. propAssertion.property(prop, val[prop]);
  822. } catch (err) {
  823. if (!_.checkError.compatibleConstructor(err, AssertionError)) {
  824. throw err;
  825. }
  826. if (firstErr === null) firstErr = err;
  827. numErrs++;
  828. }
  829. }, this);
  830. // When validating .not.include with multiple properties, we only want
  831. // to throw an assertion error if all of the properties are included,
  832. // in which case we throw the first property assertion error that we
  833. // encountered.
  834. if (negate && props.length > 1 && numErrs === props.length) {
  835. throw firstErr;
  836. }
  837. return;
  838. }
  839. // Assert inclusion in collection or substring in a string.
  840. this.assert(
  841. included
  842. , 'expected #{this} to ' + descriptor + 'include ' + _.inspect(val)
  843. , 'expected #{this} to not ' + descriptor + 'include ' + _.inspect(val));
  844. }
  845. Assertion.addChainableMethod('include', include, includeChainingBehavior);
  846. Assertion.addChainableMethod('contain', include, includeChainingBehavior);
  847. Assertion.addChainableMethod('contains', include, includeChainingBehavior);
  848. Assertion.addChainableMethod('includes', include, includeChainingBehavior);
  849. /**
  850. * ### .ok
  851. *
  852. * Asserts that the target is a truthy value (considered `true` in boolean context).
  853. * However, it's often best to assert that the target is strictly (`===`) or
  854. * deeply equal to its expected value.
  855. *
  856. * expect(1).to.equal(1); // Recommended
  857. * expect(1).to.be.ok; // Not recommended
  858. *
  859. * expect(true).to.be.true; // Recommended
  860. * expect(true).to.be.ok; // Not recommended
  861. *
  862. * Add `.not` earlier in the chain to negate `.ok`.
  863. *
  864. * expect(0).to.equal(0); // Recommended
  865. * expect(0).to.not.be.ok; // Not recommended
  866. *
  867. * expect(false).to.be.false; // Recommended
  868. * expect(false).to.not.be.ok; // Not recommended
  869. *
  870. * expect(null).to.be.null; // Recommended
  871. * expect(null).to.not.be.ok; // Not recommended
  872. *
  873. * expect(undefined).to.be.undefined; // Recommended
  874. * expect(undefined).to.not.be.ok; // Not recommended
  875. *
  876. * A custom error message can be given as the second argument to `expect`.
  877. *
  878. * expect(false, 'nooo why fail??').to.be.ok;
  879. *
  880. * @name ok
  881. * @namespace BDD
  882. * @api public
  883. */
  884. Assertion.addProperty('ok', function () {
  885. this.assert(
  886. flag(this, 'object')
  887. , 'expected #{this} to be truthy'
  888. , 'expected #{this} to be falsy');
  889. });
  890. /**
  891. * ### .true
  892. *
  893. * Asserts that the target is strictly (`===`) equal to `true`.
  894. *
  895. * expect(true).to.be.true;
  896. *
  897. * Add `.not` earlier in the chain to negate `.true`. However, it's often best
  898. * to assert that the target is equal to its expected value, rather than not
  899. * equal to `true`.
  900. *
  901. * expect(false).to.be.false; // Recommended
  902. * expect(false).to.not.be.true; // Not recommended
  903. *
  904. * expect(1).to.equal(1); // Recommended
  905. * expect(1).to.not.be.true; // Not recommended
  906. *
  907. * A custom error message can be given as the second argument to `expect`.
  908. *
  909. * expect(false, 'nooo why fail??').to.be.true;
  910. *
  911. * @name true
  912. * @namespace BDD
  913. * @api public
  914. */
  915. Assertion.addProperty('true', function () {
  916. this.assert(
  917. true === flag(this, 'object')
  918. , 'expected #{this} to be true'
  919. , 'expected #{this} to be false'
  920. , flag(this, 'negate') ? false : true
  921. );
  922. });
  923. /**
  924. * ### .false
  925. *
  926. * Asserts that the target is strictly (`===`) equal to `false`.
  927. *
  928. * expect(false).to.be.false;
  929. *
  930. * Add `.not` earlier in the chain to negate `.false`. However, it's often
  931. * best to assert that the target is equal to its expected value, rather than
  932. * not equal to `false`.
  933. *
  934. * expect(true).to.be.true; // Recommended
  935. * expect(true).to.not.be.false; // Not recommended
  936. *
  937. * expect(1).to.equal(1); // Recommended
  938. * expect(1).to.not.be.false; // Not recommended
  939. *
  940. * A custom error message can be given as the second argument to `expect`.
  941. *
  942. * expect(true, 'nooo why fail??').to.be.false;
  943. *
  944. * @name false
  945. * @namespace BDD
  946. * @api public
  947. */
  948. Assertion.addProperty('false', function () {
  949. this.assert(
  950. false === flag(this, 'object')
  951. , 'expected #{this} to be false'
  952. , 'expected #{this} to be true'
  953. , flag(this, 'negate') ? true : false
  954. );
  955. });
  956. /**
  957. * ### .null
  958. *
  959. * Asserts that the target is strictly (`===`) equal to `null`.
  960. *
  961. * expect(null).to.be.null;
  962. *
  963. * Add `.not` earlier in the chain to negate `.null`. However, it's often best
  964. * to assert that the target is equal to its expected value, rather than not
  965. * equal to `null`.
  966. *
  967. * expect(1).to.equal(1); // Recommended
  968. * expect(1).to.not.be.null; // Not recommended
  969. *
  970. * A custom error message can be given as the second argument to `expect`.
  971. *
  972. * expect(42, 'nooo why fail??').to.be.null;
  973. *
  974. * @name null
  975. * @namespace BDD
  976. * @api public
  977. */
  978. Assertion.addProperty('null', function () {
  979. this.assert(
  980. null === flag(this, 'object')
  981. , 'expected #{this} to be null'
  982. , 'expected #{this} not to be null'
  983. );
  984. });
  985. /**
  986. * ### .undefined
  987. *
  988. * Asserts that the target is strictly (`===`) equal to `undefined`.
  989. *
  990. * expect(undefined).to.be.undefined;
  991. *
  992. * Add `.not` earlier in the chain to negate `.undefined`. However, it's often
  993. * best to assert that the target is equal to its expected value, rather than
  994. * not equal to `undefined`.
  995. *
  996. * expect(1).to.equal(1); // Recommended
  997. * expect(1).to.not.be.undefined; // Not recommended
  998. *
  999. * A custom error message can be given as the second argument to `expect`.
  1000. *
  1001. * expect(42, 'nooo why fail??').to.be.undefined;
  1002. *
  1003. * @name undefined
  1004. * @namespace BDD
  1005. * @api public
  1006. */
  1007. Assertion.addProperty('undefined', function () {
  1008. this.assert(
  1009. undefined === flag(this, 'object')
  1010. , 'expected #{this} to be undefined'
  1011. , 'expected #{this} not to be undefined'
  1012. );
  1013. });
  1014. /**
  1015. * ### .NaN
  1016. *
  1017. * Asserts that the target is exactly `NaN`.
  1018. *
  1019. * expect(NaN).to.be.NaN;
  1020. *
  1021. * Add `.not` earlier in the chain to negate `.NaN`. However, it's often best
  1022. * to assert that the target is equal to its expected value, rather than not
  1023. * equal to `NaN`.
  1024. *
  1025. * expect('foo').to.equal('foo'); // Recommended
  1026. * expect('foo').to.not.be.NaN; // Not recommended
  1027. *
  1028. * A custom error message can be given as the second argument to `expect`.
  1029. *
  1030. * expect(42, 'nooo why fail??').to.be.NaN;
  1031. *
  1032. * @name NaN
  1033. * @namespace BDD
  1034. * @api public
  1035. */
  1036. Assertion.addProperty('NaN', function () {
  1037. this.assert(
  1038. _.isNaN(flag(this, 'object'))
  1039. , 'expected #{this} to be NaN'
  1040. , 'expected #{this} not to be NaN'
  1041. );
  1042. });
  1043. /**
  1044. * ### .exist
  1045. *
  1046. * Asserts that the target is not strictly (`===`) equal to either `null` or
  1047. * `undefined`. However, it's often best to assert that the target is equal to
  1048. * its expected value.
  1049. *
  1050. * expect(1).to.equal(1); // Recommended
  1051. * expect(1).to.exist; // Not recommended
  1052. *
  1053. * expect(0).to.equal(0); // Recommended
  1054. * expect(0).to.exist; // Not recommended
  1055. *
  1056. * Add `.not` earlier in the chain to negate `.exist`.
  1057. *
  1058. * expect(null).to.be.null; // Recommended
  1059. * expect(null).to.not.exist; // Not recommended
  1060. *
  1061. * expect(undefined).to.be.undefined; // Recommended
  1062. * expect(undefined).to.not.exist; // Not recommended
  1063. *
  1064. * A custom error message can be given as the second argument to `expect`.
  1065. *
  1066. * expect(null, 'nooo why fail??').to.exist;
  1067. *
  1068. * @name exist
  1069. * @namespace BDD
  1070. * @api public
  1071. */
  1072. Assertion.addProperty('exist', function () {
  1073. var val = flag(this, 'object');
  1074. this.assert(
  1075. val !== null && val !== undefined
  1076. , 'expected #{this} to exist'
  1077. , 'expected #{this} to not exist'
  1078. );
  1079. });
  1080. /**
  1081. * ### .empty
  1082. *
  1083. * When the target is a string or array, `.empty` asserts that the target's
  1084. * `length` property is strictly (`===`) equal to `0`.
  1085. *
  1086. * expect([]).to.be.empty;
  1087. * expect('').to.be.empty;
  1088. *
  1089. * When the target is a map or set, `.empty` asserts that the target's `size`
  1090. * property is strictly equal to `0`.
  1091. *
  1092. * expect(new Set()).to.be.empty;
  1093. * expect(new Map()).to.be.empty;
  1094. *
  1095. * When the target is a non-function object, `.empty` asserts that the target
  1096. * doesn't have any own enumerable properties. Properties with Symbol-based
  1097. * keys are excluded from the count.
  1098. *
  1099. * expect({}).to.be.empty;
  1100. *
  1101. * Because `.empty` does different things based on the target's type, it's
  1102. * important to check the target's type before using `.empty`. See the `.a`
  1103. * doc for info on testing a target's type.
  1104. *
  1105. * expect([]).to.be.an('array').that.is.empty;
  1106. *
  1107. * Add `.not` earlier in the chain to negate `.empty`. However, it's often
  1108. * best to assert that the target contains its expected number of values,
  1109. * rather than asserting that it's not empty.
  1110. *
  1111. * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended
  1112. * expect([1, 2, 3]).to.not.be.empty; // Not recommended
  1113. *
  1114. * expect(new Set([1, 2, 3])).to.have.property('size', 3); // Recommended
  1115. * expect(new Set([1, 2, 3])).to.not.be.empty; // Not recommended
  1116. *
  1117. * expect(Object.keys({a: 1})).to.have.lengthOf(1); // Recommended
  1118. * expect({a: 1}).to.not.be.empty; // Not recommended
  1119. *
  1120. * A custom error message can be given as the second argument to `expect`.
  1121. *
  1122. * expect([1, 2, 3], 'nooo why fail??').to.be.empty;
  1123. *
  1124. * @name empty
  1125. * @namespace BDD
  1126. * @api public
  1127. */
  1128. Assertion.addProperty('empty', function () {
  1129. var val = flag(this, 'object')
  1130. , ssfi = flag(this, 'ssfi')
  1131. , flagMsg = flag(this, 'message')
  1132. , itemsCount;
  1133. flagMsg = flagMsg ? flagMsg + ': ' : '';
  1134. switch (_.type(val).toLowerCase()) {
  1135. case 'array':
  1136. case 'string':
  1137. itemsCount = val.length;
  1138. break;
  1139. case 'map':
  1140. case 'set':
  1141. itemsCount = val.size;
  1142. break;
  1143. case 'weakmap':
  1144. case 'weakset':
  1145. throw new AssertionError(
  1146. flagMsg + '.empty was passed a weak collection',
  1147. undefined,
  1148. ssfi
  1149. );
  1150. case 'function':
  1151. var msg = flagMsg + '.empty was passed a function ' + _.getName(val);
  1152. throw new AssertionError(msg.trim(), undefined, ssfi);
  1153. default:
  1154. if (val !== Object(val)) {
  1155. throw new AssertionError(
  1156. flagMsg + '.empty was passed non-string primitive ' + _.inspect(val),
  1157. undefined,
  1158. ssfi
  1159. );
  1160. }
  1161. itemsCount = Object.keys(val).length;
  1162. }
  1163. this.assert(
  1164. 0 === itemsCount
  1165. , 'expected #{this} to be empty'
  1166. , 'expected #{this} not to be empty'
  1167. );
  1168. });
  1169. /**
  1170. * ### .arguments
  1171. *
  1172. * Asserts that the target is an `arguments` object.
  1173. *
  1174. * function test () {
  1175. * expect(arguments).to.be.arguments;
  1176. * }
  1177. *
  1178. * test();
  1179. *
  1180. * Add `.not` earlier in the chain to negate `.arguments`. However, it's often
  1181. * best to assert which type the target is expected to be, rather than
  1182. * asserting that its not an `arguments` object.
  1183. *
  1184. * expect('foo').to.be.a('string'); // Recommended
  1185. * expect('foo').to.not.be.arguments; // Not recommended
  1186. *
  1187. * A custom error message can be given as the second argument to `expect`.
  1188. *
  1189. * expect({}, 'nooo why fail??').to.be.arguments;
  1190. *
  1191. * The alias `.Arguments` can be used interchangeably with `.arguments`.
  1192. *
  1193. * @name arguments
  1194. * @alias Arguments
  1195. * @namespace BDD
  1196. * @api public
  1197. */
  1198. function checkArguments () {
  1199. var obj = flag(this, 'object')
  1200. , type = _.type(obj);
  1201. this.assert(
  1202. 'Arguments' === type
  1203. , 'expected #{this} to be arguments but got ' + type
  1204. , 'expected #{this} to not be arguments'
  1205. );
  1206. }
  1207. Assertion.addProperty('arguments', checkArguments);
  1208. Assertion.addProperty('Arguments', checkArguments);
  1209. /**
  1210. * ### .equal(val[, msg])
  1211. *
  1212. * Asserts that the target is strictly (`===`) equal to the given `val`.
  1213. *
  1214. * expect(1).to.equal(1);
  1215. * expect('foo').to.equal('foo');
  1216. *
  1217. * Add `.deep` earlier in the chain to use deep equality instead. See the
  1218. * `deep-eql` project page for info on the deep equality algorithm:
  1219. * https://github.com/chaijs/deep-eql.
  1220. *
  1221. * // Target object deeply (but not strictly) equals `{a: 1}`
  1222. * expect({a: 1}).to.deep.equal({a: 1});
  1223. * expect({a: 1}).to.not.equal({a: 1});
  1224. *
  1225. * // Target array deeply (but not strictly) equals `[1, 2]`
  1226. * expect([1, 2]).to.deep.equal([1, 2]);
  1227. * expect([1, 2]).to.not.equal([1, 2]);
  1228. *
  1229. * Add `.not` earlier in the chain to negate `.equal`. However, it's often
  1230. * best to assert that the target is equal to its expected value, rather than
  1231. * not equal to one of countless unexpected values.
  1232. *
  1233. * expect(1).to.equal(1); // Recommended
  1234. * expect(1).to.not.equal(2); // Not recommended
  1235. *
  1236. * `.equal` accepts an optional `msg` argument which is a custom error message
  1237. * to show when the assertion fails. The message can also be given as the
  1238. * second argument to `expect`.
  1239. *
  1240. * expect(1).to.equal(2, 'nooo why fail??');
  1241. * expect(1, 'nooo why fail??').to.equal(2);
  1242. *
  1243. * The aliases `.equals` and `eq` can be used interchangeably with `.equal`.
  1244. *
  1245. * @name equal
  1246. * @alias equals
  1247. * @alias eq
  1248. * @param {Mixed} val
  1249. * @param {String} msg _optional_
  1250. * @namespace BDD
  1251. * @api public
  1252. */
  1253. function assertEqual (val, msg) {
  1254. if (msg) flag(this, 'message', msg);
  1255. var obj = flag(this, 'object');
  1256. if (flag(this, 'deep')) {
  1257. var prevLockSsfi = flag(this, 'lockSsfi');
  1258. flag(this, 'lockSsfi', true);
  1259. this.eql(val);
  1260. flag(this, 'lockSsfi', prevLockSsfi);
  1261. } else {
  1262. this.assert(
  1263. val === obj
  1264. , 'expected #{this} to equal #{exp}'
  1265. , 'expected #{this} to not equal #{exp}'
  1266. , val
  1267. , this._obj
  1268. , true
  1269. );
  1270. }
  1271. }
  1272. Assertion.addMethod('equal', assertEqual);
  1273. Assertion.addMethod('equals', assertEqual);
  1274. Assertion.addMethod('eq', assertEqual);
  1275. /**
  1276. * ### .eql(obj[, msg])
  1277. *
  1278. * Asserts that the target is deeply equal to the given `obj`. See the
  1279. * `deep-eql` project page for info on the deep equality algorithm:
  1280. * https://github.com/chaijs/deep-eql.
  1281. *
  1282. * // Target object is deeply (but not strictly) equal to {a: 1}
  1283. * expect({a: 1}).to.eql({a: 1}).but.not.equal({a: 1});
  1284. *
  1285. * // Target array is deeply (but not strictly) equal to [1, 2]
  1286. * expect([1, 2]).to.eql([1, 2]).but.not.equal([1, 2]);
  1287. *
  1288. * Add `.not` earlier in the chain to negate `.eql`. However, it's often best
  1289. * to assert that the target is deeply equal to its expected value, rather
  1290. * than not deeply equal to one of countless unexpected values.
  1291. *
  1292. * expect({a: 1}).to.eql({a: 1}); // Recommended
  1293. * expect({a: 1}).to.not.eql({b: 2}); // Not recommended
  1294. *
  1295. * `.eql` accepts an optional `msg` argument which is a custom error message
  1296. * to show when the assertion fails. The message can also be given as the
  1297. * second argument to `expect`.
  1298. *
  1299. * expect({a: 1}).to.eql({b: 2}, 'nooo why fail??');
  1300. * expect({a: 1}, 'nooo why fail??').to.eql({b: 2});
  1301. *
  1302. * The alias `.eqls` can be used interchangeably with `.eql`.
  1303. *
  1304. * The `.deep.equal` assertion is almost identical to `.eql` but with one
  1305. * difference: `.deep.equal` causes deep equality comparisons to also be used
  1306. * for any other assertions that follow in the chain.
  1307. *
  1308. * @name eql
  1309. * @alias eqls
  1310. * @param {Mixed} obj
  1311. * @param {String} msg _optional_
  1312. * @namespace BDD
  1313. * @api public
  1314. */
  1315. function assertEql(obj, msg) {
  1316. if (msg) flag(this, 'message', msg);
  1317. this.assert(
  1318. _.eql(obj, flag(this, 'object'))
  1319. , 'expected #{this} to deeply equal #{exp}'
  1320. , 'expected #{this} to not deeply equal #{exp}'
  1321. , obj
  1322. , this._obj
  1323. , true
  1324. );
  1325. }
  1326. Assertion.addMethod('eql', assertEql);
  1327. Assertion.addMethod('eqls', assertEql);
  1328. /**
  1329. * ### .above(n[, msg])
  1330. *
  1331. * Asserts that the target is a number or a date greater than the given number or date `n` respectively.
  1332. * However, it's often best to assert that the target is equal to its expected
  1333. * value.
  1334. *
  1335. * expect(2).to.equal(2); // Recommended
  1336. * expect(2).to.be.above(1); // Not recommended
  1337. *
  1338. * Add `.lengthOf` earlier in the chain to assert that the target's `length`
  1339. * or `size` is greater than the given number `n`.
  1340. *
  1341. * expect('foo').to.have.lengthOf(3); // Recommended
  1342. * expect('foo').to.have.lengthOf.above(2); // Not recommended
  1343. *
  1344. * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended
  1345. * expect([1, 2, 3]).to.have.lengthOf.above(2); // Not recommended
  1346. *
  1347. * Add `.not` earlier in the chain to negate `.above`.
  1348. *
  1349. * expect(2).to.equal(2); // Recommended
  1350. * expect(1).to.not.be.above(2); // Not recommended
  1351. *
  1352. * `.above` accepts an optional `msg` argument which is a custom error message
  1353. * to show when the assertion fails. The message can also be given as the
  1354. * second argument to `expect`.
  1355. *
  1356. * expect(1).to.be.above(2, 'nooo why fail??');
  1357. * expect(1, 'nooo why fail??').to.be.above(2);
  1358. *
  1359. * The aliases `.gt` and `.greaterThan` can be used interchangeably with
  1360. * `.above`.
  1361. *
  1362. * @name above
  1363. * @alias gt
  1364. * @alias greaterThan
  1365. * @param {Number} n
  1366. * @param {String} msg _optional_
  1367. * @namespace BDD
  1368. * @api public
  1369. */
  1370. function assertAbove (n, msg) {
  1371. if (msg) flag(this, 'message', msg);
  1372. var obj = flag(this, 'object')
  1373. , doLength = flag(this, 'doLength')
  1374. , flagMsg = flag(this, 'message')
  1375. , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
  1376. , ssfi = flag(this, 'ssfi')
  1377. , objType = _.type(obj).toLowerCase()
  1378. , nType = _.type(n).toLowerCase()
  1379. , errorMessage
  1380. , shouldThrow = true;
  1381. if (doLength && objType !== 'map' && objType !== 'set') {
  1382. new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
  1383. }
  1384. if (!doLength && (objType === 'date' && nType !== 'date')) {
  1385. errorMessage = msgPrefix + 'the argument to above must be a date';
  1386. } else if (nType !== 'number' && (doLength || objType === 'number')) {
  1387. errorMessage = msgPrefix + 'the argument to above must be a number';
  1388. } else if (!doLength && (objType !== 'date' && objType !== 'number')) {
  1389. var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
  1390. errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
  1391. } else {
  1392. shouldThrow = false;
  1393. }
  1394. if (shouldThrow) {
  1395. throw new AssertionError(errorMessage, undefined, ssfi);
  1396. }
  1397. if (doLength) {
  1398. var descriptor = 'length'
  1399. , itemsCount;
  1400. if (objType === 'map' || objType === 'set') {
  1401. descriptor = 'size';
  1402. itemsCount = obj.size;
  1403. } else {
  1404. itemsCount = obj.length;
  1405. }
  1406. this.assert(
  1407. itemsCount > n
  1408. , 'expected #{this} to have a ' + descriptor + ' above #{exp} but got #{act}'
  1409. , 'expected #{this} to not have a ' + descriptor + ' above #{exp}'
  1410. , n
  1411. , itemsCount
  1412. );
  1413. } else {
  1414. this.assert(
  1415. obj > n
  1416. , 'expected #{this} to be above #{exp}'
  1417. , 'expected #{this} to be at most #{exp}'
  1418. , n
  1419. );
  1420. }
  1421. }
  1422. Assertion.addMethod('above', assertAbove);
  1423. Assertion.addMethod('gt', assertAbove);
  1424. Assertion.addMethod('greaterThan', assertAbove);
  1425. /**
  1426. * ### .least(n[, msg])
  1427. *
  1428. * Asserts that the target is a number or a date greater than or equal to the given
  1429. * number or date `n` respectively. However, it's often best to assert that the target is equal to
  1430. * its expected value.
  1431. *
  1432. * expect(2).to.equal(2); // Recommended
  1433. * expect(2).to.be.at.least(1); // Not recommended
  1434. * expect(2).to.be.at.least(2); // Not recommended
  1435. *
  1436. * Add `.lengthOf` earlier in the chain to assert that the target's `length`
  1437. * or `size` is greater than or equal to the given number `n`.
  1438. *
  1439. * expect('foo').to.have.lengthOf(3); // Recommended
  1440. * expect('foo').to.have.lengthOf.at.least(2); // Not recommended
  1441. *
  1442. * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended
  1443. * expect([1, 2, 3]).to.have.lengthOf.at.least(2); // Not recommended
  1444. *
  1445. * Add `.not` earlier in the chain to negate `.least`.
  1446. *
  1447. * expect(1).to.equal(1); // Recommended
  1448. * expect(1).to.not.be.at.least(2); // Not recommended
  1449. *
  1450. * `.least` accepts an optional `msg` argument which is a custom error message
  1451. * to show when the assertion fails. The message can also be given as the
  1452. * second argument to `expect`.
  1453. *
  1454. * expect(1).to.be.at.least(2, 'nooo why fail??');
  1455. * expect(1, 'nooo why fail??').to.be.at.least(2);
  1456. *
  1457. * The alias `.gte` can be used interchangeably with `.least`.
  1458. *
  1459. * @name least
  1460. * @alias gte
  1461. * @param {Number} n
  1462. * @param {String} msg _optional_
  1463. * @namespace BDD
  1464. * @api public
  1465. */
  1466. function assertLeast (n, msg) {
  1467. if (msg) flag(this, 'message', msg);
  1468. var obj = flag(this, 'object')
  1469. , doLength = flag(this, 'doLength')
  1470. , flagMsg = flag(this, 'message')
  1471. , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
  1472. , ssfi = flag(this, 'ssfi')
  1473. , objType = _.type(obj).toLowerCase()
  1474. , nType = _.type(n).toLowerCase()
  1475. , errorMessage
  1476. , shouldThrow = true;
  1477. if (doLength && objType !== 'map' && objType !== 'set') {
  1478. new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
  1479. }
  1480. if (!doLength && (objType === 'date' && nType !== 'date')) {
  1481. errorMessage = msgPrefix + 'the argument to least must be a date';
  1482. } else if (nType !== 'number' && (doLength || objType === 'number')) {
  1483. errorMessage = msgPrefix + 'the argument to least must be a number';
  1484. } else if (!doLength && (objType !== 'date' && objType !== 'number')) {
  1485. var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
  1486. errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
  1487. } else {
  1488. shouldThrow = false;
  1489. }
  1490. if (shouldThrow) {
  1491. throw new AssertionError(errorMessage, undefined, ssfi);
  1492. }
  1493. if (doLength) {
  1494. var descriptor = 'length'
  1495. , itemsCount;
  1496. if (objType === 'map' || objType === 'set') {
  1497. descriptor = 'size';
  1498. itemsCount = obj.size;
  1499. } else {
  1500. itemsCount = obj.length;
  1501. }
  1502. this.assert(
  1503. itemsCount >= n
  1504. , 'expected #{this} to have a ' + descriptor + ' at least #{exp} but got #{act}'
  1505. , 'expected #{this} to have a ' + descriptor + ' below #{exp}'
  1506. , n
  1507. , itemsCount
  1508. );
  1509. } else {
  1510. this.assert(
  1511. obj >= n
  1512. , 'expected #{this} to be at least #{exp}'
  1513. , 'expected #{this} to be below #{exp}'
  1514. , n
  1515. );
  1516. }
  1517. }
  1518. Assertion.addMethod('least', assertLeast);
  1519. Assertion.addMethod('gte', assertLeast);
  1520. /**
  1521. * ### .below(n[, msg])
  1522. *
  1523. * Asserts that the target is a number or a date less than the given number or date `n` respectively.
  1524. * However, it's often best to assert that the target is equal to its expected
  1525. * value.
  1526. *
  1527. * expect(1).to.equal(1); // Recommended
  1528. * expect(1).to.be.below(2); // Not recommended
  1529. *
  1530. * Add `.lengthOf` earlier in the chain to assert that the target's `length`
  1531. * or `size` is less than the given number `n`.
  1532. *
  1533. * expect('foo').to.have.lengthOf(3); // Recommended
  1534. * expect('foo').to.have.lengthOf.below(4); // Not recommended
  1535. *
  1536. * expect([1, 2, 3]).to.have.length(3); // Recommended
  1537. * expect([1, 2, 3]).to.have.lengthOf.below(4); // Not recommended
  1538. *
  1539. * Add `.not` earlier in the chain to negate `.below`.
  1540. *
  1541. * expect(2).to.equal(2); // Recommended
  1542. * expect(2).to.not.be.below(1); // Not recommended
  1543. *
  1544. * `.below` accepts an optional `msg` argument which is a custom error message
  1545. * to show when the assertion fails. The message can also be given as the
  1546. * second argument to `expect`.
  1547. *
  1548. * expect(2).to.be.below(1, 'nooo why fail??');
  1549. * expect(2, 'nooo why fail??').to.be.below(1);
  1550. *
  1551. * The aliases `.lt` and `.lessThan` can be used interchangeably with
  1552. * `.below`.
  1553. *
  1554. * @name below
  1555. * @alias lt
  1556. * @alias lessThan
  1557. * @param {Number} n
  1558. * @param {String} msg _optional_
  1559. * @namespace BDD
  1560. * @api public
  1561. */
  1562. function assertBelow (n, msg) {
  1563. if (msg) flag(this, 'message', msg);
  1564. var obj = flag(this, 'object')
  1565. , doLength = flag(this, 'doLength')
  1566. , flagMsg = flag(this, 'message')
  1567. , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
  1568. , ssfi = flag(this, 'ssfi')
  1569. , objType = _.type(obj).toLowerCase()
  1570. , nType = _.type(n).toLowerCase()
  1571. , errorMessage
  1572. , shouldThrow = true;
  1573. if (doLength && objType !== 'map' && objType !== 'set') {
  1574. new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
  1575. }
  1576. if (!doLength && (objType === 'date' && nType !== 'date')) {
  1577. errorMessage = msgPrefix + 'the argument to below must be a date';
  1578. } else if (nType !== 'number' && (doLength || objType === 'number')) {
  1579. errorMessage = msgPrefix + 'the argument to below must be a number';
  1580. } else if (!doLength && (objType !== 'date' && objType !== 'number')) {
  1581. var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
  1582. errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
  1583. } else {
  1584. shouldThrow = false;
  1585. }
  1586. if (shouldThrow) {
  1587. throw new AssertionError(errorMessage, undefined, ssfi);
  1588. }
  1589. if (doLength) {
  1590. var descriptor = 'length'
  1591. , itemsCount;
  1592. if (objType === 'map' || objType === 'set') {
  1593. descriptor = 'size';
  1594. itemsCount = obj.size;
  1595. } else {
  1596. itemsCount = obj.length;
  1597. }
  1598. this.assert(
  1599. itemsCount < n
  1600. , 'expected #{this} to have a ' + descriptor + ' below #{exp} but got #{act}'
  1601. , 'expected #{this} to not have a ' + descriptor + ' below #{exp}'
  1602. , n
  1603. , itemsCount
  1604. );
  1605. } else {
  1606. this.assert(
  1607. obj < n
  1608. , 'expected #{this} to be below #{exp}'
  1609. , 'expected #{this} to be at least #{exp}'
  1610. , n
  1611. );
  1612. }
  1613. }
  1614. Assertion.addMethod('below', assertBelow);
  1615. Assertion.addMethod('lt', assertBelow);
  1616. Assertion.addMethod('lessThan', assertBelow);
  1617. /**
  1618. * ### .most(n[, msg])
  1619. *
  1620. * Asserts that the target is a number or a date less than or equal to the given number
  1621. * or date `n` respectively. However, it's often best to assert that the target is equal to its
  1622. * expected value.
  1623. *
  1624. * expect(1).to.equal(1); // Recommended
  1625. * expect(1).to.be.at.most(2); // Not recommended
  1626. * expect(1).to.be.at.most(1); // Not recommended
  1627. *
  1628. * Add `.lengthOf` earlier in the chain to assert that the target's `length`
  1629. * or `size` is less than or equal to the given number `n`.
  1630. *
  1631. * expect('foo').to.have.lengthOf(3); // Recommended
  1632. * expect('foo').to.have.lengthOf.at.most(4); // Not recommended
  1633. *
  1634. * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended
  1635. * expect([1, 2, 3]).to.have.lengthOf.at.most(4); // Not recommended
  1636. *
  1637. * Add `.not` earlier in the chain to negate `.most`.
  1638. *
  1639. * expect(2).to.equal(2); // Recommended
  1640. * expect(2).to.not.be.at.most(1); // Not recommended
  1641. *
  1642. * `.most` accepts an optional `msg` argument which is a custom error message
  1643. * to show when the assertion fails. The message can also be given as the
  1644. * second argument to `expect`.
  1645. *
  1646. * expect(2).to.be.at.most(1, 'nooo why fail??');
  1647. * expect(2, 'nooo why fail??').to.be.at.most(1);
  1648. *
  1649. * The alias `.lte` can be used interchangeably with `.most`.
  1650. *
  1651. * @name most
  1652. * @alias lte
  1653. * @param {Number} n
  1654. * @param {String} msg _optional_
  1655. * @namespace BDD
  1656. * @api public
  1657. */
  1658. function assertMost (n, msg) {
  1659. if (msg) flag(this, 'message', msg);
  1660. var obj = flag(this, 'object')
  1661. , doLength = flag(this, 'doLength')
  1662. , flagMsg = flag(this, 'message')
  1663. , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
  1664. , ssfi = flag(this, 'ssfi')
  1665. , objType = _.type(obj).toLowerCase()
  1666. , nType = _.type(n).toLowerCase()
  1667. , errorMessage
  1668. , shouldThrow = true;
  1669. if (doLength && objType !== 'map' && objType !== 'set') {
  1670. new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
  1671. }
  1672. if (!doLength && (objType === 'date' && nType !== 'date')) {
  1673. errorMessage = msgPrefix + 'the argument to most must be a date';
  1674. } else if (nType !== 'number' && (doLength || objType === 'number')) {
  1675. errorMessage = msgPrefix + 'the argument to most must be a number';
  1676. } else if (!doLength && (objType !== 'date' && objType !== 'number')) {
  1677. var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
  1678. errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
  1679. } else {
  1680. shouldThrow = false;
  1681. }
  1682. if (shouldThrow) {
  1683. throw new AssertionError(errorMessage, undefined, ssfi);
  1684. }
  1685. if (doLength) {
  1686. var descriptor = 'length'
  1687. , itemsCount;
  1688. if (objType === 'map' || objType === 'set') {
  1689. descriptor = 'size';
  1690. itemsCount = obj.size;
  1691. } else {
  1692. itemsCount = obj.length;
  1693. }
  1694. this.assert(
  1695. itemsCount <= n
  1696. , 'expected #{this} to have a ' + descriptor + ' at most #{exp} but got #{act}'
  1697. , 'expected #{this} to have a ' + descriptor + ' above #{exp}'
  1698. , n
  1699. , itemsCount
  1700. );
  1701. } else {
  1702. this.assert(
  1703. obj <= n
  1704. , 'expected #{this} to be at most #{exp}'
  1705. , 'expected #{this} to be above #{exp}'
  1706. , n
  1707. );
  1708. }
  1709. }
  1710. Assertion.addMethod('most', assertMost);
  1711. Assertion.addMethod('lte', assertMost);
  1712. /**
  1713. * ### .within(start, finish[, msg])
  1714. *
  1715. * Asserts that the target is a number or a date greater than or equal to the given
  1716. * number or date `start`, and less than or equal to the given number or date `finish` respectively.
  1717. * However, it's often best to assert that the target is equal to its expected
  1718. * value.
  1719. *
  1720. * expect(2).to.equal(2); // Recommended
  1721. * expect(2).to.be.within(1, 3); // Not recommended
  1722. * expect(2).to.be.within(2, 3); // Not recommended
  1723. * expect(2).to.be.within(1, 2); // Not recommended
  1724. *
  1725. * Add `.lengthOf` earlier in the chain to assert that the target's `length`
  1726. * or `size` is greater than or equal to the given number `start`, and less
  1727. * than or equal to the given number `finish`.
  1728. *
  1729. * expect('foo').to.have.lengthOf(3); // Recommended
  1730. * expect('foo').to.have.lengthOf.within(2, 4); // Not recommended
  1731. *
  1732. * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended
  1733. * expect([1, 2, 3]).to.have.lengthOf.within(2, 4); // Not recommended
  1734. *
  1735. * Add `.not` earlier in the chain to negate `.within`.
  1736. *
  1737. * expect(1).to.equal(1); // Recommended
  1738. * expect(1).to.not.be.within(2, 4); // Not recommended
  1739. *
  1740. * `.within` accepts an optional `msg` argument which is a custom error
  1741. * message to show when the assertion fails. The message can also be given as
  1742. * the second argument to `expect`.
  1743. *
  1744. * expect(4).to.be.within(1, 3, 'nooo why fail??');
  1745. * expect(4, 'nooo why fail??').to.be.within(1, 3);
  1746. *
  1747. * @name within
  1748. * @param {Number} start lower bound inclusive
  1749. * @param {Number} finish upper bound inclusive
  1750. * @param {String} msg _optional_
  1751. * @namespace BDD
  1752. * @api public
  1753. */
  1754. Assertion.addMethod('within', function (start, finish, msg) {
  1755. if (msg) flag(this, 'message', msg);
  1756. var obj = flag(this, 'object')
  1757. , doLength = flag(this, 'doLength')
  1758. , flagMsg = flag(this, 'message')
  1759. , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
  1760. , ssfi = flag(this, 'ssfi')
  1761. , objType = _.type(obj).toLowerCase()
  1762. , startType = _.type(start).toLowerCase()
  1763. , finishType = _.type(finish).toLowerCase()
  1764. , errorMessage
  1765. , shouldThrow = true
  1766. , range = (startType === 'date' && finishType === 'date')
  1767. ? start.toUTCString() + '..' + finish.toUTCString()
  1768. : start + '..' + finish;
  1769. if (doLength && objType !== 'map' && objType !== 'set') {
  1770. new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
  1771. }
  1772. if (!doLength && (objType === 'date' && (startType !== 'date' || finishType !== 'date'))) {
  1773. errorMessage = msgPrefix + 'the arguments to within must be dates';
  1774. } else if ((startType !== 'number' || finishType !== 'number') && (doLength || objType === 'number')) {
  1775. errorMessage = msgPrefix + 'the arguments to within must be numbers';
  1776. } else if (!doLength && (objType !== 'date' && objType !== 'number')) {
  1777. var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
  1778. errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
  1779. } else {
  1780. shouldThrow = false;
  1781. }
  1782. if (shouldThrow) {
  1783. throw new AssertionError(errorMessage, undefined, ssfi);
  1784. }
  1785. if (doLength) {
  1786. var descriptor = 'length'
  1787. , itemsCount;
  1788. if (objType === 'map' || objType === 'set') {
  1789. descriptor = 'size';
  1790. itemsCount = obj.size;
  1791. } else {
  1792. itemsCount = obj.length;
  1793. }
  1794. this.assert(
  1795. itemsCount >= start && itemsCount <= finish
  1796. , 'expected #{this} to have a ' + descriptor + ' within ' + range
  1797. , 'expected #{this} to not have a ' + descriptor + ' within ' + range
  1798. );
  1799. } else {
  1800. this.assert(
  1801. obj >= start && obj <= finish
  1802. , 'expected #{this} to be within ' + range
  1803. , 'expected #{this} to not be within ' + range
  1804. );
  1805. }
  1806. });
  1807. /**
  1808. * ### .instanceof(constructor[, msg])
  1809. *
  1810. * Asserts that the target is an instance of the given `constructor`.
  1811. *
  1812. * function Cat () { }
  1813. *
  1814. * expect(new Cat()).to.be.an.instanceof(Cat);
  1815. * expect([1, 2]).to.be.an.instanceof(Array);
  1816. *
  1817. * Add `.not` earlier in the chain to negate `.instanceof`.
  1818. *
  1819. * expect({a: 1}).to.not.be.an.instanceof(Array);
  1820. *
  1821. * `.instanceof` accepts an optional `msg` argument which is a custom error
  1822. * message to show when the assertion fails. The message can also be given as
  1823. * the second argument to `expect`.
  1824. *
  1825. * expect(1).to.be.an.instanceof(Array, 'nooo why fail??');
  1826. * expect(1, 'nooo why fail??').to.be.an.instanceof(Array);
  1827. *
  1828. * Due to limitations in ES5, `.instanceof` may not always work as expected
  1829. * when using a transpiler such as Babel or TypeScript. In particular, it may
  1830. * produce unexpected results when subclassing built-in object such as
  1831. * `Array`, `Error`, and `Map`. See your transpiler's docs for details:
  1832. *
  1833. * - ([Babel](https://babeljs.io/docs/usage/caveats/#classes))
  1834. * - ([TypeScript](https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work))
  1835. *
  1836. * The alias `.instanceOf` can be used interchangeably with `.instanceof`.
  1837. *
  1838. * @name instanceof
  1839. * @param {Constructor} constructor
  1840. * @param {String} msg _optional_
  1841. * @alias instanceOf
  1842. * @namespace BDD
  1843. * @api public
  1844. */
  1845. function assertInstanceOf (constructor, msg) {
  1846. if (msg) flag(this, 'message', msg);
  1847. var target = flag(this, 'object')
  1848. var ssfi = flag(this, 'ssfi');
  1849. var flagMsg = flag(this, 'message');
  1850. try {
  1851. var isInstanceOf = target instanceof constructor;
  1852. } catch (err) {
  1853. if (err instanceof TypeError) {
  1854. flagMsg = flagMsg ? flagMsg + ': ' : '';
  1855. throw new AssertionError(
  1856. flagMsg + 'The instanceof assertion needs a constructor but '
  1857. + _.type(constructor) + ' was given.',
  1858. undefined,
  1859. ssfi
  1860. );
  1861. }
  1862. throw err;
  1863. }
  1864. var name = _.getName(constructor);
  1865. if (name === null) {
  1866. name = 'an unnamed constructor';
  1867. }
  1868. this.assert(
  1869. isInstanceOf
  1870. , 'expected #{this} to be an instance of ' + name
  1871. , 'expected #{this} to not be an instance of ' + name
  1872. );
  1873. };
  1874. Assertion.addMethod('instanceof', assertInstanceOf);
  1875. Assertion.addMethod('instanceOf', assertInstanceOf);
  1876. /**
  1877. * ### .property(name[, val[, msg]])
  1878. *
  1879. * Asserts that the target has a property with the given key `name`.
  1880. *
  1881. * expect({a: 1}).to.have.property('a');
  1882. *
  1883. * When `val` is provided, `.property` also asserts that the property's value
  1884. * is equal to the given `val`.
  1885. *
  1886. * expect({a: 1}).to.have.property('a', 1);
  1887. *
  1888. * By default, strict (`===`) equality is used. Add `.deep` earlier in the
  1889. * chain to use deep equality instead. See the `deep-eql` project page for
  1890. * info on the deep equality algorithm: https://github.com/chaijs/deep-eql.
  1891. *
  1892. * // Target object deeply (but not strictly) has property `x: {a: 1}`
  1893. * expect({x: {a: 1}}).to.have.deep.property('x', {a: 1});
  1894. * expect({x: {a: 1}}).to.not.have.property('x', {a: 1});
  1895. *
  1896. * The target's enumerable and non-enumerable properties are always included
  1897. * in the search. By default, both own and inherited properties are included.
  1898. * Add `.own` earlier in the chain to exclude inherited properties from the
  1899. * search.
  1900. *
  1901. * Object.prototype.b = 2;
  1902. *
  1903. * expect({a: 1}).to.have.own.property('a');
  1904. * expect({a: 1}).to.have.own.property('a', 1);
  1905. * expect({a: 1}).to.have.property('b');
  1906. * expect({a: 1}).to.not.have.own.property('b');
  1907. *
  1908. * `.deep` and `.own` can be combined.
  1909. *
  1910. * expect({x: {a: 1}}).to.have.deep.own.property('x', {a: 1});
  1911. *
  1912. * Add `.nested` earlier in the chain to enable dot- and bracket-notation when
  1913. * referencing nested properties.
  1914. *
  1915. * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]');
  1916. * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]', 'y');
  1917. *
  1918. * If `.` or `[]` are part of an actual property name, they can be escaped by
  1919. * adding two backslashes before them.
  1920. *
  1921. * expect({'.a': {'[b]': 'x'}}).to.have.nested.property('\\.a.\\[b\\]');
  1922. *
  1923. * `.deep` and `.nested` can be combined.
  1924. *
  1925. * expect({a: {b: [{c: 3}]}})
  1926. * .to.have.deep.nested.property('a.b[0]', {c: 3});
  1927. *
  1928. * `.own` and `.nested` cannot be combined.
  1929. *
  1930. * Add `.not` earlier in the chain to negate `.property`.
  1931. *
  1932. * expect({a: 1}).to.not.have.property('b');
  1933. *
  1934. * However, it's dangerous to negate `.property` when providing `val`. The
  1935. * problem is that it creates uncertain expectations by asserting that the
  1936. * target either doesn't have a property with the given key `name`, or that it
  1937. * does have a property with the given key `name` but its value isn't equal to
  1938. * the given `val`. It's often best to identify the exact output that's
  1939. * expected, and then write an assertion that only accepts that exact output.
  1940. *
  1941. * When the target isn't expected to have a property with the given key
  1942. * `name`, it's often best to assert exactly that.
  1943. *
  1944. * expect({b: 2}).to.not.have.property('a'); // Recommended
  1945. * expect({b: 2}).to.not.have.property('a', 1); // Not recommended
  1946. *
  1947. * When the target is expected to have a property with the given key `name`,
  1948. * it's often best to assert that the property has its expected value, rather
  1949. * than asserting that it doesn't have one of many unexpected values.
  1950. *
  1951. * expect({a: 3}).to.have.property('a', 3); // Recommended
  1952. * expect({a: 3}).to.not.have.property('a', 1); // Not recommended
  1953. *
  1954. * `.property` changes the target of any assertions that follow in the chain
  1955. * to be the value of the property from the original target object.
  1956. *
  1957. * expect({a: 1}).to.have.property('a').that.is.a('number');
  1958. *
  1959. * `.property` accepts an optional `msg` argument which is a custom error
  1960. * message to show when the assertion fails. The message can also be given as
  1961. * the second argument to `expect`. When not providing `val`, only use the
  1962. * second form.
  1963. *
  1964. * // Recommended
  1965. * expect({a: 1}).to.have.property('a', 2, 'nooo why fail??');
  1966. * expect({a: 1}, 'nooo why fail??').to.have.property('a', 2);
  1967. * expect({a: 1}, 'nooo why fail??').to.have.property('b');
  1968. *
  1969. * // Not recommended
  1970. * expect({a: 1}).to.have.property('b', undefined, 'nooo why fail??');
  1971. *
  1972. * The above assertion isn't the same thing as not providing `val`. Instead,
  1973. * it's asserting that the target object has a `b` property that's equal to
  1974. * `undefined`.
  1975. *
  1976. * The assertions `.ownProperty` and `.haveOwnProperty` can be used
  1977. * interchangeably with `.own.property`.
  1978. *
  1979. * @name property
  1980. * @param {String} name
  1981. * @param {Mixed} val (optional)
  1982. * @param {String} msg _optional_
  1983. * @returns value of property for chaining
  1984. * @namespace BDD
  1985. * @api public
  1986. */
  1987. function assertProperty (name, val, msg) {
  1988. if (msg) flag(this, 'message', msg);
  1989. var isNested = flag(this, 'nested')
  1990. , isOwn = flag(this, 'own')
  1991. , flagMsg = flag(this, 'message')
  1992. , obj = flag(this, 'object')
  1993. , ssfi = flag(this, 'ssfi')
  1994. , nameType = typeof name;
  1995. flagMsg = flagMsg ? flagMsg + ': ' : '';
  1996. if (isNested) {
  1997. if (nameType !== 'string') {
  1998. throw new AssertionError(
  1999. flagMsg + 'the argument to property must be a string when using nested syntax',
  2000. undefined,
  2001. ssfi
  2002. );
  2003. }
  2004. } else {
  2005. if (nameType !== 'string' && nameType !== 'number' && nameType !== 'symbol') {
  2006. throw new AssertionError(
  2007. flagMsg + 'the argument to property must be a string, number, or symbol',
  2008. undefined,
  2009. ssfi
  2010. );
  2011. }
  2012. }
  2013. if (isNested && isOwn) {
  2014. throw new AssertionError(
  2015. flagMsg + 'The "nested" and "own" flags cannot be combined.',
  2016. undefined,
  2017. ssfi
  2018. );
  2019. }
  2020. if (obj === null || obj === undefined) {
  2021. throw new AssertionError(
  2022. flagMsg + 'Target cannot be null or undefined.',
  2023. undefined,
  2024. ssfi
  2025. );
  2026. }
  2027. var isDeep = flag(this, 'deep')
  2028. , negate = flag(this, 'negate')
  2029. , pathInfo = isNested ? _.getPathInfo(obj, name) : null
  2030. , value = isNested ? pathInfo.value : obj[name];
  2031. var descriptor = '';
  2032. if (isDeep) descriptor += 'deep ';
  2033. if (isOwn) descriptor += 'own ';
  2034. if (isNested) descriptor += 'nested ';
  2035. descriptor += 'property ';
  2036. var hasProperty;
  2037. if (isOwn) hasProperty = Object.prototype.hasOwnProperty.call(obj, name);
  2038. else if (isNested) hasProperty = pathInfo.exists;
  2039. else hasProperty = _.hasProperty(obj, name);
  2040. // When performing a negated assertion for both name and val, merely having
  2041. // a property with the given name isn't enough to cause the assertion to
  2042. // fail. It must both have a property with the given name, and the value of
  2043. // that property must equal the given val. Therefore, skip this assertion in
  2044. // favor of the next.
  2045. if (!negate || arguments.length === 1) {
  2046. this.assert(
  2047. hasProperty
  2048. , 'expected #{this} to have ' + descriptor + _.inspect(name)
  2049. , 'expected #{this} to not have ' + descriptor + _.inspect(name));
  2050. }
  2051. if (arguments.length > 1) {
  2052. this.assert(
  2053. hasProperty && (isDeep ? _.eql(val, value) : val === value)
  2054. , 'expected #{this} to have ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}'
  2055. , 'expected #{this} to not have ' + descriptor + _.inspect(name) + ' of #{act}'
  2056. , val
  2057. , value
  2058. );
  2059. }
  2060. flag(this, 'object', value);
  2061. }
  2062. Assertion.addMethod('property', assertProperty);
  2063. function assertOwnProperty (name, value, msg) {
  2064. flag(this, 'own', true);
  2065. assertProperty.apply(this, arguments);
  2066. }
  2067. Assertion.addMethod('ownProperty', assertOwnProperty);
  2068. Assertion.addMethod('haveOwnProperty', assertOwnProperty);
  2069. /**
  2070. * ### .ownPropertyDescriptor(name[, descriptor[, msg]])
  2071. *
  2072. * Asserts that the target has its own property descriptor with the given key
  2073. * `name`. Enumerable and non-enumerable properties are included in the
  2074. * search.
  2075. *
  2076. * expect({a: 1}).to.have.ownPropertyDescriptor('a');
  2077. *
  2078. * When `descriptor` is provided, `.ownPropertyDescriptor` also asserts that
  2079. * the property's descriptor is deeply equal to the given `descriptor`. See
  2080. * the `deep-eql` project page for info on the deep equality algorithm:
  2081. * https://github.com/chaijs/deep-eql.
  2082. *
  2083. * expect({a: 1}).to.have.ownPropertyDescriptor('a', {
  2084. * configurable: true,
  2085. * enumerable: true,
  2086. * writable: true,
  2087. * value: 1,
  2088. * });
  2089. *
  2090. * Add `.not` earlier in the chain to negate `.ownPropertyDescriptor`.
  2091. *
  2092. * expect({a: 1}).to.not.have.ownPropertyDescriptor('b');
  2093. *
  2094. * However, it's dangerous to negate `.ownPropertyDescriptor` when providing
  2095. * a `descriptor`. The problem is that it creates uncertain expectations by
  2096. * asserting that the target either doesn't have a property descriptor with
  2097. * the given key `name`, or that it does have a property descriptor with the
  2098. * given key `name` but its not deeply equal to the given `descriptor`. It's
  2099. * often best to identify the exact output that's expected, and then write an
  2100. * assertion that only accepts that exact output.
  2101. *
  2102. * When the target isn't expected to have a property descriptor with the given
  2103. * key `name`, it's often best to assert exactly that.
  2104. *
  2105. * // Recommended
  2106. * expect({b: 2}).to.not.have.ownPropertyDescriptor('a');
  2107. *
  2108. * // Not recommended
  2109. * expect({b: 2}).to.not.have.ownPropertyDescriptor('a', {
  2110. * configurable: true,
  2111. * enumerable: true,
  2112. * writable: true,
  2113. * value: 1,
  2114. * });
  2115. *
  2116. * When the target is expected to have a property descriptor with the given
  2117. * key `name`, it's often best to assert that the property has its expected
  2118. * descriptor, rather than asserting that it doesn't have one of many
  2119. * unexpected descriptors.
  2120. *
  2121. * // Recommended
  2122. * expect({a: 3}).to.have.ownPropertyDescriptor('a', {
  2123. * configurable: true,
  2124. * enumerable: true,
  2125. * writable: true,
  2126. * value: 3,
  2127. * });
  2128. *
  2129. * // Not recommended
  2130. * expect({a: 3}).to.not.have.ownPropertyDescriptor('a', {
  2131. * configurable: true,
  2132. * enumerable: true,
  2133. * writable: true,
  2134. * value: 1,
  2135. * });
  2136. *
  2137. * `.ownPropertyDescriptor` changes the target of any assertions that follow
  2138. * in the chain to be the value of the property descriptor from the original
  2139. * target object.
  2140. *
  2141. * expect({a: 1}).to.have.ownPropertyDescriptor('a')
  2142. * .that.has.property('enumerable', true);
  2143. *
  2144. * `.ownPropertyDescriptor` accepts an optional `msg` argument which is a
  2145. * custom error message to show when the assertion fails. The message can also
  2146. * be given as the second argument to `expect`. When not providing
  2147. * `descriptor`, only use the second form.
  2148. *
  2149. * // Recommended
  2150. * expect({a: 1}).to.have.ownPropertyDescriptor('a', {
  2151. * configurable: true,
  2152. * enumerable: true,
  2153. * writable: true,
  2154. * value: 2,
  2155. * }, 'nooo why fail??');
  2156. *
  2157. * // Recommended
  2158. * expect({a: 1}, 'nooo why fail??').to.have.ownPropertyDescriptor('a', {
  2159. * configurable: true,
  2160. * enumerable: true,
  2161. * writable: true,
  2162. * value: 2,
  2163. * });
  2164. *
  2165. * // Recommended
  2166. * expect({a: 1}, 'nooo why fail??').to.have.ownPropertyDescriptor('b');
  2167. *
  2168. * // Not recommended
  2169. * expect({a: 1})
  2170. * .to.have.ownPropertyDescriptor('b', undefined, 'nooo why fail??');
  2171. *
  2172. * The above assertion isn't the same thing as not providing `descriptor`.
  2173. * Instead, it's asserting that the target object has a `b` property
  2174. * descriptor that's deeply equal to `undefined`.
  2175. *
  2176. * The alias `.haveOwnPropertyDescriptor` can be used interchangeably with
  2177. * `.ownPropertyDescriptor`.
  2178. *
  2179. * @name ownPropertyDescriptor
  2180. * @alias haveOwnPropertyDescriptor
  2181. * @param {String} name
  2182. * @param {Object} descriptor _optional_
  2183. * @param {String} msg _optional_
  2184. * @namespace BDD
  2185. * @api public
  2186. */
  2187. function assertOwnPropertyDescriptor (name, descriptor, msg) {
  2188. if (typeof descriptor === 'string') {
  2189. msg = descriptor;
  2190. descriptor = null;
  2191. }
  2192. if (msg) flag(this, 'message', msg);
  2193. var obj = flag(this, 'object');
  2194. var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name);
  2195. if (actualDescriptor && descriptor) {
  2196. this.assert(
  2197. _.eql(descriptor, actualDescriptor)
  2198. , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor)
  2199. , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor)
  2200. , descriptor
  2201. , actualDescriptor
  2202. , true
  2203. );
  2204. } else {
  2205. this.assert(
  2206. actualDescriptor
  2207. , 'expected #{this} to have an own property descriptor for ' + _.inspect(name)
  2208. , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name)
  2209. );
  2210. }
  2211. flag(this, 'object', actualDescriptor);
  2212. }
  2213. Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor);
  2214. Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor);
  2215. /**
  2216. * ### .lengthOf(n[, msg])
  2217. *
  2218. * Asserts that the target's `length` or `size` is equal to the given number
  2219. * `n`.
  2220. *
  2221. * expect([1, 2, 3]).to.have.lengthOf(3);
  2222. * expect('foo').to.have.lengthOf(3);
  2223. * expect(new Set([1, 2, 3])).to.have.lengthOf(3);
  2224. * expect(new Map([['a', 1], ['b', 2], ['c', 3]])).to.have.lengthOf(3);
  2225. *
  2226. * Add `.not` earlier in the chain to negate `.lengthOf`. However, it's often
  2227. * best to assert that the target's `length` property is equal to its expected
  2228. * value, rather than not equal to one of many unexpected values.
  2229. *
  2230. * expect('foo').to.have.lengthOf(3); // Recommended
  2231. * expect('foo').to.not.have.lengthOf(4); // Not recommended
  2232. *
  2233. * `.lengthOf` accepts an optional `msg` argument which is a custom error
  2234. * message to show when the assertion fails. The message can also be given as
  2235. * the second argument to `expect`.
  2236. *
  2237. * expect([1, 2, 3]).to.have.lengthOf(2, 'nooo why fail??');
  2238. * expect([1, 2, 3], 'nooo why fail??').to.have.lengthOf(2);
  2239. *
  2240. * `.lengthOf` can also be used as a language chain, causing all `.above`,
  2241. * `.below`, `.least`, `.most`, and `.within` assertions that follow in the
  2242. * chain to use the target's `length` property as the target. However, it's
  2243. * often best to assert that the target's `length` property is equal to its
  2244. * expected length, rather than asserting that its `length` property falls
  2245. * within some range of values.
  2246. *
  2247. * // Recommended
  2248. * expect([1, 2, 3]).to.have.lengthOf(3);
  2249. *
  2250. * // Not recommended
  2251. * expect([1, 2, 3]).to.have.lengthOf.above(2);
  2252. * expect([1, 2, 3]).to.have.lengthOf.below(4);
  2253. * expect([1, 2, 3]).to.have.lengthOf.at.least(3);
  2254. * expect([1, 2, 3]).to.have.lengthOf.at.most(3);
  2255. * expect([1, 2, 3]).to.have.lengthOf.within(2,4);
  2256. *
  2257. * Due to a compatibility issue, the alias `.length` can't be chained directly
  2258. * off of an uninvoked method such as `.a`. Therefore, `.length` can't be used
  2259. * interchangeably with `.lengthOf` in every situation. It's recommended to
  2260. * always use `.lengthOf` instead of `.length`.
  2261. *
  2262. * expect([1, 2, 3]).to.have.a.length(3); // incompatible; throws error
  2263. * expect([1, 2, 3]).to.have.a.lengthOf(3); // passes as expected
  2264. *
  2265. * @name lengthOf
  2266. * @alias length
  2267. * @param {Number} n
  2268. * @param {String} msg _optional_
  2269. * @namespace BDD
  2270. * @api public
  2271. */
  2272. function assertLengthChain () {
  2273. flag(this, 'doLength', true);
  2274. }
  2275. function assertLength (n, msg) {
  2276. if (msg) flag(this, 'message', msg);
  2277. var obj = flag(this, 'object')
  2278. , objType = _.type(obj).toLowerCase()
  2279. , flagMsg = flag(this, 'message')
  2280. , ssfi = flag(this, 'ssfi')
  2281. , descriptor = 'length'
  2282. , itemsCount;
  2283. switch (objType) {
  2284. case 'map':
  2285. case 'set':
  2286. descriptor = 'size';
  2287. itemsCount = obj.size;
  2288. break;
  2289. default:
  2290. new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
  2291. itemsCount = obj.length;
  2292. }
  2293. this.assert(
  2294. itemsCount == n
  2295. , 'expected #{this} to have a ' + descriptor + ' of #{exp} but got #{act}'
  2296. , 'expected #{this} to not have a ' + descriptor + ' of #{act}'
  2297. , n
  2298. , itemsCount
  2299. );
  2300. }
  2301. Assertion.addChainableMethod('length', assertLength, assertLengthChain);
  2302. Assertion.addChainableMethod('lengthOf', assertLength, assertLengthChain);
  2303. /**
  2304. * ### .match(re[, msg])
  2305. *
  2306. * Asserts that the target matches the given regular expression `re`.
  2307. *
  2308. * expect('foobar').to.match(/^foo/);
  2309. *
  2310. * Add `.not` earlier in the chain to negate `.match`.
  2311. *
  2312. * expect('foobar').to.not.match(/taco/);
  2313. *
  2314. * `.match` accepts an optional `msg` argument which is a custom error message
  2315. * to show when the assertion fails. The message can also be given as the
  2316. * second argument to `expect`.
  2317. *
  2318. * expect('foobar').to.match(/taco/, 'nooo why fail??');
  2319. * expect('foobar', 'nooo why fail??').to.match(/taco/);
  2320. *
  2321. * The alias `.matches` can be used interchangeably with `.match`.
  2322. *
  2323. * @name match
  2324. * @alias matches
  2325. * @param {RegExp} re
  2326. * @param {String} msg _optional_
  2327. * @namespace BDD
  2328. * @api public
  2329. */
  2330. function assertMatch(re, msg) {
  2331. if (msg) flag(this, 'message', msg);
  2332. var obj = flag(this, 'object');
  2333. this.assert(
  2334. re.exec(obj)
  2335. , 'expected #{this} to match ' + re
  2336. , 'expected #{this} not to match ' + re
  2337. );
  2338. }
  2339. Assertion.addMethod('match', assertMatch);
  2340. Assertion.addMethod('matches', assertMatch);
  2341. /**
  2342. * ### .string(str[, msg])
  2343. *
  2344. * Asserts that the target string contains the given substring `str`.
  2345. *
  2346. * expect('foobar').to.have.string('bar');
  2347. *
  2348. * Add `.not` earlier in the chain to negate `.string`.
  2349. *
  2350. * expect('foobar').to.not.have.string('taco');
  2351. *
  2352. * `.string` accepts an optional `msg` argument which is a custom error
  2353. * message to show when the assertion fails. The message can also be given as
  2354. * the second argument to `expect`.
  2355. *
  2356. * expect('foobar').to.have.string('taco', 'nooo why fail??');
  2357. * expect('foobar', 'nooo why fail??').to.have.string('taco');
  2358. *
  2359. * @name string
  2360. * @param {String} str
  2361. * @param {String} msg _optional_
  2362. * @namespace BDD
  2363. * @api public
  2364. */
  2365. Assertion.addMethod('string', function (str, msg) {
  2366. if (msg) flag(this, 'message', msg);
  2367. var obj = flag(this, 'object')
  2368. , flagMsg = flag(this, 'message')
  2369. , ssfi = flag(this, 'ssfi');
  2370. new Assertion(obj, flagMsg, ssfi, true).is.a('string');
  2371. this.assert(
  2372. ~obj.indexOf(str)
  2373. , 'expected #{this} to contain ' + _.inspect(str)
  2374. , 'expected #{this} to not contain ' + _.inspect(str)
  2375. );
  2376. });
  2377. /**
  2378. * ### .keys(key1[, key2[, ...]])
  2379. *
  2380. * Asserts that the target object, array, map, or set has the given keys. Only
  2381. * the target's own inherited properties are included in the search.
  2382. *
  2383. * When the target is an object or array, keys can be provided as one or more
  2384. * string arguments, a single array argument, or a single object argument. In
  2385. * the latter case, only the keys in the given object matter; the values are
  2386. * ignored.
  2387. *
  2388. * expect({a: 1, b: 2}).to.have.all.keys('a', 'b');
  2389. * expect(['x', 'y']).to.have.all.keys(0, 1);
  2390. *
  2391. * expect({a: 1, b: 2}).to.have.all.keys(['a', 'b']);
  2392. * expect(['x', 'y']).to.have.all.keys([0, 1]);
  2393. *
  2394. * expect({a: 1, b: 2}).to.have.all.keys({a: 4, b: 5}); // ignore 4 and 5
  2395. * expect(['x', 'y']).to.have.all.keys({0: 4, 1: 5}); // ignore 4 and 5
  2396. *
  2397. * When the target is a map or set, each key must be provided as a separate
  2398. * argument.
  2399. *
  2400. * expect(new Map([['a', 1], ['b', 2]])).to.have.all.keys('a', 'b');
  2401. * expect(new Set(['a', 'b'])).to.have.all.keys('a', 'b');
  2402. *
  2403. * Because `.keys` does different things based on the target's type, it's
  2404. * important to check the target's type before using `.keys`. See the `.a` doc
  2405. * for info on testing a target's type.
  2406. *
  2407. * expect({a: 1, b: 2}).to.be.an('object').that.has.all.keys('a', 'b');
  2408. *
  2409. * By default, strict (`===`) equality is used to compare keys of maps and
  2410. * sets. Add `.deep` earlier in the chain to use deep equality instead. See
  2411. * the `deep-eql` project page for info on the deep equality algorithm:
  2412. * https://github.com/chaijs/deep-eql.
  2413. *
  2414. * // Target set deeply (but not strictly) has key `{a: 1}`
  2415. * expect(new Set([{a: 1}])).to.have.all.deep.keys([{a: 1}]);
  2416. * expect(new Set([{a: 1}])).to.not.have.all.keys([{a: 1}]);
  2417. *
  2418. * By default, the target must have all of the given keys and no more. Add
  2419. * `.any` earlier in the chain to only require that the target have at least
  2420. * one of the given keys. Also, add `.not` earlier in the chain to negate
  2421. * `.keys`. It's often best to add `.any` when negating `.keys`, and to use
  2422. * `.all` when asserting `.keys` without negation.
  2423. *
  2424. * When negating `.keys`, `.any` is preferred because `.not.any.keys` asserts
  2425. * exactly what's expected of the output, whereas `.not.all.keys` creates
  2426. * uncertain expectations.
  2427. *
  2428. * // Recommended; asserts that target doesn't have any of the given keys
  2429. * expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd');
  2430. *
  2431. * // Not recommended; asserts that target doesn't have all of the given
  2432. * // keys but may or may not have some of them
  2433. * expect({a: 1, b: 2}).to.not.have.all.keys('c', 'd');
  2434. *
  2435. * When asserting `.keys` without negation, `.all` is preferred because
  2436. * `.all.keys` asserts exactly what's expected of the output, whereas
  2437. * `.any.keys` creates uncertain expectations.
  2438. *
  2439. * // Recommended; asserts that target has all the given keys
  2440. * expect({a: 1, b: 2}).to.have.all.keys('a', 'b');
  2441. *
  2442. * // Not recommended; asserts that target has at least one of the given
  2443. * // keys but may or may not have more of them
  2444. * expect({a: 1, b: 2}).to.have.any.keys('a', 'b');
  2445. *
  2446. * Note that `.all` is used by default when neither `.all` nor `.any` appear
  2447. * earlier in the chain. However, it's often best to add `.all` anyway because
  2448. * it improves readability.
  2449. *
  2450. * // Both assertions are identical
  2451. * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); // Recommended
  2452. * expect({a: 1, b: 2}).to.have.keys('a', 'b'); // Not recommended
  2453. *
  2454. * Add `.include` earlier in the chain to require that the target's keys be a
  2455. * superset of the expected keys, rather than identical sets.
  2456. *
  2457. * // Target object's keys are a superset of ['a', 'b'] but not identical
  2458. * expect({a: 1, b: 2, c: 3}).to.include.all.keys('a', 'b');
  2459. * expect({a: 1, b: 2, c: 3}).to.not.have.all.keys('a', 'b');
  2460. *
  2461. * However, if `.any` and `.include` are combined, only the `.any` takes
  2462. * effect. The `.include` is ignored in this case.
  2463. *
  2464. * // Both assertions are identical
  2465. * expect({a: 1}).to.have.any.keys('a', 'b');
  2466. * expect({a: 1}).to.include.any.keys('a', 'b');
  2467. *
  2468. * A custom error message can be given as the second argument to `expect`.
  2469. *
  2470. * expect({a: 1}, 'nooo why fail??').to.have.key('b');
  2471. *
  2472. * The alias `.key` can be used interchangeably with `.keys`.
  2473. *
  2474. * @name keys
  2475. * @alias key
  2476. * @param {...String|Array|Object} keys
  2477. * @namespace BDD
  2478. * @api public
  2479. */
  2480. function assertKeys (keys) {
  2481. var obj = flag(this, 'object')
  2482. , objType = _.type(obj)
  2483. , keysType = _.type(keys)
  2484. , ssfi = flag(this, 'ssfi')
  2485. , isDeep = flag(this, 'deep')
  2486. , str
  2487. , deepStr = ''
  2488. , actual
  2489. , ok = true
  2490. , flagMsg = flag(this, 'message');
  2491. flagMsg = flagMsg ? flagMsg + ': ' : '';
  2492. 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';
  2493. if (objType === 'Map' || objType === 'Set') {
  2494. deepStr = isDeep ? 'deeply ' : '';
  2495. actual = [];
  2496. // Map and Set '.keys' aren't supported in IE 11. Therefore, use .forEach.
  2497. obj.forEach(function (val, key) { actual.push(key) });
  2498. if (keysType !== 'Array') {
  2499. keys = Array.prototype.slice.call(arguments);
  2500. }
  2501. } else {
  2502. actual = _.getOwnEnumerableProperties(obj);
  2503. switch (keysType) {
  2504. case 'Array':
  2505. if (arguments.length > 1) {
  2506. throw new AssertionError(mixedArgsMsg, undefined, ssfi);
  2507. }
  2508. break;
  2509. case 'Object':
  2510. if (arguments.length > 1) {
  2511. throw new AssertionError(mixedArgsMsg, undefined, ssfi);
  2512. }
  2513. keys = Object.keys(keys);
  2514. break;
  2515. default:
  2516. keys = Array.prototype.slice.call(arguments);
  2517. }
  2518. // Only stringify non-Symbols because Symbols would become "Symbol()"
  2519. keys = keys.map(function (val) {
  2520. return typeof val === 'symbol' ? val : String(val);
  2521. });
  2522. }
  2523. if (!keys.length) {
  2524. throw new AssertionError(flagMsg + 'keys required', undefined, ssfi);
  2525. }
  2526. var len = keys.length
  2527. , any = flag(this, 'any')
  2528. , all = flag(this, 'all')
  2529. , expected = keys;
  2530. if (!any && !all) {
  2531. all = true;
  2532. }
  2533. // Has any
  2534. if (any) {
  2535. ok = expected.some(function(expectedKey) {
  2536. return actual.some(function(actualKey) {
  2537. if (isDeep) {
  2538. return _.eql(expectedKey, actualKey);
  2539. } else {
  2540. return expectedKey === actualKey;
  2541. }
  2542. });
  2543. });
  2544. }
  2545. // Has all
  2546. if (all) {
  2547. ok = expected.every(function(expectedKey) {
  2548. return actual.some(function(actualKey) {
  2549. if (isDeep) {
  2550. return _.eql(expectedKey, actualKey);
  2551. } else {
  2552. return expectedKey === actualKey;
  2553. }
  2554. });
  2555. });
  2556. if (!flag(this, 'contains')) {
  2557. ok = ok && keys.length == actual.length;
  2558. }
  2559. }
  2560. // Key string
  2561. if (len > 1) {
  2562. keys = keys.map(function(key) {
  2563. return _.inspect(key);
  2564. });
  2565. var last = keys.pop();
  2566. if (all) {
  2567. str = keys.join(', ') + ', and ' + last;
  2568. }
  2569. if (any) {
  2570. str = keys.join(', ') + ', or ' + last;
  2571. }
  2572. } else {
  2573. str = _.inspect(keys[0]);
  2574. }
  2575. // Form
  2576. str = (len > 1 ? 'keys ' : 'key ') + str;
  2577. // Have / include
  2578. str = (flag(this, 'contains') ? 'contain ' : 'have ') + str;
  2579. // Assertion
  2580. this.assert(
  2581. ok
  2582. , 'expected #{this} to ' + deepStr + str
  2583. , 'expected #{this} to not ' + deepStr + str
  2584. , expected.slice(0).sort(_.compareByInspect)
  2585. , actual.sort(_.compareByInspect)
  2586. , true
  2587. );
  2588. }
  2589. Assertion.addMethod('keys', assertKeys);
  2590. Assertion.addMethod('key', assertKeys);
  2591. /**
  2592. * ### .throw([errorLike], [errMsgMatcher], [msg])
  2593. *
  2594. * When no arguments are provided, `.throw` invokes the target function and
  2595. * asserts that an error is thrown.
  2596. *
  2597. * var badFn = function () { throw new TypeError('Illegal salmon!'); };
  2598. *
  2599. * expect(badFn).to.throw();
  2600. *
  2601. * When one argument is provided, and it's an error constructor, `.throw`
  2602. * invokes the target function and asserts that an error is thrown that's an
  2603. * instance of that error constructor.
  2604. *
  2605. * var badFn = function () { throw new TypeError('Illegal salmon!'); };
  2606. *
  2607. * expect(badFn).to.throw(TypeError);
  2608. *
  2609. * When one argument is provided, and it's an error instance, `.throw` invokes
  2610. * the target function and asserts that an error is thrown that's strictly
  2611. * (`===`) equal to that error instance.
  2612. *
  2613. * var err = new TypeError('Illegal salmon!');
  2614. * var badFn = function () { throw err; };
  2615. *
  2616. * expect(badFn).to.throw(err);
  2617. *
  2618. * When one argument is provided, and it's a string, `.throw` invokes the
  2619. * target function and asserts that an error is thrown with a message that
  2620. * contains that string.
  2621. *
  2622. * var badFn = function () { throw new TypeError('Illegal salmon!'); };
  2623. *
  2624. * expect(badFn).to.throw('salmon');
  2625. *
  2626. * When one argument is provided, and it's a regular expression, `.throw`
  2627. * invokes the target function and asserts that an error is thrown with a
  2628. * message that matches that regular expression.
  2629. *
  2630. * var badFn = function () { throw new TypeError('Illegal salmon!'); };
  2631. *
  2632. * expect(badFn).to.throw(/salmon/);
  2633. *
  2634. * When two arguments are provided, and the first is an error instance or
  2635. * constructor, and the second is a string or regular expression, `.throw`
  2636. * invokes the function and asserts that an error is thrown that fulfills both
  2637. * conditions as described above.
  2638. *
  2639. * var err = new TypeError('Illegal salmon!');
  2640. * var badFn = function () { throw err; };
  2641. *
  2642. * expect(badFn).to.throw(TypeError, 'salmon');
  2643. * expect(badFn).to.throw(TypeError, /salmon/);
  2644. * expect(badFn).to.throw(err, 'salmon');
  2645. * expect(badFn).to.throw(err, /salmon/);
  2646. *
  2647. * Add `.not` earlier in the chain to negate `.throw`.
  2648. *
  2649. * var goodFn = function () {};
  2650. *
  2651. * expect(goodFn).to.not.throw();
  2652. *
  2653. * However, it's dangerous to negate `.throw` when providing any arguments.
  2654. * The problem is that it creates uncertain expectations by asserting that the
  2655. * target either doesn't throw an error, or that it throws an error but of a
  2656. * different type than the given type, or that it throws an error of the given
  2657. * type but with a message that doesn't include the given string. It's often
  2658. * best to identify the exact output that's expected, and then write an
  2659. * assertion that only accepts that exact output.
  2660. *
  2661. * When the target isn't expected to throw an error, it's often best to assert
  2662. * exactly that.
  2663. *
  2664. * var goodFn = function () {};
  2665. *
  2666. * expect(goodFn).to.not.throw(); // Recommended
  2667. * expect(goodFn).to.not.throw(ReferenceError, 'x'); // Not recommended
  2668. *
  2669. * When the target is expected to throw an error, it's often best to assert
  2670. * that the error is of its expected type, and has a message that includes an
  2671. * expected string, rather than asserting that it doesn't have one of many
  2672. * unexpected types, and doesn't have a message that includes some string.
  2673. *
  2674. * var badFn = function () { throw new TypeError('Illegal salmon!'); };
  2675. *
  2676. * expect(badFn).to.throw(TypeError, 'salmon'); // Recommended
  2677. * expect(badFn).to.not.throw(ReferenceError, 'x'); // Not recommended
  2678. *
  2679. * `.throw` changes the target of any assertions that follow in the chain to
  2680. * be the error object that's thrown.
  2681. *
  2682. * var err = new TypeError('Illegal salmon!');
  2683. * err.code = 42;
  2684. * var badFn = function () { throw err; };
  2685. *
  2686. * expect(badFn).to.throw(TypeError).with.property('code', 42);
  2687. *
  2688. * `.throw` accepts an optional `msg` argument which is a custom error message
  2689. * to show when the assertion fails. The message can also be given as the
  2690. * second argument to `expect`. When not providing two arguments, always use
  2691. * the second form.
  2692. *
  2693. * var goodFn = function () {};
  2694. *
  2695. * expect(goodFn).to.throw(TypeError, 'x', 'nooo why fail??');
  2696. * expect(goodFn, 'nooo why fail??').to.throw();
  2697. *
  2698. * Due to limitations in ES5, `.throw` may not always work as expected when
  2699. * using a transpiler such as Babel or TypeScript. In particular, it may
  2700. * produce unexpected results when subclassing the built-in `Error` object and
  2701. * then passing the subclassed constructor to `.throw`. See your transpiler's
  2702. * docs for details:
  2703. *
  2704. * - ([Babel](https://babeljs.io/docs/usage/caveats/#classes))
  2705. * - ([TypeScript](https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work))
  2706. *
  2707. * Beware of some common mistakes when using the `throw` assertion. One common
  2708. * mistake is to accidentally invoke the function yourself instead of letting
  2709. * the `throw` assertion invoke the function for you. For example, when
  2710. * testing if a function named `fn` throws, provide `fn` instead of `fn()` as
  2711. * the target for the assertion.
  2712. *
  2713. * expect(fn).to.throw(); // Good! Tests `fn` as desired
  2714. * expect(fn()).to.throw(); // Bad! Tests result of `fn()`, not `fn`
  2715. *
  2716. * If you need to assert that your function `fn` throws when passed certain
  2717. * arguments, then wrap a call to `fn` inside of another function.
  2718. *
  2719. * expect(function () { fn(42); }).to.throw(); // Function expression
  2720. * expect(() => fn(42)).to.throw(); // ES6 arrow function
  2721. *
  2722. * Another common mistake is to provide an object method (or any stand-alone
  2723. * function that relies on `this`) as the target of the assertion. Doing so is
  2724. * problematic because the `this` context will be lost when the function is
  2725. * invoked by `.throw`; there's no way for it to know what `this` is supposed
  2726. * to be. There are two ways around this problem. One solution is to wrap the
  2727. * method or function call inside of another function. Another solution is to
  2728. * use `bind`.
  2729. *
  2730. * expect(function () { cat.meow(); }).to.throw(); // Function expression
  2731. * expect(() => cat.meow()).to.throw(); // ES6 arrow function
  2732. * expect(cat.meow.bind(cat)).to.throw(); // Bind
  2733. *
  2734. * Finally, it's worth mentioning that it's a best practice in JavaScript to
  2735. * only throw `Error` and derivatives of `Error` such as `ReferenceError`,
  2736. * `TypeError`, and user-defined objects that extend `Error`. No other type of
  2737. * value will generate a stack trace when initialized. With that said, the
  2738. * `throw` assertion does technically support any type of value being thrown,
  2739. * not just `Error` and its derivatives.
  2740. *
  2741. * The aliases `.throws` and `.Throw` can be used interchangeably with
  2742. * `.throw`.
  2743. *
  2744. * @name throw
  2745. * @alias throws
  2746. * @alias Throw
  2747. * @param {Error|ErrorConstructor} errorLike
  2748. * @param {String|RegExp} errMsgMatcher error message
  2749. * @param {String} msg _optional_
  2750. * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
  2751. * @returns error for chaining (null if no error)
  2752. * @namespace BDD
  2753. * @api public
  2754. */
  2755. function assertThrows (errorLike, errMsgMatcher, msg) {
  2756. if (msg) flag(this, 'message', msg);
  2757. var obj = flag(this, 'object')
  2758. , ssfi = flag(this, 'ssfi')
  2759. , flagMsg = flag(this, 'message')
  2760. , negate = flag(this, 'negate') || false;
  2761. new Assertion(obj, flagMsg, ssfi, true).is.a('function');
  2762. if (errorLike instanceof RegExp || typeof errorLike === 'string') {
  2763. errMsgMatcher = errorLike;
  2764. errorLike = null;
  2765. }
  2766. var caughtErr;
  2767. try {
  2768. obj();
  2769. } catch (err) {
  2770. caughtErr = err;
  2771. }
  2772. // If we have the negate flag enabled and at least one valid argument it means we do expect an error
  2773. // but we want it to match a given set of criteria
  2774. var everyArgIsUndefined = errorLike === undefined && errMsgMatcher === undefined;
  2775. // If we've got the negate flag enabled and both args, we should only fail if both aren't compatible
  2776. // See Issue #551 and PR #683@GitHub
  2777. var everyArgIsDefined = Boolean(errorLike && errMsgMatcher);
  2778. var errorLikeFail = false;
  2779. var errMsgMatcherFail = false;
  2780. // Checking if error was thrown
  2781. if (everyArgIsUndefined || !everyArgIsUndefined && !negate) {
  2782. // We need this to display results correctly according to their types
  2783. var errorLikeString = 'an error';
  2784. if (errorLike instanceof Error) {
  2785. errorLikeString = '#{exp}';
  2786. } else if (errorLike) {
  2787. errorLikeString = _.checkError.getConstructorName(errorLike);
  2788. }
  2789. this.assert(
  2790. caughtErr
  2791. , 'expected #{this} to throw ' + errorLikeString
  2792. , 'expected #{this} to not throw an error but #{act} was thrown'
  2793. , errorLike && errorLike.toString()
  2794. , (caughtErr instanceof Error ?
  2795. caughtErr.toString() : (typeof caughtErr === 'string' ? caughtErr : caughtErr &&
  2796. _.checkError.getConstructorName(caughtErr)))
  2797. );
  2798. }
  2799. if (errorLike && caughtErr) {
  2800. // We should compare instances only if `errorLike` is an instance of `Error`
  2801. if (errorLike instanceof Error) {
  2802. var isCompatibleInstance = _.checkError.compatibleInstance(caughtErr, errorLike);
  2803. if (isCompatibleInstance === negate) {
  2804. // These checks were created to ensure we won't fail too soon when we've got both args and a negate
  2805. // See Issue #551 and PR #683@GitHub
  2806. if (everyArgIsDefined && negate) {
  2807. errorLikeFail = true;
  2808. } else {
  2809. this.assert(
  2810. negate
  2811. , 'expected #{this} to throw #{exp} but #{act} was thrown'
  2812. , 'expected #{this} to not throw #{exp}' + (caughtErr && !negate ? ' but #{act} was thrown' : '')
  2813. , errorLike.toString()
  2814. , caughtErr.toString()
  2815. );
  2816. }
  2817. }
  2818. }
  2819. var isCompatibleConstructor = _.checkError.compatibleConstructor(caughtErr, errorLike);
  2820. if (isCompatibleConstructor === negate) {
  2821. if (everyArgIsDefined && negate) {
  2822. errorLikeFail = true;
  2823. } else {
  2824. this.assert(
  2825. negate
  2826. , 'expected #{this} to throw #{exp} but #{act} was thrown'
  2827. , 'expected #{this} to not throw #{exp}' + (caughtErr ? ' but #{act} was thrown' : '')
  2828. , (errorLike instanceof Error ? errorLike.toString() : errorLike && _.checkError.getConstructorName(errorLike))
  2829. , (caughtErr instanceof Error ? caughtErr.toString() : caughtErr && _.checkError.getConstructorName(caughtErr))
  2830. );
  2831. }
  2832. }
  2833. }
  2834. if (caughtErr && errMsgMatcher !== undefined && errMsgMatcher !== null) {
  2835. // Here we check compatible messages
  2836. var placeholder = 'including';
  2837. if (errMsgMatcher instanceof RegExp) {
  2838. placeholder = 'matching'
  2839. }
  2840. var isCompatibleMessage = _.checkError.compatibleMessage(caughtErr, errMsgMatcher);
  2841. if (isCompatibleMessage === negate) {
  2842. if (everyArgIsDefined && negate) {
  2843. errMsgMatcherFail = true;
  2844. } else {
  2845. this.assert(
  2846. negate
  2847. , 'expected #{this} to throw error ' + placeholder + ' #{exp} but got #{act}'
  2848. , 'expected #{this} to throw error not ' + placeholder + ' #{exp}'
  2849. , errMsgMatcher
  2850. , _.checkError.getMessage(caughtErr)
  2851. );
  2852. }
  2853. }
  2854. }
  2855. // If both assertions failed and both should've matched we throw an error
  2856. if (errorLikeFail && errMsgMatcherFail) {
  2857. this.assert(
  2858. negate
  2859. , 'expected #{this} to throw #{exp} but #{act} was thrown'
  2860. , 'expected #{this} to not throw #{exp}' + (caughtErr ? ' but #{act} was thrown' : '')
  2861. , (errorLike instanceof Error ? errorLike.toString() : errorLike && _.checkError.getConstructorName(errorLike))
  2862. , (caughtErr instanceof Error ? caughtErr.toString() : caughtErr && _.checkError.getConstructorName(caughtErr))
  2863. );
  2864. }
  2865. flag(this, 'object', caughtErr);
  2866. };
  2867. Assertion.addMethod('throw', assertThrows);
  2868. Assertion.addMethod('throws', assertThrows);
  2869. Assertion.addMethod('Throw', assertThrows);
  2870. /**
  2871. * ### .respondTo(method[, msg])
  2872. *
  2873. * When the target is a non-function object, `.respondTo` asserts that the
  2874. * target has a method with the given name `method`. The method can be own or
  2875. * inherited, and it can be enumerable or non-enumerable.
  2876. *
  2877. * function Cat () {}
  2878. * Cat.prototype.meow = function () {};
  2879. *
  2880. * expect(new Cat()).to.respondTo('meow');
  2881. *
  2882. * When the target is a function, `.respondTo` asserts that the target's
  2883. * `prototype` property has a method with the given name `method`. Again, the
  2884. * method can be own or inherited, and it can be enumerable or non-enumerable.
  2885. *
  2886. * function Cat () {}
  2887. * Cat.prototype.meow = function () {};
  2888. *
  2889. * expect(Cat).to.respondTo('meow');
  2890. *
  2891. * Add `.itself` earlier in the chain to force `.respondTo` to treat the
  2892. * target as a non-function object, even if it's a function. Thus, it asserts
  2893. * that the target has a method with the given name `method`, rather than
  2894. * asserting that the target's `prototype` property has a method with the
  2895. * given name `method`.
  2896. *
  2897. * function Cat () {}
  2898. * Cat.prototype.meow = function () {};
  2899. * Cat.hiss = function () {};
  2900. *
  2901. * expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow');
  2902. *
  2903. * When not adding `.itself`, it's important to check the target's type before
  2904. * using `.respondTo`. See the `.a` doc for info on checking a target's type.
  2905. *
  2906. * function Cat () {}
  2907. * Cat.prototype.meow = function () {};
  2908. *
  2909. * expect(new Cat()).to.be.an('object').that.respondsTo('meow');
  2910. *
  2911. * Add `.not` earlier in the chain to negate `.respondTo`.
  2912. *
  2913. * function Dog () {}
  2914. * Dog.prototype.bark = function () {};
  2915. *
  2916. * expect(new Dog()).to.not.respondTo('meow');
  2917. *
  2918. * `.respondTo` accepts an optional `msg` argument which is a custom error
  2919. * message to show when the assertion fails. The message can also be given as
  2920. * the second argument to `expect`.
  2921. *
  2922. * expect({}).to.respondTo('meow', 'nooo why fail??');
  2923. * expect({}, 'nooo why fail??').to.respondTo('meow');
  2924. *
  2925. * The alias `.respondsTo` can be used interchangeably with `.respondTo`.
  2926. *
  2927. * @name respondTo
  2928. * @alias respondsTo
  2929. * @param {String} method
  2930. * @param {String} msg _optional_
  2931. * @namespace BDD
  2932. * @api public
  2933. */
  2934. function respondTo (method, msg) {
  2935. if (msg) flag(this, 'message', msg);
  2936. var obj = flag(this, 'object')
  2937. , itself = flag(this, 'itself')
  2938. , context = ('function' === typeof obj && !itself)
  2939. ? obj.prototype[method]
  2940. : obj[method];
  2941. this.assert(
  2942. 'function' === typeof context
  2943. , 'expected #{this} to respond to ' + _.inspect(method)
  2944. , 'expected #{this} to not respond to ' + _.inspect(method)
  2945. );
  2946. }
  2947. Assertion.addMethod('respondTo', respondTo);
  2948. Assertion.addMethod('respondsTo', respondTo);
  2949. /**
  2950. * ### .itself
  2951. *
  2952. * Forces all `.respondTo` assertions that follow in the chain to behave as if
  2953. * the target is a non-function object, even if it's a function. Thus, it
  2954. * causes `.respondTo` to assert that the target has a method with the given
  2955. * name, rather than asserting that the target's `prototype` property has a
  2956. * method with the given name.
  2957. *
  2958. * function Cat () {}
  2959. * Cat.prototype.meow = function () {};
  2960. * Cat.hiss = function () {};
  2961. *
  2962. * expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow');
  2963. *
  2964. * @name itself
  2965. * @namespace BDD
  2966. * @api public
  2967. */
  2968. Assertion.addProperty('itself', function () {
  2969. flag(this, 'itself', true);
  2970. });
  2971. /**
  2972. * ### .satisfy(matcher[, msg])
  2973. *
  2974. * Invokes the given `matcher` function with the target being passed as the
  2975. * first argument, and asserts that the value returned is truthy.
  2976. *
  2977. * expect(1).to.satisfy(function(num) {
  2978. * return num > 0;
  2979. * });
  2980. *
  2981. * Add `.not` earlier in the chain to negate `.satisfy`.
  2982. *
  2983. * expect(1).to.not.satisfy(function(num) {
  2984. * return num > 2;
  2985. * });
  2986. *
  2987. * `.satisfy` accepts an optional `msg` argument which is a custom error
  2988. * message to show when the assertion fails. The message can also be given as
  2989. * the second argument to `expect`.
  2990. *
  2991. * expect(1).to.satisfy(function(num) {
  2992. * return num > 2;
  2993. * }, 'nooo why fail??');
  2994. *
  2995. * expect(1, 'nooo why fail??').to.satisfy(function(num) {
  2996. * return num > 2;
  2997. * });
  2998. *
  2999. * The alias `.satisfies` can be used interchangeably with `.satisfy`.
  3000. *
  3001. * @name satisfy
  3002. * @alias satisfies
  3003. * @param {Function} matcher
  3004. * @param {String} msg _optional_
  3005. * @namespace BDD
  3006. * @api public
  3007. */
  3008. function satisfy (matcher, msg) {
  3009. if (msg) flag(this, 'message', msg);
  3010. var obj = flag(this, 'object');
  3011. var result = matcher(obj);
  3012. this.assert(
  3013. result
  3014. , 'expected #{this} to satisfy ' + _.objDisplay(matcher)
  3015. , 'expected #{this} to not satisfy' + _.objDisplay(matcher)
  3016. , flag(this, 'negate') ? false : true
  3017. , result
  3018. );
  3019. }
  3020. Assertion.addMethod('satisfy', satisfy);
  3021. Assertion.addMethod('satisfies', satisfy);
  3022. /**
  3023. * ### .closeTo(expected, delta[, msg])
  3024. *
  3025. * Asserts that the target is a number that's within a given +/- `delta` range
  3026. * of the given number `expected`. However, it's often best to assert that the
  3027. * target is equal to its expected value.
  3028. *
  3029. * // Recommended
  3030. * expect(1.5).to.equal(1.5);
  3031. *
  3032. * // Not recommended
  3033. * expect(1.5).to.be.closeTo(1, 0.5);
  3034. * expect(1.5).to.be.closeTo(2, 0.5);
  3035. * expect(1.5).to.be.closeTo(1, 1);
  3036. *
  3037. * Add `.not` earlier in the chain to negate `.closeTo`.
  3038. *
  3039. * expect(1.5).to.equal(1.5); // Recommended
  3040. * expect(1.5).to.not.be.closeTo(3, 1); // Not recommended
  3041. *
  3042. * `.closeTo` accepts an optional `msg` argument which is a custom error
  3043. * message to show when the assertion fails. The message can also be given as
  3044. * the second argument to `expect`.
  3045. *
  3046. * expect(1.5).to.be.closeTo(3, 1, 'nooo why fail??');
  3047. * expect(1.5, 'nooo why fail??').to.be.closeTo(3, 1);
  3048. *
  3049. * The alias `.approximately` can be used interchangeably with `.closeTo`.
  3050. *
  3051. * @name closeTo
  3052. * @alias approximately
  3053. * @param {Number} expected
  3054. * @param {Number} delta
  3055. * @param {String} msg _optional_
  3056. * @namespace BDD
  3057. * @api public
  3058. */
  3059. function closeTo(expected, delta, msg) {
  3060. if (msg) flag(this, 'message', msg);
  3061. var obj = flag(this, 'object')
  3062. , flagMsg = flag(this, 'message')
  3063. , ssfi = flag(this, 'ssfi');
  3064. new Assertion(obj, flagMsg, ssfi, true).is.a('number');
  3065. if (typeof expected !== 'number' || typeof delta !== 'number') {
  3066. flagMsg = flagMsg ? flagMsg + ': ' : '';
  3067. throw new AssertionError(
  3068. flagMsg + 'the arguments to closeTo or approximately must be numbers',
  3069. undefined,
  3070. ssfi
  3071. );
  3072. }
  3073. this.assert(
  3074. Math.abs(obj - expected) <= delta
  3075. , 'expected #{this} to be close to ' + expected + ' +/- ' + delta
  3076. , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta
  3077. );
  3078. }
  3079. Assertion.addMethod('closeTo', closeTo);
  3080. Assertion.addMethod('approximately', closeTo);
  3081. // Note: Duplicates are ignored if testing for inclusion instead of sameness.
  3082. function isSubsetOf(subset, superset, cmp, contains, ordered) {
  3083. if (!contains) {
  3084. if (subset.length !== superset.length) return false;
  3085. superset = superset.slice();
  3086. }
  3087. return subset.every(function(elem, idx) {
  3088. if (ordered) return cmp ? cmp(elem, superset[idx]) : elem === superset[idx];
  3089. if (!cmp) {
  3090. var matchIdx = superset.indexOf(elem);
  3091. if (matchIdx === -1) return false;
  3092. // Remove match from superset so not counted twice if duplicate in subset.
  3093. if (!contains) superset.splice(matchIdx, 1);
  3094. return true;
  3095. }
  3096. return superset.some(function(elem2, matchIdx) {
  3097. if (!cmp(elem, elem2)) return false;
  3098. // Remove match from superset so not counted twice if duplicate in subset.
  3099. if (!contains) superset.splice(matchIdx, 1);
  3100. return true;
  3101. });
  3102. });
  3103. }
  3104. /**
  3105. * ### .members(set[, msg])
  3106. *
  3107. * Asserts that the target array has the same members as the given array
  3108. * `set`.
  3109. *
  3110. * expect([1, 2, 3]).to.have.members([2, 1, 3]);
  3111. * expect([1, 2, 2]).to.have.members([2, 1, 2]);
  3112. *
  3113. * By default, members are compared using strict (`===`) equality. Add `.deep`
  3114. * earlier in the chain to use deep equality instead. See the `deep-eql`
  3115. * project page for info on the deep equality algorithm:
  3116. * https://github.com/chaijs/deep-eql.
  3117. *
  3118. * // Target array deeply (but not strictly) has member `{a: 1}`
  3119. * expect([{a: 1}]).to.have.deep.members([{a: 1}]);
  3120. * expect([{a: 1}]).to.not.have.members([{a: 1}]);
  3121. *
  3122. * By default, order doesn't matter. Add `.ordered` earlier in the chain to
  3123. * require that members appear in the same order.
  3124. *
  3125. * expect([1, 2, 3]).to.have.ordered.members([1, 2, 3]);
  3126. * expect([1, 2, 3]).to.have.members([2, 1, 3])
  3127. * .but.not.ordered.members([2, 1, 3]);
  3128. *
  3129. * By default, both arrays must be the same size. Add `.include` earlier in
  3130. * the chain to require that the target's members be a superset of the
  3131. * expected members. Note that duplicates are ignored in the subset when
  3132. * `.include` is added.
  3133. *
  3134. * // Target array is a superset of [1, 2] but not identical
  3135. * expect([1, 2, 3]).to.include.members([1, 2]);
  3136. * expect([1, 2, 3]).to.not.have.members([1, 2]);
  3137. *
  3138. * // Duplicates in the subset are ignored
  3139. * expect([1, 2, 3]).to.include.members([1, 2, 2, 2]);
  3140. *
  3141. * `.deep`, `.ordered`, and `.include` can all be combined. However, if
  3142. * `.include` and `.ordered` are combined, the ordering begins at the start of
  3143. * both arrays.
  3144. *
  3145. * expect([{a: 1}, {b: 2}, {c: 3}])
  3146. * .to.include.deep.ordered.members([{a: 1}, {b: 2}])
  3147. * .but.not.include.deep.ordered.members([{b: 2}, {c: 3}]);
  3148. *
  3149. * Add `.not` earlier in the chain to negate `.members`. However, it's
  3150. * dangerous to do so. The problem is that it creates uncertain expectations
  3151. * by asserting that the target array doesn't have all of the same members as
  3152. * the given array `set` but may or may not have some of them. It's often best
  3153. * to identify the exact output that's expected, and then write an assertion
  3154. * that only accepts that exact output.
  3155. *
  3156. * expect([1, 2]).to.not.include(3).and.not.include(4); // Recommended
  3157. * expect([1, 2]).to.not.have.members([3, 4]); // Not recommended
  3158. *
  3159. * `.members` accepts an optional `msg` argument which is a custom error
  3160. * message to show when the assertion fails. The message can also be given as
  3161. * the second argument to `expect`.
  3162. *
  3163. * expect([1, 2]).to.have.members([1, 2, 3], 'nooo why fail??');
  3164. * expect([1, 2], 'nooo why fail??').to.have.members([1, 2, 3]);
  3165. *
  3166. * @name members
  3167. * @param {Array} set
  3168. * @param {String} msg _optional_
  3169. * @namespace BDD
  3170. * @api public
  3171. */
  3172. Assertion.addMethod('members', function (subset, msg) {
  3173. if (msg) flag(this, 'message', msg);
  3174. var obj = flag(this, 'object')
  3175. , flagMsg = flag(this, 'message')
  3176. , ssfi = flag(this, 'ssfi');
  3177. new Assertion(obj, flagMsg, ssfi, true).to.be.an('array');
  3178. new Assertion(subset, flagMsg, ssfi, true).to.be.an('array');
  3179. var contains = flag(this, 'contains');
  3180. var ordered = flag(this, 'ordered');
  3181. var subject, failMsg, failNegateMsg;
  3182. if (contains) {
  3183. subject = ordered ? 'an ordered superset' : 'a superset';
  3184. failMsg = 'expected #{this} to be ' + subject + ' of #{exp}';
  3185. failNegateMsg = 'expected #{this} to not be ' + subject + ' of #{exp}';
  3186. } else {
  3187. subject = ordered ? 'ordered members' : 'members';
  3188. failMsg = 'expected #{this} to have the same ' + subject + ' as #{exp}';
  3189. failNegateMsg = 'expected #{this} to not have the same ' + subject + ' as #{exp}';
  3190. }
  3191. var cmp = flag(this, 'deep') ? _.eql : undefined;
  3192. this.assert(
  3193. isSubsetOf(subset, obj, cmp, contains, ordered)
  3194. , failMsg
  3195. , failNegateMsg
  3196. , subset
  3197. , obj
  3198. , true
  3199. );
  3200. });
  3201. /**
  3202. * ### .oneOf(list[, msg])
  3203. *
  3204. * Asserts that the target is a member of the given array `list`. However,
  3205. * it's often best to assert that the target is equal to its expected value.
  3206. *
  3207. * expect(1).to.equal(1); // Recommended
  3208. * expect(1).to.be.oneOf([1, 2, 3]); // Not recommended
  3209. *
  3210. * Comparisons are performed using strict (`===`) equality.
  3211. *
  3212. * Add `.not` earlier in the chain to negate `.oneOf`.
  3213. *
  3214. * expect(1).to.equal(1); // Recommended
  3215. * expect(1).to.not.be.oneOf([2, 3, 4]); // Not recommended
  3216. *
  3217. * `.oneOf` accepts an optional `msg` argument which is a custom error message
  3218. * to show when the assertion fails. The message can also be given as the
  3219. * second argument to `expect`.
  3220. *
  3221. * expect(1).to.be.oneOf([2, 3, 4], 'nooo why fail??');
  3222. * expect(1, 'nooo why fail??').to.be.oneOf([2, 3, 4]);
  3223. *
  3224. * @name oneOf
  3225. * @param {Array<*>} list
  3226. * @param {String} msg _optional_
  3227. * @namespace BDD
  3228. * @api public
  3229. */
  3230. function oneOf (list, msg) {
  3231. if (msg) flag(this, 'message', msg);
  3232. var expected = flag(this, 'object')
  3233. , flagMsg = flag(this, 'message')
  3234. , ssfi = flag(this, 'ssfi');
  3235. new Assertion(list, flagMsg, ssfi, true).to.be.an('array');
  3236. this.assert(
  3237. list.indexOf(expected) > -1
  3238. , 'expected #{this} to be one of #{exp}'
  3239. , 'expected #{this} to not be one of #{exp}'
  3240. , list
  3241. , expected
  3242. );
  3243. }
  3244. Assertion.addMethod('oneOf', oneOf);
  3245. /**
  3246. * ### .change(subject[, prop[, msg]])
  3247. *
  3248. * When one argument is provided, `.change` asserts that the given function
  3249. * `subject` returns a different value when it's invoked before the target
  3250. * function compared to when it's invoked afterward. However, it's often best
  3251. * to assert that `subject` is equal to its expected value.
  3252. *
  3253. * var dots = ''
  3254. * , addDot = function () { dots += '.'; }
  3255. * , getDots = function () { return dots; };
  3256. *
  3257. * // Recommended
  3258. * expect(getDots()).to.equal('');
  3259. * addDot();
  3260. * expect(getDots()).to.equal('.');
  3261. *
  3262. * // Not recommended
  3263. * expect(addDot).to.change(getDots);
  3264. *
  3265. * When two arguments are provided, `.change` asserts that the value of the
  3266. * given object `subject`'s `prop` property is different before invoking the
  3267. * target function compared to afterward.
  3268. *
  3269. * var myObj = {dots: ''}
  3270. * , addDot = function () { myObj.dots += '.'; };
  3271. *
  3272. * // Recommended
  3273. * expect(myObj).to.have.property('dots', '');
  3274. * addDot();
  3275. * expect(myObj).to.have.property('dots', '.');
  3276. *
  3277. * // Not recommended
  3278. * expect(addDot).to.change(myObj, 'dots');
  3279. *
  3280. * Strict (`===`) equality is used to compare before and after values.
  3281. *
  3282. * Add `.not` earlier in the chain to negate `.change`.
  3283. *
  3284. * var dots = ''
  3285. * , noop = function () {}
  3286. * , getDots = function () { return dots; };
  3287. *
  3288. * expect(noop).to.not.change(getDots);
  3289. *
  3290. * var myObj = {dots: ''}
  3291. * , noop = function () {};
  3292. *
  3293. * expect(noop).to.not.change(myObj, 'dots');
  3294. *
  3295. * `.change` accepts an optional `msg` argument which is a custom error
  3296. * message to show when the assertion fails. The message can also be given as
  3297. * the second argument to `expect`. When not providing two arguments, always
  3298. * use the second form.
  3299. *
  3300. * var myObj = {dots: ''}
  3301. * , addDot = function () { myObj.dots += '.'; };
  3302. *
  3303. * expect(addDot).to.not.change(myObj, 'dots', 'nooo why fail??');
  3304. *
  3305. * var dots = ''
  3306. * , addDot = function () { dots += '.'; }
  3307. * , getDots = function () { return dots; };
  3308. *
  3309. * expect(addDot, 'nooo why fail??').to.not.change(getDots);
  3310. *
  3311. * `.change` also causes all `.by` assertions that follow in the chain to
  3312. * assert how much a numeric subject was increased or decreased by. However,
  3313. * it's dangerous to use `.change.by`. The problem is that it creates
  3314. * uncertain expectations by asserting that the subject either increases by
  3315. * the given delta, or that it decreases by the given delta. It's often best
  3316. * to identify the exact output that's expected, and then write an assertion
  3317. * that only accepts that exact output.
  3318. *
  3319. * var myObj = {val: 1}
  3320. * , addTwo = function () { myObj.val += 2; }
  3321. * , subtractTwo = function () { myObj.val -= 2; };
  3322. *
  3323. * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended
  3324. * expect(addTwo).to.change(myObj, 'val').by(2); // Not recommended
  3325. *
  3326. * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended
  3327. * expect(subtractTwo).to.change(myObj, 'val').by(2); // Not recommended
  3328. *
  3329. * The alias `.changes` can be used interchangeably with `.change`.
  3330. *
  3331. * @name change
  3332. * @alias changes
  3333. * @param {String} subject
  3334. * @param {String} prop name _optional_
  3335. * @param {String} msg _optional_
  3336. * @namespace BDD
  3337. * @api public
  3338. */
  3339. function assertChanges (subject, prop, msg) {
  3340. if (msg) flag(this, 'message', msg);
  3341. var fn = flag(this, 'object')
  3342. , flagMsg = flag(this, 'message')
  3343. , ssfi = flag(this, 'ssfi');
  3344. new Assertion(fn, flagMsg, ssfi, true).is.a('function');
  3345. var initial;
  3346. if (!prop) {
  3347. new Assertion(subject, flagMsg, ssfi, true).is.a('function');
  3348. initial = subject();
  3349. } else {
  3350. new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop);
  3351. initial = subject[prop];
  3352. }
  3353. fn();
  3354. var final = prop === undefined || prop === null ? subject() : subject[prop];
  3355. var msgObj = prop === undefined || prop === null ? initial : '.' + prop;
  3356. // This gets flagged because of the .by(delta) assertion
  3357. flag(this, 'deltaMsgObj', msgObj);
  3358. flag(this, 'initialDeltaValue', initial);
  3359. flag(this, 'finalDeltaValue', final);
  3360. flag(this, 'deltaBehavior', 'change');
  3361. flag(this, 'realDelta', final !== initial);
  3362. this.assert(
  3363. initial !== final
  3364. , 'expected ' + msgObj + ' to change'
  3365. , 'expected ' + msgObj + ' to not change'
  3366. );
  3367. }
  3368. Assertion.addMethod('change', assertChanges);
  3369. Assertion.addMethod('changes', assertChanges);
  3370. /**
  3371. * ### .increase(subject[, prop[, msg]])
  3372. *
  3373. * When one argument is provided, `.increase` asserts that the given function
  3374. * `subject` returns a greater number when it's invoked after invoking the
  3375. * target function compared to when it's invoked beforehand. `.increase` also
  3376. * causes all `.by` assertions that follow in the chain to assert how much
  3377. * greater of a number is returned. It's often best to assert that the return
  3378. * value increased by the expected amount, rather than asserting it increased
  3379. * by any amount.
  3380. *
  3381. * var val = 1
  3382. * , addTwo = function () { val += 2; }
  3383. * , getVal = function () { return val; };
  3384. *
  3385. * expect(addTwo).to.increase(getVal).by(2); // Recommended
  3386. * expect(addTwo).to.increase(getVal); // Not recommended
  3387. *
  3388. * When two arguments are provided, `.increase` asserts that the value of the
  3389. * given object `subject`'s `prop` property is greater after invoking the
  3390. * target function compared to beforehand.
  3391. *
  3392. * var myObj = {val: 1}
  3393. * , addTwo = function () { myObj.val += 2; };
  3394. *
  3395. * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended
  3396. * expect(addTwo).to.increase(myObj, 'val'); // Not recommended
  3397. *
  3398. * Add `.not` earlier in the chain to negate `.increase`. However, it's
  3399. * dangerous to do so. The problem is that it creates uncertain expectations
  3400. * by asserting that the subject either decreases, or that it stays the same.
  3401. * It's often best to identify the exact output that's expected, and then
  3402. * write an assertion that only accepts that exact output.
  3403. *
  3404. * When the subject is expected to decrease, it's often best to assert that it
  3405. * decreased by the expected amount.
  3406. *
  3407. * var myObj = {val: 1}
  3408. * , subtractTwo = function () { myObj.val -= 2; };
  3409. *
  3410. * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended
  3411. * expect(subtractTwo).to.not.increase(myObj, 'val'); // Not recommended
  3412. *
  3413. * When the subject is expected to stay the same, it's often best to assert
  3414. * exactly that.
  3415. *
  3416. * var myObj = {val: 1}
  3417. * , noop = function () {};
  3418. *
  3419. * expect(noop).to.not.change(myObj, 'val'); // Recommended
  3420. * expect(noop).to.not.increase(myObj, 'val'); // Not recommended
  3421. *
  3422. * `.increase` accepts an optional `msg` argument which is a custom error
  3423. * message to show when the assertion fails. The message can also be given as
  3424. * the second argument to `expect`. When not providing two arguments, always
  3425. * use the second form.
  3426. *
  3427. * var myObj = {val: 1}
  3428. * , noop = function () {};
  3429. *
  3430. * expect(noop).to.increase(myObj, 'val', 'nooo why fail??');
  3431. *
  3432. * var val = 1
  3433. * , noop = function () {}
  3434. * , getVal = function () { return val; };
  3435. *
  3436. * expect(noop, 'nooo why fail??').to.increase(getVal);
  3437. *
  3438. * The alias `.increases` can be used interchangeably with `.increase`.
  3439. *
  3440. * @name increase
  3441. * @alias increases
  3442. * @param {String|Function} subject
  3443. * @param {String} prop name _optional_
  3444. * @param {String} msg _optional_
  3445. * @namespace BDD
  3446. * @api public
  3447. */
  3448. function assertIncreases (subject, prop, msg) {
  3449. if (msg) flag(this, 'message', msg);
  3450. var fn = flag(this, 'object')
  3451. , flagMsg = flag(this, 'message')
  3452. , ssfi = flag(this, 'ssfi');
  3453. new Assertion(fn, flagMsg, ssfi, true).is.a('function');
  3454. var initial;
  3455. if (!prop) {
  3456. new Assertion(subject, flagMsg, ssfi, true).is.a('function');
  3457. initial = subject();
  3458. } else {
  3459. new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop);
  3460. initial = subject[prop];
  3461. }
  3462. // Make sure that the target is a number
  3463. new Assertion(initial, flagMsg, ssfi, true).is.a('number');
  3464. fn();
  3465. var final = prop === undefined || prop === null ? subject() : subject[prop];
  3466. var msgObj = prop === undefined || prop === null ? initial : '.' + prop;
  3467. flag(this, 'deltaMsgObj', msgObj);
  3468. flag(this, 'initialDeltaValue', initial);
  3469. flag(this, 'finalDeltaValue', final);
  3470. flag(this, 'deltaBehavior', 'increase');
  3471. flag(this, 'realDelta', final - initial);
  3472. this.assert(
  3473. final - initial > 0
  3474. , 'expected ' + msgObj + ' to increase'
  3475. , 'expected ' + msgObj + ' to not increase'
  3476. );
  3477. }
  3478. Assertion.addMethod('increase', assertIncreases);
  3479. Assertion.addMethod('increases', assertIncreases);
  3480. /**
  3481. * ### .decrease(subject[, prop[, msg]])
  3482. *
  3483. * When one argument is provided, `.decrease` asserts that the given function
  3484. * `subject` returns a lesser number when it's invoked after invoking the
  3485. * target function compared to when it's invoked beforehand. `.decrease` also
  3486. * causes all `.by` assertions that follow in the chain to assert how much
  3487. * lesser of a number is returned. It's often best to assert that the return
  3488. * value decreased by the expected amount, rather than asserting it decreased
  3489. * by any amount.
  3490. *
  3491. * var val = 1
  3492. * , subtractTwo = function () { val -= 2; }
  3493. * , getVal = function () { return val; };
  3494. *
  3495. * expect(subtractTwo).to.decrease(getVal).by(2); // Recommended
  3496. * expect(subtractTwo).to.decrease(getVal); // Not recommended
  3497. *
  3498. * When two arguments are provided, `.decrease` asserts that the value of the
  3499. * given object `subject`'s `prop` property is lesser after invoking the
  3500. * target function compared to beforehand.
  3501. *
  3502. * var myObj = {val: 1}
  3503. * , subtractTwo = function () { myObj.val -= 2; };
  3504. *
  3505. * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended
  3506. * expect(subtractTwo).to.decrease(myObj, 'val'); // Not recommended
  3507. *
  3508. * Add `.not` earlier in the chain to negate `.decrease`. However, it's
  3509. * dangerous to do so. The problem is that it creates uncertain expectations
  3510. * by asserting that the subject either increases, or that it stays the same.
  3511. * It's often best to identify the exact output that's expected, and then
  3512. * write an assertion that only accepts that exact output.
  3513. *
  3514. * When the subject is expected to increase, it's often best to assert that it
  3515. * increased by the expected amount.
  3516. *
  3517. * var myObj = {val: 1}
  3518. * , addTwo = function () { myObj.val += 2; };
  3519. *
  3520. * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended
  3521. * expect(addTwo).to.not.decrease(myObj, 'val'); // Not recommended
  3522. *
  3523. * When the subject is expected to stay the same, it's often best to assert
  3524. * exactly that.
  3525. *
  3526. * var myObj = {val: 1}
  3527. * , noop = function () {};
  3528. *
  3529. * expect(noop).to.not.change(myObj, 'val'); // Recommended
  3530. * expect(noop).to.not.decrease(myObj, 'val'); // Not recommended
  3531. *
  3532. * `.decrease` accepts an optional `msg` argument which is a custom error
  3533. * message to show when the assertion fails. The message can also be given as
  3534. * the second argument to `expect`. When not providing two arguments, always
  3535. * use the second form.
  3536. *
  3537. * var myObj = {val: 1}
  3538. * , noop = function () {};
  3539. *
  3540. * expect(noop).to.decrease(myObj, 'val', 'nooo why fail??');
  3541. *
  3542. * var val = 1
  3543. * , noop = function () {}
  3544. * , getVal = function () { return val; };
  3545. *
  3546. * expect(noop, 'nooo why fail??').to.decrease(getVal);
  3547. *
  3548. * The alias `.decreases` can be used interchangeably with `.decrease`.
  3549. *
  3550. * @name decrease
  3551. * @alias decreases
  3552. * @param {String|Function} subject
  3553. * @param {String} prop name _optional_
  3554. * @param {String} msg _optional_
  3555. * @namespace BDD
  3556. * @api public
  3557. */
  3558. function assertDecreases (subject, prop, msg) {
  3559. if (msg) flag(this, 'message', msg);
  3560. var fn = flag(this, 'object')
  3561. , flagMsg = flag(this, 'message')
  3562. , ssfi = flag(this, 'ssfi');
  3563. new Assertion(fn, flagMsg, ssfi, true).is.a('function');
  3564. var initial;
  3565. if (!prop) {
  3566. new Assertion(subject, flagMsg, ssfi, true).is.a('function');
  3567. initial = subject();
  3568. } else {
  3569. new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop);
  3570. initial = subject[prop];
  3571. }
  3572. // Make sure that the target is a number
  3573. new Assertion(initial, flagMsg, ssfi, true).is.a('number');
  3574. fn();
  3575. var final = prop === undefined || prop === null ? subject() : subject[prop];
  3576. var msgObj = prop === undefined || prop === null ? initial : '.' + prop;
  3577. flag(this, 'deltaMsgObj', msgObj);
  3578. flag(this, 'initialDeltaValue', initial);
  3579. flag(this, 'finalDeltaValue', final);
  3580. flag(this, 'deltaBehavior', 'decrease');
  3581. flag(this, 'realDelta', initial - final);
  3582. this.assert(
  3583. final - initial < 0
  3584. , 'expected ' + msgObj + ' to decrease'
  3585. , 'expected ' + msgObj + ' to not decrease'
  3586. );
  3587. }
  3588. Assertion.addMethod('decrease', assertDecreases);
  3589. Assertion.addMethod('decreases', assertDecreases);
  3590. /**
  3591. * ### .by(delta[, msg])
  3592. *
  3593. * When following an `.increase` assertion in the chain, `.by` asserts that
  3594. * the subject of the `.increase` assertion increased by the given `delta`.
  3595. *
  3596. * var myObj = {val: 1}
  3597. * , addTwo = function () { myObj.val += 2; };
  3598. *
  3599. * expect(addTwo).to.increase(myObj, 'val').by(2);
  3600. *
  3601. * When following a `.decrease` assertion in the chain, `.by` asserts that the
  3602. * subject of the `.decrease` assertion decreased by the given `delta`.
  3603. *
  3604. * var myObj = {val: 1}
  3605. * , subtractTwo = function () { myObj.val -= 2; };
  3606. *
  3607. * expect(subtractTwo).to.decrease(myObj, 'val').by(2);
  3608. *
  3609. * When following a `.change` assertion in the chain, `.by` asserts that the
  3610. * subject of the `.change` assertion either increased or decreased by the
  3611. * given `delta`. However, it's dangerous to use `.change.by`. The problem is
  3612. * that it creates uncertain expectations. It's often best to identify the
  3613. * exact output that's expected, and then write an assertion that only accepts
  3614. * that exact output.
  3615. *
  3616. * var myObj = {val: 1}
  3617. * , addTwo = function () { myObj.val += 2; }
  3618. * , subtractTwo = function () { myObj.val -= 2; };
  3619. *
  3620. * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended
  3621. * expect(addTwo).to.change(myObj, 'val').by(2); // Not recommended
  3622. *
  3623. * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended
  3624. * expect(subtractTwo).to.change(myObj, 'val').by(2); // Not recommended
  3625. *
  3626. * Add `.not` earlier in the chain to negate `.by`. However, it's often best
  3627. * to assert that the subject changed by its expected delta, rather than
  3628. * asserting that it didn't change by one of countless unexpected deltas.
  3629. *
  3630. * var myObj = {val: 1}
  3631. * , addTwo = function () { myObj.val += 2; };
  3632. *
  3633. * // Recommended
  3634. * expect(addTwo).to.increase(myObj, 'val').by(2);
  3635. *
  3636. * // Not recommended
  3637. * expect(addTwo).to.increase(myObj, 'val').but.not.by(3);
  3638. *
  3639. * `.by` accepts an optional `msg` argument which is a custom error message to
  3640. * show when the assertion fails. The message can also be given as the second
  3641. * argument to `expect`.
  3642. *
  3643. * var myObj = {val: 1}
  3644. * , addTwo = function () { myObj.val += 2; };
  3645. *
  3646. * expect(addTwo).to.increase(myObj, 'val').by(3, 'nooo why fail??');
  3647. * expect(addTwo, 'nooo why fail??').to.increase(myObj, 'val').by(3);
  3648. *
  3649. * @name by
  3650. * @param {Number} delta
  3651. * @param {String} msg _optional_
  3652. * @namespace BDD
  3653. * @api public
  3654. */
  3655. function assertDelta(delta, msg) {
  3656. if (msg) flag(this, 'message', msg);
  3657. var msgObj = flag(this, 'deltaMsgObj');
  3658. var initial = flag(this, 'initialDeltaValue');
  3659. var final = flag(this, 'finalDeltaValue');
  3660. var behavior = flag(this, 'deltaBehavior');
  3661. var realDelta = flag(this, 'realDelta');
  3662. var expression;
  3663. if (behavior === 'change') {
  3664. expression = Math.abs(final - initial) === Math.abs(delta);
  3665. } else {
  3666. expression = realDelta === Math.abs(delta);
  3667. }
  3668. this.assert(
  3669. expression
  3670. , 'expected ' + msgObj + ' to ' + behavior + ' by ' + delta
  3671. , 'expected ' + msgObj + ' to not ' + behavior + ' by ' + delta
  3672. );
  3673. }
  3674. Assertion.addMethod('by', assertDelta);
  3675. /**
  3676. * ### .extensible
  3677. *
  3678. * Asserts that the target is extensible, which means that new properties can
  3679. * be added to it. Primitives are never extensible.
  3680. *
  3681. * expect({a: 1}).to.be.extensible;
  3682. *
  3683. * Add `.not` earlier in the chain to negate `.extensible`.
  3684. *
  3685. * var nonExtensibleObject = Object.preventExtensions({})
  3686. * , sealedObject = Object.seal({})
  3687. * , frozenObject = Object.freeze({});
  3688. *
  3689. * expect(nonExtensibleObject).to.not.be.extensible;
  3690. * expect(sealedObject).to.not.be.extensible;
  3691. * expect(frozenObject).to.not.be.extensible;
  3692. * expect(1).to.not.be.extensible;
  3693. *
  3694. * A custom error message can be given as the second argument to `expect`.
  3695. *
  3696. * expect(1, 'nooo why fail??').to.be.extensible;
  3697. *
  3698. * @name extensible
  3699. * @namespace BDD
  3700. * @api public
  3701. */
  3702. Assertion.addProperty('extensible', function() {
  3703. var obj = flag(this, 'object');
  3704. // In ES5, if the argument to this method is a primitive, then it will cause a TypeError.
  3705. // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false.
  3706. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible
  3707. // The following provides ES6 behavior for ES5 environments.
  3708. var isExtensible = obj === Object(obj) && Object.isExtensible(obj);
  3709. this.assert(
  3710. isExtensible
  3711. , 'expected #{this} to be extensible'
  3712. , 'expected #{this} to not be extensible'
  3713. );
  3714. });
  3715. /**
  3716. * ### .sealed
  3717. *
  3718. * Asserts that the target is sealed, which means that new properties can't be
  3719. * added to it, and its existing properties can't be reconfigured or deleted.
  3720. * However, it's possible that its existing properties can still be reassigned
  3721. * to different values. Primitives are always sealed.
  3722. *
  3723. * var sealedObject = Object.seal({});
  3724. * var frozenObject = Object.freeze({});
  3725. *
  3726. * expect(sealedObject).to.be.sealed;
  3727. * expect(frozenObject).to.be.sealed;
  3728. * expect(1).to.be.sealed;
  3729. *
  3730. * Add `.not` earlier in the chain to negate `.sealed`.
  3731. *
  3732. * expect({a: 1}).to.not.be.sealed;
  3733. *
  3734. * A custom error message can be given as the second argument to `expect`.
  3735. *
  3736. * expect({a: 1}, 'nooo why fail??').to.be.sealed;
  3737. *
  3738. * @name sealed
  3739. * @namespace BDD
  3740. * @api public
  3741. */
  3742. Assertion.addProperty('sealed', function() {
  3743. var obj = flag(this, 'object');
  3744. // In ES5, if the argument to this method is a primitive, then it will cause a TypeError.
  3745. // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true.
  3746. // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed
  3747. // The following provides ES6 behavior for ES5 environments.
  3748. var isSealed = obj === Object(obj) ? Object.isSealed(obj) : true;
  3749. this.assert(
  3750. isSealed
  3751. , 'expected #{this} to be sealed'
  3752. , 'expected #{this} to not be sealed'
  3753. );
  3754. });
  3755. /**
  3756. * ### .frozen
  3757. *
  3758. * Asserts that the target is frozen, which means that new properties can't be
  3759. * added to it, and its existing properties can't be reassigned to different
  3760. * values, reconfigured, or deleted. Primitives are always frozen.
  3761. *
  3762. * var frozenObject = Object.freeze({});
  3763. *
  3764. * expect(frozenObject).to.be.frozen;
  3765. * expect(1).to.be.frozen;
  3766. *
  3767. * Add `.not` earlier in the chain to negate `.frozen`.
  3768. *
  3769. * expect({a: 1}).to.not.be.frozen;
  3770. *
  3771. * A custom error message can be given as the second argument to `expect`.
  3772. *
  3773. * expect({a: 1}, 'nooo why fail??').to.be.frozen;
  3774. *
  3775. * @name frozen
  3776. * @namespace BDD
  3777. * @api public
  3778. */
  3779. Assertion.addProperty('frozen', function() {
  3780. var obj = flag(this, 'object');
  3781. // In ES5, if the argument to this method is a primitive, then it will cause a TypeError.
  3782. // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true.
  3783. // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen
  3784. // The following provides ES6 behavior for ES5 environments.
  3785. var isFrozen = obj === Object(obj) ? Object.isFrozen(obj) : true;
  3786. this.assert(
  3787. isFrozen
  3788. , 'expected #{this} to be frozen'
  3789. , 'expected #{this} to not be frozen'
  3790. );
  3791. });
  3792. /**
  3793. * ### .finite
  3794. *
  3795. * Asserts that the target is a number, and isn't `NaN` or positive/negative
  3796. * `Infinity`.
  3797. *
  3798. * expect(1).to.be.finite;
  3799. *
  3800. * Add `.not` earlier in the chain to negate `.finite`. However, it's
  3801. * dangerous to do so. The problem is that it creates uncertain expectations
  3802. * by asserting that the subject either isn't a number, or that it's `NaN`, or
  3803. * that it's positive `Infinity`, or that it's negative `Infinity`. It's often
  3804. * best to identify the exact output that's expected, and then write an
  3805. * assertion that only accepts that exact output.
  3806. *
  3807. * When the target isn't expected to be a number, it's often best to assert
  3808. * that it's the expected type, rather than asserting that it isn't one of
  3809. * many unexpected types.
  3810. *
  3811. * expect('foo').to.be.a('string'); // Recommended
  3812. * expect('foo').to.not.be.finite; // Not recommended
  3813. *
  3814. * When the target is expected to be `NaN`, it's often best to assert exactly
  3815. * that.
  3816. *
  3817. * expect(NaN).to.be.NaN; // Recommended
  3818. * expect(NaN).to.not.be.finite; // Not recommended
  3819. *
  3820. * When the target is expected to be positive infinity, it's often best to
  3821. * assert exactly that.
  3822. *
  3823. * expect(Infinity).to.equal(Infinity); // Recommended
  3824. * expect(Infinity).to.not.be.finite; // Not recommended
  3825. *
  3826. * When the target is expected to be negative infinity, it's often best to
  3827. * assert exactly that.
  3828. *
  3829. * expect(-Infinity).to.equal(-Infinity); // Recommended
  3830. * expect(-Infinity).to.not.be.finite; // Not recommended
  3831. *
  3832. * A custom error message can be given as the second argument to `expect`.
  3833. *
  3834. * expect('foo', 'nooo why fail??').to.be.finite;
  3835. *
  3836. * @name finite
  3837. * @namespace BDD
  3838. * @api public
  3839. */
  3840. Assertion.addProperty('finite', function(msg) {
  3841. var obj = flag(this, 'object');
  3842. this.assert(
  3843. typeof obj === 'number' && isFinite(obj)
  3844. , 'expected #{this} to be a finite number'
  3845. , 'expected #{this} to not be a finite number'
  3846. );
  3847. });
  3848. };
  3849. },{}],6:[function(require,module,exports){
  3850. /*!
  3851. * chai
  3852. * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
  3853. * MIT Licensed
  3854. */
  3855. module.exports = function (chai, util) {
  3856. /*!
  3857. * Chai dependencies.
  3858. */
  3859. var Assertion = chai.Assertion
  3860. , flag = util.flag;
  3861. /*!
  3862. * Module export.
  3863. */
  3864. /**
  3865. * ### assert(expression, message)
  3866. *
  3867. * Write your own test expressions.
  3868. *
  3869. * assert('foo' !== 'bar', 'foo is not bar');
  3870. * assert(Array.isArray([]), 'empty arrays are arrays');
  3871. *
  3872. * @param {Mixed} expression to test for truthiness
  3873. * @param {String} message to display on error
  3874. * @name assert
  3875. * @namespace Assert
  3876. * @api public
  3877. */
  3878. var assert = chai.assert = function (express, errmsg) {
  3879. var test = new Assertion(null, null, chai.assert, true);
  3880. test.assert(
  3881. express
  3882. , errmsg
  3883. , '[ negation message unavailable ]'
  3884. );
  3885. };
  3886. /**
  3887. * ### .fail([message])
  3888. * ### .fail(actual, expected, [message], [operator])
  3889. *
  3890. * Throw a failure. Node.js `assert` module-compatible.
  3891. *
  3892. * assert.fail();
  3893. * assert.fail("custom error message");
  3894. * assert.fail(1, 2);
  3895. * assert.fail(1, 2, "custom error message");
  3896. * assert.fail(1, 2, "custom error message", ">");
  3897. * assert.fail(1, 2, undefined, ">");
  3898. *
  3899. * @name fail
  3900. * @param {Mixed} actual
  3901. * @param {Mixed} expected
  3902. * @param {String} message
  3903. * @param {String} operator
  3904. * @namespace Assert
  3905. * @api public
  3906. */
  3907. assert.fail = function (actual, expected, message, operator) {
  3908. if (arguments.length < 2) {
  3909. // Comply with Node's fail([message]) interface
  3910. message = actual;
  3911. actual = undefined;
  3912. }
  3913. message = message || 'assert.fail()';
  3914. throw new chai.AssertionError(message, {
  3915. actual: actual
  3916. , expected: expected
  3917. , operator: operator
  3918. }, assert.fail);
  3919. };
  3920. /**
  3921. * ### .isOk(object, [message])
  3922. *
  3923. * Asserts that `object` is truthy.
  3924. *
  3925. * assert.isOk('everything', 'everything is ok');
  3926. * assert.isOk(false, 'this will fail');
  3927. *
  3928. * @name isOk
  3929. * @alias ok
  3930. * @param {Mixed} object to test
  3931. * @param {String} message
  3932. * @namespace Assert
  3933. * @api public
  3934. */
  3935. assert.isOk = function (val, msg) {
  3936. new Assertion(val, msg, assert.isOk, true).is.ok;
  3937. };
  3938. /**
  3939. * ### .isNotOk(object, [message])
  3940. *
  3941. * Asserts that `object` is falsy.
  3942. *
  3943. * assert.isNotOk('everything', 'this will fail');
  3944. * assert.isNotOk(false, 'this will pass');
  3945. *
  3946. * @name isNotOk
  3947. * @alias notOk
  3948. * @param {Mixed} object to test
  3949. * @param {String} message
  3950. * @namespace Assert
  3951. * @api public
  3952. */
  3953. assert.isNotOk = function (val, msg) {
  3954. new Assertion(val, msg, assert.isNotOk, true).is.not.ok;
  3955. };
  3956. /**
  3957. * ### .equal(actual, expected, [message])
  3958. *
  3959. * Asserts non-strict equality (`==`) of `actual` and `expected`.
  3960. *
  3961. * assert.equal(3, '3', '== coerces values to strings');
  3962. *
  3963. * @name equal
  3964. * @param {Mixed} actual
  3965. * @param {Mixed} expected
  3966. * @param {String} message
  3967. * @namespace Assert
  3968. * @api public
  3969. */
  3970. assert.equal = function (act, exp, msg) {
  3971. var test = new Assertion(act, msg, assert.equal, true);
  3972. test.assert(
  3973. exp == flag(test, 'object')
  3974. , 'expected #{this} to equal #{exp}'
  3975. , 'expected #{this} to not equal #{act}'
  3976. , exp
  3977. , act
  3978. , true
  3979. );
  3980. };
  3981. /**
  3982. * ### .notEqual(actual, expected, [message])
  3983. *
  3984. * Asserts non-strict inequality (`!=`) of `actual` and `expected`.
  3985. *
  3986. * assert.notEqual(3, 4, 'these numbers are not equal');
  3987. *
  3988. * @name notEqual
  3989. * @param {Mixed} actual
  3990. * @param {Mixed} expected
  3991. * @param {String} message
  3992. * @namespace Assert
  3993. * @api public
  3994. */
  3995. assert.notEqual = function (act, exp, msg) {
  3996. var test = new Assertion(act, msg, assert.notEqual, true);
  3997. test.assert(
  3998. exp != flag(test, 'object')
  3999. , 'expected #{this} to not equal #{exp}'
  4000. , 'expected #{this} to equal #{act}'
  4001. , exp
  4002. , act
  4003. , true
  4004. );
  4005. };
  4006. /**
  4007. * ### .strictEqual(actual, expected, [message])
  4008. *
  4009. * Asserts strict equality (`===`) of `actual` and `expected`.
  4010. *
  4011. * assert.strictEqual(true, true, 'these booleans are strictly equal');
  4012. *
  4013. * @name strictEqual
  4014. * @param {Mixed} actual
  4015. * @param {Mixed} expected
  4016. * @param {String} message
  4017. * @namespace Assert
  4018. * @api public
  4019. */
  4020. assert.strictEqual = function (act, exp, msg) {
  4021. new Assertion(act, msg, assert.strictEqual, true).to.equal(exp);
  4022. };
  4023. /**
  4024. * ### .notStrictEqual(actual, expected, [message])
  4025. *
  4026. * Asserts strict inequality (`!==`) of `actual` and `expected`.
  4027. *
  4028. * assert.notStrictEqual(3, '3', 'no coercion for strict equality');
  4029. *
  4030. * @name notStrictEqual
  4031. * @param {Mixed} actual
  4032. * @param {Mixed} expected
  4033. * @param {String} message
  4034. * @namespace Assert
  4035. * @api public
  4036. */
  4037. assert.notStrictEqual = function (act, exp, msg) {
  4038. new Assertion(act, msg, assert.notStrictEqual, true).to.not.equal(exp);
  4039. };
  4040. /**
  4041. * ### .deepEqual(actual, expected, [message])
  4042. *
  4043. * Asserts that `actual` is deeply equal to `expected`.
  4044. *
  4045. * assert.deepEqual({ tea: 'green' }, { tea: 'green' });
  4046. *
  4047. * @name deepEqual
  4048. * @param {Mixed} actual
  4049. * @param {Mixed} expected
  4050. * @param {String} message
  4051. * @alias deepStrictEqual
  4052. * @namespace Assert
  4053. * @api public
  4054. */
  4055. assert.deepEqual = assert.deepStrictEqual = function (act, exp, msg) {
  4056. new Assertion(act, msg, assert.deepEqual, true).to.eql(exp);
  4057. };
  4058. /**
  4059. * ### .notDeepEqual(actual, expected, [message])
  4060. *
  4061. * Assert that `actual` is not deeply equal to `expected`.
  4062. *
  4063. * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' });
  4064. *
  4065. * @name notDeepEqual
  4066. * @param {Mixed} actual
  4067. * @param {Mixed} expected
  4068. * @param {String} message
  4069. * @namespace Assert
  4070. * @api public
  4071. */
  4072. assert.notDeepEqual = function (act, exp, msg) {
  4073. new Assertion(act, msg, assert.notDeepEqual, true).to.not.eql(exp);
  4074. };
  4075. /**
  4076. * ### .isAbove(valueToCheck, valueToBeAbove, [message])
  4077. *
  4078. * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove`.
  4079. *
  4080. * assert.isAbove(5, 2, '5 is strictly greater than 2');
  4081. *
  4082. * @name isAbove
  4083. * @param {Mixed} valueToCheck
  4084. * @param {Mixed} valueToBeAbove
  4085. * @param {String} message
  4086. * @namespace Assert
  4087. * @api public
  4088. */
  4089. assert.isAbove = function (val, abv, msg) {
  4090. new Assertion(val, msg, assert.isAbove, true).to.be.above(abv);
  4091. };
  4092. /**
  4093. * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message])
  4094. *
  4095. * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast`.
  4096. *
  4097. * assert.isAtLeast(5, 2, '5 is greater or equal to 2');
  4098. * assert.isAtLeast(3, 3, '3 is greater or equal to 3');
  4099. *
  4100. * @name isAtLeast
  4101. * @param {Mixed} valueToCheck
  4102. * @param {Mixed} valueToBeAtLeast
  4103. * @param {String} message
  4104. * @namespace Assert
  4105. * @api public
  4106. */
  4107. assert.isAtLeast = function (val, atlst, msg) {
  4108. new Assertion(val, msg, assert.isAtLeast, true).to.be.least(atlst);
  4109. };
  4110. /**
  4111. * ### .isBelow(valueToCheck, valueToBeBelow, [message])
  4112. *
  4113. * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow`.
  4114. *
  4115. * assert.isBelow(3, 6, '3 is strictly less than 6');
  4116. *
  4117. * @name isBelow
  4118. * @param {Mixed} valueToCheck
  4119. * @param {Mixed} valueToBeBelow
  4120. * @param {String} message
  4121. * @namespace Assert
  4122. * @api public
  4123. */
  4124. assert.isBelow = function (val, blw, msg) {
  4125. new Assertion(val, msg, assert.isBelow, true).to.be.below(blw);
  4126. };
  4127. /**
  4128. * ### .isAtMost(valueToCheck, valueToBeAtMost, [message])
  4129. *
  4130. * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost`.
  4131. *
  4132. * assert.isAtMost(3, 6, '3 is less than or equal to 6');
  4133. * assert.isAtMost(4, 4, '4 is less than or equal to 4');
  4134. *
  4135. * @name isAtMost
  4136. * @param {Mixed} valueToCheck
  4137. * @param {Mixed} valueToBeAtMost
  4138. * @param {String} message
  4139. * @namespace Assert
  4140. * @api public
  4141. */
  4142. assert.isAtMost = function (val, atmst, msg) {
  4143. new Assertion(val, msg, assert.isAtMost, true).to.be.most(atmst);
  4144. };
  4145. /**
  4146. * ### .isTrue(value, [message])
  4147. *
  4148. * Asserts that `value` is true.
  4149. *
  4150. * var teaServed = true;
  4151. * assert.isTrue(teaServed, 'the tea has been served');
  4152. *
  4153. * @name isTrue
  4154. * @param {Mixed} value
  4155. * @param {String} message
  4156. * @namespace Assert
  4157. * @api public
  4158. */
  4159. assert.isTrue = function (val, msg) {
  4160. new Assertion(val, msg, assert.isTrue, true).is['true'];
  4161. };
  4162. /**
  4163. * ### .isNotTrue(value, [message])
  4164. *
  4165. * Asserts that `value` is not true.
  4166. *
  4167. * var tea = 'tasty chai';
  4168. * assert.isNotTrue(tea, 'great, time for tea!');
  4169. *
  4170. * @name isNotTrue
  4171. * @param {Mixed} value
  4172. * @param {String} message
  4173. * @namespace Assert
  4174. * @api public
  4175. */
  4176. assert.isNotTrue = function (val, msg) {
  4177. new Assertion(val, msg, assert.isNotTrue, true).to.not.equal(true);
  4178. };
  4179. /**
  4180. * ### .isFalse(value, [message])
  4181. *
  4182. * Asserts that `value` is false.
  4183. *
  4184. * var teaServed = false;
  4185. * assert.isFalse(teaServed, 'no tea yet? hmm...');
  4186. *
  4187. * @name isFalse
  4188. * @param {Mixed} value
  4189. * @param {String} message
  4190. * @namespace Assert
  4191. * @api public
  4192. */
  4193. assert.isFalse = function (val, msg) {
  4194. new Assertion(val, msg, assert.isFalse, true).is['false'];
  4195. };
  4196. /**
  4197. * ### .isNotFalse(value, [message])
  4198. *
  4199. * Asserts that `value` is not false.
  4200. *
  4201. * var tea = 'tasty chai';
  4202. * assert.isNotFalse(tea, 'great, time for tea!');
  4203. *
  4204. * @name isNotFalse
  4205. * @param {Mixed} value
  4206. * @param {String} message
  4207. * @namespace Assert
  4208. * @api public
  4209. */
  4210. assert.isNotFalse = function (val, msg) {
  4211. new Assertion(val, msg, assert.isNotFalse, true).to.not.equal(false);
  4212. };
  4213. /**
  4214. * ### .isNull(value, [message])
  4215. *
  4216. * Asserts that `value` is null.
  4217. *
  4218. * assert.isNull(err, 'there was no error');
  4219. *
  4220. * @name isNull
  4221. * @param {Mixed} value
  4222. * @param {String} message
  4223. * @namespace Assert
  4224. * @api public
  4225. */
  4226. assert.isNull = function (val, msg) {
  4227. new Assertion(val, msg, assert.isNull, true).to.equal(null);
  4228. };
  4229. /**
  4230. * ### .isNotNull(value, [message])
  4231. *
  4232. * Asserts that `value` is not null.
  4233. *
  4234. * var tea = 'tasty chai';
  4235. * assert.isNotNull(tea, 'great, time for tea!');
  4236. *
  4237. * @name isNotNull
  4238. * @param {Mixed} value
  4239. * @param {String} message
  4240. * @namespace Assert
  4241. * @api public
  4242. */
  4243. assert.isNotNull = function (val, msg) {
  4244. new Assertion(val, msg, assert.isNotNull, true).to.not.equal(null);
  4245. };
  4246. /**
  4247. * ### .isNaN
  4248. *
  4249. * Asserts that value is NaN.
  4250. *
  4251. * assert.isNaN(NaN, 'NaN is NaN');
  4252. *
  4253. * @name isNaN
  4254. * @param {Mixed} value
  4255. * @param {String} message
  4256. * @namespace Assert
  4257. * @api public
  4258. */
  4259. assert.isNaN = function (val, msg) {
  4260. new Assertion(val, msg, assert.isNaN, true).to.be.NaN;
  4261. };
  4262. /**
  4263. * ### .isNotNaN
  4264. *
  4265. * Asserts that value is not NaN.
  4266. *
  4267. * assert.isNotNaN(4, '4 is not NaN');
  4268. *
  4269. * @name isNotNaN
  4270. * @param {Mixed} value
  4271. * @param {String} message
  4272. * @namespace Assert
  4273. * @api public
  4274. */
  4275. assert.isNotNaN = function (val, msg) {
  4276. new Assertion(val, msg, assert.isNotNaN, true).not.to.be.NaN;
  4277. };
  4278. /**
  4279. * ### .exists
  4280. *
  4281. * Asserts that the target is neither `null` nor `undefined`.
  4282. *
  4283. * var foo = 'hi';
  4284. *
  4285. * assert.exists(foo, 'foo is neither `null` nor `undefined`');
  4286. *
  4287. * @name exists
  4288. * @param {Mixed} value
  4289. * @param {String} message
  4290. * @namespace Assert
  4291. * @api public
  4292. */
  4293. assert.exists = function (val, msg) {
  4294. new Assertion(val, msg, assert.exists, true).to.exist;
  4295. };
  4296. /**
  4297. * ### .notExists
  4298. *
  4299. * Asserts that the target is either `null` or `undefined`.
  4300. *
  4301. * var bar = null
  4302. * , baz;
  4303. *
  4304. * assert.notExists(bar);
  4305. * assert.notExists(baz, 'baz is either null or undefined');
  4306. *
  4307. * @name notExists
  4308. * @param {Mixed} value
  4309. * @param {String} message
  4310. * @namespace Assert
  4311. * @api public
  4312. */
  4313. assert.notExists = function (val, msg) {
  4314. new Assertion(val, msg, assert.notExists, true).to.not.exist;
  4315. };
  4316. /**
  4317. * ### .isUndefined(value, [message])
  4318. *
  4319. * Asserts that `value` is `undefined`.
  4320. *
  4321. * var tea;
  4322. * assert.isUndefined(tea, 'no tea defined');
  4323. *
  4324. * @name isUndefined
  4325. * @param {Mixed} value
  4326. * @param {String} message
  4327. * @namespace Assert
  4328. * @api public
  4329. */
  4330. assert.isUndefined = function (val, msg) {
  4331. new Assertion(val, msg, assert.isUndefined, true).to.equal(undefined);
  4332. };
  4333. /**
  4334. * ### .isDefined(value, [message])
  4335. *
  4336. * Asserts that `value` is not `undefined`.
  4337. *
  4338. * var tea = 'cup of chai';
  4339. * assert.isDefined(tea, 'tea has been defined');
  4340. *
  4341. * @name isDefined
  4342. * @param {Mixed} value
  4343. * @param {String} message
  4344. * @namespace Assert
  4345. * @api public
  4346. */
  4347. assert.isDefined = function (val, msg) {
  4348. new Assertion(val, msg, assert.isDefined, true).to.not.equal(undefined);
  4349. };
  4350. /**
  4351. * ### .isFunction(value, [message])
  4352. *
  4353. * Asserts that `value` is a function.
  4354. *
  4355. * function serveTea() { return 'cup of tea'; };
  4356. * assert.isFunction(serveTea, 'great, we can have tea now');
  4357. *
  4358. * @name isFunction
  4359. * @param {Mixed} value
  4360. * @param {String} message
  4361. * @namespace Assert
  4362. * @api public
  4363. */
  4364. assert.isFunction = function (val, msg) {
  4365. new Assertion(val, msg, assert.isFunction, true).to.be.a('function');
  4366. };
  4367. /**
  4368. * ### .isNotFunction(value, [message])
  4369. *
  4370. * Asserts that `value` is _not_ a function.
  4371. *
  4372. * var serveTea = [ 'heat', 'pour', 'sip' ];
  4373. * assert.isNotFunction(serveTea, 'great, we have listed the steps');
  4374. *
  4375. * @name isNotFunction
  4376. * @param {Mixed} value
  4377. * @param {String} message
  4378. * @namespace Assert
  4379. * @api public
  4380. */
  4381. assert.isNotFunction = function (val, msg) {
  4382. new Assertion(val, msg, assert.isNotFunction, true).to.not.be.a('function');
  4383. };
  4384. /**
  4385. * ### .isObject(value, [message])
  4386. *
  4387. * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`).
  4388. * _The assertion does not match subclassed objects._
  4389. *
  4390. * var selection = { name: 'Chai', serve: 'with spices' };
  4391. * assert.isObject(selection, 'tea selection is an object');
  4392. *
  4393. * @name isObject
  4394. * @param {Mixed} value
  4395. * @param {String} message
  4396. * @namespace Assert
  4397. * @api public
  4398. */
  4399. assert.isObject = function (val, msg) {
  4400. new Assertion(val, msg, assert.isObject, true).to.be.a('object');
  4401. };
  4402. /**
  4403. * ### .isNotObject(value, [message])
  4404. *
  4405. * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`).
  4406. *
  4407. * var selection = 'chai'
  4408. * assert.isNotObject(selection, 'tea selection is not an object');
  4409. * assert.isNotObject(null, 'null is not an object');
  4410. *
  4411. * @name isNotObject
  4412. * @param {Mixed} value
  4413. * @param {String} message
  4414. * @namespace Assert
  4415. * @api public
  4416. */
  4417. assert.isNotObject = function (val, msg) {
  4418. new Assertion(val, msg, assert.isNotObject, true).to.not.be.a('object');
  4419. };
  4420. /**
  4421. * ### .isArray(value, [message])
  4422. *
  4423. * Asserts that `value` is an array.
  4424. *
  4425. * var menu = [ 'green', 'chai', 'oolong' ];
  4426. * assert.isArray(menu, 'what kind of tea do we want?');
  4427. *
  4428. * @name isArray
  4429. * @param {Mixed} value
  4430. * @param {String} message
  4431. * @namespace Assert
  4432. * @api public
  4433. */
  4434. assert.isArray = function (val, msg) {
  4435. new Assertion(val, msg, assert.isArray, true).to.be.an('array');
  4436. };
  4437. /**
  4438. * ### .isNotArray(value, [message])
  4439. *
  4440. * Asserts that `value` is _not_ an array.
  4441. *
  4442. * var menu = 'green|chai|oolong';
  4443. * assert.isNotArray(menu, 'what kind of tea do we want?');
  4444. *
  4445. * @name isNotArray
  4446. * @param {Mixed} value
  4447. * @param {String} message
  4448. * @namespace Assert
  4449. * @api public
  4450. */
  4451. assert.isNotArray = function (val, msg) {
  4452. new Assertion(val, msg, assert.isNotArray, true).to.not.be.an('array');
  4453. };
  4454. /**
  4455. * ### .isString(value, [message])
  4456. *
  4457. * Asserts that `value` is a string.
  4458. *
  4459. * var teaOrder = 'chai';
  4460. * assert.isString(teaOrder, 'order placed');
  4461. *
  4462. * @name isString
  4463. * @param {Mixed} value
  4464. * @param {String} message
  4465. * @namespace Assert
  4466. * @api public
  4467. */
  4468. assert.isString = function (val, msg) {
  4469. new Assertion(val, msg, assert.isString, true).to.be.a('string');
  4470. };
  4471. /**
  4472. * ### .isNotString(value, [message])
  4473. *
  4474. * Asserts that `value` is _not_ a string.
  4475. *
  4476. * var teaOrder = 4;
  4477. * assert.isNotString(teaOrder, 'order placed');
  4478. *
  4479. * @name isNotString
  4480. * @param {Mixed} value
  4481. * @param {String} message
  4482. * @namespace Assert
  4483. * @api public
  4484. */
  4485. assert.isNotString = function (val, msg) {
  4486. new Assertion(val, msg, assert.isNotString, true).to.not.be.a('string');
  4487. };
  4488. /**
  4489. * ### .isNumber(value, [message])
  4490. *
  4491. * Asserts that `value` is a number.
  4492. *
  4493. * var cups = 2;
  4494. * assert.isNumber(cups, 'how many cups');
  4495. *
  4496. * @name isNumber
  4497. * @param {Number} value
  4498. * @param {String} message
  4499. * @namespace Assert
  4500. * @api public
  4501. */
  4502. assert.isNumber = function (val, msg) {
  4503. new Assertion(val, msg, assert.isNumber, true).to.be.a('number');
  4504. };
  4505. /**
  4506. * ### .isNotNumber(value, [message])
  4507. *
  4508. * Asserts that `value` is _not_ a number.
  4509. *
  4510. * var cups = '2 cups please';
  4511. * assert.isNotNumber(cups, 'how many cups');
  4512. *
  4513. * @name isNotNumber
  4514. * @param {Mixed} value
  4515. * @param {String} message
  4516. * @namespace Assert
  4517. * @api public
  4518. */
  4519. assert.isNotNumber = function (val, msg) {
  4520. new Assertion(val, msg, assert.isNotNumber, true).to.not.be.a('number');
  4521. };
  4522. /**
  4523. * ### .isFinite(value, [message])
  4524. *
  4525. * Asserts that `value` is a finite number. Unlike `.isNumber`, this will fail for `NaN` and `Infinity`.
  4526. *
  4527. * var cups = 2;
  4528. * assert.isFinite(cups, 'how many cups');
  4529. *
  4530. * assert.isFinite(NaN); // throws
  4531. *
  4532. * @name isFinite
  4533. * @param {Number} value
  4534. * @param {String} message
  4535. * @namespace Assert
  4536. * @api public
  4537. */
  4538. assert.isFinite = function (val, msg) {
  4539. new Assertion(val, msg, assert.isFinite, true).to.be.finite;
  4540. };
  4541. /**
  4542. * ### .isBoolean(value, [message])
  4543. *
  4544. * Asserts that `value` is a boolean.
  4545. *
  4546. * var teaReady = true
  4547. * , teaServed = false;
  4548. *
  4549. * assert.isBoolean(teaReady, 'is the tea ready');
  4550. * assert.isBoolean(teaServed, 'has tea been served');
  4551. *
  4552. * @name isBoolean
  4553. * @param {Mixed} value
  4554. * @param {String} message
  4555. * @namespace Assert
  4556. * @api public
  4557. */
  4558. assert.isBoolean = function (val, msg) {
  4559. new Assertion(val, msg, assert.isBoolean, true).to.be.a('boolean');
  4560. };
  4561. /**
  4562. * ### .isNotBoolean(value, [message])
  4563. *
  4564. * Asserts that `value` is _not_ a boolean.
  4565. *
  4566. * var teaReady = 'yep'
  4567. * , teaServed = 'nope';
  4568. *
  4569. * assert.isNotBoolean(teaReady, 'is the tea ready');
  4570. * assert.isNotBoolean(teaServed, 'has tea been served');
  4571. *
  4572. * @name isNotBoolean
  4573. * @param {Mixed} value
  4574. * @param {String} message
  4575. * @namespace Assert
  4576. * @api public
  4577. */
  4578. assert.isNotBoolean = function (val, msg) {
  4579. new Assertion(val, msg, assert.isNotBoolean, true).to.not.be.a('boolean');
  4580. };
  4581. /**
  4582. * ### .typeOf(value, name, [message])
  4583. *
  4584. * Asserts that `value`'s type is `name`, as determined by
  4585. * `Object.prototype.toString`.
  4586. *
  4587. * assert.typeOf({ tea: 'chai' }, 'object', 'we have an object');
  4588. * assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array');
  4589. * assert.typeOf('tea', 'string', 'we have a string');
  4590. * assert.typeOf(/tea/, 'regexp', 'we have a regular expression');
  4591. * assert.typeOf(null, 'null', 'we have a null');
  4592. * assert.typeOf(undefined, 'undefined', 'we have an undefined');
  4593. *
  4594. * @name typeOf
  4595. * @param {Mixed} value
  4596. * @param {String} name
  4597. * @param {String} message
  4598. * @namespace Assert
  4599. * @api public
  4600. */
  4601. assert.typeOf = function (val, type, msg) {
  4602. new Assertion(val, msg, assert.typeOf, true).to.be.a(type);
  4603. };
  4604. /**
  4605. * ### .notTypeOf(value, name, [message])
  4606. *
  4607. * Asserts that `value`'s type is _not_ `name`, as determined by
  4608. * `Object.prototype.toString`.
  4609. *
  4610. * assert.notTypeOf('tea', 'number', 'strings are not numbers');
  4611. *
  4612. * @name notTypeOf
  4613. * @param {Mixed} value
  4614. * @param {String} typeof name
  4615. * @param {String} message
  4616. * @namespace Assert
  4617. * @api public
  4618. */
  4619. assert.notTypeOf = function (val, type, msg) {
  4620. new Assertion(val, msg, assert.notTypeOf, true).to.not.be.a(type);
  4621. };
  4622. /**
  4623. * ### .instanceOf(object, constructor, [message])
  4624. *
  4625. * Asserts that `value` is an instance of `constructor`.
  4626. *
  4627. * var Tea = function (name) { this.name = name; }
  4628. * , chai = new Tea('chai');
  4629. *
  4630. * assert.instanceOf(chai, Tea, 'chai is an instance of tea');
  4631. *
  4632. * @name instanceOf
  4633. * @param {Object} object
  4634. * @param {Constructor} constructor
  4635. * @param {String} message
  4636. * @namespace Assert
  4637. * @api public
  4638. */
  4639. assert.instanceOf = function (val, type, msg) {
  4640. new Assertion(val, msg, assert.instanceOf, true).to.be.instanceOf(type);
  4641. };
  4642. /**
  4643. * ### .notInstanceOf(object, constructor, [message])
  4644. *
  4645. * Asserts `value` is not an instance of `constructor`.
  4646. *
  4647. * var Tea = function (name) { this.name = name; }
  4648. * , chai = new String('chai');
  4649. *
  4650. * assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea');
  4651. *
  4652. * @name notInstanceOf
  4653. * @param {Object} object
  4654. * @param {Constructor} constructor
  4655. * @param {String} message
  4656. * @namespace Assert
  4657. * @api public
  4658. */
  4659. assert.notInstanceOf = function (val, type, msg) {
  4660. new Assertion(val, msg, assert.notInstanceOf, true)
  4661. .to.not.be.instanceOf(type);
  4662. };
  4663. /**
  4664. * ### .include(haystack, needle, [message])
  4665. *
  4666. * Asserts that `haystack` includes `needle`. Can be used to assert the
  4667. * inclusion of a value in an array, a substring in a string, or a subset of
  4668. * properties in an object.
  4669. *
  4670. * assert.include([1,2,3], 2, 'array contains value');
  4671. * assert.include('foobar', 'foo', 'string contains substring');
  4672. * assert.include({ foo: 'bar', hello: 'universe' }, { foo: 'bar' }, 'object contains property');
  4673. *
  4674. * Strict equality (===) is used. When asserting the inclusion of a value in
  4675. * an array, the array is searched for an element that's strictly equal to the
  4676. * given value. When asserting a subset of properties in an object, the object
  4677. * is searched for the given property keys, checking that each one is present
  4678. * and strictly equal to the given property value. For instance:
  4679. *
  4680. * var obj1 = {a: 1}
  4681. * , obj2 = {b: 2};
  4682. * assert.include([obj1, obj2], obj1);
  4683. * assert.include({foo: obj1, bar: obj2}, {foo: obj1});
  4684. * assert.include({foo: obj1, bar: obj2}, {foo: obj1, bar: obj2});
  4685. *
  4686. * @name include
  4687. * @param {Array|String} haystack
  4688. * @param {Mixed} needle
  4689. * @param {String} message
  4690. * @namespace Assert
  4691. * @api public
  4692. */
  4693. assert.include = function (exp, inc, msg) {
  4694. new Assertion(exp, msg, assert.include, true).include(inc);
  4695. };
  4696. /**
  4697. * ### .notInclude(haystack, needle, [message])
  4698. *
  4699. * Asserts that `haystack` does not include `needle`. Can be used to assert
  4700. * the absence of a value in an array, a substring in a string, or a subset of
  4701. * properties in an object.
  4702. *
  4703. * assert.notInclude([1,2,3], 4, "array doesn't contain value");
  4704. * assert.notInclude('foobar', 'baz', "string doesn't contain substring");
  4705. * assert.notInclude({ foo: 'bar', hello: 'universe' }, { foo: 'baz' }, 'object doesn't contain property');
  4706. *
  4707. * Strict equality (===) is used. When asserting the absence of a value in an
  4708. * array, the array is searched to confirm the absence of an element that's
  4709. * strictly equal to the given value. When asserting a subset of properties in
  4710. * an object, the object is searched to confirm that at least one of the given
  4711. * property keys is either not present or not strictly equal to the given
  4712. * property value. For instance:
  4713. *
  4714. * var obj1 = {a: 1}
  4715. * , obj2 = {b: 2};
  4716. * assert.notInclude([obj1, obj2], {a: 1});
  4717. * assert.notInclude({foo: obj1, bar: obj2}, {foo: {a: 1}});
  4718. * assert.notInclude({foo: obj1, bar: obj2}, {foo: obj1, bar: {b: 2}});
  4719. *
  4720. * @name notInclude
  4721. * @param {Array|String} haystack
  4722. * @param {Mixed} needle
  4723. * @param {String} message
  4724. * @namespace Assert
  4725. * @api public
  4726. */
  4727. assert.notInclude = function (exp, inc, msg) {
  4728. new Assertion(exp, msg, assert.notInclude, true).not.include(inc);
  4729. };
  4730. /**
  4731. * ### .deepInclude(haystack, needle, [message])
  4732. *
  4733. * Asserts that `haystack` includes `needle`. Can be used to assert the
  4734. * inclusion of a value in an array or a subset of properties in an object.
  4735. * Deep equality is used.
  4736. *
  4737. * var obj1 = {a: 1}
  4738. * , obj2 = {b: 2};
  4739. * assert.deepInclude([obj1, obj2], {a: 1});
  4740. * assert.deepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}});
  4741. * assert.deepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}, bar: {b: 2}});
  4742. *
  4743. * @name deepInclude
  4744. * @param {Array|String} haystack
  4745. * @param {Mixed} needle
  4746. * @param {String} message
  4747. * @namespace Assert
  4748. * @api public
  4749. */
  4750. assert.deepInclude = function (exp, inc, msg) {
  4751. new Assertion(exp, msg, assert.deepInclude, true).deep.include(inc);
  4752. };
  4753. /**
  4754. * ### .notDeepInclude(haystack, needle, [message])
  4755. *
  4756. * Asserts that `haystack` does not include `needle`. Can be used to assert
  4757. * the absence of a value in an array or a subset of properties in an object.
  4758. * Deep equality is used.
  4759. *
  4760. * var obj1 = {a: 1}
  4761. * , obj2 = {b: 2};
  4762. * assert.notDeepInclude([obj1, obj2], {a: 9});
  4763. * assert.notDeepInclude({foo: obj1, bar: obj2}, {foo: {a: 9}});
  4764. * assert.notDeepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}, bar: {b: 9}});
  4765. *
  4766. * @name notDeepInclude
  4767. * @param {Array|String} haystack
  4768. * @param {Mixed} needle
  4769. * @param {String} message
  4770. * @namespace Assert
  4771. * @api public
  4772. */
  4773. assert.notDeepInclude = function (exp, inc, msg) {
  4774. new Assertion(exp, msg, assert.notDeepInclude, true).not.deep.include(inc);
  4775. };
  4776. /**
  4777. * ### .nestedInclude(haystack, needle, [message])
  4778. *
  4779. * Asserts that 'haystack' includes 'needle'.
  4780. * Can be used to assert the inclusion of a subset of properties in an
  4781. * object.
  4782. * Enables the use of dot- and bracket-notation for referencing nested
  4783. * properties.
  4784. * '[]' and '.' in property names can be escaped using double backslashes.
  4785. *
  4786. * assert.nestedInclude({'.a': {'b': 'x'}}, {'\\.a.[b]': 'x'});
  4787. * assert.nestedInclude({'a': {'[b]': 'x'}}, {'a.\\[b\\]': 'x'});
  4788. *
  4789. * @name nestedInclude
  4790. * @param {Object} haystack
  4791. * @param {Object} needle
  4792. * @param {String} message
  4793. * @namespace Assert
  4794. * @api public
  4795. */
  4796. assert.nestedInclude = function (exp, inc, msg) {
  4797. new Assertion(exp, msg, assert.nestedInclude, true).nested.include(inc);
  4798. };
  4799. /**
  4800. * ### .notNestedInclude(haystack, needle, [message])
  4801. *
  4802. * Asserts that 'haystack' does not include 'needle'.
  4803. * Can be used to assert the absence of a subset of properties in an
  4804. * object.
  4805. * Enables the use of dot- and bracket-notation for referencing nested
  4806. * properties.
  4807. * '[]' and '.' in property names can be escaped using double backslashes.
  4808. *
  4809. * assert.notNestedInclude({'.a': {'b': 'x'}}, {'\\.a.b': 'y'});
  4810. * assert.notNestedInclude({'a': {'[b]': 'x'}}, {'a.\\[b\\]': 'y'});
  4811. *
  4812. * @name notNestedInclude
  4813. * @param {Object} haystack
  4814. * @param {Object} needle
  4815. * @param {String} message
  4816. * @namespace Assert
  4817. * @api public
  4818. */
  4819. assert.notNestedInclude = function (exp, inc, msg) {
  4820. new Assertion(exp, msg, assert.notNestedInclude, true)
  4821. .not.nested.include(inc);
  4822. };
  4823. /**
  4824. * ### .deepNestedInclude(haystack, needle, [message])
  4825. *
  4826. * Asserts that 'haystack' includes 'needle'.
  4827. * Can be used to assert the inclusion of a subset of properties in an
  4828. * object while checking for deep equality.
  4829. * Enables the use of dot- and bracket-notation for referencing nested
  4830. * properties.
  4831. * '[]' and '.' in property names can be escaped using double backslashes.
  4832. *
  4833. * assert.deepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {x: 1}});
  4834. * assert.deepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {x: 1}});
  4835. *
  4836. * @name deepNestedInclude
  4837. * @param {Object} haystack
  4838. * @param {Object} needle
  4839. * @param {String} message
  4840. * @namespace Assert
  4841. * @api public
  4842. */
  4843. assert.deepNestedInclude = function(exp, inc, msg) {
  4844. new Assertion(exp, msg, assert.deepNestedInclude, true)
  4845. .deep.nested.include(inc);
  4846. };
  4847. /**
  4848. * ### .notDeepNestedInclude(haystack, needle, [message])
  4849. *
  4850. * Asserts that 'haystack' does not include 'needle'.
  4851. * Can be used to assert the absence of a subset of properties in an
  4852. * object while checking for deep equality.
  4853. * Enables the use of dot- and bracket-notation for referencing nested
  4854. * properties.
  4855. * '[]' and '.' in property names can be escaped using double backslashes.
  4856. *
  4857. * assert.notDeepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {y: 1}})
  4858. * assert.notDeepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {y: 2}});
  4859. *
  4860. * @name notDeepNestedInclude
  4861. * @param {Object} haystack
  4862. * @param {Object} needle
  4863. * @param {String} message
  4864. * @namespace Assert
  4865. * @api public
  4866. */
  4867. assert.notDeepNestedInclude = function(exp, inc, msg) {
  4868. new Assertion(exp, msg, assert.notDeepNestedInclude, true)
  4869. .not.deep.nested.include(inc);
  4870. };
  4871. /**
  4872. * ### .ownInclude(haystack, needle, [message])
  4873. *
  4874. * Asserts that 'haystack' includes 'needle'.
  4875. * Can be used to assert the inclusion of a subset of properties in an
  4876. * object while ignoring inherited properties.
  4877. *
  4878. * assert.ownInclude({ a: 1 }, { a: 1 });
  4879. *
  4880. * @name ownInclude
  4881. * @param {Object} haystack
  4882. * @param {Object} needle
  4883. * @param {String} message
  4884. * @namespace Assert
  4885. * @api public
  4886. */
  4887. assert.ownInclude = function(exp, inc, msg) {
  4888. new Assertion(exp, msg, assert.ownInclude, true).own.include(inc);
  4889. };
  4890. /**
  4891. * ### .notOwnInclude(haystack, needle, [message])
  4892. *
  4893. * Asserts that 'haystack' includes 'needle'.
  4894. * Can be used to assert the absence of a subset of properties in an
  4895. * object while ignoring inherited properties.
  4896. *
  4897. * Object.prototype.b = 2;
  4898. *
  4899. * assert.notOwnInclude({ a: 1 }, { b: 2 });
  4900. *
  4901. * @name notOwnInclude
  4902. * @param {Object} haystack
  4903. * @param {Object} needle
  4904. * @param {String} message
  4905. * @namespace Assert
  4906. * @api public
  4907. */
  4908. assert.notOwnInclude = function(exp, inc, msg) {
  4909. new Assertion(exp, msg, assert.notOwnInclude, true).not.own.include(inc);
  4910. };
  4911. /**
  4912. * ### .deepOwnInclude(haystack, needle, [message])
  4913. *
  4914. * Asserts that 'haystack' includes 'needle'.
  4915. * Can be used to assert the inclusion of a subset of properties in an
  4916. * object while ignoring inherited properties and checking for deep equality.
  4917. *
  4918. * assert.deepOwnInclude({a: {b: 2}}, {a: {b: 2}});
  4919. *
  4920. * @name deepOwnInclude
  4921. * @param {Object} haystack
  4922. * @param {Object} needle
  4923. * @param {String} message
  4924. * @namespace Assert
  4925. * @api public
  4926. */
  4927. assert.deepOwnInclude = function(exp, inc, msg) {
  4928. new Assertion(exp, msg, assert.deepOwnInclude, true)
  4929. .deep.own.include(inc);
  4930. };
  4931. /**
  4932. * ### .notDeepOwnInclude(haystack, needle, [message])
  4933. *
  4934. * Asserts that 'haystack' includes 'needle'.
  4935. * Can be used to assert the absence of a subset of properties in an
  4936. * object while ignoring inherited properties and checking for deep equality.
  4937. *
  4938. * assert.notDeepOwnInclude({a: {b: 2}}, {a: {c: 3}});
  4939. *
  4940. * @name notDeepOwnInclude
  4941. * @param {Object} haystack
  4942. * @param {Object} needle
  4943. * @param {String} message
  4944. * @namespace Assert
  4945. * @api public
  4946. */
  4947. assert.notDeepOwnInclude = function(exp, inc, msg) {
  4948. new Assertion(exp, msg, assert.notDeepOwnInclude, true)
  4949. .not.deep.own.include(inc);
  4950. };
  4951. /**
  4952. * ### .match(value, regexp, [message])
  4953. *
  4954. * Asserts that `value` matches the regular expression `regexp`.
  4955. *
  4956. * assert.match('foobar', /^foo/, 'regexp matches');
  4957. *
  4958. * @name match
  4959. * @param {Mixed} value
  4960. * @param {RegExp} regexp
  4961. * @param {String} message
  4962. * @namespace Assert
  4963. * @api public
  4964. */
  4965. assert.match = function (exp, re, msg) {
  4966. new Assertion(exp, msg, assert.match, true).to.match(re);
  4967. };
  4968. /**
  4969. * ### .notMatch(value, regexp, [message])
  4970. *
  4971. * Asserts that `value` does not match the regular expression `regexp`.
  4972. *
  4973. * assert.notMatch('foobar', /^foo/, 'regexp does not match');
  4974. *
  4975. * @name notMatch
  4976. * @param {Mixed} value
  4977. * @param {RegExp} regexp
  4978. * @param {String} message
  4979. * @namespace Assert
  4980. * @api public
  4981. */
  4982. assert.notMatch = function (exp, re, msg) {
  4983. new Assertion(exp, msg, assert.notMatch, true).to.not.match(re);
  4984. };
  4985. /**
  4986. * ### .property(object, property, [message])
  4987. *
  4988. * Asserts that `object` has a direct or inherited property named by
  4989. * `property`.
  4990. *
  4991. * assert.property({ tea: { green: 'matcha' }}, 'tea');
  4992. * assert.property({ tea: { green: 'matcha' }}, 'toString');
  4993. *
  4994. * @name property
  4995. * @param {Object} object
  4996. * @param {String} property
  4997. * @param {String} message
  4998. * @namespace Assert
  4999. * @api public
  5000. */
  5001. assert.property = function (obj, prop, msg) {
  5002. new Assertion(obj, msg, assert.property, true).to.have.property(prop);
  5003. };
  5004. /**
  5005. * ### .notProperty(object, property, [message])
  5006. *
  5007. * Asserts that `object` does _not_ have a direct or inherited property named
  5008. * by `property`.
  5009. *
  5010. * assert.notProperty({ tea: { green: 'matcha' }}, 'coffee');
  5011. *
  5012. * @name notProperty
  5013. * @param {Object} object
  5014. * @param {String} property
  5015. * @param {String} message
  5016. * @namespace Assert
  5017. * @api public
  5018. */
  5019. assert.notProperty = function (obj, prop, msg) {
  5020. new Assertion(obj, msg, assert.notProperty, true)
  5021. .to.not.have.property(prop);
  5022. };
  5023. /**
  5024. * ### .propertyVal(object, property, value, [message])
  5025. *
  5026. * Asserts that `object` has a direct or inherited property named by
  5027. * `property` with a value given by `value`. Uses a strict equality check
  5028. * (===).
  5029. *
  5030. * assert.propertyVal({ tea: 'is good' }, 'tea', 'is good');
  5031. *
  5032. * @name propertyVal
  5033. * @param {Object} object
  5034. * @param {String} property
  5035. * @param {Mixed} value
  5036. * @param {String} message
  5037. * @namespace Assert
  5038. * @api public
  5039. */
  5040. assert.propertyVal = function (obj, prop, val, msg) {
  5041. new Assertion(obj, msg, assert.propertyVal, true)
  5042. .to.have.property(prop, val);
  5043. };
  5044. /**
  5045. * ### .notPropertyVal(object, property, value, [message])
  5046. *
  5047. * Asserts that `object` does _not_ have a direct or inherited property named
  5048. * by `property` with value given by `value`. Uses a strict equality check
  5049. * (===).
  5050. *
  5051. * assert.notPropertyVal({ tea: 'is good' }, 'tea', 'is bad');
  5052. * assert.notPropertyVal({ tea: 'is good' }, 'coffee', 'is good');
  5053. *
  5054. * @name notPropertyVal
  5055. * @param {Object} object
  5056. * @param {String} property
  5057. * @param {Mixed} value
  5058. * @param {String} message
  5059. * @namespace Assert
  5060. * @api public
  5061. */
  5062. assert.notPropertyVal = function (obj, prop, val, msg) {
  5063. new Assertion(obj, msg, assert.notPropertyVal, true)
  5064. .to.not.have.property(prop, val);
  5065. };
  5066. /**
  5067. * ### .deepPropertyVal(object, property, value, [message])
  5068. *
  5069. * Asserts that `object` has a direct or inherited property named by
  5070. * `property` with a value given by `value`. Uses a deep equality check.
  5071. *
  5072. * assert.deepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'matcha' });
  5073. *
  5074. * @name deepPropertyVal
  5075. * @param {Object} object
  5076. * @param {String} property
  5077. * @param {Mixed} value
  5078. * @param {String} message
  5079. * @namespace Assert
  5080. * @api public
  5081. */
  5082. assert.deepPropertyVal = function (obj, prop, val, msg) {
  5083. new Assertion(obj, msg, assert.deepPropertyVal, true)
  5084. .to.have.deep.property(prop, val);
  5085. };
  5086. /**
  5087. * ### .notDeepPropertyVal(object, property, value, [message])
  5088. *
  5089. * Asserts that `object` does _not_ have a direct or inherited property named
  5090. * by `property` with value given by `value`. Uses a deep equality check.
  5091. *
  5092. * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { black: 'matcha' });
  5093. * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'oolong' });
  5094. * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'coffee', { green: 'matcha' });
  5095. *
  5096. * @name notDeepPropertyVal
  5097. * @param {Object} object
  5098. * @param {String} property
  5099. * @param {Mixed} value
  5100. * @param {String} message
  5101. * @namespace Assert
  5102. * @api public
  5103. */
  5104. assert.notDeepPropertyVal = function (obj, prop, val, msg) {
  5105. new Assertion(obj, msg, assert.notDeepPropertyVal, true)
  5106. .to.not.have.deep.property(prop, val);
  5107. };
  5108. /**
  5109. * ### .ownProperty(object, property, [message])
  5110. *
  5111. * Asserts that `object` has a direct property named by `property`. Inherited
  5112. * properties aren't checked.
  5113. *
  5114. * assert.ownProperty({ tea: { green: 'matcha' }}, 'tea');
  5115. *
  5116. * @name ownProperty
  5117. * @param {Object} object
  5118. * @param {String} property
  5119. * @param {String} message
  5120. * @api public
  5121. */
  5122. assert.ownProperty = function (obj, prop, msg) {
  5123. new Assertion(obj, msg, assert.ownProperty, true)
  5124. .to.have.own.property(prop);
  5125. };
  5126. /**
  5127. * ### .notOwnProperty(object, property, [message])
  5128. *
  5129. * Asserts that `object` does _not_ have a direct property named by
  5130. * `property`. Inherited properties aren't checked.
  5131. *
  5132. * assert.notOwnProperty({ tea: { green: 'matcha' }}, 'coffee');
  5133. * assert.notOwnProperty({}, 'toString');
  5134. *
  5135. * @name notOwnProperty
  5136. * @param {Object} object
  5137. * @param {String} property
  5138. * @param {String} message
  5139. * @api public
  5140. */
  5141. assert.notOwnProperty = function (obj, prop, msg) {
  5142. new Assertion(obj, msg, assert.notOwnProperty, true)
  5143. .to.not.have.own.property(prop);
  5144. };
  5145. /**
  5146. * ### .ownPropertyVal(object, property, value, [message])
  5147. *
  5148. * Asserts that `object` has a direct property named by `property` and a value
  5149. * equal to the provided `value`. Uses a strict equality check (===).
  5150. * Inherited properties aren't checked.
  5151. *
  5152. * assert.ownPropertyVal({ coffee: 'is good'}, 'coffee', 'is good');
  5153. *
  5154. * @name ownPropertyVal
  5155. * @param {Object} object
  5156. * @param {String} property
  5157. * @param {Mixed} value
  5158. * @param {String} message
  5159. * @api public
  5160. */
  5161. assert.ownPropertyVal = function (obj, prop, value, msg) {
  5162. new Assertion(obj, msg, assert.ownPropertyVal, true)
  5163. .to.have.own.property(prop, value);
  5164. };
  5165. /**
  5166. * ### .notOwnPropertyVal(object, property, value, [message])
  5167. *
  5168. * Asserts that `object` does _not_ have a direct property named by `property`
  5169. * with a value equal to the provided `value`. Uses a strict equality check
  5170. * (===). Inherited properties aren't checked.
  5171. *
  5172. * assert.notOwnPropertyVal({ tea: 'is better'}, 'tea', 'is worse');
  5173. * assert.notOwnPropertyVal({}, 'toString', Object.prototype.toString);
  5174. *
  5175. * @name notOwnPropertyVal
  5176. * @param {Object} object
  5177. * @param {String} property
  5178. * @param {Mixed} value
  5179. * @param {String} message
  5180. * @api public
  5181. */
  5182. assert.notOwnPropertyVal = function (obj, prop, value, msg) {
  5183. new Assertion(obj, msg, assert.notOwnPropertyVal, true)
  5184. .to.not.have.own.property(prop, value);
  5185. };
  5186. /**
  5187. * ### .deepOwnPropertyVal(object, property, value, [message])
  5188. *
  5189. * Asserts that `object` has a direct property named by `property` and a value
  5190. * equal to the provided `value`. Uses a deep equality check. Inherited
  5191. * properties aren't checked.
  5192. *
  5193. * assert.deepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'matcha' });
  5194. *
  5195. * @name deepOwnPropertyVal
  5196. * @param {Object} object
  5197. * @param {String} property
  5198. * @param {Mixed} value
  5199. * @param {String} message
  5200. * @api public
  5201. */
  5202. assert.deepOwnPropertyVal = function (obj, prop, value, msg) {
  5203. new Assertion(obj, msg, assert.deepOwnPropertyVal, true)
  5204. .to.have.deep.own.property(prop, value);
  5205. };
  5206. /**
  5207. * ### .notDeepOwnPropertyVal(object, property, value, [message])
  5208. *
  5209. * Asserts that `object` does _not_ have a direct property named by `property`
  5210. * with a value equal to the provided `value`. Uses a deep equality check.
  5211. * Inherited properties aren't checked.
  5212. *
  5213. * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { black: 'matcha' });
  5214. * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'oolong' });
  5215. * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'coffee', { green: 'matcha' });
  5216. * assert.notDeepOwnPropertyVal({}, 'toString', Object.prototype.toString);
  5217. *
  5218. * @name notDeepOwnPropertyVal
  5219. * @param {Object} object
  5220. * @param {String} property
  5221. * @param {Mixed} value
  5222. * @param {String} message
  5223. * @api public
  5224. */
  5225. assert.notDeepOwnPropertyVal = function (obj, prop, value, msg) {
  5226. new Assertion(obj, msg, assert.notDeepOwnPropertyVal, true)
  5227. .to.not.have.deep.own.property(prop, value);
  5228. };
  5229. /**
  5230. * ### .nestedProperty(object, property, [message])
  5231. *
  5232. * Asserts that `object` has a direct or inherited property named by
  5233. * `property`, which can be a string using dot- and bracket-notation for
  5234. * nested reference.
  5235. *
  5236. * assert.nestedProperty({ tea: { green: 'matcha' }}, 'tea.green');
  5237. *
  5238. * @name nestedProperty
  5239. * @param {Object} object
  5240. * @param {String} property
  5241. * @param {String} message
  5242. * @namespace Assert
  5243. * @api public
  5244. */
  5245. assert.nestedProperty = function (obj, prop, msg) {
  5246. new Assertion(obj, msg, assert.nestedProperty, true)
  5247. .to.have.nested.property(prop);
  5248. };
  5249. /**
  5250. * ### .notNestedProperty(object, property, [message])
  5251. *
  5252. * Asserts that `object` does _not_ have a property named by `property`, which
  5253. * can be a string using dot- and bracket-notation for nested reference. The
  5254. * property cannot exist on the object nor anywhere in its prototype chain.
  5255. *
  5256. * assert.notNestedProperty({ tea: { green: 'matcha' }}, 'tea.oolong');
  5257. *
  5258. * @name notNestedProperty
  5259. * @param {Object} object
  5260. * @param {String} property
  5261. * @param {String} message
  5262. * @namespace Assert
  5263. * @api public
  5264. */
  5265. assert.notNestedProperty = function (obj, prop, msg) {
  5266. new Assertion(obj, msg, assert.notNestedProperty, true)
  5267. .to.not.have.nested.property(prop);
  5268. };
  5269. /**
  5270. * ### .nestedPropertyVal(object, property, value, [message])
  5271. *
  5272. * Asserts that `object` has a property named by `property` with value given
  5273. * by `value`. `property` can use dot- and bracket-notation for nested
  5274. * reference. Uses a strict equality check (===).
  5275. *
  5276. * assert.nestedPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha');
  5277. *
  5278. * @name nestedPropertyVal
  5279. * @param {Object} object
  5280. * @param {String} property
  5281. * @param {Mixed} value
  5282. * @param {String} message
  5283. * @namespace Assert
  5284. * @api public
  5285. */
  5286. assert.nestedPropertyVal = function (obj, prop, val, msg) {
  5287. new Assertion(obj, msg, assert.nestedPropertyVal, true)
  5288. .to.have.nested.property(prop, val);
  5289. };
  5290. /**
  5291. * ### .notNestedPropertyVal(object, property, value, [message])
  5292. *
  5293. * Asserts that `object` does _not_ have a property named by `property` with
  5294. * value given by `value`. `property` can use dot- and bracket-notation for
  5295. * nested reference. Uses a strict equality check (===).
  5296. *
  5297. * assert.notNestedPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha');
  5298. * assert.notNestedPropertyVal({ tea: { green: 'matcha' }}, 'coffee.green', 'matcha');
  5299. *
  5300. * @name notNestedPropertyVal
  5301. * @param {Object} object
  5302. * @param {String} property
  5303. * @param {Mixed} value
  5304. * @param {String} message
  5305. * @namespace Assert
  5306. * @api public
  5307. */
  5308. assert.notNestedPropertyVal = function (obj, prop, val, msg) {
  5309. new Assertion(obj, msg, assert.notNestedPropertyVal, true)
  5310. .to.not.have.nested.property(prop, val);
  5311. };
  5312. /**
  5313. * ### .deepNestedPropertyVal(object, property, value, [message])
  5314. *
  5315. * Asserts that `object` has a property named by `property` with a value given
  5316. * by `value`. `property` can use dot- and bracket-notation for nested
  5317. * reference. Uses a deep equality check.
  5318. *
  5319. * assert.deepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { matcha: 'yum' });
  5320. *
  5321. * @name deepNestedPropertyVal
  5322. * @param {Object} object
  5323. * @param {String} property
  5324. * @param {Mixed} value
  5325. * @param {String} message
  5326. * @namespace Assert
  5327. * @api public
  5328. */
  5329. assert.deepNestedPropertyVal = function (obj, prop, val, msg) {
  5330. new Assertion(obj, msg, assert.deepNestedPropertyVal, true)
  5331. .to.have.deep.nested.property(prop, val);
  5332. };
  5333. /**
  5334. * ### .notDeepNestedPropertyVal(object, property, value, [message])
  5335. *
  5336. * Asserts that `object` does _not_ have a property named by `property` with
  5337. * value given by `value`. `property` can use dot- and bracket-notation for
  5338. * nested reference. Uses a deep equality check.
  5339. *
  5340. * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { oolong: 'yum' });
  5341. * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { matcha: 'yuck' });
  5342. * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.black', { matcha: 'yum' });
  5343. *
  5344. * @name notDeepNestedPropertyVal
  5345. * @param {Object} object
  5346. * @param {String} property
  5347. * @param {Mixed} value
  5348. * @param {String} message
  5349. * @namespace Assert
  5350. * @api public
  5351. */
  5352. assert.notDeepNestedPropertyVal = function (obj, prop, val, msg) {
  5353. new Assertion(obj, msg, assert.notDeepNestedPropertyVal, true)
  5354. .to.not.have.deep.nested.property(prop, val);
  5355. }
  5356. /**
  5357. * ### .lengthOf(object, length, [message])
  5358. *
  5359. * Asserts that `object` has a `length` or `size` with the expected value.
  5360. *
  5361. * assert.lengthOf([1,2,3], 3, 'array has length of 3');
  5362. * assert.lengthOf('foobar', 6, 'string has length of 6');
  5363. * assert.lengthOf(new Set([1,2,3]), 3, 'set has size of 3');
  5364. * assert.lengthOf(new Map([['a',1],['b',2],['c',3]]), 3, 'map has size of 3');
  5365. *
  5366. * @name lengthOf
  5367. * @param {Mixed} object
  5368. * @param {Number} length
  5369. * @param {String} message
  5370. * @namespace Assert
  5371. * @api public
  5372. */
  5373. assert.lengthOf = function (exp, len, msg) {
  5374. new Assertion(exp, msg, assert.lengthOf, true).to.have.lengthOf(len);
  5375. };
  5376. /**
  5377. * ### .hasAnyKeys(object, [keys], [message])
  5378. *
  5379. * Asserts that `object` has at least one of the `keys` provided.
  5380. * You can also provide a single object instead of a `keys` array and its keys
  5381. * will be used as the expected set of keys.
  5382. *
  5383. * assert.hasAnyKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'iDontExist', 'baz']);
  5384. * assert.hasAnyKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, iDontExist: 99, baz: 1337});
  5385. * assert.hasAnyKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']);
  5386. * assert.hasAnyKeys(new Set([{foo: 'bar'}, 'anotherKey']), [{foo: 'bar'}, 'anotherKey']);
  5387. *
  5388. * @name hasAnyKeys
  5389. * @param {Mixed} object
  5390. * @param {Array|Object} keys
  5391. * @param {String} message
  5392. * @namespace Assert
  5393. * @api public
  5394. */
  5395. assert.hasAnyKeys = function (obj, keys, msg) {
  5396. new Assertion(obj, msg, assert.hasAnyKeys, true).to.have.any.keys(keys);
  5397. }
  5398. /**
  5399. * ### .hasAllKeys(object, [keys], [message])
  5400. *
  5401. * Asserts that `object` has all and only all of the `keys` provided.
  5402. * You can also provide a single object instead of a `keys` array and its keys
  5403. * will be used as the expected set of keys.
  5404. *
  5405. * assert.hasAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'bar', 'baz']);
  5406. * assert.hasAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, bar: 99, baz: 1337]);
  5407. * assert.hasAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']);
  5408. * assert.hasAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}, 'anotherKey']);
  5409. *
  5410. * @name hasAllKeys
  5411. * @param {Mixed} object
  5412. * @param {String[]} keys
  5413. * @param {String} message
  5414. * @namespace Assert
  5415. * @api public
  5416. */
  5417. assert.hasAllKeys = function (obj, keys, msg) {
  5418. new Assertion(obj, msg, assert.hasAllKeys, true).to.have.all.keys(keys);
  5419. }
  5420. /**
  5421. * ### .containsAllKeys(object, [keys], [message])
  5422. *
  5423. * Asserts that `object` has all of the `keys` provided but may have more keys not listed.
  5424. * You can also provide a single object instead of a `keys` array and its keys
  5425. * will be used as the expected set of keys.
  5426. *
  5427. * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'baz']);
  5428. * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'bar', 'baz']);
  5429. * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, baz: 1337});
  5430. * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, bar: 99, baz: 1337});
  5431. * assert.containsAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}]);
  5432. * assert.containsAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']);
  5433. * assert.containsAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}]);
  5434. * assert.containsAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}, 'anotherKey']);
  5435. *
  5436. * @name containsAllKeys
  5437. * @param {Mixed} object
  5438. * @param {String[]} keys
  5439. * @param {String} message
  5440. * @namespace Assert
  5441. * @api public
  5442. */
  5443. assert.containsAllKeys = function (obj, keys, msg) {
  5444. new Assertion(obj, msg, assert.containsAllKeys, true)
  5445. .to.contain.all.keys(keys);
  5446. }
  5447. /**
  5448. * ### .doesNotHaveAnyKeys(object, [keys], [message])
  5449. *
  5450. * Asserts that `object` has none of the `keys` provided.
  5451. * You can also provide a single object instead of a `keys` array and its keys
  5452. * will be used as the expected set of keys.
  5453. *
  5454. * assert.doesNotHaveAnyKeys({foo: 1, bar: 2, baz: 3}, ['one', 'two', 'example']);
  5455. * assert.doesNotHaveAnyKeys({foo: 1, bar: 2, baz: 3}, {one: 1, two: 2, example: 'foo'});
  5456. * assert.doesNotHaveAnyKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{one: 'two'}, 'example']);
  5457. * assert.doesNotHaveAnyKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{one: 'two'}, 'example']);
  5458. *
  5459. * @name doesNotHaveAnyKeys
  5460. * @param {Mixed} object
  5461. * @param {String[]} keys
  5462. * @param {String} message
  5463. * @namespace Assert
  5464. * @api public
  5465. */
  5466. assert.doesNotHaveAnyKeys = function (obj, keys, msg) {
  5467. new Assertion(obj, msg, assert.doesNotHaveAnyKeys, true)
  5468. .to.not.have.any.keys(keys);
  5469. }
  5470. /**
  5471. * ### .doesNotHaveAllKeys(object, [keys], [message])
  5472. *
  5473. * Asserts that `object` does not have at least one of the `keys` provided.
  5474. * You can also provide a single object instead of a `keys` array and its keys
  5475. * will be used as the expected set of keys.
  5476. *
  5477. * assert.doesNotHaveAllKeys({foo: 1, bar: 2, baz: 3}, ['one', 'two', 'example']);
  5478. * assert.doesNotHaveAllKeys({foo: 1, bar: 2, baz: 3}, {one: 1, two: 2, example: 'foo'});
  5479. * assert.doesNotHaveAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{one: 'two'}, 'example']);
  5480. * assert.doesNotHaveAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{one: 'two'}, 'example']);
  5481. *
  5482. * @name doesNotHaveAllKeys
  5483. * @param {Mixed} object
  5484. * @param {String[]} keys
  5485. * @param {String} message
  5486. * @namespace Assert
  5487. * @api public
  5488. */
  5489. assert.doesNotHaveAllKeys = function (obj, keys, msg) {
  5490. new Assertion(obj, msg, assert.doesNotHaveAllKeys, true)
  5491. .to.not.have.all.keys(keys);
  5492. }
  5493. /**
  5494. * ### .hasAnyDeepKeys(object, [keys], [message])
  5495. *
  5496. * Asserts that `object` has at least one of the `keys` provided.
  5497. * Since Sets and Maps can have objects as keys you can use this assertion to perform
  5498. * a deep comparison.
  5499. * You can also provide a single object instead of a `keys` array and its keys
  5500. * will be used as the expected set of keys.
  5501. *
  5502. * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {one: 'one'});
  5503. * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), [{one: 'one'}, {two: 'two'}]);
  5504. * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]);
  5505. * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {one: 'one'});
  5506. * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {three: 'three'}]);
  5507. * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]);
  5508. *
  5509. * @name doesNotHaveAllKeys
  5510. * @param {Mixed} object
  5511. * @param {Array|Object} keys
  5512. * @param {String} message
  5513. * @namespace Assert
  5514. * @api public
  5515. */
  5516. assert.hasAnyDeepKeys = function (obj, keys, msg) {
  5517. new Assertion(obj, msg, assert.hasAnyDeepKeys, true)
  5518. .to.have.any.deep.keys(keys);
  5519. }
  5520. /**
  5521. * ### .hasAllDeepKeys(object, [keys], [message])
  5522. *
  5523. * Asserts that `object` has all and only all of the `keys` provided.
  5524. * Since Sets and Maps can have objects as keys you can use this assertion to perform
  5525. * a deep comparison.
  5526. * You can also provide a single object instead of a `keys` array and its keys
  5527. * will be used as the expected set of keys.
  5528. *
  5529. * assert.hasAllDeepKeys(new Map([[{one: 'one'}, 'valueOne']]), {one: 'one'});
  5530. * assert.hasAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]);
  5531. * assert.hasAllDeepKeys(new Set([{one: 'one'}]), {one: 'one'});
  5532. * assert.hasAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]);
  5533. *
  5534. * @name hasAllDeepKeys
  5535. * @param {Mixed} object
  5536. * @param {Array|Object} keys
  5537. * @param {String} message
  5538. * @namespace Assert
  5539. * @api public
  5540. */
  5541. assert.hasAllDeepKeys = function (obj, keys, msg) {
  5542. new Assertion(obj, msg, assert.hasAllDeepKeys, true)
  5543. .to.have.all.deep.keys(keys);
  5544. }
  5545. /**
  5546. * ### .containsAllDeepKeys(object, [keys], [message])
  5547. *
  5548. * Asserts that `object` contains all of the `keys` provided.
  5549. * Since Sets and Maps can have objects as keys you can use this assertion to perform
  5550. * a deep comparison.
  5551. * You can also provide a single object instead of a `keys` array and its keys
  5552. * will be used as the expected set of keys.
  5553. *
  5554. * assert.containsAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {one: 'one'});
  5555. * assert.containsAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]);
  5556. * assert.containsAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {one: 'one'});
  5557. * assert.containsAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]);
  5558. *
  5559. * @name containsAllDeepKeys
  5560. * @param {Mixed} object
  5561. * @param {Array|Object} keys
  5562. * @param {String} message
  5563. * @namespace Assert
  5564. * @api public
  5565. */
  5566. assert.containsAllDeepKeys = function (obj, keys, msg) {
  5567. new Assertion(obj, msg, assert.containsAllDeepKeys, true)
  5568. .to.contain.all.deep.keys(keys);
  5569. }
  5570. /**
  5571. * ### .doesNotHaveAnyDeepKeys(object, [keys], [message])
  5572. *
  5573. * Asserts that `object` has none of the `keys` provided.
  5574. * Since Sets and Maps can have objects as keys you can use this assertion to perform
  5575. * a deep comparison.
  5576. * You can also provide a single object instead of a `keys` array and its keys
  5577. * will be used as the expected set of keys.
  5578. *
  5579. * assert.doesNotHaveAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {thisDoesNot: 'exist'});
  5580. * assert.doesNotHaveAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{twenty: 'twenty'}, {fifty: 'fifty'}]);
  5581. * assert.doesNotHaveAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {twenty: 'twenty'});
  5582. * assert.doesNotHaveAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{twenty: 'twenty'}, {fifty: 'fifty'}]);
  5583. *
  5584. * @name doesNotHaveAnyDeepKeys
  5585. * @param {Mixed} object
  5586. * @param {Array|Object} keys
  5587. * @param {String} message
  5588. * @namespace Assert
  5589. * @api public
  5590. */
  5591. assert.doesNotHaveAnyDeepKeys = function (obj, keys, msg) {
  5592. new Assertion(obj, msg, assert.doesNotHaveAnyDeepKeys, true)
  5593. .to.not.have.any.deep.keys(keys);
  5594. }
  5595. /**
  5596. * ### .doesNotHaveAllDeepKeys(object, [keys], [message])
  5597. *
  5598. * Asserts that `object` does not have at least one of the `keys` provided.
  5599. * Since Sets and Maps can have objects as keys you can use this assertion to perform
  5600. * a deep comparison.
  5601. * You can also provide a single object instead of a `keys` array and its keys
  5602. * will be used as the expected set of keys.
  5603. *
  5604. * assert.doesNotHaveAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {thisDoesNot: 'exist'});
  5605. * assert.doesNotHaveAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{twenty: 'twenty'}, {one: 'one'}]);
  5606. * assert.doesNotHaveAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {twenty: 'twenty'});
  5607. * assert.doesNotHaveAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {fifty: 'fifty'}]);
  5608. *
  5609. * @name doesNotHaveAllDeepKeys
  5610. * @param {Mixed} object
  5611. * @param {Array|Object} keys
  5612. * @param {String} message
  5613. * @namespace Assert
  5614. * @api public
  5615. */
  5616. assert.doesNotHaveAllDeepKeys = function (obj, keys, msg) {
  5617. new Assertion(obj, msg, assert.doesNotHaveAllDeepKeys, true)
  5618. .to.not.have.all.deep.keys(keys);
  5619. }
  5620. /**
  5621. * ### .throws(fn, [errorLike/string/regexp], [string/regexp], [message])
  5622. *
  5623. * If `errorLike` is an `Error` constructor, asserts that `fn` will throw an error that is an
  5624. * instance of `errorLike`.
  5625. * If `errorLike` is an `Error` instance, asserts that the error thrown is the same
  5626. * instance as `errorLike`.
  5627. * If `errMsgMatcher` is provided, it also asserts that the error thrown will have a
  5628. * message matching `errMsgMatcher`.
  5629. *
  5630. * assert.throws(fn, 'Error thrown must have this msg');
  5631. * assert.throws(fn, /Error thrown must have a msg that matches this/);
  5632. * assert.throws(fn, ReferenceError);
  5633. * assert.throws(fn, errorInstance);
  5634. * assert.throws(fn, ReferenceError, 'Error thrown must be a ReferenceError and have this msg');
  5635. * assert.throws(fn, errorInstance, 'Error thrown must be the same errorInstance and have this msg');
  5636. * assert.throws(fn, ReferenceError, /Error thrown must be a ReferenceError and match this/);
  5637. * assert.throws(fn, errorInstance, /Error thrown must be the same errorInstance and match this/);
  5638. *
  5639. * @name throws
  5640. * @alias throw
  5641. * @alias Throw
  5642. * @param {Function} fn
  5643. * @param {ErrorConstructor|Error} errorLike
  5644. * @param {RegExp|String} errMsgMatcher
  5645. * @param {String} message
  5646. * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
  5647. * @namespace Assert
  5648. * @api public
  5649. */
  5650. assert.throws = function (fn, errorLike, errMsgMatcher, msg) {
  5651. if ('string' === typeof errorLike || errorLike instanceof RegExp) {
  5652. errMsgMatcher = errorLike;
  5653. errorLike = null;
  5654. }
  5655. var assertErr = new Assertion(fn, msg, assert.throws, true)
  5656. .to.throw(errorLike, errMsgMatcher);
  5657. return flag(assertErr, 'object');
  5658. };
  5659. /**
  5660. * ### .doesNotThrow(fn, [errorLike/string/regexp], [string/regexp], [message])
  5661. *
  5662. * If `errorLike` is an `Error` constructor, asserts that `fn` will _not_ throw an error that is an
  5663. * instance of `errorLike`.
  5664. * If `errorLike` is an `Error` instance, asserts that the error thrown is _not_ the same
  5665. * instance as `errorLike`.
  5666. * If `errMsgMatcher` is provided, it also asserts that the error thrown will _not_ have a
  5667. * message matching `errMsgMatcher`.
  5668. *
  5669. * assert.doesNotThrow(fn, 'Any Error thrown must not have this message');
  5670. * assert.doesNotThrow(fn, /Any Error thrown must not match this/);
  5671. * assert.doesNotThrow(fn, Error);
  5672. * assert.doesNotThrow(fn, errorInstance);
  5673. * assert.doesNotThrow(fn, Error, 'Error must not have this message');
  5674. * assert.doesNotThrow(fn, errorInstance, 'Error must not have this message');
  5675. * assert.doesNotThrow(fn, Error, /Error must not match this/);
  5676. * assert.doesNotThrow(fn, errorInstance, /Error must not match this/);
  5677. *
  5678. * @name doesNotThrow
  5679. * @param {Function} fn
  5680. * @param {ErrorConstructor} errorLike
  5681. * @param {RegExp|String} errMsgMatcher
  5682. * @param {String} message
  5683. * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
  5684. * @namespace Assert
  5685. * @api public
  5686. */
  5687. assert.doesNotThrow = function (fn, errorLike, errMsgMatcher, msg) {
  5688. if ('string' === typeof errorLike || errorLike instanceof RegExp) {
  5689. errMsgMatcher = errorLike;
  5690. errorLike = null;
  5691. }
  5692. new Assertion(fn, msg, assert.doesNotThrow, true)
  5693. .to.not.throw(errorLike, errMsgMatcher);
  5694. };
  5695. /**
  5696. * ### .operator(val1, operator, val2, [message])
  5697. *
  5698. * Compares two values using `operator`.
  5699. *
  5700. * assert.operator(1, '<', 2, 'everything is ok');
  5701. * assert.operator(1, '>', 2, 'this will fail');
  5702. *
  5703. * @name operator
  5704. * @param {Mixed} val1
  5705. * @param {String} operator
  5706. * @param {Mixed} val2
  5707. * @param {String} message
  5708. * @namespace Assert
  5709. * @api public
  5710. */
  5711. assert.operator = function (val, operator, val2, msg) {
  5712. var ok;
  5713. switch(operator) {
  5714. case '==':
  5715. ok = val == val2;
  5716. break;
  5717. case '===':
  5718. ok = val === val2;
  5719. break;
  5720. case '>':
  5721. ok = val > val2;
  5722. break;
  5723. case '>=':
  5724. ok = val >= val2;
  5725. break;
  5726. case '<':
  5727. ok = val < val2;
  5728. break;
  5729. case '<=':
  5730. ok = val <= val2;
  5731. break;
  5732. case '!=':
  5733. ok = val != val2;
  5734. break;
  5735. case '!==':
  5736. ok = val !== val2;
  5737. break;
  5738. default:
  5739. msg = msg ? msg + ': ' : msg;
  5740. throw new chai.AssertionError(
  5741. msg + 'Invalid operator "' + operator + '"',
  5742. undefined,
  5743. assert.operator
  5744. );
  5745. }
  5746. var test = new Assertion(ok, msg, assert.operator, true);
  5747. test.assert(
  5748. true === flag(test, 'object')
  5749. , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2)
  5750. , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) );
  5751. };
  5752. /**
  5753. * ### .closeTo(actual, expected, delta, [message])
  5754. *
  5755. * Asserts that the target is equal `expected`, to within a +/- `delta` range.
  5756. *
  5757. * assert.closeTo(1.5, 1, 0.5, 'numbers are close');
  5758. *
  5759. * @name closeTo
  5760. * @param {Number} actual
  5761. * @param {Number} expected
  5762. * @param {Number} delta
  5763. * @param {String} message
  5764. * @namespace Assert
  5765. * @api public
  5766. */
  5767. assert.closeTo = function (act, exp, delta, msg) {
  5768. new Assertion(act, msg, assert.closeTo, true).to.be.closeTo(exp, delta);
  5769. };
  5770. /**
  5771. * ### .approximately(actual, expected, delta, [message])
  5772. *
  5773. * Asserts that the target is equal `expected`, to within a +/- `delta` range.
  5774. *
  5775. * assert.approximately(1.5, 1, 0.5, 'numbers are close');
  5776. *
  5777. * @name approximately
  5778. * @param {Number} actual
  5779. * @param {Number} expected
  5780. * @param {Number} delta
  5781. * @param {String} message
  5782. * @namespace Assert
  5783. * @api public
  5784. */
  5785. assert.approximately = function (act, exp, delta, msg) {
  5786. new Assertion(act, msg, assert.approximately, true)
  5787. .to.be.approximately(exp, delta);
  5788. };
  5789. /**
  5790. * ### .sameMembers(set1, set2, [message])
  5791. *
  5792. * Asserts that `set1` and `set2` have the same members in any order. Uses a
  5793. * strict equality check (===).
  5794. *
  5795. * assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members');
  5796. *
  5797. * @name sameMembers
  5798. * @param {Array} set1
  5799. * @param {Array} set2
  5800. * @param {String} message
  5801. * @namespace Assert
  5802. * @api public
  5803. */
  5804. assert.sameMembers = function (set1, set2, msg) {
  5805. new Assertion(set1, msg, assert.sameMembers, true)
  5806. .to.have.same.members(set2);
  5807. }
  5808. /**
  5809. * ### .notSameMembers(set1, set2, [message])
  5810. *
  5811. * Asserts that `set1` and `set2` don't have the same members in any order.
  5812. * Uses a strict equality check (===).
  5813. *
  5814. * assert.notSameMembers([ 1, 2, 3 ], [ 5, 1, 3 ], 'not same members');
  5815. *
  5816. * @name notSameMembers
  5817. * @param {Array} set1
  5818. * @param {Array} set2
  5819. * @param {String} message
  5820. * @namespace Assert
  5821. * @api public
  5822. */
  5823. assert.notSameMembers = function (set1, set2, msg) {
  5824. new Assertion(set1, msg, assert.notSameMembers, true)
  5825. .to.not.have.same.members(set2);
  5826. }
  5827. /**
  5828. * ### .sameDeepMembers(set1, set2, [message])
  5829. *
  5830. * Asserts that `set1` and `set2` have the same members in any order. Uses a
  5831. * deep equality check.
  5832. *
  5833. * assert.sameDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [{ b: 2 }, { a: 1 }, { c: 3 }], 'same deep members');
  5834. *
  5835. * @name sameDeepMembers
  5836. * @param {Array} set1
  5837. * @param {Array} set2
  5838. * @param {String} message
  5839. * @namespace Assert
  5840. * @api public
  5841. */
  5842. assert.sameDeepMembers = function (set1, set2, msg) {
  5843. new Assertion(set1, msg, assert.sameDeepMembers, true)
  5844. .to.have.same.deep.members(set2);
  5845. }
  5846. /**
  5847. * ### .notSameDeepMembers(set1, set2, [message])
  5848. *
  5849. * Asserts that `set1` and `set2` don't have the same members in any order.
  5850. * Uses a deep equality check.
  5851. *
  5852. * assert.notSameDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [{ b: 2 }, { a: 1 }, { f: 5 }], 'not same deep members');
  5853. *
  5854. * @name notSameDeepMembers
  5855. * @param {Array} set1
  5856. * @param {Array} set2
  5857. * @param {String} message
  5858. * @namespace Assert
  5859. * @api public
  5860. */
  5861. assert.notSameDeepMembers = function (set1, set2, msg) {
  5862. new Assertion(set1, msg, assert.notSameDeepMembers, true)
  5863. .to.not.have.same.deep.members(set2);
  5864. }
  5865. /**
  5866. * ### .sameOrderedMembers(set1, set2, [message])
  5867. *
  5868. * Asserts that `set1` and `set2` have the same members in the same order.
  5869. * Uses a strict equality check (===).
  5870. *
  5871. * assert.sameOrderedMembers([ 1, 2, 3 ], [ 1, 2, 3 ], 'same ordered members');
  5872. *
  5873. * @name sameOrderedMembers
  5874. * @param {Array} set1
  5875. * @param {Array} set2
  5876. * @param {String} message
  5877. * @namespace Assert
  5878. * @api public
  5879. */
  5880. assert.sameOrderedMembers = function (set1, set2, msg) {
  5881. new Assertion(set1, msg, assert.sameOrderedMembers, true)
  5882. .to.have.same.ordered.members(set2);
  5883. }
  5884. /**
  5885. * ### .notSameOrderedMembers(set1, set2, [message])
  5886. *
  5887. * Asserts that `set1` and `set2` don't have the same members in the same
  5888. * order. Uses a strict equality check (===).
  5889. *
  5890. * assert.notSameOrderedMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'not same ordered members');
  5891. *
  5892. * @name notSameOrderedMembers
  5893. * @param {Array} set1
  5894. * @param {Array} set2
  5895. * @param {String} message
  5896. * @namespace Assert
  5897. * @api public
  5898. */
  5899. assert.notSameOrderedMembers = function (set1, set2, msg) {
  5900. new Assertion(set1, msg, assert.notSameOrderedMembers, true)
  5901. .to.not.have.same.ordered.members(set2);
  5902. }
  5903. /**
  5904. * ### .sameDeepOrderedMembers(set1, set2, [message])
  5905. *
  5906. * Asserts that `set1` and `set2` have the same members in the same order.
  5907. * Uses a deep equality check.
  5908. *
  5909. * assert.sameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 }, { c: 3 } ], 'same deep ordered members');
  5910. *
  5911. * @name sameDeepOrderedMembers
  5912. * @param {Array} set1
  5913. * @param {Array} set2
  5914. * @param {String} message
  5915. * @namespace Assert
  5916. * @api public
  5917. */
  5918. assert.sameDeepOrderedMembers = function (set1, set2, msg) {
  5919. new Assertion(set1, msg, assert.sameDeepOrderedMembers, true)
  5920. .to.have.same.deep.ordered.members(set2);
  5921. }
  5922. /**
  5923. * ### .notSameDeepOrderedMembers(set1, set2, [message])
  5924. *
  5925. * Asserts that `set1` and `set2` don't have the same members in the same
  5926. * order. Uses a deep equality check.
  5927. *
  5928. * assert.notSameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 }, { z: 5 } ], 'not same deep ordered members');
  5929. * assert.notSameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 }, { c: 3 } ], 'not same deep ordered members');
  5930. *
  5931. * @name notSameDeepOrderedMembers
  5932. * @param {Array} set1
  5933. * @param {Array} set2
  5934. * @param {String} message
  5935. * @namespace Assert
  5936. * @api public
  5937. */
  5938. assert.notSameDeepOrderedMembers = function (set1, set2, msg) {
  5939. new Assertion(set1, msg, assert.notSameDeepOrderedMembers, true)
  5940. .to.not.have.same.deep.ordered.members(set2);
  5941. }
  5942. /**
  5943. * ### .includeMembers(superset, subset, [message])
  5944. *
  5945. * Asserts that `subset` is included in `superset` in any order. Uses a
  5946. * strict equality check (===). Duplicates are ignored.
  5947. *
  5948. * assert.includeMembers([ 1, 2, 3 ], [ 2, 1, 2 ], 'include members');
  5949. *
  5950. * @name includeMembers
  5951. * @param {Array} superset
  5952. * @param {Array} subset
  5953. * @param {String} message
  5954. * @namespace Assert
  5955. * @api public
  5956. */
  5957. assert.includeMembers = function (superset, subset, msg) {
  5958. new Assertion(superset, msg, assert.includeMembers, true)
  5959. .to.include.members(subset);
  5960. }
  5961. /**
  5962. * ### .notIncludeMembers(superset, subset, [message])
  5963. *
  5964. * Asserts that `subset` isn't included in `superset` in any order. Uses a
  5965. * strict equality check (===). Duplicates are ignored.
  5966. *
  5967. * assert.notIncludeMembers([ 1, 2, 3 ], [ 5, 1 ], 'not include members');
  5968. *
  5969. * @name notIncludeMembers
  5970. * @param {Array} superset
  5971. * @param {Array} subset
  5972. * @param {String} message
  5973. * @namespace Assert
  5974. * @api public
  5975. */
  5976. assert.notIncludeMembers = function (superset, subset, msg) {
  5977. new Assertion(superset, msg, assert.notIncludeMembers, true)
  5978. .to.not.include.members(subset);
  5979. }
  5980. /**
  5981. * ### .includeDeepMembers(superset, subset, [message])
  5982. *
  5983. * Asserts that `subset` is included in `superset` in any order. Uses a deep
  5984. * equality check. Duplicates are ignored.
  5985. *
  5986. * assert.includeDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 }, { b: 2 } ], 'include deep members');
  5987. *
  5988. * @name includeDeepMembers
  5989. * @param {Array} superset
  5990. * @param {Array} subset
  5991. * @param {String} message
  5992. * @namespace Assert
  5993. * @api public
  5994. */
  5995. assert.includeDeepMembers = function (superset, subset, msg) {
  5996. new Assertion(superset, msg, assert.includeDeepMembers, true)
  5997. .to.include.deep.members(subset);
  5998. }
  5999. /**
  6000. * ### .notIncludeDeepMembers(superset, subset, [message])
  6001. *
  6002. * Asserts that `subset` isn't included in `superset` in any order. Uses a
  6003. * deep equality check. Duplicates are ignored.
  6004. *
  6005. * assert.notIncludeDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { f: 5 } ], 'not include deep members');
  6006. *
  6007. * @name notIncludeDeepMembers
  6008. * @param {Array} superset
  6009. * @param {Array} subset
  6010. * @param {String} message
  6011. * @namespace Assert
  6012. * @api public
  6013. */
  6014. assert.notIncludeDeepMembers = function (superset, subset, msg) {
  6015. new Assertion(superset, msg, assert.notIncludeDeepMembers, true)
  6016. .to.not.include.deep.members(subset);
  6017. }
  6018. /**
  6019. * ### .includeOrderedMembers(superset, subset, [message])
  6020. *
  6021. * Asserts that `subset` is included in `superset` in the same order
  6022. * beginning with the first element in `superset`. Uses a strict equality
  6023. * check (===).
  6024. *
  6025. * assert.includeOrderedMembers([ 1, 2, 3 ], [ 1, 2 ], 'include ordered members');
  6026. *
  6027. * @name includeOrderedMembers
  6028. * @param {Array} superset
  6029. * @param {Array} subset
  6030. * @param {String} message
  6031. * @namespace Assert
  6032. * @api public
  6033. */
  6034. assert.includeOrderedMembers = function (superset, subset, msg) {
  6035. new Assertion(superset, msg, assert.includeOrderedMembers, true)
  6036. .to.include.ordered.members(subset);
  6037. }
  6038. /**
  6039. * ### .notIncludeOrderedMembers(superset, subset, [message])
  6040. *
  6041. * Asserts that `subset` isn't included in `superset` in the same order
  6042. * beginning with the first element in `superset`. Uses a strict equality
  6043. * check (===).
  6044. *
  6045. * assert.notIncludeOrderedMembers([ 1, 2, 3 ], [ 2, 1 ], 'not include ordered members');
  6046. * assert.notIncludeOrderedMembers([ 1, 2, 3 ], [ 2, 3 ], 'not include ordered members');
  6047. *
  6048. * @name notIncludeOrderedMembers
  6049. * @param {Array} superset
  6050. * @param {Array} subset
  6051. * @param {String} message
  6052. * @namespace Assert
  6053. * @api public
  6054. */
  6055. assert.notIncludeOrderedMembers = function (superset, subset, msg) {
  6056. new Assertion(superset, msg, assert.notIncludeOrderedMembers, true)
  6057. .to.not.include.ordered.members(subset);
  6058. }
  6059. /**
  6060. * ### .includeDeepOrderedMembers(superset, subset, [message])
  6061. *
  6062. * Asserts that `subset` is included in `superset` in the same order
  6063. * beginning with the first element in `superset`. Uses a deep equality
  6064. * check.
  6065. *
  6066. * assert.includeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 } ], 'include deep ordered members');
  6067. *
  6068. * @name includeDeepOrderedMembers
  6069. * @param {Array} superset
  6070. * @param {Array} subset
  6071. * @param {String} message
  6072. * @namespace Assert
  6073. * @api public
  6074. */
  6075. assert.includeDeepOrderedMembers = function (superset, subset, msg) {
  6076. new Assertion(superset, msg, assert.includeDeepOrderedMembers, true)
  6077. .to.include.deep.ordered.members(subset);
  6078. }
  6079. /**
  6080. * ### .notIncludeDeepOrderedMembers(superset, subset, [message])
  6081. *
  6082. * Asserts that `subset` isn't included in `superset` in the same order
  6083. * beginning with the first element in `superset`. Uses a deep equality
  6084. * check.
  6085. *
  6086. * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { f: 5 } ], 'not include deep ordered members');
  6087. * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 } ], 'not include deep ordered members');
  6088. * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { c: 3 } ], 'not include deep ordered members');
  6089. *
  6090. * @name notIncludeDeepOrderedMembers
  6091. * @param {Array} superset
  6092. * @param {Array} subset
  6093. * @param {String} message
  6094. * @namespace Assert
  6095. * @api public
  6096. */
  6097. assert.notIncludeDeepOrderedMembers = function (superset, subset, msg) {
  6098. new Assertion(superset, msg, assert.notIncludeDeepOrderedMembers, true)
  6099. .to.not.include.deep.ordered.members(subset);
  6100. }
  6101. /**
  6102. * ### .oneOf(inList, list, [message])
  6103. *
  6104. * Asserts that non-object, non-array value `inList` appears in the flat array `list`.
  6105. *
  6106. * assert.oneOf(1, [ 2, 1 ], 'Not found in list');
  6107. *
  6108. * @name oneOf
  6109. * @param {*} inList
  6110. * @param {Array<*>} list
  6111. * @param {String} message
  6112. * @namespace Assert
  6113. * @api public
  6114. */
  6115. assert.oneOf = function (inList, list, msg) {
  6116. new Assertion(inList, msg, assert.oneOf, true).to.be.oneOf(list);
  6117. }
  6118. /**
  6119. * ### .changes(function, object, property, [message])
  6120. *
  6121. * Asserts that a function changes the value of a property.
  6122. *
  6123. * var obj = { val: 10 };
  6124. * var fn = function() { obj.val = 22 };
  6125. * assert.changes(fn, obj, 'val');
  6126. *
  6127. * @name changes
  6128. * @param {Function} modifier function
  6129. * @param {Object} object or getter function
  6130. * @param {String} property name _optional_
  6131. * @param {String} message _optional_
  6132. * @namespace Assert
  6133. * @api public
  6134. */
  6135. assert.changes = function (fn, obj, prop, msg) {
  6136. if (arguments.length === 3 && typeof obj === 'function') {
  6137. msg = prop;
  6138. prop = null;
  6139. }
  6140. new Assertion(fn, msg, assert.changes, true).to.change(obj, prop);
  6141. }
  6142. /**
  6143. * ### .changesBy(function, object, property, delta, [message])
  6144. *
  6145. * Asserts that a function changes the value of a property by an amount (delta).
  6146. *
  6147. * var obj = { val: 10 };
  6148. * var fn = function() { obj.val += 2 };
  6149. * assert.changesBy(fn, obj, 'val', 2);
  6150. *
  6151. * @name changesBy
  6152. * @param {Function} modifier function
  6153. * @param {Object} object or getter function
  6154. * @param {String} property name _optional_
  6155. * @param {Number} change amount (delta)
  6156. * @param {String} message _optional_
  6157. * @namespace Assert
  6158. * @api public
  6159. */
  6160. assert.changesBy = function (fn, obj, prop, delta, msg) {
  6161. if (arguments.length === 4 && typeof obj === 'function') {
  6162. var tmpMsg = delta;
  6163. delta = prop;
  6164. msg = tmpMsg;
  6165. } else if (arguments.length === 3) {
  6166. delta = prop;
  6167. prop = null;
  6168. }
  6169. new Assertion(fn, msg, assert.changesBy, true)
  6170. .to.change(obj, prop).by(delta);
  6171. }
  6172. /**
  6173. * ### .doesNotChange(function, object, property, [message])
  6174. *
  6175. * Asserts that a function does not change the value of a property.
  6176. *
  6177. * var obj = { val: 10 };
  6178. * var fn = function() { console.log('foo'); };
  6179. * assert.doesNotChange(fn, obj, 'val');
  6180. *
  6181. * @name doesNotChange
  6182. * @param {Function} modifier function
  6183. * @param {Object} object or getter function
  6184. * @param {String} property name _optional_
  6185. * @param {String} message _optional_
  6186. * @namespace Assert
  6187. * @api public
  6188. */
  6189. assert.doesNotChange = function (fn, obj, prop, msg) {
  6190. if (arguments.length === 3 && typeof obj === 'function') {
  6191. msg = prop;
  6192. prop = null;
  6193. }
  6194. return new Assertion(fn, msg, assert.doesNotChange, true)
  6195. .to.not.change(obj, prop);
  6196. }
  6197. /**
  6198. * ### .changesButNotBy(function, object, property, delta, [message])
  6199. *
  6200. * Asserts that a function does not change the value of a property or of a function's return value by an amount (delta)
  6201. *
  6202. * var obj = { val: 10 };
  6203. * var fn = function() { obj.val += 10 };
  6204. * assert.changesButNotBy(fn, obj, 'val', 5);
  6205. *
  6206. * @name changesButNotBy
  6207. * @param {Function} modifier function
  6208. * @param {Object} object or getter function
  6209. * @param {String} property name _optional_
  6210. * @param {Number} change amount (delta)
  6211. * @param {String} message _optional_
  6212. * @namespace Assert
  6213. * @api public
  6214. */
  6215. assert.changesButNotBy = function (fn, obj, prop, delta, msg) {
  6216. if (arguments.length === 4 && typeof obj === 'function') {
  6217. var tmpMsg = delta;
  6218. delta = prop;
  6219. msg = tmpMsg;
  6220. } else if (arguments.length === 3) {
  6221. delta = prop;
  6222. prop = null;
  6223. }
  6224. new Assertion(fn, msg, assert.changesButNotBy, true)
  6225. .to.change(obj, prop).but.not.by(delta);
  6226. }
  6227. /**
  6228. * ### .increases(function, object, property, [message])
  6229. *
  6230. * Asserts that a function increases a numeric object property.
  6231. *
  6232. * var obj = { val: 10 };
  6233. * var fn = function() { obj.val = 13 };
  6234. * assert.increases(fn, obj, 'val');
  6235. *
  6236. * @name increases
  6237. * @param {Function} modifier function
  6238. * @param {Object} object or getter function
  6239. * @param {String} property name _optional_
  6240. * @param {String} message _optional_
  6241. * @namespace Assert
  6242. * @api public
  6243. */
  6244. assert.increases = function (fn, obj, prop, msg) {
  6245. if (arguments.length === 3 && typeof obj === 'function') {
  6246. msg = prop;
  6247. prop = null;
  6248. }
  6249. return new Assertion(fn, msg, assert.increases, true)
  6250. .to.increase(obj, prop);
  6251. }
  6252. /**
  6253. * ### .increasesBy(function, object, property, delta, [message])
  6254. *
  6255. * Asserts that a function increases a numeric object property or a function's return value by an amount (delta).
  6256. *
  6257. * var obj = { val: 10 };
  6258. * var fn = function() { obj.val += 10 };
  6259. * assert.increasesBy(fn, obj, 'val', 10);
  6260. *
  6261. * @name increasesBy
  6262. * @param {Function} modifier function
  6263. * @param {Object} object or getter function
  6264. * @param {String} property name _optional_
  6265. * @param {Number} change amount (delta)
  6266. * @param {String} message _optional_
  6267. * @namespace Assert
  6268. * @api public
  6269. */
  6270. assert.increasesBy = function (fn, obj, prop, delta, msg) {
  6271. if (arguments.length === 4 && typeof obj === 'function') {
  6272. var tmpMsg = delta;
  6273. delta = prop;
  6274. msg = tmpMsg;
  6275. } else if (arguments.length === 3) {
  6276. delta = prop;
  6277. prop = null;
  6278. }
  6279. new Assertion(fn, msg, assert.increasesBy, true)
  6280. .to.increase(obj, prop).by(delta);
  6281. }
  6282. /**
  6283. * ### .doesNotIncrease(function, object, property, [message])
  6284. *
  6285. * Asserts that a function does not increase a numeric object property.
  6286. *
  6287. * var obj = { val: 10 };
  6288. * var fn = function() { obj.val = 8 };
  6289. * assert.doesNotIncrease(fn, obj, 'val');
  6290. *
  6291. * @name doesNotIncrease
  6292. * @param {Function} modifier function
  6293. * @param {Object} object or getter function
  6294. * @param {String} property name _optional_
  6295. * @param {String} message _optional_
  6296. * @namespace Assert
  6297. * @api public
  6298. */
  6299. assert.doesNotIncrease = function (fn, obj, prop, msg) {
  6300. if (arguments.length === 3 && typeof obj === 'function') {
  6301. msg = prop;
  6302. prop = null;
  6303. }
  6304. return new Assertion(fn, msg, assert.doesNotIncrease, true)
  6305. .to.not.increase(obj, prop);
  6306. }
  6307. /**
  6308. * ### .increasesButNotBy(function, object, property, [message])
  6309. *
  6310. * Asserts that a function does not increase a numeric object property or function's return value by an amount (delta).
  6311. *
  6312. * var obj = { val: 10 };
  6313. * var fn = function() { obj.val = 15 };
  6314. * assert.increasesButNotBy(fn, obj, 'val', 10);
  6315. *
  6316. * @name increasesButNotBy
  6317. * @param {Function} modifier function
  6318. * @param {Object} object or getter function
  6319. * @param {String} property name _optional_
  6320. * @param {Number} change amount (delta)
  6321. * @param {String} message _optional_
  6322. * @namespace Assert
  6323. * @api public
  6324. */
  6325. assert.increasesButNotBy = function (fn, obj, prop, delta, msg) {
  6326. if (arguments.length === 4 && typeof obj === 'function') {
  6327. var tmpMsg = delta;
  6328. delta = prop;
  6329. msg = tmpMsg;
  6330. } else if (arguments.length === 3) {
  6331. delta = prop;
  6332. prop = null;
  6333. }
  6334. new Assertion(fn, msg, assert.increasesButNotBy, true)
  6335. .to.increase(obj, prop).but.not.by(delta);
  6336. }
  6337. /**
  6338. * ### .decreases(function, object, property, [message])
  6339. *
  6340. * Asserts that a function decreases a numeric object property.
  6341. *
  6342. * var obj = { val: 10 };
  6343. * var fn = function() { obj.val = 5 };
  6344. * assert.decreases(fn, obj, 'val');
  6345. *
  6346. * @name decreases
  6347. * @param {Function} modifier function
  6348. * @param {Object} object or getter function
  6349. * @param {String} property name _optional_
  6350. * @param {String} message _optional_
  6351. * @namespace Assert
  6352. * @api public
  6353. */
  6354. assert.decreases = function (fn, obj, prop, msg) {
  6355. if (arguments.length === 3 && typeof obj === 'function') {
  6356. msg = prop;
  6357. prop = null;
  6358. }
  6359. return new Assertion(fn, msg, assert.decreases, true)
  6360. .to.decrease(obj, prop);
  6361. }
  6362. /**
  6363. * ### .decreasesBy(function, object, property, delta, [message])
  6364. *
  6365. * Asserts that a function decreases a numeric object property or a function's return value by an amount (delta)
  6366. *
  6367. * var obj = { val: 10 };
  6368. * var fn = function() { obj.val -= 5 };
  6369. * assert.decreasesBy(fn, obj, 'val', 5);
  6370. *
  6371. * @name decreasesBy
  6372. * @param {Function} modifier function
  6373. * @param {Object} object or getter function
  6374. * @param {String} property name _optional_
  6375. * @param {Number} change amount (delta)
  6376. * @param {String} message _optional_
  6377. * @namespace Assert
  6378. * @api public
  6379. */
  6380. assert.decreasesBy = function (fn, obj, prop, delta, msg) {
  6381. if (arguments.length === 4 && typeof obj === 'function') {
  6382. var tmpMsg = delta;
  6383. delta = prop;
  6384. msg = tmpMsg;
  6385. } else if (arguments.length === 3) {
  6386. delta = prop;
  6387. prop = null;
  6388. }
  6389. new Assertion(fn, msg, assert.decreasesBy, true)
  6390. .to.decrease(obj, prop).by(delta);
  6391. }
  6392. /**
  6393. * ### .doesNotDecrease(function, object, property, [message])
  6394. *
  6395. * Asserts that a function does not decreases a numeric object property.
  6396. *
  6397. * var obj = { val: 10 };
  6398. * var fn = function() { obj.val = 15 };
  6399. * assert.doesNotDecrease(fn, obj, 'val');
  6400. *
  6401. * @name doesNotDecrease
  6402. * @param {Function} modifier function
  6403. * @param {Object} object or getter function
  6404. * @param {String} property name _optional_
  6405. * @param {String} message _optional_
  6406. * @namespace Assert
  6407. * @api public
  6408. */
  6409. assert.doesNotDecrease = function (fn, obj, prop, msg) {
  6410. if (arguments.length === 3 && typeof obj === 'function') {
  6411. msg = prop;
  6412. prop = null;
  6413. }
  6414. return new Assertion(fn, msg, assert.doesNotDecrease, true)
  6415. .to.not.decrease(obj, prop);
  6416. }
  6417. /**
  6418. * ### .doesNotDecreaseBy(function, object, property, delta, [message])
  6419. *
  6420. * Asserts that a function does not decreases a numeric object property or a function's return value by an amount (delta)
  6421. *
  6422. * var obj = { val: 10 };
  6423. * var fn = function() { obj.val = 5 };
  6424. * assert.doesNotDecreaseBy(fn, obj, 'val', 1);
  6425. *
  6426. * @name doesNotDecrease
  6427. * @param {Function} modifier function
  6428. * @param {Object} object or getter function
  6429. * @param {String} property name _optional_
  6430. * @param {Number} change amount (delta)
  6431. * @param {String} message _optional_
  6432. * @namespace Assert
  6433. * @api public
  6434. */
  6435. assert.doesNotDecreaseBy = function (fn, obj, prop, delta, msg) {
  6436. if (arguments.length === 4 && typeof obj === 'function') {
  6437. var tmpMsg = delta;
  6438. delta = prop;
  6439. msg = tmpMsg;
  6440. } else if (arguments.length === 3) {
  6441. delta = prop;
  6442. prop = null;
  6443. }
  6444. return new Assertion(fn, msg, assert.doesNotDecreaseBy, true)
  6445. .to.not.decrease(obj, prop).by(delta);
  6446. }
  6447. /**
  6448. * ### .decreasesButNotBy(function, object, property, delta, [message])
  6449. *
  6450. * Asserts that a function does not decreases a numeric object property or a function's return value by an amount (delta)
  6451. *
  6452. * var obj = { val: 10 };
  6453. * var fn = function() { obj.val = 5 };
  6454. * assert.decreasesButNotBy(fn, obj, 'val', 1);
  6455. *
  6456. * @name decreasesButNotBy
  6457. * @param {Function} modifier function
  6458. * @param {Object} object or getter function
  6459. * @param {String} property name _optional_
  6460. * @param {Number} change amount (delta)
  6461. * @param {String} message _optional_
  6462. * @namespace Assert
  6463. * @api public
  6464. */
  6465. assert.decreasesButNotBy = function (fn, obj, prop, delta, msg) {
  6466. if (arguments.length === 4 && typeof obj === 'function') {
  6467. var tmpMsg = delta;
  6468. delta = prop;
  6469. msg = tmpMsg;
  6470. } else if (arguments.length === 3) {
  6471. delta = prop;
  6472. prop = null;
  6473. }
  6474. new Assertion(fn, msg, assert.decreasesButNotBy, true)
  6475. .to.decrease(obj, prop).but.not.by(delta);
  6476. }
  6477. /*!
  6478. * ### .ifError(object)
  6479. *
  6480. * Asserts if value is not a false value, and throws if it is a true value.
  6481. * This is added to allow for chai to be a drop-in replacement for Node's
  6482. * assert class.
  6483. *
  6484. * var err = new Error('I am a custom error');
  6485. * assert.ifError(err); // Rethrows err!
  6486. *
  6487. * @name ifError
  6488. * @param {Object} object
  6489. * @namespace Assert
  6490. * @api public
  6491. */
  6492. assert.ifError = function (val) {
  6493. if (val) {
  6494. throw(val);
  6495. }
  6496. };
  6497. /**
  6498. * ### .isExtensible(object)
  6499. *
  6500. * Asserts that `object` is extensible (can have new properties added to it).
  6501. *
  6502. * assert.isExtensible({});
  6503. *
  6504. * @name isExtensible
  6505. * @alias extensible
  6506. * @param {Object} object
  6507. * @param {String} message _optional_
  6508. * @namespace Assert
  6509. * @api public
  6510. */
  6511. assert.isExtensible = function (obj, msg) {
  6512. new Assertion(obj, msg, assert.isExtensible, true).to.be.extensible;
  6513. };
  6514. /**
  6515. * ### .isNotExtensible(object)
  6516. *
  6517. * Asserts that `object` is _not_ extensible.
  6518. *
  6519. * var nonExtensibleObject = Object.preventExtensions({});
  6520. * var sealedObject = Object.seal({});
  6521. * var frozenObject = Object.freeze({});
  6522. *
  6523. * assert.isNotExtensible(nonExtensibleObject);
  6524. * assert.isNotExtensible(sealedObject);
  6525. * assert.isNotExtensible(frozenObject);
  6526. *
  6527. * @name isNotExtensible
  6528. * @alias notExtensible
  6529. * @param {Object} object
  6530. * @param {String} message _optional_
  6531. * @namespace Assert
  6532. * @api public
  6533. */
  6534. assert.isNotExtensible = function (obj, msg) {
  6535. new Assertion(obj, msg, assert.isNotExtensible, true).to.not.be.extensible;
  6536. };
  6537. /**
  6538. * ### .isSealed(object)
  6539. *
  6540. * Asserts that `object` is sealed (cannot have new properties added to it
  6541. * and its existing properties cannot be removed).
  6542. *
  6543. * var sealedObject = Object.seal({});
  6544. * var frozenObject = Object.seal({});
  6545. *
  6546. * assert.isSealed(sealedObject);
  6547. * assert.isSealed(frozenObject);
  6548. *
  6549. * @name isSealed
  6550. * @alias sealed
  6551. * @param {Object} object
  6552. * @param {String} message _optional_
  6553. * @namespace Assert
  6554. * @api public
  6555. */
  6556. assert.isSealed = function (obj, msg) {
  6557. new Assertion(obj, msg, assert.isSealed, true).to.be.sealed;
  6558. };
  6559. /**
  6560. * ### .isNotSealed(object)
  6561. *
  6562. * Asserts that `object` is _not_ sealed.
  6563. *
  6564. * assert.isNotSealed({});
  6565. *
  6566. * @name isNotSealed
  6567. * @alias notSealed
  6568. * @param {Object} object
  6569. * @param {String} message _optional_
  6570. * @namespace Assert
  6571. * @api public
  6572. */
  6573. assert.isNotSealed = function (obj, msg) {
  6574. new Assertion(obj, msg, assert.isNotSealed, true).to.not.be.sealed;
  6575. };
  6576. /**
  6577. * ### .isFrozen(object)
  6578. *
  6579. * Asserts that `object` is frozen (cannot have new properties added to it
  6580. * and its existing properties cannot be modified).
  6581. *
  6582. * var frozenObject = Object.freeze({});
  6583. * assert.frozen(frozenObject);
  6584. *
  6585. * @name isFrozen
  6586. * @alias frozen
  6587. * @param {Object} object
  6588. * @param {String} message _optional_
  6589. * @namespace Assert
  6590. * @api public
  6591. */
  6592. assert.isFrozen = function (obj, msg) {
  6593. new Assertion(obj, msg, assert.isFrozen, true).to.be.frozen;
  6594. };
  6595. /**
  6596. * ### .isNotFrozen(object)
  6597. *
  6598. * Asserts that `object` is _not_ frozen.
  6599. *
  6600. * assert.isNotFrozen({});
  6601. *
  6602. * @name isNotFrozen
  6603. * @alias notFrozen
  6604. * @param {Object} object
  6605. * @param {String} message _optional_
  6606. * @namespace Assert
  6607. * @api public
  6608. */
  6609. assert.isNotFrozen = function (obj, msg) {
  6610. new Assertion(obj, msg, assert.isNotFrozen, true).to.not.be.frozen;
  6611. };
  6612. /**
  6613. * ### .isEmpty(target)
  6614. *
  6615. * Asserts that the target does not contain any values.
  6616. * For arrays and strings, it checks the `length` property.
  6617. * For `Map` and `Set` instances, it checks the `size` property.
  6618. * For non-function objects, it gets the count of own
  6619. * enumerable string keys.
  6620. *
  6621. * assert.isEmpty([]);
  6622. * assert.isEmpty('');
  6623. * assert.isEmpty(new Map);
  6624. * assert.isEmpty({});
  6625. *
  6626. * @name isEmpty
  6627. * @alias empty
  6628. * @param {Object|Array|String|Map|Set} target
  6629. * @param {String} message _optional_
  6630. * @namespace Assert
  6631. * @api public
  6632. */
  6633. assert.isEmpty = function(val, msg) {
  6634. new Assertion(val, msg, assert.isEmpty, true).to.be.empty;
  6635. };
  6636. /**
  6637. * ### .isNotEmpty(target)
  6638. *
  6639. * Asserts that the target contains values.
  6640. * For arrays and strings, it checks the `length` property.
  6641. * For `Map` and `Set` instances, it checks the `size` property.
  6642. * For non-function objects, it gets the count of own
  6643. * enumerable string keys.
  6644. *
  6645. * assert.isNotEmpty([1, 2]);
  6646. * assert.isNotEmpty('34');
  6647. * assert.isNotEmpty(new Set([5, 6]));
  6648. * assert.isNotEmpty({ key: 7 });
  6649. *
  6650. * @name isNotEmpty
  6651. * @alias notEmpty
  6652. * @param {Object|Array|String|Map|Set} target
  6653. * @param {String} message _optional_
  6654. * @namespace Assert
  6655. * @api public
  6656. */
  6657. assert.isNotEmpty = function(val, msg) {
  6658. new Assertion(val, msg, assert.isNotEmpty, true).to.not.be.empty;
  6659. };
  6660. /*!
  6661. * Aliases.
  6662. */
  6663. (function alias(name, as){
  6664. assert[as] = assert[name];
  6665. return alias;
  6666. })
  6667. ('isOk', 'ok')
  6668. ('isNotOk', 'notOk')
  6669. ('throws', 'throw')
  6670. ('throws', 'Throw')
  6671. ('isExtensible', 'extensible')
  6672. ('isNotExtensible', 'notExtensible')
  6673. ('isSealed', 'sealed')
  6674. ('isNotSealed', 'notSealed')
  6675. ('isFrozen', 'frozen')
  6676. ('isNotFrozen', 'notFrozen')
  6677. ('isEmpty', 'empty')
  6678. ('isNotEmpty', 'notEmpty');
  6679. };
  6680. },{}],7:[function(require,module,exports){
  6681. /*!
  6682. * chai
  6683. * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
  6684. * MIT Licensed
  6685. */
  6686. module.exports = function (chai, util) {
  6687. chai.expect = function (val, message) {
  6688. return new chai.Assertion(val, message);
  6689. };
  6690. /**
  6691. * ### .fail([message])
  6692. * ### .fail(actual, expected, [message], [operator])
  6693. *
  6694. * Throw a failure.
  6695. *
  6696. * expect.fail();
  6697. * expect.fail("custom error message");
  6698. * expect.fail(1, 2);
  6699. * expect.fail(1, 2, "custom error message");
  6700. * expect.fail(1, 2, "custom error message", ">");
  6701. * expect.fail(1, 2, undefined, ">");
  6702. *
  6703. * @name fail
  6704. * @param {Mixed} actual
  6705. * @param {Mixed} expected
  6706. * @param {String} message
  6707. * @param {String} operator
  6708. * @namespace BDD
  6709. * @api public
  6710. */
  6711. chai.expect.fail = function (actual, expected, message, operator) {
  6712. if (arguments.length < 2) {
  6713. message = actual;
  6714. actual = undefined;
  6715. }
  6716. message = message || 'expect.fail()';
  6717. throw new chai.AssertionError(message, {
  6718. actual: actual
  6719. , expected: expected
  6720. , operator: operator
  6721. }, chai.expect.fail);
  6722. };
  6723. };
  6724. },{}],8:[function(require,module,exports){
  6725. /*!
  6726. * chai
  6727. * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
  6728. * MIT Licensed
  6729. */
  6730. module.exports = function (chai, util) {
  6731. var Assertion = chai.Assertion;
  6732. function loadShould () {
  6733. // explicitly define this method as function as to have it's name to include as `ssfi`
  6734. function shouldGetter() {
  6735. if (this instanceof String
  6736. || this instanceof Number
  6737. || this instanceof Boolean
  6738. || typeof Symbol === 'function' && this instanceof Symbol) {
  6739. return new Assertion(this.valueOf(), null, shouldGetter);
  6740. }
  6741. return new Assertion(this, null, shouldGetter);
  6742. }
  6743. function shouldSetter(value) {
  6744. // See https://github.com/chaijs/chai/issues/86: this makes
  6745. // `whatever.should = someValue` actually set `someValue`, which is
  6746. // especially useful for `global.should = require('chai').should()`.
  6747. //
  6748. // Note that we have to use [[DefineProperty]] instead of [[Put]]
  6749. // since otherwise we would trigger this very setter!
  6750. Object.defineProperty(this, 'should', {
  6751. value: value,
  6752. enumerable: true,
  6753. configurable: true,
  6754. writable: true
  6755. });
  6756. }
  6757. // modify Object.prototype to have `should`
  6758. Object.defineProperty(Object.prototype, 'should', {
  6759. set: shouldSetter
  6760. , get: shouldGetter
  6761. , configurable: true
  6762. });
  6763. var should = {};
  6764. /**
  6765. * ### .fail([message])
  6766. * ### .fail(actual, expected, [message], [operator])
  6767. *
  6768. * Throw a failure.
  6769. *
  6770. * should.fail();
  6771. * should.fail("custom error message");
  6772. * should.fail(1, 2);
  6773. * should.fail(1, 2, "custom error message");
  6774. * should.fail(1, 2, "custom error message", ">");
  6775. * should.fail(1, 2, undefined, ">");
  6776. *
  6777. *
  6778. * @name fail
  6779. * @param {Mixed} actual
  6780. * @param {Mixed} expected
  6781. * @param {String} message
  6782. * @param {String} operator
  6783. * @namespace BDD
  6784. * @api public
  6785. */
  6786. should.fail = function (actual, expected, message, operator) {
  6787. if (arguments.length < 2) {
  6788. message = actual;
  6789. actual = undefined;
  6790. }
  6791. message = message || 'should.fail()';
  6792. throw new chai.AssertionError(message, {
  6793. actual: actual
  6794. , expected: expected
  6795. , operator: operator
  6796. }, should.fail);
  6797. };
  6798. /**
  6799. * ### .equal(actual, expected, [message])
  6800. *
  6801. * Asserts non-strict equality (`==`) of `actual` and `expected`.
  6802. *
  6803. * should.equal(3, '3', '== coerces values to strings');
  6804. *
  6805. * @name equal
  6806. * @param {Mixed} actual
  6807. * @param {Mixed} expected
  6808. * @param {String} message
  6809. * @namespace Should
  6810. * @api public
  6811. */
  6812. should.equal = function (val1, val2, msg) {
  6813. new Assertion(val1, msg).to.equal(val2);
  6814. };
  6815. /**
  6816. * ### .throw(function, [constructor/string/regexp], [string/regexp], [message])
  6817. *
  6818. * Asserts that `function` will throw an error that is an instance of
  6819. * `constructor`, or alternately that it will throw an error with message
  6820. * matching `regexp`.
  6821. *
  6822. * should.throw(fn, 'function throws a reference error');
  6823. * should.throw(fn, /function throws a reference error/);
  6824. * should.throw(fn, ReferenceError);
  6825. * should.throw(fn, ReferenceError, 'function throws a reference error');
  6826. * should.throw(fn, ReferenceError, /function throws a reference error/);
  6827. *
  6828. * @name throw
  6829. * @alias Throw
  6830. * @param {Function} function
  6831. * @param {ErrorConstructor} constructor
  6832. * @param {RegExp} regexp
  6833. * @param {String} message
  6834. * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
  6835. * @namespace Should
  6836. * @api public
  6837. */
  6838. should.Throw = function (fn, errt, errs, msg) {
  6839. new Assertion(fn, msg).to.Throw(errt, errs);
  6840. };
  6841. /**
  6842. * ### .exist
  6843. *
  6844. * Asserts that the target is neither `null` nor `undefined`.
  6845. *
  6846. * var foo = 'hi';
  6847. *
  6848. * should.exist(foo, 'foo exists');
  6849. *
  6850. * @name exist
  6851. * @namespace Should
  6852. * @api public
  6853. */
  6854. should.exist = function (val, msg) {
  6855. new Assertion(val, msg).to.exist;
  6856. }
  6857. // negation
  6858. should.not = {}
  6859. /**
  6860. * ### .not.equal(actual, expected, [message])
  6861. *
  6862. * Asserts non-strict inequality (`!=`) of `actual` and `expected`.
  6863. *
  6864. * should.not.equal(3, 4, 'these numbers are not equal');
  6865. *
  6866. * @name not.equal
  6867. * @param {Mixed} actual
  6868. * @param {Mixed} expected
  6869. * @param {String} message
  6870. * @namespace Should
  6871. * @api public
  6872. */
  6873. should.not.equal = function (val1, val2, msg) {
  6874. new Assertion(val1, msg).to.not.equal(val2);
  6875. };
  6876. /**
  6877. * ### .throw(function, [constructor/regexp], [message])
  6878. *
  6879. * Asserts that `function` will _not_ throw an error that is an instance of
  6880. * `constructor`, or alternately that it will not throw an error with message
  6881. * matching `regexp`.
  6882. *
  6883. * should.not.throw(fn, Error, 'function does not throw');
  6884. *
  6885. * @name not.throw
  6886. * @alias not.Throw
  6887. * @param {Function} function
  6888. * @param {ErrorConstructor} constructor
  6889. * @param {RegExp} regexp
  6890. * @param {String} message
  6891. * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
  6892. * @namespace Should
  6893. * @api public
  6894. */
  6895. should.not.Throw = function (fn, errt, errs, msg) {
  6896. new Assertion(fn, msg).to.not.Throw(errt, errs);
  6897. };
  6898. /**
  6899. * ### .not.exist
  6900. *
  6901. * Asserts that the target is neither `null` nor `undefined`.
  6902. *
  6903. * var bar = null;
  6904. *
  6905. * should.not.exist(bar, 'bar does not exist');
  6906. *
  6907. * @name not.exist
  6908. * @namespace Should
  6909. * @api public
  6910. */
  6911. should.not.exist = function (val, msg) {
  6912. new Assertion(val, msg).to.not.exist;
  6913. }
  6914. should['throw'] = should['Throw'];
  6915. should.not['throw'] = should.not['Throw'];
  6916. return should;
  6917. };
  6918. chai.should = loadShould;
  6919. chai.Should = loadShould;
  6920. };
  6921. },{}],9:[function(require,module,exports){
  6922. /*!
  6923. * Chai - addChainingMethod utility
  6924. * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  6925. * MIT Licensed
  6926. */
  6927. /*!
  6928. * Module dependencies
  6929. */
  6930. var addLengthGuard = require('./addLengthGuard');
  6931. var chai = require('../../chai');
  6932. var flag = require('./flag');
  6933. var proxify = require('./proxify');
  6934. var transferFlags = require('./transferFlags');
  6935. /*!
  6936. * Module variables
  6937. */
  6938. // Check whether `Object.setPrototypeOf` is supported
  6939. var canSetPrototype = typeof Object.setPrototypeOf === 'function';
  6940. // Without `Object.setPrototypeOf` support, this module will need to add properties to a function.
  6941. // However, some of functions' own props are not configurable and should be skipped.
  6942. var testFn = function() {};
  6943. var excludeNames = Object.getOwnPropertyNames(testFn).filter(function(name) {
  6944. var propDesc = Object.getOwnPropertyDescriptor(testFn, name);
  6945. // Note: PhantomJS 1.x includes `callee` as one of `testFn`'s own properties,
  6946. // but then returns `undefined` as the property descriptor for `callee`. As a
  6947. // workaround, we perform an otherwise unnecessary type-check for `propDesc`,
  6948. // and then filter it out if it's not an object as it should be.
  6949. if (typeof propDesc !== 'object')
  6950. return true;
  6951. return !propDesc.configurable;
  6952. });
  6953. // Cache `Function` properties
  6954. var call = Function.prototype.call,
  6955. apply = Function.prototype.apply;
  6956. /**
  6957. * ### .addChainableMethod(ctx, name, method, chainingBehavior)
  6958. *
  6959. * Adds a method to an object, such that the method can also be chained.
  6960. *
  6961. * utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) {
  6962. * var obj = utils.flag(this, 'object');
  6963. * new chai.Assertion(obj).to.be.equal(str);
  6964. * });
  6965. *
  6966. * Can also be accessed directly from `chai.Assertion`.
  6967. *
  6968. * chai.Assertion.addChainableMethod('foo', fn, chainingBehavior);
  6969. *
  6970. * The result can then be used as both a method assertion, executing both `method` and
  6971. * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`.
  6972. *
  6973. * expect(fooStr).to.be.foo('bar');
  6974. * expect(fooStr).to.be.foo.equal('foo');
  6975. *
  6976. * @param {Object} ctx object to which the method is added
  6977. * @param {String} name of method to add
  6978. * @param {Function} method function to be used for `name`, when called
  6979. * @param {Function} chainingBehavior function to be called every time the property is accessed
  6980. * @namespace Utils
  6981. * @name addChainableMethod
  6982. * @api public
  6983. */
  6984. module.exports = function addChainableMethod(ctx, name, method, chainingBehavior) {
  6985. if (typeof chainingBehavior !== 'function') {
  6986. chainingBehavior = function () { };
  6987. }
  6988. var chainableBehavior = {
  6989. method: method
  6990. , chainingBehavior: chainingBehavior
  6991. };
  6992. // save the methods so we can overwrite them later, if we need to.
  6993. if (!ctx.__methods) {
  6994. ctx.__methods = {};
  6995. }
  6996. ctx.__methods[name] = chainableBehavior;
  6997. Object.defineProperty(ctx, name,
  6998. { get: function chainableMethodGetter() {
  6999. chainableBehavior.chainingBehavior.call(this);
  7000. var chainableMethodWrapper = function () {
  7001. // Setting the `ssfi` flag to `chainableMethodWrapper` causes this
  7002. // function to be the starting point for removing implementation
  7003. // frames from the stack trace of a failed assertion.
  7004. //
  7005. // However, we only want to use this function as the starting point if
  7006. // the `lockSsfi` flag isn't set.
  7007. //
  7008. // If the `lockSsfi` flag is set, then this assertion is being
  7009. // invoked from inside of another assertion. In this case, the `ssfi`
  7010. // flag has already been set by the outer assertion.
  7011. //
  7012. // Note that overwriting a chainable method merely replaces the saved
  7013. // methods in `ctx.__methods` instead of completely replacing the
  7014. // overwritten assertion. Therefore, an overwriting assertion won't
  7015. // set the `ssfi` or `lockSsfi` flags.
  7016. if (!flag(this, 'lockSsfi')) {
  7017. flag(this, 'ssfi', chainableMethodWrapper);
  7018. }
  7019. var result = chainableBehavior.method.apply(this, arguments);
  7020. if (result !== undefined) {
  7021. return result;
  7022. }
  7023. var newAssertion = new chai.Assertion();
  7024. transferFlags(this, newAssertion);
  7025. return newAssertion;
  7026. };
  7027. addLengthGuard(chainableMethodWrapper, name, true);
  7028. // Use `Object.setPrototypeOf` if available
  7029. if (canSetPrototype) {
  7030. // Inherit all properties from the object by replacing the `Function` prototype
  7031. var prototype = Object.create(this);
  7032. // Restore the `call` and `apply` methods from `Function`
  7033. prototype.call = call;
  7034. prototype.apply = apply;
  7035. Object.setPrototypeOf(chainableMethodWrapper, prototype);
  7036. }
  7037. // Otherwise, redefine all properties (slow!)
  7038. else {
  7039. var asserterNames = Object.getOwnPropertyNames(ctx);
  7040. asserterNames.forEach(function (asserterName) {
  7041. if (excludeNames.indexOf(asserterName) !== -1) {
  7042. return;
  7043. }
  7044. var pd = Object.getOwnPropertyDescriptor(ctx, asserterName);
  7045. Object.defineProperty(chainableMethodWrapper, asserterName, pd);
  7046. });
  7047. }
  7048. transferFlags(this, chainableMethodWrapper);
  7049. return proxify(chainableMethodWrapper);
  7050. }
  7051. , configurable: true
  7052. });
  7053. };
  7054. },{"../../chai":2,"./addLengthGuard":10,"./flag":15,"./proxify":30,"./transferFlags":32}],10:[function(require,module,exports){
  7055. var fnLengthDesc = Object.getOwnPropertyDescriptor(function () {}, 'length');
  7056. /*!
  7057. * Chai - addLengthGuard utility
  7058. * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  7059. * MIT Licensed
  7060. */
  7061. /**
  7062. * ### .addLengthGuard(fn, assertionName, isChainable)
  7063. *
  7064. * Define `length` as a getter on the given uninvoked method assertion. The
  7065. * getter acts as a guard against chaining `length` directly off of an uninvoked
  7066. * method assertion, which is a problem because it references `function`'s
  7067. * built-in `length` property instead of Chai's `length` assertion. When the
  7068. * getter catches the user making this mistake, it throws an error with a
  7069. * helpful message.
  7070. *
  7071. * There are two ways in which this mistake can be made. The first way is by
  7072. * chaining the `length` assertion directly off of an uninvoked chainable
  7073. * method. In this case, Chai suggests that the user use `lengthOf` instead. The
  7074. * second way is by chaining the `length` assertion directly off of an uninvoked
  7075. * non-chainable method. Non-chainable methods must be invoked prior to
  7076. * chaining. In this case, Chai suggests that the user consult the docs for the
  7077. * given assertion.
  7078. *
  7079. * If the `length` property of functions is unconfigurable, then return `fn`
  7080. * without modification.
  7081. *
  7082. * Note that in ES6, the function's `length` property is configurable, so once
  7083. * support for legacy environments is dropped, Chai's `length` property can
  7084. * replace the built-in function's `length` property, and this length guard will
  7085. * no longer be necessary. In the mean time, maintaining consistency across all
  7086. * environments is the priority.
  7087. *
  7088. * @param {Function} fn
  7089. * @param {String} assertionName
  7090. * @param {Boolean} isChainable
  7091. * @namespace Utils
  7092. * @name addLengthGuard
  7093. */
  7094. module.exports = function addLengthGuard (fn, assertionName, isChainable) {
  7095. if (!fnLengthDesc.configurable) return fn;
  7096. Object.defineProperty(fn, 'length', {
  7097. get: function () {
  7098. if (isChainable) {
  7099. throw Error('Invalid Chai property: ' + assertionName + '.length. Due' +
  7100. ' to a compatibility issue, "length" cannot directly follow "' +
  7101. assertionName + '". Use "' + assertionName + '.lengthOf" instead.');
  7102. }
  7103. throw Error('Invalid Chai property: ' + assertionName + '.length. See' +
  7104. ' docs for proper usage of "' + assertionName + '".');
  7105. }
  7106. });
  7107. return fn;
  7108. };
  7109. },{}],11:[function(require,module,exports){
  7110. /*!
  7111. * Chai - addMethod utility
  7112. * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  7113. * MIT Licensed
  7114. */
  7115. var addLengthGuard = require('./addLengthGuard');
  7116. var chai = require('../../chai');
  7117. var flag = require('./flag');
  7118. var proxify = require('./proxify');
  7119. var transferFlags = require('./transferFlags');
  7120. /**
  7121. * ### .addMethod(ctx, name, method)
  7122. *
  7123. * Adds a method to the prototype of an object.
  7124. *
  7125. * utils.addMethod(chai.Assertion.prototype, 'foo', function (str) {
  7126. * var obj = utils.flag(this, 'object');
  7127. * new chai.Assertion(obj).to.be.equal(str);
  7128. * });
  7129. *
  7130. * Can also be accessed directly from `chai.Assertion`.
  7131. *
  7132. * chai.Assertion.addMethod('foo', fn);
  7133. *
  7134. * Then can be used as any other assertion.
  7135. *
  7136. * expect(fooStr).to.be.foo('bar');
  7137. *
  7138. * @param {Object} ctx object to which the method is added
  7139. * @param {String} name of method to add
  7140. * @param {Function} method function to be used for name
  7141. * @namespace Utils
  7142. * @name addMethod
  7143. * @api public
  7144. */
  7145. module.exports = function addMethod(ctx, name, method) {
  7146. var methodWrapper = function () {
  7147. // Setting the `ssfi` flag to `methodWrapper` causes this function to be the
  7148. // starting point for removing implementation frames from the stack trace of
  7149. // a failed assertion.
  7150. //
  7151. // However, we only want to use this function as the starting point if the
  7152. // `lockSsfi` flag isn't set.
  7153. //
  7154. // If the `lockSsfi` flag is set, then either this assertion has been
  7155. // overwritten by another assertion, or this assertion is being invoked from
  7156. // inside of another assertion. In the first case, the `ssfi` flag has
  7157. // already been set by the overwriting assertion. In the second case, the
  7158. // `ssfi` flag has already been set by the outer assertion.
  7159. if (!flag(this, 'lockSsfi')) {
  7160. flag(this, 'ssfi', methodWrapper);
  7161. }
  7162. var result = method.apply(this, arguments);
  7163. if (result !== undefined)
  7164. return result;
  7165. var newAssertion = new chai.Assertion();
  7166. transferFlags(this, newAssertion);
  7167. return newAssertion;
  7168. };
  7169. addLengthGuard(methodWrapper, name, false);
  7170. ctx[name] = proxify(methodWrapper, name);
  7171. };
  7172. },{"../../chai":2,"./addLengthGuard":10,"./flag":15,"./proxify":30,"./transferFlags":32}],12:[function(require,module,exports){
  7173. /*!
  7174. * Chai - addProperty utility
  7175. * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  7176. * MIT Licensed
  7177. */
  7178. var chai = require('../../chai');
  7179. var flag = require('./flag');
  7180. var isProxyEnabled = require('./isProxyEnabled');
  7181. var transferFlags = require('./transferFlags');
  7182. /**
  7183. * ### .addProperty(ctx, name, getter)
  7184. *
  7185. * Adds a property to the prototype of an object.
  7186. *
  7187. * utils.addProperty(chai.Assertion.prototype, 'foo', function () {
  7188. * var obj = utils.flag(this, 'object');
  7189. * new chai.Assertion(obj).to.be.instanceof(Foo);
  7190. * });
  7191. *
  7192. * Can also be accessed directly from `chai.Assertion`.
  7193. *
  7194. * chai.Assertion.addProperty('foo', fn);
  7195. *
  7196. * Then can be used as any other assertion.
  7197. *
  7198. * expect(myFoo).to.be.foo;
  7199. *
  7200. * @param {Object} ctx object to which the property is added
  7201. * @param {String} name of property to add
  7202. * @param {Function} getter function to be used for name
  7203. * @namespace Utils
  7204. * @name addProperty
  7205. * @api public
  7206. */
  7207. module.exports = function addProperty(ctx, name, getter) {
  7208. getter = getter === undefined ? function () {} : getter;
  7209. Object.defineProperty(ctx, name,
  7210. { get: function propertyGetter() {
  7211. // Setting the `ssfi` flag to `propertyGetter` causes this function to
  7212. // be the starting point for removing implementation frames from the
  7213. // stack trace of a failed assertion.
  7214. //
  7215. // However, we only want to use this function as the starting point if
  7216. // the `lockSsfi` flag isn't set and proxy protection is disabled.
  7217. //
  7218. // If the `lockSsfi` flag is set, then either this assertion has been
  7219. // overwritten by another assertion, or this assertion is being invoked
  7220. // from inside of another assertion. In the first case, the `ssfi` flag
  7221. // has already been set by the overwriting assertion. In the second
  7222. // case, the `ssfi` flag has already been set by the outer assertion.
  7223. //
  7224. // If proxy protection is enabled, then the `ssfi` flag has already been
  7225. // set by the proxy getter.
  7226. if (!isProxyEnabled() && !flag(this, 'lockSsfi')) {
  7227. flag(this, 'ssfi', propertyGetter);
  7228. }
  7229. var result = getter.call(this);
  7230. if (result !== undefined)
  7231. return result;
  7232. var newAssertion = new chai.Assertion();
  7233. transferFlags(this, newAssertion);
  7234. return newAssertion;
  7235. }
  7236. , configurable: true
  7237. });
  7238. };
  7239. },{"../../chai":2,"./flag":15,"./isProxyEnabled":25,"./transferFlags":32}],13:[function(require,module,exports){
  7240. /*!
  7241. * Chai - compareByInspect utility
  7242. * Copyright(c) 2011-2016 Jake Luer <jake@alogicalparadox.com>
  7243. * MIT Licensed
  7244. */
  7245. /*!
  7246. * Module dependencies
  7247. */
  7248. var inspect = require('./inspect');
  7249. /**
  7250. * ### .compareByInspect(mixed, mixed)
  7251. *
  7252. * To be used as a compareFunction with Array.prototype.sort. Compares elements
  7253. * using inspect instead of default behavior of using toString so that Symbols
  7254. * and objects with irregular/missing toString can still be sorted without a
  7255. * TypeError.
  7256. *
  7257. * @param {Mixed} first element to compare
  7258. * @param {Mixed} second element to compare
  7259. * @returns {Number} -1 if 'a' should come before 'b'; otherwise 1
  7260. * @name compareByInspect
  7261. * @namespace Utils
  7262. * @api public
  7263. */
  7264. module.exports = function compareByInspect(a, b) {
  7265. return inspect(a) < inspect(b) ? -1 : 1;
  7266. };
  7267. },{"./inspect":23}],14:[function(require,module,exports){
  7268. /*!
  7269. * Chai - expectTypes utility
  7270. * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  7271. * MIT Licensed
  7272. */
  7273. /**
  7274. * ### .expectTypes(obj, types)
  7275. *
  7276. * Ensures that the object being tested against is of a valid type.
  7277. *
  7278. * utils.expectTypes(this, ['array', 'object', 'string']);
  7279. *
  7280. * @param {Mixed} obj constructed Assertion
  7281. * @param {Array} type A list of allowed types for this assertion
  7282. * @namespace Utils
  7283. * @name expectTypes
  7284. * @api public
  7285. */
  7286. var AssertionError = require('assertion-error');
  7287. var flag = require('./flag');
  7288. var type = require('type-detect');
  7289. module.exports = function expectTypes(obj, types) {
  7290. var flagMsg = flag(obj, 'message');
  7291. var ssfi = flag(obj, 'ssfi');
  7292. flagMsg = flagMsg ? flagMsg + ': ' : '';
  7293. obj = flag(obj, 'object');
  7294. types = types.map(function (t) { return t.toLowerCase(); });
  7295. types.sort();
  7296. // Transforms ['lorem', 'ipsum'] into 'a lorem, or an ipsum'
  7297. var str = types.map(function (t, index) {
  7298. var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a';
  7299. var or = types.length > 1 && index === types.length - 1 ? 'or ' : '';
  7300. return or + art + ' ' + t;
  7301. }).join(', ');
  7302. var objType = type(obj).toLowerCase();
  7303. if (!types.some(function (expected) { return objType === expected; })) {
  7304. throw new AssertionError(
  7305. flagMsg + 'object tested must be ' + str + ', but ' + objType + ' given',
  7306. undefined,
  7307. ssfi
  7308. );
  7309. }
  7310. };
  7311. },{"./flag":15,"assertion-error":33,"type-detect":38}],15:[function(require,module,exports){
  7312. /*!
  7313. * Chai - flag utility
  7314. * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  7315. * MIT Licensed
  7316. */
  7317. /**
  7318. * ### .flag(object, key, [value])
  7319. *
  7320. * Get or set a flag value on an object. If a
  7321. * value is provided it will be set, else it will
  7322. * return the currently set value or `undefined` if
  7323. * the value is not set.
  7324. *
  7325. * utils.flag(this, 'foo', 'bar'); // setter
  7326. * utils.flag(this, 'foo'); // getter, returns `bar`
  7327. *
  7328. * @param {Object} object constructed Assertion
  7329. * @param {String} key
  7330. * @param {Mixed} value (optional)
  7331. * @namespace Utils
  7332. * @name flag
  7333. * @api private
  7334. */
  7335. module.exports = function flag(obj, key, value) {
  7336. var flags = obj.__flags || (obj.__flags = Object.create(null));
  7337. if (arguments.length === 3) {
  7338. flags[key] = value;
  7339. } else {
  7340. return flags[key];
  7341. }
  7342. };
  7343. },{}],16:[function(require,module,exports){
  7344. /*!
  7345. * Chai - getActual utility
  7346. * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  7347. * MIT Licensed
  7348. */
  7349. /**
  7350. * ### .getActual(object, [actual])
  7351. *
  7352. * Returns the `actual` value for an Assertion.
  7353. *
  7354. * @param {Object} object (constructed Assertion)
  7355. * @param {Arguments} chai.Assertion.prototype.assert arguments
  7356. * @namespace Utils
  7357. * @name getActual
  7358. */
  7359. module.exports = function getActual(obj, args) {
  7360. return args.length > 4 ? args[4] : obj._obj;
  7361. };
  7362. },{}],17:[function(require,module,exports){
  7363. /*!
  7364. * Chai - getEnumerableProperties utility
  7365. * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  7366. * MIT Licensed
  7367. */
  7368. /**
  7369. * ### .getEnumerableProperties(object)
  7370. *
  7371. * This allows the retrieval of enumerable property names of an object,
  7372. * inherited or not.
  7373. *
  7374. * @param {Object} object
  7375. * @returns {Array}
  7376. * @namespace Utils
  7377. * @name getEnumerableProperties
  7378. * @api public
  7379. */
  7380. module.exports = function getEnumerableProperties(object) {
  7381. var result = [];
  7382. for (var name in object) {
  7383. result.push(name);
  7384. }
  7385. return result;
  7386. };
  7387. },{}],18:[function(require,module,exports){
  7388. /*!
  7389. * Chai - message composition utility
  7390. * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  7391. * MIT Licensed
  7392. */
  7393. /*!
  7394. * Module dependencies
  7395. */
  7396. var flag = require('./flag')
  7397. , getActual = require('./getActual')
  7398. , objDisplay = require('./objDisplay');
  7399. /**
  7400. * ### .getMessage(object, message, negateMessage)
  7401. *
  7402. * Construct the error message based on flags
  7403. * and template tags. Template tags will return
  7404. * a stringified inspection of the object referenced.
  7405. *
  7406. * Message template tags:
  7407. * - `#{this}` current asserted object
  7408. * - `#{act}` actual value
  7409. * - `#{exp}` expected value
  7410. *
  7411. * @param {Object} object (constructed Assertion)
  7412. * @param {Arguments} chai.Assertion.prototype.assert arguments
  7413. * @namespace Utils
  7414. * @name getMessage
  7415. * @api public
  7416. */
  7417. module.exports = function getMessage(obj, args) {
  7418. var negate = flag(obj, 'negate')
  7419. , val = flag(obj, 'object')
  7420. , expected = args[3]
  7421. , actual = getActual(obj, args)
  7422. , msg = negate ? args[2] : args[1]
  7423. , flagMsg = flag(obj, 'message');
  7424. if(typeof msg === "function") msg = msg();
  7425. msg = msg || '';
  7426. msg = msg
  7427. .replace(/#\{this\}/g, function () { return objDisplay(val); })
  7428. .replace(/#\{act\}/g, function () { return objDisplay(actual); })
  7429. .replace(/#\{exp\}/g, function () { return objDisplay(expected); });
  7430. return flagMsg ? flagMsg + ': ' + msg : msg;
  7431. };
  7432. },{"./flag":15,"./getActual":16,"./objDisplay":26}],19:[function(require,module,exports){
  7433. /*!
  7434. * Chai - getOwnEnumerableProperties utility
  7435. * Copyright(c) 2011-2016 Jake Luer <jake@alogicalparadox.com>
  7436. * MIT Licensed
  7437. */
  7438. /*!
  7439. * Module dependencies
  7440. */
  7441. var getOwnEnumerablePropertySymbols = require('./getOwnEnumerablePropertySymbols');
  7442. /**
  7443. * ### .getOwnEnumerableProperties(object)
  7444. *
  7445. * This allows the retrieval of directly-owned enumerable property names and
  7446. * symbols of an object. This function is necessary because Object.keys only
  7447. * returns enumerable property names, not enumerable property symbols.
  7448. *
  7449. * @param {Object} object
  7450. * @returns {Array}
  7451. * @namespace Utils
  7452. * @name getOwnEnumerableProperties
  7453. * @api public
  7454. */
  7455. module.exports = function getOwnEnumerableProperties(obj) {
  7456. return Object.keys(obj).concat(getOwnEnumerablePropertySymbols(obj));
  7457. };
  7458. },{"./getOwnEnumerablePropertySymbols":20}],20:[function(require,module,exports){
  7459. /*!
  7460. * Chai - getOwnEnumerablePropertySymbols utility
  7461. * Copyright(c) 2011-2016 Jake Luer <jake@alogicalparadox.com>
  7462. * MIT Licensed
  7463. */
  7464. /**
  7465. * ### .getOwnEnumerablePropertySymbols(object)
  7466. *
  7467. * This allows the retrieval of directly-owned enumerable property symbols of an
  7468. * object. This function is necessary because Object.getOwnPropertySymbols
  7469. * returns both enumerable and non-enumerable property symbols.
  7470. *
  7471. * @param {Object} object
  7472. * @returns {Array}
  7473. * @namespace Utils
  7474. * @name getOwnEnumerablePropertySymbols
  7475. * @api public
  7476. */
  7477. module.exports = function getOwnEnumerablePropertySymbols(obj) {
  7478. if (typeof Object.getOwnPropertySymbols !== 'function') return [];
  7479. return Object.getOwnPropertySymbols(obj).filter(function (sym) {
  7480. return Object.getOwnPropertyDescriptor(obj, sym).enumerable;
  7481. });
  7482. };
  7483. },{}],21:[function(require,module,exports){
  7484. /*!
  7485. * Chai - getProperties utility
  7486. * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  7487. * MIT Licensed
  7488. */
  7489. /**
  7490. * ### .getProperties(object)
  7491. *
  7492. * This allows the retrieval of property names of an object, enumerable or not,
  7493. * inherited or not.
  7494. *
  7495. * @param {Object} object
  7496. * @returns {Array}
  7497. * @namespace Utils
  7498. * @name getProperties
  7499. * @api public
  7500. */
  7501. module.exports = function getProperties(object) {
  7502. var result = Object.getOwnPropertyNames(object);
  7503. function addProperty(property) {
  7504. if (result.indexOf(property) === -1) {
  7505. result.push(property);
  7506. }
  7507. }
  7508. var proto = Object.getPrototypeOf(object);
  7509. while (proto !== null) {
  7510. Object.getOwnPropertyNames(proto).forEach(addProperty);
  7511. proto = Object.getPrototypeOf(proto);
  7512. }
  7513. return result;
  7514. };
  7515. },{}],22:[function(require,module,exports){
  7516. /*!
  7517. * chai
  7518. * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com>
  7519. * MIT Licensed
  7520. */
  7521. /*!
  7522. * Dependencies that are used for multiple exports are required here only once
  7523. */
  7524. var pathval = require('pathval');
  7525. /*!
  7526. * test utility
  7527. */
  7528. exports.test = require('./test');
  7529. /*!
  7530. * type utility
  7531. */
  7532. exports.type = require('type-detect');
  7533. /*!
  7534. * expectTypes utility
  7535. */
  7536. exports.expectTypes = require('./expectTypes');
  7537. /*!
  7538. * message utility
  7539. */
  7540. exports.getMessage = require('./getMessage');
  7541. /*!
  7542. * actual utility
  7543. */
  7544. exports.getActual = require('./getActual');
  7545. /*!
  7546. * Inspect util
  7547. */
  7548. exports.inspect = require('./inspect');
  7549. /*!
  7550. * Object Display util
  7551. */
  7552. exports.objDisplay = require('./objDisplay');
  7553. /*!
  7554. * Flag utility
  7555. */
  7556. exports.flag = require('./flag');
  7557. /*!
  7558. * Flag transferring utility
  7559. */
  7560. exports.transferFlags = require('./transferFlags');
  7561. /*!
  7562. * Deep equal utility
  7563. */
  7564. exports.eql = require('deep-eql');
  7565. /*!
  7566. * Deep path info
  7567. */
  7568. exports.getPathInfo = pathval.getPathInfo;
  7569. /*!
  7570. * Check if a property exists
  7571. */
  7572. exports.hasProperty = pathval.hasProperty;
  7573. /*!
  7574. * Function name
  7575. */
  7576. exports.getName = require('get-func-name');
  7577. /*!
  7578. * add Property
  7579. */
  7580. exports.addProperty = require('./addProperty');
  7581. /*!
  7582. * add Method
  7583. */
  7584. exports.addMethod = require('./addMethod');
  7585. /*!
  7586. * overwrite Property
  7587. */
  7588. exports.overwriteProperty = require('./overwriteProperty');
  7589. /*!
  7590. * overwrite Method
  7591. */
  7592. exports.overwriteMethod = require('./overwriteMethod');
  7593. /*!
  7594. * Add a chainable method
  7595. */
  7596. exports.addChainableMethod = require('./addChainableMethod');
  7597. /*!
  7598. * Overwrite chainable method
  7599. */
  7600. exports.overwriteChainableMethod = require('./overwriteChainableMethod');
  7601. /*!
  7602. * Compare by inspect method
  7603. */
  7604. exports.compareByInspect = require('./compareByInspect');
  7605. /*!
  7606. * Get own enumerable property symbols method
  7607. */
  7608. exports.getOwnEnumerablePropertySymbols = require('./getOwnEnumerablePropertySymbols');
  7609. /*!
  7610. * Get own enumerable properties method
  7611. */
  7612. exports.getOwnEnumerableProperties = require('./getOwnEnumerableProperties');
  7613. /*!
  7614. * Checks error against a given set of criteria
  7615. */
  7616. exports.checkError = require('check-error');
  7617. /*!
  7618. * Proxify util
  7619. */
  7620. exports.proxify = require('./proxify');
  7621. /*!
  7622. * addLengthGuard util
  7623. */
  7624. exports.addLengthGuard = require('./addLengthGuard');
  7625. /*!
  7626. * isProxyEnabled helper
  7627. */
  7628. exports.isProxyEnabled = require('./isProxyEnabled');
  7629. /*!
  7630. * isNaN method
  7631. */
  7632. exports.isNaN = require('./isNaN');
  7633. },{"./addChainableMethod":9,"./addLengthGuard":10,"./addMethod":11,"./addProperty":12,"./compareByInspect":13,"./expectTypes":14,"./flag":15,"./getActual":16,"./getMessage":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":37,"type-detect":38}],23:[function(require,module,exports){
  7634. // This is (almost) directly from Node.js utils
  7635. // https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js
  7636. var getName = require('get-func-name');
  7637. var getProperties = require('./getProperties');
  7638. var getEnumerableProperties = require('./getEnumerableProperties');
  7639. var config = require('../config');
  7640. module.exports = inspect;
  7641. /**
  7642. * ### .inspect(obj, [showHidden], [depth], [colors])
  7643. *
  7644. * Echoes the value of a value. Tries to print the value out
  7645. * in the best way possible given the different types.
  7646. *
  7647. * @param {Object} obj The object to print out.
  7648. * @param {Boolean} showHidden Flag that shows hidden (not enumerable)
  7649. * properties of objects. Default is false.
  7650. * @param {Number} depth Depth in which to descend in object. Default is 2.
  7651. * @param {Boolean} colors Flag to turn on ANSI escape codes to color the
  7652. * output. Default is false (no coloring).
  7653. * @namespace Utils
  7654. * @name inspect
  7655. */
  7656. function inspect(obj, showHidden, depth, colors) {
  7657. var ctx = {
  7658. showHidden: showHidden,
  7659. seen: [],
  7660. stylize: function (str) { return str; }
  7661. };
  7662. return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth));
  7663. }
  7664. // Returns true if object is a DOM element.
  7665. var isDOMElement = function (object) {
  7666. if (typeof HTMLElement === 'object') {
  7667. return object instanceof HTMLElement;
  7668. } else {
  7669. return object &&
  7670. typeof object === 'object' &&
  7671. 'nodeType' in object &&
  7672. object.nodeType === 1 &&
  7673. typeof object.nodeName === 'string';
  7674. }
  7675. };
  7676. function formatValue(ctx, value, recurseTimes) {
  7677. // Provide a hook for user-specified inspect functions.
  7678. // Check that value is an object with an inspect function on it
  7679. if (value && typeof value.inspect === 'function' &&
  7680. // Filter out the util module, it's inspect function is special
  7681. value.inspect !== exports.inspect &&
  7682. // Also filter out any prototype objects using the circular check.
  7683. !(value.constructor && value.constructor.prototype === value)) {
  7684. var ret = value.inspect(recurseTimes, ctx);
  7685. if (typeof ret !== 'string') {
  7686. ret = formatValue(ctx, ret, recurseTimes);
  7687. }
  7688. return ret;
  7689. }
  7690. // Primitive types cannot have properties
  7691. var primitive = formatPrimitive(ctx, value);
  7692. if (primitive) {
  7693. return primitive;
  7694. }
  7695. // If this is a DOM element, try to get the outer HTML.
  7696. if (isDOMElement(value)) {
  7697. if ('outerHTML' in value) {
  7698. return value.outerHTML;
  7699. // This value does not have an outerHTML attribute,
  7700. // it could still be an XML element
  7701. } else {
  7702. // Attempt to serialize it
  7703. try {
  7704. if (document.xmlVersion) {
  7705. var xmlSerializer = new XMLSerializer();
  7706. return xmlSerializer.serializeToString(value);
  7707. } else {
  7708. // Firefox 11- do not support outerHTML
  7709. // It does, however, support innerHTML
  7710. // Use the following to render the element
  7711. var ns = "http://www.w3.org/1999/xhtml";
  7712. var container = document.createElementNS(ns, '_');
  7713. container.appendChild(value.cloneNode(false));
  7714. var html = container.innerHTML
  7715. .replace('><', '>' + value.innerHTML + '<');
  7716. container.innerHTML = '';
  7717. return html;
  7718. }
  7719. } catch (err) {
  7720. // This could be a non-native DOM implementation,
  7721. // continue with the normal flow:
  7722. // printing the element as if it is an object.
  7723. }
  7724. }
  7725. }
  7726. // Look up the keys of the object.
  7727. var visibleKeys = getEnumerableProperties(value);
  7728. var keys = ctx.showHidden ? getProperties(value) : visibleKeys;
  7729. var name, nameSuffix;
  7730. // Some type of object without properties can be shortcut.
  7731. // In IE, errors have a single `stack` property, or if they are vanilla `Error`,
  7732. // a `stack` plus `description` property; ignore those for consistency.
  7733. if (keys.length === 0 || (isError(value) && (
  7734. (keys.length === 1 && keys[0] === 'stack') ||
  7735. (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack')
  7736. ))) {
  7737. if (typeof value === 'function') {
  7738. name = getName(value);
  7739. nameSuffix = name ? ': ' + name : '';
  7740. return ctx.stylize('[Function' + nameSuffix + ']', 'special');
  7741. }
  7742. if (isRegExp(value)) {
  7743. return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
  7744. }
  7745. if (isDate(value)) {
  7746. return ctx.stylize(Date.prototype.toUTCString.call(value), 'date');
  7747. }
  7748. if (isError(value)) {
  7749. return formatError(value);
  7750. }
  7751. }
  7752. var base = ''
  7753. , array = false
  7754. , typedArray = false
  7755. , braces = ['{', '}'];
  7756. if (isTypedArray(value)) {
  7757. typedArray = true;
  7758. braces = ['[', ']'];
  7759. }
  7760. // Make Array say that they are Array
  7761. if (isArray(value)) {
  7762. array = true;
  7763. braces = ['[', ']'];
  7764. }
  7765. // Make functions say that they are functions
  7766. if (typeof value === 'function') {
  7767. name = getName(value);
  7768. nameSuffix = name ? ': ' + name : '';
  7769. base = ' [Function' + nameSuffix + ']';
  7770. }
  7771. // Make RegExps say that they are RegExps
  7772. if (isRegExp(value)) {
  7773. base = ' ' + RegExp.prototype.toString.call(value);
  7774. }
  7775. // Make dates with properties first say the date
  7776. if (isDate(value)) {
  7777. base = ' ' + Date.prototype.toUTCString.call(value);
  7778. }
  7779. // Make error with message first say the error
  7780. if (isError(value)) {
  7781. return formatError(value);
  7782. }
  7783. if (keys.length === 0 && (!array || value.length == 0)) {
  7784. return braces[0] + base + braces[1];
  7785. }
  7786. if (recurseTimes < 0) {
  7787. if (isRegExp(value)) {
  7788. return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
  7789. } else {
  7790. return ctx.stylize('[Object]', 'special');
  7791. }
  7792. }
  7793. ctx.seen.push(value);
  7794. var output;
  7795. if (array) {
  7796. output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
  7797. } else if (typedArray) {
  7798. return formatTypedArray(value);
  7799. } else {
  7800. output = keys.map(function(key) {
  7801. return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
  7802. });
  7803. }
  7804. ctx.seen.pop();
  7805. return reduceToSingleString(output, base, braces);
  7806. }
  7807. function formatPrimitive(ctx, value) {
  7808. switch (typeof value) {
  7809. case 'undefined':
  7810. return ctx.stylize('undefined', 'undefined');
  7811. case 'string':
  7812. var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
  7813. .replace(/'/g, "\\'")
  7814. .replace(/\\"/g, '"') + '\'';
  7815. return ctx.stylize(simple, 'string');
  7816. case 'number':
  7817. if (value === 0 && (1/value) === -Infinity) {
  7818. return ctx.stylize('-0', 'number');
  7819. }
  7820. return ctx.stylize('' + value, 'number');
  7821. case 'boolean':
  7822. return ctx.stylize('' + value, 'boolean');
  7823. case 'symbol':
  7824. return ctx.stylize(value.toString(), 'symbol');
  7825. }
  7826. // For some reason typeof null is "object", so special case here.
  7827. if (value === null) {
  7828. return ctx.stylize('null', 'null');
  7829. }
  7830. }
  7831. function formatError(value) {
  7832. return '[' + Error.prototype.toString.call(value) + ']';
  7833. }
  7834. function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
  7835. var output = [];
  7836. for (var i = 0, l = value.length; i < l; ++i) {
  7837. if (Object.prototype.hasOwnProperty.call(value, String(i))) {
  7838. output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
  7839. String(i), true));
  7840. } else {
  7841. output.push('');
  7842. }
  7843. }
  7844. keys.forEach(function(key) {
  7845. if (!key.match(/^\d+$/)) {
  7846. output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
  7847. key, true));
  7848. }
  7849. });
  7850. return output;
  7851. }
  7852. function formatTypedArray(value) {
  7853. var str = '[ ';
  7854. for (var i = 0; i < value.length; ++i) {
  7855. if (str.length >= config.truncateThreshold - 7) {
  7856. str += '...';
  7857. break;
  7858. }
  7859. str += value[i] + ', ';
  7860. }
  7861. str += ' ]';
  7862. // Removing trailing `, ` if the array was not truncated
  7863. if (str.indexOf(', ]') !== -1) {
  7864. str = str.replace(', ]', ' ]');
  7865. }
  7866. return str;
  7867. }
  7868. function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
  7869. var name;
  7870. var propDescriptor = Object.getOwnPropertyDescriptor(value, key);
  7871. var str;
  7872. if (propDescriptor) {
  7873. if (propDescriptor.get) {
  7874. if (propDescriptor.set) {
  7875. str = ctx.stylize('[Getter/Setter]', 'special');
  7876. } else {
  7877. str = ctx.stylize('[Getter]', 'special');
  7878. }
  7879. } else {
  7880. if (propDescriptor.set) {
  7881. str = ctx.stylize('[Setter]', 'special');
  7882. }
  7883. }
  7884. }
  7885. if (visibleKeys.indexOf(key) < 0) {
  7886. name = '[' + key + ']';
  7887. }
  7888. if (!str) {
  7889. if (ctx.seen.indexOf(value[key]) < 0) {
  7890. if (recurseTimes === null) {
  7891. str = formatValue(ctx, value[key], null);
  7892. } else {
  7893. str = formatValue(ctx, value[key], recurseTimes - 1);
  7894. }
  7895. if (str.indexOf('\n') > -1) {
  7896. if (array) {
  7897. str = str.split('\n').map(function(line) {
  7898. return ' ' + line;
  7899. }).join('\n').substr(2);
  7900. } else {
  7901. str = '\n' + str.split('\n').map(function(line) {
  7902. return ' ' + line;
  7903. }).join('\n');
  7904. }
  7905. }
  7906. } else {
  7907. str = ctx.stylize('[Circular]', 'special');
  7908. }
  7909. }
  7910. if (typeof name === 'undefined') {
  7911. if (array && key.match(/^\d+$/)) {
  7912. return str;
  7913. }
  7914. name = JSON.stringify('' + key);
  7915. if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
  7916. name = name.substr(1, name.length - 2);
  7917. name = ctx.stylize(name, 'name');
  7918. } else {
  7919. name = name.replace(/'/g, "\\'")
  7920. .replace(/\\"/g, '"')
  7921. .replace(/(^"|"$)/g, "'");
  7922. name = ctx.stylize(name, 'string');
  7923. }
  7924. }
  7925. return name + ': ' + str;
  7926. }
  7927. function reduceToSingleString(output, base, braces) {
  7928. var length = output.reduce(function(prev, cur) {
  7929. return prev + cur.length + 1;
  7930. }, 0);
  7931. if (length > 60) {
  7932. return braces[0] +
  7933. (base === '' ? '' : base + '\n ') +
  7934. ' ' +
  7935. output.join(',\n ') +
  7936. ' ' +
  7937. braces[1];
  7938. }
  7939. return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
  7940. }
  7941. function isTypedArray(ar) {
  7942. // Unfortunately there's no way to check if an object is a TypedArray
  7943. // We have to check if it's one of these types
  7944. return (typeof ar === 'object' && /\w+Array]$/.test(objectToString(ar)));
  7945. }
  7946. function isArray(ar) {
  7947. return Array.isArray(ar) ||
  7948. (typeof ar === 'object' && objectToString(ar) === '[object Array]');
  7949. }
  7950. function isRegExp(re) {
  7951. return typeof re === 'object' && objectToString(re) === '[object RegExp]';
  7952. }
  7953. function isDate(d) {
  7954. return typeof d === 'object' && objectToString(d) === '[object Date]';
  7955. }
  7956. function isError(e) {
  7957. return typeof e === 'object' && objectToString(e) === '[object Error]';
  7958. }
  7959. function objectToString(o) {
  7960. return Object.prototype.toString.call(o);
  7961. }
  7962. },{"../config":4,"./getEnumerableProperties":17,"./getProperties":21,"get-func-name":36}],24:[function(require,module,exports){
  7963. /*!
  7964. * Chai - isNaN utility
  7965. * Copyright(c) 2012-2015 Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
  7966. * MIT Licensed
  7967. */
  7968. /**
  7969. * ### .isNaN(value)
  7970. *
  7971. * Checks if the given value is NaN or not.
  7972. *
  7973. * utils.isNaN(NaN); // true
  7974. *
  7975. * @param {Value} The value which has to be checked if it is NaN
  7976. * @name isNaN
  7977. * @api private
  7978. */
  7979. function isNaN(value) {
  7980. // Refer http://www.ecma-international.org/ecma-262/6.0/#sec-isnan-number
  7981. // section's NOTE.
  7982. return value !== value;
  7983. }
  7984. // If ECMAScript 6's Number.isNaN is present, prefer that.
  7985. module.exports = Number.isNaN || isNaN;
  7986. },{}],25:[function(require,module,exports){
  7987. var config = require('../config');
  7988. /*!
  7989. * Chai - isProxyEnabled helper
  7990. * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  7991. * MIT Licensed
  7992. */
  7993. /**
  7994. * ### .isProxyEnabled()
  7995. *
  7996. * Helper function to check if Chai's proxy protection feature is enabled. If
  7997. * proxies are unsupported or disabled via the user's Chai config, then return
  7998. * false. Otherwise, return true.
  7999. *
  8000. * @namespace Utils
  8001. * @name isProxyEnabled
  8002. */
  8003. module.exports = function isProxyEnabled() {
  8004. return config.useProxy &&
  8005. typeof Proxy !== 'undefined' &&
  8006. typeof Reflect !== 'undefined';
  8007. };
  8008. },{"../config":4}],26:[function(require,module,exports){
  8009. /*!
  8010. * Chai - flag utility
  8011. * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  8012. * MIT Licensed
  8013. */
  8014. /*!
  8015. * Module dependencies
  8016. */
  8017. var inspect = require('./inspect');
  8018. var config = require('../config');
  8019. /**
  8020. * ### .objDisplay(object)
  8021. *
  8022. * Determines if an object or an array matches
  8023. * criteria to be inspected in-line for error
  8024. * messages or should be truncated.
  8025. *
  8026. * @param {Mixed} javascript object to inspect
  8027. * @name objDisplay
  8028. * @namespace Utils
  8029. * @api public
  8030. */
  8031. module.exports = function objDisplay(obj) {
  8032. var str = inspect(obj)
  8033. , type = Object.prototype.toString.call(obj);
  8034. if (config.truncateThreshold && str.length >= config.truncateThreshold) {
  8035. if (type === '[object Function]') {
  8036. return !obj.name || obj.name === ''
  8037. ? '[Function]'
  8038. : '[Function: ' + obj.name + ']';
  8039. } else if (type === '[object Array]') {
  8040. return '[ Array(' + obj.length + ') ]';
  8041. } else if (type === '[object Object]') {
  8042. var keys = Object.keys(obj)
  8043. , kstr = keys.length > 2
  8044. ? keys.splice(0, 2).join(', ') + ', ...'
  8045. : keys.join(', ');
  8046. return '{ Object (' + kstr + ') }';
  8047. } else {
  8048. return str;
  8049. }
  8050. } else {
  8051. return str;
  8052. }
  8053. };
  8054. },{"../config":4,"./inspect":23}],27:[function(require,module,exports){
  8055. /*!
  8056. * Chai - overwriteChainableMethod utility
  8057. * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  8058. * MIT Licensed
  8059. */
  8060. var chai = require('../../chai');
  8061. var transferFlags = require('./transferFlags');
  8062. /**
  8063. * ### .overwriteChainableMethod(ctx, name, method, chainingBehavior)
  8064. *
  8065. * Overwrites an already existing chainable method
  8066. * and provides access to the previous function or
  8067. * property. Must return functions to be used for
  8068. * name.
  8069. *
  8070. * utils.overwriteChainableMethod(chai.Assertion.prototype, 'lengthOf',
  8071. * function (_super) {
  8072. * }
  8073. * , function (_super) {
  8074. * }
  8075. * );
  8076. *
  8077. * Can also be accessed directly from `chai.Assertion`.
  8078. *
  8079. * chai.Assertion.overwriteChainableMethod('foo', fn, fn);
  8080. *
  8081. * Then can be used as any other assertion.
  8082. *
  8083. * expect(myFoo).to.have.lengthOf(3);
  8084. * expect(myFoo).to.have.lengthOf.above(3);
  8085. *
  8086. * @param {Object} ctx object whose method / property is to be overwritten
  8087. * @param {String} name of method / property to overwrite
  8088. * @param {Function} method function that returns a function to be used for name
  8089. * @param {Function} chainingBehavior function that returns a function to be used for property
  8090. * @namespace Utils
  8091. * @name overwriteChainableMethod
  8092. * @api public
  8093. */
  8094. module.exports = function overwriteChainableMethod(ctx, name, method, chainingBehavior) {
  8095. var chainableBehavior = ctx.__methods[name];
  8096. var _chainingBehavior = chainableBehavior.chainingBehavior;
  8097. chainableBehavior.chainingBehavior = function overwritingChainableMethodGetter() {
  8098. var result = chainingBehavior(_chainingBehavior).call(this);
  8099. if (result !== undefined) {
  8100. return result;
  8101. }
  8102. var newAssertion = new chai.Assertion();
  8103. transferFlags(this, newAssertion);
  8104. return newAssertion;
  8105. };
  8106. var _method = chainableBehavior.method;
  8107. chainableBehavior.method = function overwritingChainableMethodWrapper() {
  8108. var result = method(_method).apply(this, arguments);
  8109. if (result !== undefined) {
  8110. return result;
  8111. }
  8112. var newAssertion = new chai.Assertion();
  8113. transferFlags(this, newAssertion);
  8114. return newAssertion;
  8115. };
  8116. };
  8117. },{"../../chai":2,"./transferFlags":32}],28:[function(require,module,exports){
  8118. /*!
  8119. * Chai - overwriteMethod utility
  8120. * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  8121. * MIT Licensed
  8122. */
  8123. var addLengthGuard = require('./addLengthGuard');
  8124. var chai = require('../../chai');
  8125. var flag = require('./flag');
  8126. var proxify = require('./proxify');
  8127. var transferFlags = require('./transferFlags');
  8128. /**
  8129. * ### .overwriteMethod(ctx, name, fn)
  8130. *
  8131. * Overwrites an already existing method and provides
  8132. * access to previous function. Must return function
  8133. * to be used for name.
  8134. *
  8135. * utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) {
  8136. * return function (str) {
  8137. * var obj = utils.flag(this, 'object');
  8138. * if (obj instanceof Foo) {
  8139. * new chai.Assertion(obj.value).to.equal(str);
  8140. * } else {
  8141. * _super.apply(this, arguments);
  8142. * }
  8143. * }
  8144. * });
  8145. *
  8146. * Can also be accessed directly from `chai.Assertion`.
  8147. *
  8148. * chai.Assertion.overwriteMethod('foo', fn);
  8149. *
  8150. * Then can be used as any other assertion.
  8151. *
  8152. * expect(myFoo).to.equal('bar');
  8153. *
  8154. * @param {Object} ctx object whose method is to be overwritten
  8155. * @param {String} name of method to overwrite
  8156. * @param {Function} method function that returns a function to be used for name
  8157. * @namespace Utils
  8158. * @name overwriteMethod
  8159. * @api public
  8160. */
  8161. module.exports = function overwriteMethod(ctx, name, method) {
  8162. var _method = ctx[name]
  8163. , _super = function () {
  8164. throw new Error(name + ' is not a function');
  8165. };
  8166. if (_method && 'function' === typeof _method)
  8167. _super = _method;
  8168. var overwritingMethodWrapper = function () {
  8169. // Setting the `ssfi` flag to `overwritingMethodWrapper` causes this
  8170. // function to be the starting point for removing implementation frames from
  8171. // the stack trace of a failed assertion.
  8172. //
  8173. // However, we only want to use this function as the starting point if the
  8174. // `lockSsfi` flag isn't set.
  8175. //
  8176. // If the `lockSsfi` flag is set, then either this assertion has been
  8177. // overwritten by another assertion, or this assertion is being invoked from
  8178. // inside of another assertion. In the first case, the `ssfi` flag has
  8179. // already been set by the overwriting assertion. In the second case, the
  8180. // `ssfi` flag has already been set by the outer assertion.
  8181. if (!flag(this, 'lockSsfi')) {
  8182. flag(this, 'ssfi', overwritingMethodWrapper);
  8183. }
  8184. // Setting the `lockSsfi` flag to `true` prevents the overwritten assertion
  8185. // from changing the `ssfi` flag. By this point, the `ssfi` flag is already
  8186. // set to the correct starting point for this assertion.
  8187. var origLockSsfi = flag(this, 'lockSsfi');
  8188. flag(this, 'lockSsfi', true);
  8189. var result = method(_super).apply(this, arguments);
  8190. flag(this, 'lockSsfi', origLockSsfi);
  8191. if (result !== undefined) {
  8192. return result;
  8193. }
  8194. var newAssertion = new chai.Assertion();
  8195. transferFlags(this, newAssertion);
  8196. return newAssertion;
  8197. }
  8198. addLengthGuard(overwritingMethodWrapper, name, false);
  8199. ctx[name] = proxify(overwritingMethodWrapper, name);
  8200. };
  8201. },{"../../chai":2,"./addLengthGuard":10,"./flag":15,"./proxify":30,"./transferFlags":32}],29:[function(require,module,exports){
  8202. /*!
  8203. * Chai - overwriteProperty utility
  8204. * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  8205. * MIT Licensed
  8206. */
  8207. var chai = require('../../chai');
  8208. var flag = require('./flag');
  8209. var isProxyEnabled = require('./isProxyEnabled');
  8210. var transferFlags = require('./transferFlags');
  8211. /**
  8212. * ### .overwriteProperty(ctx, name, fn)
  8213. *
  8214. * Overwrites an already existing property getter and provides
  8215. * access to previous value. Must return function to use as getter.
  8216. *
  8217. * utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) {
  8218. * return function () {
  8219. * var obj = utils.flag(this, 'object');
  8220. * if (obj instanceof Foo) {
  8221. * new chai.Assertion(obj.name).to.equal('bar');
  8222. * } else {
  8223. * _super.call(this);
  8224. * }
  8225. * }
  8226. * });
  8227. *
  8228. *
  8229. * Can also be accessed directly from `chai.Assertion`.
  8230. *
  8231. * chai.Assertion.overwriteProperty('foo', fn);
  8232. *
  8233. * Then can be used as any other assertion.
  8234. *
  8235. * expect(myFoo).to.be.ok;
  8236. *
  8237. * @param {Object} ctx object whose property is to be overwritten
  8238. * @param {String} name of property to overwrite
  8239. * @param {Function} getter function that returns a getter function to be used for name
  8240. * @namespace Utils
  8241. * @name overwriteProperty
  8242. * @api public
  8243. */
  8244. module.exports = function overwriteProperty(ctx, name, getter) {
  8245. var _get = Object.getOwnPropertyDescriptor(ctx, name)
  8246. , _super = function () {};
  8247. if (_get && 'function' === typeof _get.get)
  8248. _super = _get.get
  8249. Object.defineProperty(ctx, name,
  8250. { get: function overwritingPropertyGetter() {
  8251. // Setting the `ssfi` flag to `overwritingPropertyGetter` causes this
  8252. // function to be the starting point for removing implementation frames
  8253. // from the stack trace of a failed assertion.
  8254. //
  8255. // However, we only want to use this function as the starting point if
  8256. // the `lockSsfi` flag isn't set and proxy protection is disabled.
  8257. //
  8258. // If the `lockSsfi` flag is set, then either this assertion has been
  8259. // overwritten by another assertion, or this assertion is being invoked
  8260. // from inside of another assertion. In the first case, the `ssfi` flag
  8261. // has already been set by the overwriting assertion. In the second
  8262. // case, the `ssfi` flag has already been set by the outer assertion.
  8263. //
  8264. // If proxy protection is enabled, then the `ssfi` flag has already been
  8265. // set by the proxy getter.
  8266. if (!isProxyEnabled() && !flag(this, 'lockSsfi')) {
  8267. flag(this, 'ssfi', overwritingPropertyGetter);
  8268. }
  8269. // Setting the `lockSsfi` flag to `true` prevents the overwritten
  8270. // assertion from changing the `ssfi` flag. By this point, the `ssfi`
  8271. // flag is already set to the correct starting point for this assertion.
  8272. var origLockSsfi = flag(this, 'lockSsfi');
  8273. flag(this, 'lockSsfi', true);
  8274. var result = getter(_super).call(this);
  8275. flag(this, 'lockSsfi', origLockSsfi);
  8276. if (result !== undefined) {
  8277. return result;
  8278. }
  8279. var newAssertion = new chai.Assertion();
  8280. transferFlags(this, newAssertion);
  8281. return newAssertion;
  8282. }
  8283. , configurable: true
  8284. });
  8285. };
  8286. },{"../../chai":2,"./flag":15,"./isProxyEnabled":25,"./transferFlags":32}],30:[function(require,module,exports){
  8287. var config = require('../config');
  8288. var flag = require('./flag');
  8289. var getProperties = require('./getProperties');
  8290. var isProxyEnabled = require('./isProxyEnabled');
  8291. /*!
  8292. * Chai - proxify utility
  8293. * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  8294. * MIT Licensed
  8295. */
  8296. /**
  8297. * ### .proxify(object)
  8298. *
  8299. * Return a proxy of given object that throws an error when a non-existent
  8300. * property is read. By default, the root cause is assumed to be a misspelled
  8301. * property, and thus an attempt is made to offer a reasonable suggestion from
  8302. * the list of existing properties. However, if a nonChainableMethodName is
  8303. * provided, then the root cause is instead a failure to invoke a non-chainable
  8304. * method prior to reading the non-existent property.
  8305. *
  8306. * If proxies are unsupported or disabled via the user's Chai config, then
  8307. * return object without modification.
  8308. *
  8309. * @param {Object} obj
  8310. * @param {String} nonChainableMethodName
  8311. * @namespace Utils
  8312. * @name proxify
  8313. */
  8314. var builtins = ['__flags', '__methods', '_obj', 'assert'];
  8315. module.exports = function proxify(obj, nonChainableMethodName) {
  8316. if (!isProxyEnabled()) return obj;
  8317. return new Proxy(obj, {
  8318. get: function proxyGetter(target, property) {
  8319. // This check is here because we should not throw errors on Symbol properties
  8320. // such as `Symbol.toStringTag`.
  8321. // The values for which an error should be thrown can be configured using
  8322. // the `config.proxyExcludedKeys` setting.
  8323. if (typeof property === 'string' &&
  8324. config.proxyExcludedKeys.indexOf(property) === -1 &&
  8325. !Reflect.has(target, property)) {
  8326. // Special message for invalid property access of non-chainable methods.
  8327. if (nonChainableMethodName) {
  8328. throw Error('Invalid Chai property: ' + nonChainableMethodName + '.' +
  8329. property + '. See docs for proper usage of "' +
  8330. nonChainableMethodName + '".');
  8331. }
  8332. // If the property is reasonably close to an existing Chai property,
  8333. // suggest that property to the user. Only suggest properties with a
  8334. // distance less than 4.
  8335. var suggestion = null;
  8336. var suggestionDistance = 4;
  8337. getProperties(target).forEach(function(prop) {
  8338. if (
  8339. !Object.prototype.hasOwnProperty(prop) &&
  8340. builtins.indexOf(prop) === -1
  8341. ) {
  8342. var dist = stringDistanceCapped(
  8343. property,
  8344. prop,
  8345. suggestionDistance
  8346. );
  8347. if (dist < suggestionDistance) {
  8348. suggestion = prop;
  8349. suggestionDistance = dist;
  8350. }
  8351. }
  8352. });
  8353. if (suggestion !== null) {
  8354. throw Error('Invalid Chai property: ' + property +
  8355. '. Did you mean "' + suggestion + '"?');
  8356. } else {
  8357. throw Error('Invalid Chai property: ' + property);
  8358. }
  8359. }
  8360. // Use this proxy getter as the starting point for removing implementation
  8361. // frames from the stack trace of a failed assertion. For property
  8362. // assertions, this prevents the proxy getter from showing up in the stack
  8363. // trace since it's invoked before the property getter. For method and
  8364. // chainable method assertions, this flag will end up getting changed to
  8365. // the method wrapper, which is good since this frame will no longer be in
  8366. // the stack once the method is invoked. Note that Chai builtin assertion
  8367. // properties such as `__flags` are skipped since this is only meant to
  8368. // capture the starting point of an assertion. This step is also skipped
  8369. // if the `lockSsfi` flag is set, thus indicating that this assertion is
  8370. // being called from within another assertion. In that case, the `ssfi`
  8371. // flag is already set to the outer assertion's starting point.
  8372. if (builtins.indexOf(property) === -1 && !flag(target, 'lockSsfi')) {
  8373. flag(target, 'ssfi', proxyGetter);
  8374. }
  8375. return Reflect.get(target, property);
  8376. }
  8377. });
  8378. };
  8379. /**
  8380. * # stringDistanceCapped(strA, strB, cap)
  8381. * Return the Levenshtein distance between two strings, but no more than cap.
  8382. * @param {string} strA
  8383. * @param {string} strB
  8384. * @param {number} number
  8385. * @return {number} min(string distance between strA and strB, cap)
  8386. * @api private
  8387. */
  8388. function stringDistanceCapped(strA, strB, cap) {
  8389. if (Math.abs(strA.length - strB.length) >= cap) {
  8390. return cap;
  8391. }
  8392. var memo = [];
  8393. // `memo` is a two-dimensional array containing distances.
  8394. // memo[i][j] is the distance between strA.slice(0, i) and
  8395. // strB.slice(0, j).
  8396. for (var i = 0; i <= strA.length; i++) {
  8397. memo[i] = Array(strB.length + 1).fill(0);
  8398. memo[i][0] = i;
  8399. }
  8400. for (var j = 0; j < strB.length; j++) {
  8401. memo[0][j] = j;
  8402. }
  8403. for (var i = 1; i <= strA.length; i++) {
  8404. var ch = strA.charCodeAt(i - 1);
  8405. for (var j = 1; j <= strB.length; j++) {
  8406. if (Math.abs(i - j) >= cap) {
  8407. memo[i][j] = cap;
  8408. continue;
  8409. }
  8410. memo[i][j] = Math.min(
  8411. memo[i - 1][j] + 1,
  8412. memo[i][j - 1] + 1,
  8413. memo[i - 1][j - 1] +
  8414. (ch === strB.charCodeAt(j - 1) ? 0 : 1)
  8415. );
  8416. }
  8417. }
  8418. return memo[strA.length][strB.length];
  8419. }
  8420. },{"../config":4,"./flag":15,"./getProperties":21,"./isProxyEnabled":25}],31:[function(require,module,exports){
  8421. /*!
  8422. * Chai - test utility
  8423. * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  8424. * MIT Licensed
  8425. */
  8426. /*!
  8427. * Module dependencies
  8428. */
  8429. var flag = require('./flag');
  8430. /**
  8431. * ### .test(object, expression)
  8432. *
  8433. * Test and object for expression.
  8434. *
  8435. * @param {Object} object (constructed Assertion)
  8436. * @param {Arguments} chai.Assertion.prototype.assert arguments
  8437. * @namespace Utils
  8438. * @name test
  8439. */
  8440. module.exports = function test(obj, args) {
  8441. var negate = flag(obj, 'negate')
  8442. , expr = args[0];
  8443. return negate ? !expr : expr;
  8444. };
  8445. },{"./flag":15}],32:[function(require,module,exports){
  8446. /*!
  8447. * Chai - transferFlags utility
  8448. * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  8449. * MIT Licensed
  8450. */
  8451. /**
  8452. * ### .transferFlags(assertion, object, includeAll = true)
  8453. *
  8454. * Transfer all the flags for `assertion` to `object`. If
  8455. * `includeAll` is set to `false`, then the base Chai
  8456. * assertion flags (namely `object`, `ssfi`, `lockSsfi`,
  8457. * and `message`) will not be transferred.
  8458. *
  8459. *
  8460. * var newAssertion = new Assertion();
  8461. * utils.transferFlags(assertion, newAssertion);
  8462. *
  8463. * var anotherAssertion = new Assertion(myObj);
  8464. * utils.transferFlags(assertion, anotherAssertion, false);
  8465. *
  8466. * @param {Assertion} assertion the assertion to transfer the flags from
  8467. * @param {Object} object the object to transfer the flags to; usually a new assertion
  8468. * @param {Boolean} includeAll
  8469. * @namespace Utils
  8470. * @name transferFlags
  8471. * @api private
  8472. */
  8473. module.exports = function transferFlags(assertion, object, includeAll) {
  8474. var flags = assertion.__flags || (assertion.__flags = Object.create(null));
  8475. if (!object.__flags) {
  8476. object.__flags = Object.create(null);
  8477. }
  8478. includeAll = arguments.length === 3 ? includeAll : true;
  8479. for (var flag in flags) {
  8480. if (includeAll ||
  8481. (flag !== 'object' && flag !== 'ssfi' && flag !== 'lockSsfi' && flag != 'message')) {
  8482. object.__flags[flag] = flags[flag];
  8483. }
  8484. }
  8485. };
  8486. },{}],33:[function(require,module,exports){
  8487. /*!
  8488. * assertion-error
  8489. * Copyright(c) 2013 Jake Luer <jake@qualiancy.com>
  8490. * MIT Licensed
  8491. */
  8492. /*!
  8493. * Return a function that will copy properties from
  8494. * one object to another excluding any originally
  8495. * listed. Returned function will create a new `{}`.
  8496. *
  8497. * @param {String} excluded properties ...
  8498. * @return {Function}
  8499. */
  8500. function exclude () {
  8501. var excludes = [].slice.call(arguments);
  8502. function excludeProps (res, obj) {
  8503. Object.keys(obj).forEach(function (key) {
  8504. if (!~excludes.indexOf(key)) res[key] = obj[key];
  8505. });
  8506. }
  8507. return function extendExclude () {
  8508. var args = [].slice.call(arguments)
  8509. , i = 0
  8510. , res = {};
  8511. for (; i < args.length; i++) {
  8512. excludeProps(res, args[i]);
  8513. }
  8514. return res;
  8515. };
  8516. };
  8517. /*!
  8518. * Primary Exports
  8519. */
  8520. module.exports = AssertionError;
  8521. /**
  8522. * ### AssertionError
  8523. *
  8524. * An extension of the JavaScript `Error` constructor for
  8525. * assertion and validation scenarios.
  8526. *
  8527. * @param {String} message
  8528. * @param {Object} properties to include (optional)
  8529. * @param {callee} start stack function (optional)
  8530. */
  8531. function AssertionError (message, _props, ssf) {
  8532. var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON')
  8533. , props = extend(_props || {});
  8534. // default values
  8535. this.message = message || 'Unspecified AssertionError';
  8536. this.showDiff = false;
  8537. // copy from properties
  8538. for (var key in props) {
  8539. this[key] = props[key];
  8540. }
  8541. // capture stack trace
  8542. ssf = ssf || AssertionError;
  8543. if (Error.captureStackTrace) {
  8544. Error.captureStackTrace(this, ssf);
  8545. } else {
  8546. try {
  8547. throw new Error();
  8548. } catch(e) {
  8549. this.stack = e.stack;
  8550. }
  8551. }
  8552. }
  8553. /*!
  8554. * Inherit from Error.prototype
  8555. */
  8556. AssertionError.prototype = Object.create(Error.prototype);
  8557. /*!
  8558. * Statically set name
  8559. */
  8560. AssertionError.prototype.name = 'AssertionError';
  8561. /*!
  8562. * Ensure correct constructor
  8563. */
  8564. AssertionError.prototype.constructor = AssertionError;
  8565. /**
  8566. * Allow errors to be converted to JSON for static transfer.
  8567. *
  8568. * @param {Boolean} include stack (default: `true`)
  8569. * @return {Object} object that can be `JSON.stringify`
  8570. */
  8571. AssertionError.prototype.toJSON = function (stack) {
  8572. var extend = exclude('constructor', 'toJSON', 'stack')
  8573. , props = extend({ name: this.name }, this);
  8574. // include stack if exists and not turned off
  8575. if (false !== stack && this.stack) {
  8576. props.stack = this.stack;
  8577. }
  8578. return props;
  8579. };
  8580. },{}],34:[function(require,module,exports){
  8581. 'use strict';
  8582. /* !
  8583. * Chai - checkError utility
  8584. * Copyright(c) 2012-2016 Jake Luer <jake@alogicalparadox.com>
  8585. * MIT Licensed
  8586. */
  8587. /**
  8588. * ### .checkError
  8589. *
  8590. * Checks that an error conforms to a given set of criteria and/or retrieves information about it.
  8591. *
  8592. * @api public
  8593. */
  8594. /**
  8595. * ### .compatibleInstance(thrown, errorLike)
  8596. *
  8597. * Checks if two instances are compatible (strict equal).
  8598. * Returns false if errorLike is not an instance of Error, because instances
  8599. * can only be compatible if they're both error instances.
  8600. *
  8601. * @name compatibleInstance
  8602. * @param {Error} thrown error
  8603. * @param {Error|ErrorConstructor} errorLike object to compare against
  8604. * @namespace Utils
  8605. * @api public
  8606. */
  8607. function compatibleInstance(thrown, errorLike) {
  8608. return errorLike instanceof Error && thrown === errorLike;
  8609. }
  8610. /**
  8611. * ### .compatibleConstructor(thrown, errorLike)
  8612. *
  8613. * Checks if two constructors are compatible.
  8614. * This function can receive either an error constructor or
  8615. * an error instance as the `errorLike` argument.
  8616. * Constructors are compatible if they're the same or if one is
  8617. * an instance of another.
  8618. *
  8619. * @name compatibleConstructor
  8620. * @param {Error} thrown error
  8621. * @param {Error|ErrorConstructor} errorLike object to compare against
  8622. * @namespace Utils
  8623. * @api public
  8624. */
  8625. function compatibleConstructor(thrown, errorLike) {
  8626. if (errorLike instanceof Error) {
  8627. // If `errorLike` is an instance of any error we compare their constructors
  8628. return thrown.constructor === errorLike.constructor || thrown instanceof errorLike.constructor;
  8629. } else if (errorLike.prototype instanceof Error || errorLike === Error) {
  8630. // If `errorLike` is a constructor that inherits from Error, we compare `thrown` to `errorLike` directly
  8631. return thrown.constructor === errorLike || thrown instanceof errorLike;
  8632. }
  8633. return false;
  8634. }
  8635. /**
  8636. * ### .compatibleMessage(thrown, errMatcher)
  8637. *
  8638. * Checks if an error's message is compatible with a matcher (String or RegExp).
  8639. * If the message contains the String or passes the RegExp test,
  8640. * it is considered compatible.
  8641. *
  8642. * @name compatibleMessage
  8643. * @param {Error} thrown error
  8644. * @param {String|RegExp} errMatcher to look for into the message
  8645. * @namespace Utils
  8646. * @api public
  8647. */
  8648. function compatibleMessage(thrown, errMatcher) {
  8649. var comparisonString = typeof thrown === 'string' ? thrown : thrown.message;
  8650. if (errMatcher instanceof RegExp) {
  8651. return errMatcher.test(comparisonString);
  8652. } else if (typeof errMatcher === 'string') {
  8653. return comparisonString.indexOf(errMatcher) !== -1; // eslint-disable-line no-magic-numbers
  8654. }
  8655. return false;
  8656. }
  8657. /**
  8658. * ### .getFunctionName(constructorFn)
  8659. *
  8660. * Returns the name of a function.
  8661. * This also includes a polyfill function if `constructorFn.name` is not defined.
  8662. *
  8663. * @name getFunctionName
  8664. * @param {Function} constructorFn
  8665. * @namespace Utils
  8666. * @api private
  8667. */
  8668. var functionNameMatch = /\s*function(?:\s|\s*\/\*[^(?:*\/)]+\*\/\s*)*([^\(\/]+)/;
  8669. function getFunctionName(constructorFn) {
  8670. var name = '';
  8671. if (typeof constructorFn.name === 'undefined') {
  8672. // Here we run a polyfill if constructorFn.name is not defined
  8673. var match = String(constructorFn).match(functionNameMatch);
  8674. if (match) {
  8675. name = match[1];
  8676. }
  8677. } else {
  8678. name = constructorFn.name;
  8679. }
  8680. return name;
  8681. }
  8682. /**
  8683. * ### .getConstructorName(errorLike)
  8684. *
  8685. * Gets the constructor name for an Error instance or constructor itself.
  8686. *
  8687. * @name getConstructorName
  8688. * @param {Error|ErrorConstructor} errorLike
  8689. * @namespace Utils
  8690. * @api public
  8691. */
  8692. function getConstructorName(errorLike) {
  8693. var constructorName = errorLike;
  8694. if (errorLike instanceof Error) {
  8695. constructorName = getFunctionName(errorLike.constructor);
  8696. } else if (typeof errorLike === 'function') {
  8697. // If `err` is not an instance of Error it is an error constructor itself or another function.
  8698. // If we've got a common function we get its name, otherwise we may need to create a new instance
  8699. // of the error just in case it's a poorly-constructed error. Please see chaijs/chai/issues/45 to know more.
  8700. constructorName = getFunctionName(errorLike).trim() ||
  8701. getFunctionName(new errorLike()); // eslint-disable-line new-cap
  8702. }
  8703. return constructorName;
  8704. }
  8705. /**
  8706. * ### .getMessage(errorLike)
  8707. *
  8708. * Gets the error message from an error.
  8709. * If `err` is a String itself, we return it.
  8710. * If the error has no message, we return an empty string.
  8711. *
  8712. * @name getMessage
  8713. * @param {Error|String} errorLike
  8714. * @namespace Utils
  8715. * @api public
  8716. */
  8717. function getMessage(errorLike) {
  8718. var msg = '';
  8719. if (errorLike && errorLike.message) {
  8720. msg = errorLike.message;
  8721. } else if (typeof errorLike === 'string') {
  8722. msg = errorLike;
  8723. }
  8724. return msg;
  8725. }
  8726. module.exports = {
  8727. compatibleInstance: compatibleInstance,
  8728. compatibleConstructor: compatibleConstructor,
  8729. compatibleMessage: compatibleMessage,
  8730. getMessage: getMessage,
  8731. getConstructorName: getConstructorName,
  8732. };
  8733. },{}],35:[function(require,module,exports){
  8734. 'use strict';
  8735. /* globals Symbol: false, Uint8Array: false, WeakMap: false */
  8736. /*!
  8737. * deep-eql
  8738. * Copyright(c) 2013 Jake Luer <jake@alogicalparadox.com>
  8739. * MIT Licensed
  8740. */
  8741. var type = require('type-detect');
  8742. function FakeMap() {
  8743. this._key = 'chai/deep-eql__' + Math.random() + Date.now();
  8744. }
  8745. FakeMap.prototype = {
  8746. get: function getMap(key) {
  8747. return key[this._key];
  8748. },
  8749. set: function setMap(key, value) {
  8750. if (Object.isExtensible(key)) {
  8751. Object.defineProperty(key, this._key, {
  8752. value: value,
  8753. configurable: true,
  8754. });
  8755. }
  8756. },
  8757. };
  8758. var MemoizeMap = typeof WeakMap === 'function' ? WeakMap : FakeMap;
  8759. /*!
  8760. * Check to see if the MemoizeMap has recorded a result of the two operands
  8761. *
  8762. * @param {Mixed} leftHandOperand
  8763. * @param {Mixed} rightHandOperand
  8764. * @param {MemoizeMap} memoizeMap
  8765. * @returns {Boolean|null} result
  8766. */
  8767. function memoizeCompare(leftHandOperand, rightHandOperand, memoizeMap) {
  8768. // Technically, WeakMap keys can *only* be objects, not primitives.
  8769. if (!memoizeMap || isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) {
  8770. return null;
  8771. }
  8772. var leftHandMap = memoizeMap.get(leftHandOperand);
  8773. if (leftHandMap) {
  8774. var result = leftHandMap.get(rightHandOperand);
  8775. if (typeof result === 'boolean') {
  8776. return result;
  8777. }
  8778. }
  8779. return null;
  8780. }
  8781. /*!
  8782. * Set the result of the equality into the MemoizeMap
  8783. *
  8784. * @param {Mixed} leftHandOperand
  8785. * @param {Mixed} rightHandOperand
  8786. * @param {MemoizeMap} memoizeMap
  8787. * @param {Boolean} result
  8788. */
  8789. function memoizeSet(leftHandOperand, rightHandOperand, memoizeMap, result) {
  8790. // Technically, WeakMap keys can *only* be objects, not primitives.
  8791. if (!memoizeMap || isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) {
  8792. return;
  8793. }
  8794. var leftHandMap = memoizeMap.get(leftHandOperand);
  8795. if (leftHandMap) {
  8796. leftHandMap.set(rightHandOperand, result);
  8797. } else {
  8798. leftHandMap = new MemoizeMap();
  8799. leftHandMap.set(rightHandOperand, result);
  8800. memoizeMap.set(leftHandOperand, leftHandMap);
  8801. }
  8802. }
  8803. /*!
  8804. * Primary Export
  8805. */
  8806. module.exports = deepEqual;
  8807. module.exports.MemoizeMap = MemoizeMap;
  8808. /**
  8809. * Assert deeply nested sameValue equality between two objects of any type.
  8810. *
  8811. * @param {Mixed} leftHandOperand
  8812. * @param {Mixed} rightHandOperand
  8813. * @param {Object} [options] (optional) Additional options
  8814. * @param {Array} [options.comparator] (optional) Override default algorithm, determining custom equality.
  8815. * @param {Array} [options.memoize] (optional) Provide a custom memoization object which will cache the results of
  8816. complex objects for a speed boost. By passing `false` you can disable memoization, but this will cause circular
  8817. references to blow the stack.
  8818. * @return {Boolean} equal match
  8819. */
  8820. function deepEqual(leftHandOperand, rightHandOperand, options) {
  8821. // If we have a comparator, we can't assume anything; so bail to its check first.
  8822. if (options && options.comparator) {
  8823. return extensiveDeepEqual(leftHandOperand, rightHandOperand, options);
  8824. }
  8825. var simpleResult = simpleEqual(leftHandOperand, rightHandOperand);
  8826. if (simpleResult !== null) {
  8827. return simpleResult;
  8828. }
  8829. // Deeper comparisons are pushed through to a larger function
  8830. return extensiveDeepEqual(leftHandOperand, rightHandOperand, options);
  8831. }
  8832. /**
  8833. * Many comparisons can be canceled out early via simple equality or primitive checks.
  8834. * @param {Mixed} leftHandOperand
  8835. * @param {Mixed} rightHandOperand
  8836. * @return {Boolean|null} equal match
  8837. */
  8838. function simpleEqual(leftHandOperand, rightHandOperand) {
  8839. // Equal references (except for Numbers) can be returned early
  8840. if (leftHandOperand === rightHandOperand) {
  8841. // Handle +-0 cases
  8842. return leftHandOperand !== 0 || 1 / leftHandOperand === 1 / rightHandOperand;
  8843. }
  8844. // handle NaN cases
  8845. if (
  8846. leftHandOperand !== leftHandOperand && // eslint-disable-line no-self-compare
  8847. rightHandOperand !== rightHandOperand // eslint-disable-line no-self-compare
  8848. ) {
  8849. return true;
  8850. }
  8851. // Anything that is not an 'object', i.e. symbols, functions, booleans, numbers,
  8852. // strings, and undefined, can be compared by reference.
  8853. if (isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) {
  8854. // Easy out b/c it would have passed the first equality check
  8855. return false;
  8856. }
  8857. return null;
  8858. }
  8859. /*!
  8860. * The main logic of the `deepEqual` function.
  8861. *
  8862. * @param {Mixed} leftHandOperand
  8863. * @param {Mixed} rightHandOperand
  8864. * @param {Object} [options] (optional) Additional options
  8865. * @param {Array} [options.comparator] (optional) Override default algorithm, determining custom equality.
  8866. * @param {Array} [options.memoize] (optional) Provide a custom memoization object which will cache the results of
  8867. complex objects for a speed boost. By passing `false` you can disable memoization, but this will cause circular
  8868. references to blow the stack.
  8869. * @return {Boolean} equal match
  8870. */
  8871. function extensiveDeepEqual(leftHandOperand, rightHandOperand, options) {
  8872. options = options || {};
  8873. options.memoize = options.memoize === false ? false : options.memoize || new MemoizeMap();
  8874. var comparator = options && options.comparator;
  8875. // Check if a memoized result exists.
  8876. var memoizeResultLeft = memoizeCompare(leftHandOperand, rightHandOperand, options.memoize);
  8877. if (memoizeResultLeft !== null) {
  8878. return memoizeResultLeft;
  8879. }
  8880. var memoizeResultRight = memoizeCompare(rightHandOperand, leftHandOperand, options.memoize);
  8881. if (memoizeResultRight !== null) {
  8882. return memoizeResultRight;
  8883. }
  8884. // If a comparator is present, use it.
  8885. if (comparator) {
  8886. var comparatorResult = comparator(leftHandOperand, rightHandOperand);
  8887. // Comparators may return null, in which case we want to go back to default behavior.
  8888. if (comparatorResult === false || comparatorResult === true) {
  8889. memoizeSet(leftHandOperand, rightHandOperand, options.memoize, comparatorResult);
  8890. return comparatorResult;
  8891. }
  8892. // To allow comparators to override *any* behavior, we ran them first. Since it didn't decide
  8893. // what to do, we need to make sure to return the basic tests first before we move on.
  8894. var simpleResult = simpleEqual(leftHandOperand, rightHandOperand);
  8895. if (simpleResult !== null) {
  8896. // Don't memoize this, it takes longer to set/retrieve than to just compare.
  8897. return simpleResult;
  8898. }
  8899. }
  8900. var leftHandType = type(leftHandOperand);
  8901. if (leftHandType !== type(rightHandOperand)) {
  8902. memoizeSet(leftHandOperand, rightHandOperand, options.memoize, false);
  8903. return false;
  8904. }
  8905. // Temporarily set the operands in the memoize object to prevent blowing the stack
  8906. memoizeSet(leftHandOperand, rightHandOperand, options.memoize, true);
  8907. var result = extensiveDeepEqualByType(leftHandOperand, rightHandOperand, leftHandType, options);
  8908. memoizeSet(leftHandOperand, rightHandOperand, options.memoize, result);
  8909. return result;
  8910. }
  8911. function extensiveDeepEqualByType(leftHandOperand, rightHandOperand, leftHandType, options) {
  8912. switch (leftHandType) {
  8913. case 'String':
  8914. case 'Number':
  8915. case 'Boolean':
  8916. case 'Date':
  8917. // If these types are their instance types (e.g. `new Number`) then re-deepEqual against their values
  8918. return deepEqual(leftHandOperand.valueOf(), rightHandOperand.valueOf());
  8919. case 'Promise':
  8920. case 'Symbol':
  8921. case 'function':
  8922. case 'WeakMap':
  8923. case 'WeakSet':
  8924. case 'Error':
  8925. return leftHandOperand === rightHandOperand;
  8926. case 'Arguments':
  8927. case 'Int8Array':
  8928. case 'Uint8Array':
  8929. case 'Uint8ClampedArray':
  8930. case 'Int16Array':
  8931. case 'Uint16Array':
  8932. case 'Int32Array':
  8933. case 'Uint32Array':
  8934. case 'Float32Array':
  8935. case 'Float64Array':
  8936. case 'Array':
  8937. return iterableEqual(leftHandOperand, rightHandOperand, options);
  8938. case 'RegExp':
  8939. return regexpEqual(leftHandOperand, rightHandOperand);
  8940. case 'Generator':
  8941. return generatorEqual(leftHandOperand, rightHandOperand, options);
  8942. case 'DataView':
  8943. return iterableEqual(new Uint8Array(leftHandOperand.buffer), new Uint8Array(rightHandOperand.buffer), options);
  8944. case 'ArrayBuffer':
  8945. return iterableEqual(new Uint8Array(leftHandOperand), new Uint8Array(rightHandOperand), options);
  8946. case 'Set':
  8947. return entriesEqual(leftHandOperand, rightHandOperand, options);
  8948. case 'Map':
  8949. return entriesEqual(leftHandOperand, rightHandOperand, options);
  8950. default:
  8951. return objectEqual(leftHandOperand, rightHandOperand, options);
  8952. }
  8953. }
  8954. /*!
  8955. * Compare two Regular Expressions for equality.
  8956. *
  8957. * @param {RegExp} leftHandOperand
  8958. * @param {RegExp} rightHandOperand
  8959. * @return {Boolean} result
  8960. */
  8961. function regexpEqual(leftHandOperand, rightHandOperand) {
  8962. return leftHandOperand.toString() === rightHandOperand.toString();
  8963. }
  8964. /*!
  8965. * Compare two Sets/Maps for equality. Faster than other equality functions.
  8966. *
  8967. * @param {Set} leftHandOperand
  8968. * @param {Set} rightHandOperand
  8969. * @param {Object} [options] (Optional)
  8970. * @return {Boolean} result
  8971. */
  8972. function entriesEqual(leftHandOperand, rightHandOperand, options) {
  8973. // IE11 doesn't support Set#entries or Set#@@iterator, so we need manually populate using Set#forEach
  8974. if (leftHandOperand.size !== rightHandOperand.size) {
  8975. return false;
  8976. }
  8977. if (leftHandOperand.size === 0) {
  8978. return true;
  8979. }
  8980. var leftHandItems = [];
  8981. var rightHandItems = [];
  8982. leftHandOperand.forEach(function gatherEntries(key, value) {
  8983. leftHandItems.push([ key, value ]);
  8984. });
  8985. rightHandOperand.forEach(function gatherEntries(key, value) {
  8986. rightHandItems.push([ key, value ]);
  8987. });
  8988. return iterableEqual(leftHandItems.sort(), rightHandItems.sort(), options);
  8989. }
  8990. /*!
  8991. * Simple equality for flat iterable objects such as Arrays, TypedArrays or Node.js buffers.
  8992. *
  8993. * @param {Iterable} leftHandOperand
  8994. * @param {Iterable} rightHandOperand
  8995. * @param {Object} [options] (Optional)
  8996. * @return {Boolean} result
  8997. */
  8998. function iterableEqual(leftHandOperand, rightHandOperand, options) {
  8999. var length = leftHandOperand.length;
  9000. if (length !== rightHandOperand.length) {
  9001. return false;
  9002. }
  9003. if (length === 0) {
  9004. return true;
  9005. }
  9006. var index = -1;
  9007. while (++index < length) {
  9008. if (deepEqual(leftHandOperand[index], rightHandOperand[index], options) === false) {
  9009. return false;
  9010. }
  9011. }
  9012. return true;
  9013. }
  9014. /*!
  9015. * Simple equality for generator objects such as those returned by generator functions.
  9016. *
  9017. * @param {Iterable} leftHandOperand
  9018. * @param {Iterable} rightHandOperand
  9019. * @param {Object} [options] (Optional)
  9020. * @return {Boolean} result
  9021. */
  9022. function generatorEqual(leftHandOperand, rightHandOperand, options) {
  9023. return iterableEqual(getGeneratorEntries(leftHandOperand), getGeneratorEntries(rightHandOperand), options);
  9024. }
  9025. /*!
  9026. * Determine if the given object has an @@iterator function.
  9027. *
  9028. * @param {Object} target
  9029. * @return {Boolean} `true` if the object has an @@iterator function.
  9030. */
  9031. function hasIteratorFunction(target) {
  9032. return typeof Symbol !== 'undefined' &&
  9033. typeof target === 'object' &&
  9034. typeof Symbol.iterator !== 'undefined' &&
  9035. typeof target[Symbol.iterator] === 'function';
  9036. }
  9037. /*!
  9038. * Gets all iterator entries from the given Object. If the Object has no @@iterator function, returns an empty array.
  9039. * This will consume the iterator - which could have side effects depending on the @@iterator implementation.
  9040. *
  9041. * @param {Object} target
  9042. * @returns {Array} an array of entries from the @@iterator function
  9043. */
  9044. function getIteratorEntries(target) {
  9045. if (hasIteratorFunction(target)) {
  9046. try {
  9047. return getGeneratorEntries(target[Symbol.iterator]());
  9048. } catch (iteratorError) {
  9049. return [];
  9050. }
  9051. }
  9052. return [];
  9053. }
  9054. /*!
  9055. * Gets all entries from a Generator. This will consume the generator - which could have side effects.
  9056. *
  9057. * @param {Generator} target
  9058. * @returns {Array} an array of entries from the Generator.
  9059. */
  9060. function getGeneratorEntries(generator) {
  9061. var generatorResult = generator.next();
  9062. var accumulator = [ generatorResult.value ];
  9063. while (generatorResult.done === false) {
  9064. generatorResult = generator.next();
  9065. accumulator.push(generatorResult.value);
  9066. }
  9067. return accumulator;
  9068. }
  9069. /*!
  9070. * Gets all own and inherited enumerable keys from a target.
  9071. *
  9072. * @param {Object} target
  9073. * @returns {Array} an array of own and inherited enumerable keys from the target.
  9074. */
  9075. function getEnumerableKeys(target) {
  9076. var keys = [];
  9077. for (var key in target) {
  9078. keys.push(key);
  9079. }
  9080. return keys;
  9081. }
  9082. /*!
  9083. * Determines if two objects have matching values, given a set of keys. Defers to deepEqual for the equality check of
  9084. * each key. If any value of the given key is not equal, the function will return false (early).
  9085. *
  9086. * @param {Mixed} leftHandOperand
  9087. * @param {Mixed} rightHandOperand
  9088. * @param {Array} keys An array of keys to compare the values of leftHandOperand and rightHandOperand against
  9089. * @param {Object} [options] (Optional)
  9090. * @return {Boolean} result
  9091. */
  9092. function keysEqual(leftHandOperand, rightHandOperand, keys, options) {
  9093. var length = keys.length;
  9094. if (length === 0) {
  9095. return true;
  9096. }
  9097. for (var i = 0; i < length; i += 1) {
  9098. if (deepEqual(leftHandOperand[keys[i]], rightHandOperand[keys[i]], options) === false) {
  9099. return false;
  9100. }
  9101. }
  9102. return true;
  9103. }
  9104. /*!
  9105. * Recursively check the equality of two Objects. Once basic sameness has been established it will defer to `deepEqual`
  9106. * for each enumerable key in the object.
  9107. *
  9108. * @param {Mixed} leftHandOperand
  9109. * @param {Mixed} rightHandOperand
  9110. * @param {Object} [options] (Optional)
  9111. * @return {Boolean} result
  9112. */
  9113. function objectEqual(leftHandOperand, rightHandOperand, options) {
  9114. var leftHandKeys = getEnumerableKeys(leftHandOperand);
  9115. var rightHandKeys = getEnumerableKeys(rightHandOperand);
  9116. if (leftHandKeys.length && leftHandKeys.length === rightHandKeys.length) {
  9117. leftHandKeys.sort();
  9118. rightHandKeys.sort();
  9119. if (iterableEqual(leftHandKeys, rightHandKeys) === false) {
  9120. return false;
  9121. }
  9122. return keysEqual(leftHandOperand, rightHandOperand, leftHandKeys, options);
  9123. }
  9124. var leftHandEntries = getIteratorEntries(leftHandOperand);
  9125. var rightHandEntries = getIteratorEntries(rightHandOperand);
  9126. if (leftHandEntries.length && leftHandEntries.length === rightHandEntries.length) {
  9127. leftHandEntries.sort();
  9128. rightHandEntries.sort();
  9129. return iterableEqual(leftHandEntries, rightHandEntries, options);
  9130. }
  9131. if (leftHandKeys.length === 0 &&
  9132. leftHandEntries.length === 0 &&
  9133. rightHandKeys.length === 0 &&
  9134. rightHandEntries.length === 0) {
  9135. return true;
  9136. }
  9137. return false;
  9138. }
  9139. /*!
  9140. * Returns true if the argument is a primitive.
  9141. *
  9142. * This intentionally returns true for all objects that can be compared by reference,
  9143. * including functions and symbols.
  9144. *
  9145. * @param {Mixed} value
  9146. * @return {Boolean} result
  9147. */
  9148. function isPrimitive(value) {
  9149. return value === null || typeof value !== 'object';
  9150. }
  9151. },{"type-detect":38}],36:[function(require,module,exports){
  9152. 'use strict';
  9153. /* !
  9154. * Chai - getFuncName utility
  9155. * Copyright(c) 2012-2016 Jake Luer <jake@alogicalparadox.com>
  9156. * MIT Licensed
  9157. */
  9158. /**
  9159. * ### .getFuncName(constructorFn)
  9160. *
  9161. * Returns the name of a function.
  9162. * When a non-function instance is passed, returns `null`.
  9163. * This also includes a polyfill function if `aFunc.name` is not defined.
  9164. *
  9165. * @name getFuncName
  9166. * @param {Function} funct
  9167. * @namespace Utils
  9168. * @api public
  9169. */
  9170. var toString = Function.prototype.toString;
  9171. var functionNameMatch = /\s*function(?:\s|\s*\/\*[^(?:*\/)]+\*\/\s*)*([^\s\(\/]+)/;
  9172. function getFuncName(aFunc) {
  9173. if (typeof aFunc !== 'function') {
  9174. return null;
  9175. }
  9176. var name = '';
  9177. if (typeof Function.prototype.name === 'undefined' && typeof aFunc.name === 'undefined') {
  9178. // Here we run a polyfill if Function does not support the `name` property and if aFunc.name is not defined
  9179. var match = toString.call(aFunc).match(functionNameMatch);
  9180. if (match) {
  9181. name = match[1];
  9182. }
  9183. } else {
  9184. // If we've got a `name` property we just use it
  9185. name = aFunc.name;
  9186. }
  9187. return name;
  9188. }
  9189. module.exports = getFuncName;
  9190. },{}],37:[function(require,module,exports){
  9191. 'use strict';
  9192. /* !
  9193. * Chai - pathval utility
  9194. * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
  9195. * @see https://github.com/logicalparadox/filtr
  9196. * MIT Licensed
  9197. */
  9198. /**
  9199. * ### .hasProperty(object, name)
  9200. *
  9201. * This allows checking whether an object has own
  9202. * or inherited from prototype chain named property.
  9203. *
  9204. * Basically does the same thing as the `in`
  9205. * operator but works properly with null/undefined values
  9206. * and other primitives.
  9207. *
  9208. * var obj = {
  9209. * arr: ['a', 'b', 'c']
  9210. * , str: 'Hello'
  9211. * }
  9212. *
  9213. * The following would be the results.
  9214. *
  9215. * hasProperty(obj, 'str'); // true
  9216. * hasProperty(obj, 'constructor'); // true
  9217. * hasProperty(obj, 'bar'); // false
  9218. *
  9219. * hasProperty(obj.str, 'length'); // true
  9220. * hasProperty(obj.str, 1); // true
  9221. * hasProperty(obj.str, 5); // false
  9222. *
  9223. * hasProperty(obj.arr, 'length'); // true
  9224. * hasProperty(obj.arr, 2); // true
  9225. * hasProperty(obj.arr, 3); // false
  9226. *
  9227. * @param {Object} object
  9228. * @param {String|Symbol} name
  9229. * @returns {Boolean} whether it exists
  9230. * @namespace Utils
  9231. * @name hasProperty
  9232. * @api public
  9233. */
  9234. function hasProperty(obj, name) {
  9235. if (typeof obj === 'undefined' || obj === null) {
  9236. return false;
  9237. }
  9238. // The `in` operator does not work with primitives.
  9239. return name in Object(obj);
  9240. }
  9241. /* !
  9242. * ## parsePath(path)
  9243. *
  9244. * Helper function used to parse string object
  9245. * paths. Use in conjunction with `internalGetPathValue`.
  9246. *
  9247. * var parsed = parsePath('myobject.property.subprop');
  9248. *
  9249. * ### Paths:
  9250. *
  9251. * * Can be infinitely deep and nested.
  9252. * * Arrays are also valid using the formal `myobject.document[3].property`.
  9253. * * Literal dots and brackets (not delimiter) must be backslash-escaped.
  9254. *
  9255. * @param {String} path
  9256. * @returns {Object} parsed
  9257. * @api private
  9258. */
  9259. function parsePath(path) {
  9260. var str = path.replace(/([^\\])\[/g, '$1.[');
  9261. var parts = str.match(/(\\\.|[^.]+?)+/g);
  9262. return parts.map(function mapMatches(value) {
  9263. var regexp = /^\[(\d+)\]$/;
  9264. var mArr = regexp.exec(value);
  9265. var parsed = null;
  9266. if (mArr) {
  9267. parsed = { i: parseFloat(mArr[1]) };
  9268. } else {
  9269. parsed = { p: value.replace(/\\([.\[\]])/g, '$1') };
  9270. }
  9271. return parsed;
  9272. });
  9273. }
  9274. /* !
  9275. * ## internalGetPathValue(obj, parsed[, pathDepth])
  9276. *
  9277. * Helper companion function for `.parsePath` that returns
  9278. * the value located at the parsed address.
  9279. *
  9280. * var value = getPathValue(obj, parsed);
  9281. *
  9282. * @param {Object} object to search against
  9283. * @param {Object} parsed definition from `parsePath`.
  9284. * @param {Number} depth (nesting level) of the property we want to retrieve
  9285. * @returns {Object|Undefined} value
  9286. * @api private
  9287. */
  9288. function internalGetPathValue(obj, parsed, pathDepth) {
  9289. var temporaryValue = obj;
  9290. var res = null;
  9291. pathDepth = (typeof pathDepth === 'undefined' ? parsed.length : pathDepth);
  9292. for (var i = 0; i < pathDepth; i++) {
  9293. var part = parsed[i];
  9294. if (temporaryValue) {
  9295. if (typeof part.p === 'undefined') {
  9296. temporaryValue = temporaryValue[part.i];
  9297. } else {
  9298. temporaryValue = temporaryValue[part.p];
  9299. }
  9300. if (i === (pathDepth - 1)) {
  9301. res = temporaryValue;
  9302. }
  9303. }
  9304. }
  9305. return res;
  9306. }
  9307. /* !
  9308. * ## internalSetPathValue(obj, value, parsed)
  9309. *
  9310. * Companion function for `parsePath` that sets
  9311. * the value located at a parsed address.
  9312. *
  9313. * internalSetPathValue(obj, 'value', parsed);
  9314. *
  9315. * @param {Object} object to search and define on
  9316. * @param {*} value to use upon set
  9317. * @param {Object} parsed definition from `parsePath`
  9318. * @api private
  9319. */
  9320. function internalSetPathValue(obj, val, parsed) {
  9321. var tempObj = obj;
  9322. var pathDepth = parsed.length;
  9323. var part = null;
  9324. // Here we iterate through every part of the path
  9325. for (var i = 0; i < pathDepth; i++) {
  9326. var propName = null;
  9327. var propVal = null;
  9328. part = parsed[i];
  9329. // If it's the last part of the path, we set the 'propName' value with the property name
  9330. if (i === (pathDepth - 1)) {
  9331. propName = typeof part.p === 'undefined' ? part.i : part.p;
  9332. // Now we set the property with the name held by 'propName' on object with the desired val
  9333. tempObj[propName] = val;
  9334. } else if (typeof part.p !== 'undefined' && tempObj[part.p]) {
  9335. tempObj = tempObj[part.p];
  9336. } else if (typeof part.i !== 'undefined' && tempObj[part.i]) {
  9337. tempObj = tempObj[part.i];
  9338. } else {
  9339. // If the obj doesn't have the property we create one with that name to define it
  9340. var next = parsed[i + 1];
  9341. // Here we set the name of the property which will be defined
  9342. propName = typeof part.p === 'undefined' ? part.i : part.p;
  9343. // Here we decide if this property will be an array or a new object
  9344. propVal = typeof next.p === 'undefined' ? [] : {};
  9345. tempObj[propName] = propVal;
  9346. tempObj = tempObj[propName];
  9347. }
  9348. }
  9349. }
  9350. /**
  9351. * ### .getPathInfo(object, path)
  9352. *
  9353. * This allows the retrieval of property info in an
  9354. * object given a string path.
  9355. *
  9356. * The path info consists of an object with the
  9357. * following properties:
  9358. *
  9359. * * parent - The parent object of the property referenced by `path`
  9360. * * name - The name of the final property, a number if it was an array indexer
  9361. * * value - The value of the property, if it exists, otherwise `undefined`
  9362. * * exists - Whether the property exists or not
  9363. *
  9364. * @param {Object} object
  9365. * @param {String} path
  9366. * @returns {Object} info
  9367. * @namespace Utils
  9368. * @name getPathInfo
  9369. * @api public
  9370. */
  9371. function getPathInfo(obj, path) {
  9372. var parsed = parsePath(path);
  9373. var last = parsed[parsed.length - 1];
  9374. var info = {
  9375. parent: parsed.length > 1 ? internalGetPathValue(obj, parsed, parsed.length - 1) : obj,
  9376. name: last.p || last.i,
  9377. value: internalGetPathValue(obj, parsed),
  9378. };
  9379. info.exists = hasProperty(info.parent, info.name);
  9380. return info;
  9381. }
  9382. /**
  9383. * ### .getPathValue(object, path)
  9384. *
  9385. * This allows the retrieval of values in an
  9386. * object given a string path.
  9387. *
  9388. * var obj = {
  9389. * prop1: {
  9390. * arr: ['a', 'b', 'c']
  9391. * , str: 'Hello'
  9392. * }
  9393. * , prop2: {
  9394. * arr: [ { nested: 'Universe' } ]
  9395. * , str: 'Hello again!'
  9396. * }
  9397. * }
  9398. *
  9399. * The following would be the results.
  9400. *
  9401. * getPathValue(obj, 'prop1.str'); // Hello
  9402. * getPathValue(obj, 'prop1.att[2]'); // b
  9403. * getPathValue(obj, 'prop2.arr[0].nested'); // Universe
  9404. *
  9405. * @param {Object} object
  9406. * @param {String} path
  9407. * @returns {Object} value or `undefined`
  9408. * @namespace Utils
  9409. * @name getPathValue
  9410. * @api public
  9411. */
  9412. function getPathValue(obj, path) {
  9413. var info = getPathInfo(obj, path);
  9414. return info.value;
  9415. }
  9416. /**
  9417. * ### .setPathValue(object, path, value)
  9418. *
  9419. * Define the value in an object at a given string path.
  9420. *
  9421. * ```js
  9422. * var obj = {
  9423. * prop1: {
  9424. * arr: ['a', 'b', 'c']
  9425. * , str: 'Hello'
  9426. * }
  9427. * , prop2: {
  9428. * arr: [ { nested: 'Universe' } ]
  9429. * , str: 'Hello again!'
  9430. * }
  9431. * };
  9432. * ```
  9433. *
  9434. * The following would be acceptable.
  9435. *
  9436. * ```js
  9437. * var properties = require('tea-properties');
  9438. * properties.set(obj, 'prop1.str', 'Hello Universe!');
  9439. * properties.set(obj, 'prop1.arr[2]', 'B');
  9440. * properties.set(obj, 'prop2.arr[0].nested.value', { hello: 'universe' });
  9441. * ```
  9442. *
  9443. * @param {Object} object
  9444. * @param {String} path
  9445. * @param {Mixed} value
  9446. * @api private
  9447. */
  9448. function setPathValue(obj, path, val) {
  9449. var parsed = parsePath(path);
  9450. internalSetPathValue(obj, val, parsed);
  9451. return obj;
  9452. }
  9453. module.exports = {
  9454. hasProperty: hasProperty,
  9455. getPathInfo: getPathInfo,
  9456. getPathValue: getPathValue,
  9457. setPathValue: setPathValue,
  9458. };
  9459. },{}],38:[function(require,module,exports){
  9460. (function (global, factory) {
  9461. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  9462. typeof define === 'function' && define.amd ? define(factory) :
  9463. (global.typeDetect = factory());
  9464. }(this, (function () { 'use strict';
  9465. /* !
  9466. * type-detect
  9467. * Copyright(c) 2013 jake luer <jake@alogicalparadox.com>
  9468. * MIT Licensed
  9469. */
  9470. var promiseExists = typeof Promise === 'function';
  9471. /* eslint-disable no-undef */
  9472. var globalObject = typeof self === 'object' ? self : global; // eslint-disable-line id-blacklist
  9473. var symbolExists = typeof Symbol !== 'undefined';
  9474. var mapExists = typeof Map !== 'undefined';
  9475. var setExists = typeof Set !== 'undefined';
  9476. var weakMapExists = typeof WeakMap !== 'undefined';
  9477. var weakSetExists = typeof WeakSet !== 'undefined';
  9478. var dataViewExists = typeof DataView !== 'undefined';
  9479. var symbolIteratorExists = symbolExists && typeof Symbol.iterator !== 'undefined';
  9480. var symbolToStringTagExists = symbolExists && typeof Symbol.toStringTag !== 'undefined';
  9481. var setEntriesExists = setExists && typeof Set.prototype.entries === 'function';
  9482. var mapEntriesExists = mapExists && typeof Map.prototype.entries === 'function';
  9483. var setIteratorPrototype = setEntriesExists && Object.getPrototypeOf(new Set().entries());
  9484. var mapIteratorPrototype = mapEntriesExists && Object.getPrototypeOf(new Map().entries());
  9485. var arrayIteratorExists = symbolIteratorExists && typeof Array.prototype[Symbol.iterator] === 'function';
  9486. var arrayIteratorPrototype = arrayIteratorExists && Object.getPrototypeOf([][Symbol.iterator]());
  9487. var stringIteratorExists = symbolIteratorExists && typeof String.prototype[Symbol.iterator] === 'function';
  9488. var stringIteratorPrototype = stringIteratorExists && Object.getPrototypeOf(''[Symbol.iterator]());
  9489. var toStringLeftSliceLength = 8;
  9490. var toStringRightSliceLength = -1;
  9491. /**
  9492. * ### typeOf (obj)
  9493. *
  9494. * Uses `Object.prototype.toString` to determine the type of an object,
  9495. * normalising behaviour across engine versions & well optimised.
  9496. *
  9497. * @param {Mixed} object
  9498. * @return {String} object type
  9499. * @api public
  9500. */
  9501. function typeDetect(obj) {
  9502. /* ! Speed optimisation
  9503. * Pre:
  9504. * string literal x 3,039,035 ops/sec ±1.62% (78 runs sampled)
  9505. * boolean literal x 1,424,138 ops/sec ±4.54% (75 runs sampled)
  9506. * number literal x 1,653,153 ops/sec ±1.91% (82 runs sampled)
  9507. * undefined x 9,978,660 ops/sec ±1.92% (75 runs sampled)
  9508. * function x 2,556,769 ops/sec ±1.73% (77 runs sampled)
  9509. * Post:
  9510. * string literal x 38,564,796 ops/sec ±1.15% (79 runs sampled)
  9511. * boolean literal x 31,148,940 ops/sec ±1.10% (79 runs sampled)
  9512. * number literal x 32,679,330 ops/sec ±1.90% (78 runs sampled)
  9513. * undefined x 32,363,368 ops/sec ±1.07% (82 runs sampled)
  9514. * function x 31,296,870 ops/sec ±0.96% (83 runs sampled)
  9515. */
  9516. var typeofObj = typeof obj;
  9517. if (typeofObj !== 'object') {
  9518. return typeofObj;
  9519. }
  9520. /* ! Speed optimisation
  9521. * Pre:
  9522. * null x 28,645,765 ops/sec ±1.17% (82 runs sampled)
  9523. * Post:
  9524. * null x 36,428,962 ops/sec ±1.37% (84 runs sampled)
  9525. */
  9526. if (obj === null) {
  9527. return 'null';
  9528. }
  9529. /* ! Spec Conformance
  9530. * Test: `Object.prototype.toString.call(window)``
  9531. * - Node === "[object global]"
  9532. * - Chrome === "[object global]"
  9533. * - Firefox === "[object Window]"
  9534. * - PhantomJS === "[object Window]"
  9535. * - Safari === "[object Window]"
  9536. * - IE 11 === "[object Window]"
  9537. * - IE Edge === "[object Window]"
  9538. * Test: `Object.prototype.toString.call(this)``
  9539. * - Chrome Worker === "[object global]"
  9540. * - Firefox Worker === "[object DedicatedWorkerGlobalScope]"
  9541. * - Safari Worker === "[object DedicatedWorkerGlobalScope]"
  9542. * - IE 11 Worker === "[object WorkerGlobalScope]"
  9543. * - IE Edge Worker === "[object WorkerGlobalScope]"
  9544. */
  9545. if (obj === globalObject) {
  9546. return 'global';
  9547. }
  9548. /* ! Speed optimisation
  9549. * Pre:
  9550. * array literal x 2,888,352 ops/sec ±0.67% (82 runs sampled)
  9551. * Post:
  9552. * array literal x 22,479,650 ops/sec ±0.96% (81 runs sampled)
  9553. */
  9554. if (
  9555. Array.isArray(obj) &&
  9556. (symbolToStringTagExists === false || !(Symbol.toStringTag in obj))
  9557. ) {
  9558. return 'Array';
  9559. }
  9560. // Not caching existence of `window` and related properties due to potential
  9561. // for `window` to be unset before tests in quasi-browser environments.
  9562. if (typeof window === 'object' && window !== null) {
  9563. /* ! Spec Conformance
  9564. * (https://html.spec.whatwg.org/multipage/browsers.html#location)
  9565. * WhatWG HTML$7.7.3 - The `Location` interface
  9566. * Test: `Object.prototype.toString.call(window.location)``
  9567. * - IE <=11 === "[object Object]"
  9568. * - IE Edge <=13 === "[object Object]"
  9569. */
  9570. if (typeof window.location === 'object' && obj === window.location) {
  9571. return 'Location';
  9572. }
  9573. /* ! Spec Conformance
  9574. * (https://html.spec.whatwg.org/#document)
  9575. * WhatWG HTML$3.1.1 - The `Document` object
  9576. * Note: Most browsers currently adher to the W3C DOM Level 2 spec
  9577. * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-26809268)
  9578. * which suggests that browsers should use HTMLTableCellElement for
  9579. * both TD and TH elements. WhatWG separates these.
  9580. * WhatWG HTML states:
  9581. * > For historical reasons, Window objects must also have a
  9582. * > writable, configurable, non-enumerable property named
  9583. * > HTMLDocument whose value is the Document interface object.
  9584. * Test: `Object.prototype.toString.call(document)``
  9585. * - Chrome === "[object HTMLDocument]"
  9586. * - Firefox === "[object HTMLDocument]"
  9587. * - Safari === "[object HTMLDocument]"
  9588. * - IE <=10 === "[object Document]"
  9589. * - IE 11 === "[object HTMLDocument]"
  9590. * - IE Edge <=13 === "[object HTMLDocument]"
  9591. */
  9592. if (typeof window.document === 'object' && obj === window.document) {
  9593. return 'Document';
  9594. }
  9595. if (typeof window.navigator === 'object') {
  9596. /* ! Spec Conformance
  9597. * (https://html.spec.whatwg.org/multipage/webappapis.html#mimetypearray)
  9598. * WhatWG HTML$8.6.1.5 - Plugins - Interface MimeTypeArray
  9599. * Test: `Object.prototype.toString.call(navigator.mimeTypes)``
  9600. * - IE <=10 === "[object MSMimeTypesCollection]"
  9601. */
  9602. if (typeof window.navigator.mimeTypes === 'object' &&
  9603. obj === window.navigator.mimeTypes) {
  9604. return 'MimeTypeArray';
  9605. }
  9606. /* ! Spec Conformance
  9607. * (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray)
  9608. * WhatWG HTML$8.6.1.5 - Plugins - Interface PluginArray
  9609. * Test: `Object.prototype.toString.call(navigator.plugins)``
  9610. * - IE <=10 === "[object MSPluginsCollection]"
  9611. */
  9612. if (typeof window.navigator.plugins === 'object' &&
  9613. obj === window.navigator.plugins) {
  9614. return 'PluginArray';
  9615. }
  9616. }
  9617. if ((typeof window.HTMLElement === 'function' ||
  9618. typeof window.HTMLElement === 'object') &&
  9619. obj instanceof window.HTMLElement) {
  9620. /* ! Spec Conformance
  9621. * (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray)
  9622. * WhatWG HTML$4.4.4 - The `blockquote` element - Interface `HTMLQuoteElement`
  9623. * Test: `Object.prototype.toString.call(document.createElement('blockquote'))``
  9624. * - IE <=10 === "[object HTMLBlockElement]"
  9625. */
  9626. if (obj.tagName === 'BLOCKQUOTE') {
  9627. return 'HTMLQuoteElement';
  9628. }
  9629. /* ! Spec Conformance
  9630. * (https://html.spec.whatwg.org/#htmltabledatacellelement)
  9631. * WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableDataCellElement`
  9632. * Note: Most browsers currently adher to the W3C DOM Level 2 spec
  9633. * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075)
  9634. * which suggests that browsers should use HTMLTableCellElement for
  9635. * both TD and TH elements. WhatWG separates these.
  9636. * Test: Object.prototype.toString.call(document.createElement('td'))
  9637. * - Chrome === "[object HTMLTableCellElement]"
  9638. * - Firefox === "[object HTMLTableCellElement]"
  9639. * - Safari === "[object HTMLTableCellElement]"
  9640. */
  9641. if (obj.tagName === 'TD') {
  9642. return 'HTMLTableDataCellElement';
  9643. }
  9644. /* ! Spec Conformance
  9645. * (https://html.spec.whatwg.org/#htmltableheadercellelement)
  9646. * WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableHeaderCellElement`
  9647. * Note: Most browsers currently adher to the W3C DOM Level 2 spec
  9648. * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075)
  9649. * which suggests that browsers should use HTMLTableCellElement for
  9650. * both TD and TH elements. WhatWG separates these.
  9651. * Test: Object.prototype.toString.call(document.createElement('th'))
  9652. * - Chrome === "[object HTMLTableCellElement]"
  9653. * - Firefox === "[object HTMLTableCellElement]"
  9654. * - Safari === "[object HTMLTableCellElement]"
  9655. */
  9656. if (obj.tagName === 'TH') {
  9657. return 'HTMLTableHeaderCellElement';
  9658. }
  9659. }
  9660. }
  9661. /* ! Speed optimisation
  9662. * Pre:
  9663. * Float64Array x 625,644 ops/sec ±1.58% (80 runs sampled)
  9664. * Float32Array x 1,279,852 ops/sec ±2.91% (77 runs sampled)
  9665. * Uint32Array x 1,178,185 ops/sec ±1.95% (83 runs sampled)
  9666. * Uint16Array x 1,008,380 ops/sec ±2.25% (80 runs sampled)
  9667. * Uint8Array x 1,128,040 ops/sec ±2.11% (81 runs sampled)
  9668. * Int32Array x 1,170,119 ops/sec ±2.88% (80 runs sampled)
  9669. * Int16Array x 1,176,348 ops/sec ±5.79% (86 runs sampled)
  9670. * Int8Array x 1,058,707 ops/sec ±4.94% (77 runs sampled)
  9671. * Uint8ClampedArray x 1,110,633 ops/sec ±4.20% (80 runs sampled)
  9672. * Post:
  9673. * Float64Array x 7,105,671 ops/sec ±13.47% (64 runs sampled)
  9674. * Float32Array x 5,887,912 ops/sec ±1.46% (82 runs sampled)
  9675. * Uint32Array x 6,491,661 ops/sec ±1.76% (79 runs sampled)
  9676. * Uint16Array x 6,559,795 ops/sec ±1.67% (82 runs sampled)
  9677. * Uint8Array x 6,463,966 ops/sec ±1.43% (85 runs sampled)
  9678. * Int32Array x 5,641,841 ops/sec ±3.49% (81 runs sampled)
  9679. * Int16Array x 6,583,511 ops/sec ±1.98% (80 runs sampled)
  9680. * Int8Array x 6,606,078 ops/sec ±1.74% (81 runs sampled)
  9681. * Uint8ClampedArray x 6,602,224 ops/sec ±1.77% (83 runs sampled)
  9682. */
  9683. var stringTag = (symbolToStringTagExists && obj[Symbol.toStringTag]);
  9684. if (typeof stringTag === 'string') {
  9685. return stringTag;
  9686. }
  9687. var objPrototype = Object.getPrototypeOf(obj);
  9688. /* ! Speed optimisation
  9689. * Pre:
  9690. * regex literal x 1,772,385 ops/sec ±1.85% (77 runs sampled)
  9691. * regex constructor x 2,143,634 ops/sec ±2.46% (78 runs sampled)
  9692. * Post:
  9693. * regex literal x 3,928,009 ops/sec ±0.65% (78 runs sampled)
  9694. * regex constructor x 3,931,108 ops/sec ±0.58% (84 runs sampled)
  9695. */
  9696. if (objPrototype === RegExp.prototype) {
  9697. return 'RegExp';
  9698. }
  9699. /* ! Speed optimisation
  9700. * Pre:
  9701. * date x 2,130,074 ops/sec ±4.42% (68 runs sampled)
  9702. * Post:
  9703. * date x 3,953,779 ops/sec ±1.35% (77 runs sampled)
  9704. */
  9705. if (objPrototype === Date.prototype) {
  9706. return 'Date';
  9707. }
  9708. /* ! Spec Conformance
  9709. * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-promise.prototype-@@tostringtag)
  9710. * ES6$25.4.5.4 - Promise.prototype[@@toStringTag] should be "Promise":
  9711. * Test: `Object.prototype.toString.call(Promise.resolve())``
  9712. * - Chrome <=47 === "[object Object]"
  9713. * - Edge <=20 === "[object Object]"
  9714. * - Firefox 29-Latest === "[object Promise]"
  9715. * - Safari 7.1-Latest === "[object Promise]"
  9716. */
  9717. if (promiseExists && objPrototype === Promise.prototype) {
  9718. return 'Promise';
  9719. }
  9720. /* ! Speed optimisation
  9721. * Pre:
  9722. * set x 2,222,186 ops/sec ±1.31% (82 runs sampled)
  9723. * Post:
  9724. * set x 4,545,879 ops/sec ±1.13% (83 runs sampled)
  9725. */
  9726. if (setExists && objPrototype === Set.prototype) {
  9727. return 'Set';
  9728. }
  9729. /* ! Speed optimisation
  9730. * Pre:
  9731. * map x 2,396,842 ops/sec ±1.59% (81 runs sampled)
  9732. * Post:
  9733. * map x 4,183,945 ops/sec ±6.59% (82 runs sampled)
  9734. */
  9735. if (mapExists && objPrototype === Map.prototype) {
  9736. return 'Map';
  9737. }
  9738. /* ! Speed optimisation
  9739. * Pre:
  9740. * weakset x 1,323,220 ops/sec ±2.17% (76 runs sampled)
  9741. * Post:
  9742. * weakset x 4,237,510 ops/sec ±2.01% (77 runs sampled)
  9743. */
  9744. if (weakSetExists && objPrototype === WeakSet.prototype) {
  9745. return 'WeakSet';
  9746. }
  9747. /* ! Speed optimisation
  9748. * Pre:
  9749. * weakmap x 1,500,260 ops/sec ±2.02% (78 runs sampled)
  9750. * Post:
  9751. * weakmap x 3,881,384 ops/sec ±1.45% (82 runs sampled)
  9752. */
  9753. if (weakMapExists && objPrototype === WeakMap.prototype) {
  9754. return 'WeakMap';
  9755. }
  9756. /* ! Spec Conformance
  9757. * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-dataview.prototype-@@tostringtag)
  9758. * ES6$24.2.4.21 - DataView.prototype[@@toStringTag] should be "DataView":
  9759. * Test: `Object.prototype.toString.call(new DataView(new ArrayBuffer(1)))``
  9760. * - Edge <=13 === "[object Object]"
  9761. */
  9762. if (dataViewExists && objPrototype === DataView.prototype) {
  9763. return 'DataView';
  9764. }
  9765. /* ! Spec Conformance
  9766. * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%mapiteratorprototype%-@@tostringtag)
  9767. * ES6$23.1.5.2.2 - %MapIteratorPrototype%[@@toStringTag] should be "Map Iterator":
  9768. * Test: `Object.prototype.toString.call(new Map().entries())``
  9769. * - Edge <=13 === "[object Object]"
  9770. */
  9771. if (mapExists && objPrototype === mapIteratorPrototype) {
  9772. return 'Map Iterator';
  9773. }
  9774. /* ! Spec Conformance
  9775. * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%setiteratorprototype%-@@tostringtag)
  9776. * ES6$23.2.5.2.2 - %SetIteratorPrototype%[@@toStringTag] should be "Set Iterator":
  9777. * Test: `Object.prototype.toString.call(new Set().entries())``
  9778. * - Edge <=13 === "[object Object]"
  9779. */
  9780. if (setExists && objPrototype === setIteratorPrototype) {
  9781. return 'Set Iterator';
  9782. }
  9783. /* ! Spec Conformance
  9784. * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%arrayiteratorprototype%-@@tostringtag)
  9785. * ES6$22.1.5.2.2 - %ArrayIteratorPrototype%[@@toStringTag] should be "Array Iterator":
  9786. * Test: `Object.prototype.toString.call([][Symbol.iterator]())``
  9787. * - Edge <=13 === "[object Object]"
  9788. */
  9789. if (arrayIteratorExists && objPrototype === arrayIteratorPrototype) {
  9790. return 'Array Iterator';
  9791. }
  9792. /* ! Spec Conformance
  9793. * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%stringiteratorprototype%-@@tostringtag)
  9794. * ES6$21.1.5.2.2 - %StringIteratorPrototype%[@@toStringTag] should be "String Iterator":
  9795. * Test: `Object.prototype.toString.call(''[Symbol.iterator]())``
  9796. * - Edge <=13 === "[object Object]"
  9797. */
  9798. if (stringIteratorExists && objPrototype === stringIteratorPrototype) {
  9799. return 'String Iterator';
  9800. }
  9801. /* ! Speed optimisation
  9802. * Pre:
  9803. * object from null x 2,424,320 ops/sec ±1.67% (76 runs sampled)
  9804. * Post:
  9805. * object from null x 5,838,000 ops/sec ±0.99% (84 runs sampled)
  9806. */
  9807. if (objPrototype === null) {
  9808. return 'Object';
  9809. }
  9810. return Object
  9811. .prototype
  9812. .toString
  9813. .call(obj)
  9814. .slice(toStringLeftSliceLength, toStringRightSliceLength);
  9815. }
  9816. return typeDetect;
  9817. })));
  9818. },{}]},{},[1])(1)
  9819. });