mocha.js 120 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812
  1. ;(function(){
  2. // CommonJS require()
  3. function require(p){
  4. var path = require.resolve(p)
  5. , mod = require.modules[path];
  6. if (!mod) throw new Error('failed to require "' + p + '"');
  7. if (!mod.exports) {
  8. mod.exports = {};
  9. mod.call(mod.exports, mod, mod.exports, require.relative(path));
  10. }
  11. return mod.exports;
  12. }
  13. require.modules = {};
  14. require.resolve = function (path){
  15. var orig = path
  16. , reg = path + '.js'
  17. , index = path + '/index.js';
  18. return require.modules[reg] && reg
  19. || require.modules[index] && index
  20. || orig;
  21. };
  22. require.register = function (path, fn){
  23. require.modules[path] = fn;
  24. };
  25. require.relative = function (parent) {
  26. return function(p){
  27. if ('.' != p.charAt(0)) return require(p);
  28. var path = parent.split('/')
  29. , segs = p.split('/');
  30. path.pop();
  31. for (var i = 0; i < segs.length; i++) {
  32. var seg = segs[i];
  33. if ('..' == seg) path.pop();
  34. else if ('.' != seg) path.push(seg);
  35. }
  36. return require(path.join('/'));
  37. };
  38. };
  39. require.register("browser/debug.js", function(module, exports, require){
  40. module.exports = function(type){
  41. return function(){
  42. }
  43. };
  44. }); // module: browser/debug.js
  45. require.register("browser/diff.js", function(module, exports, require){
  46. /* See LICENSE file for terms of use */
  47. /*
  48. * Text diff implementation.
  49. *
  50. * This library supports the following APIS:
  51. * JsDiff.diffChars: Character by character diff
  52. * JsDiff.diffWords: Word (as defined by \b regex) diff which ignores whitespace
  53. * JsDiff.diffLines: Line based diff
  54. *
  55. * JsDiff.diffCss: Diff targeted at CSS content
  56. *
  57. * These methods are based on the implementation proposed in
  58. * "An O(ND) Difference Algorithm and its Variations" (Myers, 1986).
  59. * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927
  60. */
  61. var JsDiff = (function() {
  62. /*jshint maxparams: 5*/
  63. function clonePath(path) {
  64. return { newPos: path.newPos, components: path.components.slice(0) };
  65. }
  66. function removeEmpty(array) {
  67. var ret = [];
  68. for (var i = 0; i < array.length; i++) {
  69. if (array[i]) {
  70. ret.push(array[i]);
  71. }
  72. }
  73. return ret;
  74. }
  75. function escapeHTML(s) {
  76. var n = s;
  77. n = n.replace(/&/g, '&amp;');
  78. n = n.replace(/</g, '&lt;');
  79. n = n.replace(/>/g, '&gt;');
  80. n = n.replace(/"/g, '&quot;');
  81. return n;
  82. }
  83. var Diff = function(ignoreWhitespace) {
  84. this.ignoreWhitespace = ignoreWhitespace;
  85. };
  86. Diff.prototype = {
  87. diff: function(oldString, newString) {
  88. // Handle the identity case (this is due to unrolling editLength == 0
  89. if (newString === oldString) {
  90. return [{ value: newString }];
  91. }
  92. if (!newString) {
  93. return [{ value: oldString, removed: true }];
  94. }
  95. if (!oldString) {
  96. return [{ value: newString, added: true }];
  97. }
  98. newString = this.tokenize(newString);
  99. oldString = this.tokenize(oldString);
  100. var newLen = newString.length, oldLen = oldString.length;
  101. var maxEditLength = newLen + oldLen;
  102. var bestPath = [{ newPos: -1, components: [] }];
  103. // Seed editLength = 0
  104. var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0);
  105. if (bestPath[0].newPos+1 >= newLen && oldPos+1 >= oldLen) {
  106. return bestPath[0].components;
  107. }
  108. for (var editLength = 1; editLength <= maxEditLength; editLength++) {
  109. for (var diagonalPath = -1*editLength; diagonalPath <= editLength; diagonalPath+=2) {
  110. var basePath;
  111. var addPath = bestPath[diagonalPath-1],
  112. removePath = bestPath[diagonalPath+1];
  113. oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;
  114. if (addPath) {
  115. // No one else is going to attempt to use this value, clear it
  116. bestPath[diagonalPath-1] = undefined;
  117. }
  118. var canAdd = addPath && addPath.newPos+1 < newLen;
  119. var canRemove = removePath && 0 <= oldPos && oldPos < oldLen;
  120. if (!canAdd && !canRemove) {
  121. bestPath[diagonalPath] = undefined;
  122. continue;
  123. }
  124. // Select the diagonal that we want to branch from. We select the prior
  125. // path whose position in the new string is the farthest from the origin
  126. // and does not pass the bounds of the diff graph
  127. if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) {
  128. basePath = clonePath(removePath);
  129. this.pushComponent(basePath.components, oldString[oldPos], undefined, true);
  130. } else {
  131. basePath = clonePath(addPath);
  132. basePath.newPos++;
  133. this.pushComponent(basePath.components, newString[basePath.newPos], true, undefined);
  134. }
  135. var oldPos = this.extractCommon(basePath, newString, oldString, diagonalPath);
  136. if (basePath.newPos+1 >= newLen && oldPos+1 >= oldLen) {
  137. return basePath.components;
  138. } else {
  139. bestPath[diagonalPath] = basePath;
  140. }
  141. }
  142. }
  143. },
  144. pushComponent: function(components, value, added, removed) {
  145. var last = components[components.length-1];
  146. if (last && last.added === added && last.removed === removed) {
  147. // We need to clone here as the component clone operation is just
  148. // as shallow array clone
  149. components[components.length-1] =
  150. {value: this.join(last.value, value), added: added, removed: removed };
  151. } else {
  152. components.push({value: value, added: added, removed: removed });
  153. }
  154. },
  155. extractCommon: function(basePath, newString, oldString, diagonalPath) {
  156. var newLen = newString.length,
  157. oldLen = oldString.length,
  158. newPos = basePath.newPos,
  159. oldPos = newPos - diagonalPath;
  160. while (newPos+1 < newLen && oldPos+1 < oldLen && this.equals(newString[newPos+1], oldString[oldPos+1])) {
  161. newPos++;
  162. oldPos++;
  163. this.pushComponent(basePath.components, newString[newPos], undefined, undefined);
  164. }
  165. basePath.newPos = newPos;
  166. return oldPos;
  167. },
  168. equals: function(left, right) {
  169. var reWhitespace = /\S/;
  170. if (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right)) {
  171. return true;
  172. } else {
  173. return left === right;
  174. }
  175. },
  176. join: function(left, right) {
  177. return left + right;
  178. },
  179. tokenize: function(value) {
  180. return value;
  181. }
  182. };
  183. var CharDiff = new Diff();
  184. var WordDiff = new Diff(true);
  185. var WordWithSpaceDiff = new Diff();
  186. WordDiff.tokenize = WordWithSpaceDiff.tokenize = function(value) {
  187. return removeEmpty(value.split(/(\s+|\b)/));
  188. };
  189. var CssDiff = new Diff(true);
  190. CssDiff.tokenize = function(value) {
  191. return removeEmpty(value.split(/([{}:;,]|\s+)/));
  192. };
  193. var LineDiff = new Diff();
  194. LineDiff.tokenize = function(value) {
  195. return value.split(/^/m);
  196. };
  197. return {
  198. Diff: Diff,
  199. diffChars: function(oldStr, newStr) { return CharDiff.diff(oldStr, newStr); },
  200. diffWords: function(oldStr, newStr) { return WordDiff.diff(oldStr, newStr); },
  201. diffWordsWithSpace: function(oldStr, newStr) { return WordWithSpaceDiff.diff(oldStr, newStr); },
  202. diffLines: function(oldStr, newStr) { return LineDiff.diff(oldStr, newStr); },
  203. diffCss: function(oldStr, newStr) { return CssDiff.diff(oldStr, newStr); },
  204. createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) {
  205. var ret = [];
  206. ret.push('Index: ' + fileName);
  207. ret.push('===================================================================');
  208. ret.push('--- ' + fileName + (typeof oldHeader === 'undefined' ? '' : '\t' + oldHeader));
  209. ret.push('+++ ' + fileName + (typeof newHeader === 'undefined' ? '' : '\t' + newHeader));
  210. var diff = LineDiff.diff(oldStr, newStr);
  211. if (!diff[diff.length-1].value) {
  212. diff.pop(); // Remove trailing newline add
  213. }
  214. diff.push({value: '', lines: []}); // Append an empty value to make cleanup easier
  215. function contextLines(lines) {
  216. return lines.map(function(entry) { return ' ' + entry; });
  217. }
  218. function eofNL(curRange, i, current) {
  219. var last = diff[diff.length-2],
  220. isLast = i === diff.length-2,
  221. isLastOfType = i === diff.length-3 && (current.added !== last.added || current.removed !== last.removed);
  222. // Figure out if this is the last line for the given file and missing NL
  223. if (!/\n$/.test(current.value) && (isLast || isLastOfType)) {
  224. curRange.push('\\ No newline at end of file');
  225. }
  226. }
  227. var oldRangeStart = 0, newRangeStart = 0, curRange = [],
  228. oldLine = 1, newLine = 1;
  229. for (var i = 0; i < diff.length; i++) {
  230. var current = diff[i],
  231. lines = current.lines || current.value.replace(/\n$/, '').split('\n');
  232. current.lines = lines;
  233. if (current.added || current.removed) {
  234. if (!oldRangeStart) {
  235. var prev = diff[i-1];
  236. oldRangeStart = oldLine;
  237. newRangeStart = newLine;
  238. if (prev) {
  239. curRange = contextLines(prev.lines.slice(-4));
  240. oldRangeStart -= curRange.length;
  241. newRangeStart -= curRange.length;
  242. }
  243. }
  244. curRange.push.apply(curRange, lines.map(function(entry) { return (current.added?'+':'-') + entry; }));
  245. eofNL(curRange, i, current);
  246. if (current.added) {
  247. newLine += lines.length;
  248. } else {
  249. oldLine += lines.length;
  250. }
  251. } else {
  252. if (oldRangeStart) {
  253. // Close out any changes that have been output (or join overlapping)
  254. if (lines.length <= 8 && i < diff.length-2) {
  255. // Overlapping
  256. curRange.push.apply(curRange, contextLines(lines));
  257. } else {
  258. // end the range and output
  259. var contextSize = Math.min(lines.length, 4);
  260. ret.push(
  261. '@@ -' + oldRangeStart + ',' + (oldLine-oldRangeStart+contextSize)
  262. + ' +' + newRangeStart + ',' + (newLine-newRangeStart+contextSize)
  263. + ' @@');
  264. ret.push.apply(ret, curRange);
  265. ret.push.apply(ret, contextLines(lines.slice(0, contextSize)));
  266. if (lines.length <= 4) {
  267. eofNL(ret, i, current);
  268. }
  269. oldRangeStart = 0; newRangeStart = 0; curRange = [];
  270. }
  271. }
  272. oldLine += lines.length;
  273. newLine += lines.length;
  274. }
  275. }
  276. return ret.join('\n') + '\n';
  277. },
  278. applyPatch: function(oldStr, uniDiff) {
  279. var diffstr = uniDiff.split('\n');
  280. var diff = [];
  281. var remEOFNL = false,
  282. addEOFNL = false;
  283. for (var i = (diffstr[0][0]==='I'?4:0); i < diffstr.length; i++) {
  284. if(diffstr[i][0] === '@') {
  285. var meh = diffstr[i].split(/@@ -(\d+),(\d+) \+(\d+),(\d+) @@/);
  286. diff.unshift({
  287. start:meh[3],
  288. oldlength:meh[2],
  289. oldlines:[],
  290. newlength:meh[4],
  291. newlines:[]
  292. });
  293. } else if(diffstr[i][0] === '+') {
  294. diff[0].newlines.push(diffstr[i].substr(1));
  295. } else if(diffstr[i][0] === '-') {
  296. diff[0].oldlines.push(diffstr[i].substr(1));
  297. } else if(diffstr[i][0] === ' ') {
  298. diff[0].newlines.push(diffstr[i].substr(1));
  299. diff[0].oldlines.push(diffstr[i].substr(1));
  300. } else if(diffstr[i][0] === '\\') {
  301. if (diffstr[i-1][0] === '+') {
  302. remEOFNL = true;
  303. } else if(diffstr[i-1][0] === '-') {
  304. addEOFNL = true;
  305. }
  306. }
  307. }
  308. var str = oldStr.split('\n');
  309. for (var i = diff.length - 1; i >= 0; i--) {
  310. var d = diff[i];
  311. for (var j = 0; j < d.oldlength; j++) {
  312. if(str[d.start-1+j] !== d.oldlines[j]) {
  313. return false;
  314. }
  315. }
  316. Array.prototype.splice.apply(str,[d.start-1,+d.oldlength].concat(d.newlines));
  317. }
  318. if (remEOFNL) {
  319. while (!str[str.length-1]) {
  320. str.pop();
  321. }
  322. } else if (addEOFNL) {
  323. str.push('');
  324. }
  325. return str.join('\n');
  326. },
  327. convertChangesToXML: function(changes){
  328. var ret = [];
  329. for ( var i = 0; i < changes.length; i++) {
  330. var change = changes[i];
  331. if (change.added) {
  332. ret.push('<ins>');
  333. } else if (change.removed) {
  334. ret.push('<del>');
  335. }
  336. ret.push(escapeHTML(change.value));
  337. if (change.added) {
  338. ret.push('</ins>');
  339. } else if (change.removed) {
  340. ret.push('</del>');
  341. }
  342. }
  343. return ret.join('');
  344. },
  345. // See: http://code.google.com/p/google-diff-match-patch/wiki/API
  346. convertChangesToDMP: function(changes){
  347. var ret = [], change;
  348. for ( var i = 0; i < changes.length; i++) {
  349. change = changes[i];
  350. ret.push([(change.added ? 1 : change.removed ? -1 : 0), change.value]);
  351. }
  352. return ret;
  353. }
  354. };
  355. })();
  356. if (typeof module !== 'undefined') {
  357. module.exports = JsDiff;
  358. }
  359. }); // module: browser/diff.js
  360. require.register("browser/events.js", function(module, exports, require){
  361. /**
  362. * Module exports.
  363. */
  364. exports.EventEmitter = EventEmitter;
  365. /**
  366. * Check if `obj` is an array.
  367. */
  368. function isArray(obj) {
  369. return '[object Array]' == {}.toString.call(obj);
  370. }
  371. /**
  372. * Event emitter constructor.
  373. *
  374. * @api public
  375. */
  376. function EventEmitter(){};
  377. /**
  378. * Adds a listener.
  379. *
  380. * @api public
  381. */
  382. EventEmitter.prototype.on = function (name, fn) {
  383. if (!this.$events) {
  384. this.$events = {};
  385. }
  386. if (!this.$events[name]) {
  387. this.$events[name] = fn;
  388. } else if (isArray(this.$events[name])) {
  389. this.$events[name].push(fn);
  390. } else {
  391. this.$events[name] = [this.$events[name], fn];
  392. }
  393. return this;
  394. };
  395. EventEmitter.prototype.addListener = EventEmitter.prototype.on;
  396. /**
  397. * Adds a volatile listener.
  398. *
  399. * @api public
  400. */
  401. EventEmitter.prototype.once = function (name, fn) {
  402. var self = this;
  403. function on () {
  404. self.removeListener(name, on);
  405. fn.apply(this, arguments);
  406. };
  407. on.listener = fn;
  408. this.on(name, on);
  409. return this;
  410. };
  411. /**
  412. * Removes a listener.
  413. *
  414. * @api public
  415. */
  416. EventEmitter.prototype.removeListener = function (name, fn) {
  417. if (this.$events && this.$events[name]) {
  418. var list = this.$events[name];
  419. if (isArray(list)) {
  420. var pos = -1;
  421. for (var i = 0, l = list.length; i < l; i++) {
  422. if (list[i] === fn || (list[i].listener && list[i].listener === fn)) {
  423. pos = i;
  424. break;
  425. }
  426. }
  427. if (pos < 0) {
  428. return this;
  429. }
  430. list.splice(pos, 1);
  431. if (!list.length) {
  432. delete this.$events[name];
  433. }
  434. } else if (list === fn || (list.listener && list.listener === fn)) {
  435. delete this.$events[name];
  436. }
  437. }
  438. return this;
  439. };
  440. /**
  441. * Removes all listeners for an event.
  442. *
  443. * @api public
  444. */
  445. EventEmitter.prototype.removeAllListeners = function (name) {
  446. if (name === undefined) {
  447. this.$events = {};
  448. return this;
  449. }
  450. if (this.$events && this.$events[name]) {
  451. this.$events[name] = null;
  452. }
  453. return this;
  454. };
  455. /**
  456. * Gets all listeners for a certain event.
  457. *
  458. * @api public
  459. */
  460. EventEmitter.prototype.listeners = function (name) {
  461. if (!this.$events) {
  462. this.$events = {};
  463. }
  464. if (!this.$events[name]) {
  465. this.$events[name] = [];
  466. }
  467. if (!isArray(this.$events[name])) {
  468. this.$events[name] = [this.$events[name]];
  469. }
  470. return this.$events[name];
  471. };
  472. /**
  473. * Emits an event.
  474. *
  475. * @api public
  476. */
  477. EventEmitter.prototype.emit = function (name) {
  478. if (!this.$events) {
  479. return false;
  480. }
  481. var handler = this.$events[name];
  482. if (!handler) {
  483. return false;
  484. }
  485. var args = [].slice.call(arguments, 1);
  486. if ('function' == typeof handler) {
  487. handler.apply(this, args);
  488. } else if (isArray(handler)) {
  489. var listeners = handler.slice();
  490. for (var i = 0, l = listeners.length; i < l; i++) {
  491. listeners[i].apply(this, args);
  492. }
  493. } else {
  494. return false;
  495. }
  496. return true;
  497. };
  498. }); // module: browser/events.js
  499. require.register("browser/fs.js", function(module, exports, require){
  500. }); // module: browser/fs.js
  501. require.register("browser/path.js", function(module, exports, require){
  502. }); // module: browser/path.js
  503. require.register("browser/progress.js", function(module, exports, require){
  504. /**
  505. * Expose `Progress`.
  506. */
  507. module.exports = Progress;
  508. /**
  509. * Initialize a new `Progress` indicator.
  510. */
  511. function Progress() {
  512. this.percent = 0;
  513. this.size(0);
  514. this.fontSize(11);
  515. this.font('helvetica, arial, sans-serif');
  516. }
  517. /**
  518. * Set progress size to `n`.
  519. *
  520. * @param {Number} n
  521. * @return {Progress} for chaining
  522. * @api public
  523. */
  524. Progress.prototype.size = function(n){
  525. this._size = n;
  526. return this;
  527. };
  528. /**
  529. * Set text to `str`.
  530. *
  531. * @param {String} str
  532. * @return {Progress} for chaining
  533. * @api public
  534. */
  535. Progress.prototype.text = function(str){
  536. this._text = str;
  537. return this;
  538. };
  539. /**
  540. * Set font size to `n`.
  541. *
  542. * @param {Number} n
  543. * @return {Progress} for chaining
  544. * @api public
  545. */
  546. Progress.prototype.fontSize = function(n){
  547. this._fontSize = n;
  548. return this;
  549. };
  550. /**
  551. * Set font `family`.
  552. *
  553. * @param {String} family
  554. * @return {Progress} for chaining
  555. */
  556. Progress.prototype.font = function(family){
  557. this._font = family;
  558. return this;
  559. };
  560. /**
  561. * Update percentage to `n`.
  562. *
  563. * @param {Number} n
  564. * @return {Progress} for chaining
  565. */
  566. Progress.prototype.update = function(n){
  567. this.percent = n;
  568. return this;
  569. };
  570. /**
  571. * Draw on `ctx`.
  572. *
  573. * @param {CanvasRenderingContext2d} ctx
  574. * @return {Progress} for chaining
  575. */
  576. Progress.prototype.draw = function(ctx){
  577. try {
  578. var percent = Math.min(this.percent, 100)
  579. , size = this._size
  580. , half = size / 2
  581. , x = half
  582. , y = half
  583. , rad = half - 1
  584. , fontSize = this._fontSize;
  585. ctx.font = fontSize + 'px ' + this._font;
  586. var angle = Math.PI * 2 * (percent / 100);
  587. ctx.clearRect(0, 0, size, size);
  588. // outer circle
  589. ctx.strokeStyle = '#9f9f9f';
  590. ctx.beginPath();
  591. ctx.arc(x, y, rad, 0, angle, false);
  592. ctx.stroke();
  593. // inner circle
  594. ctx.strokeStyle = '#eee';
  595. ctx.beginPath();
  596. ctx.arc(x, y, rad - 1, 0, angle, true);
  597. ctx.stroke();
  598. // text
  599. var text = this._text || (percent | 0) + '%'
  600. , w = ctx.measureText(text).width;
  601. ctx.fillText(
  602. text
  603. , x - w / 2 + 1
  604. , y + fontSize / 2 - 1);
  605. } catch (ex) {} //don't fail if we can't render progress
  606. return this;
  607. };
  608. }); // module: browser/progress.js
  609. require.register("browser/tty.js", function(module, exports, require){
  610. exports.isatty = function(){
  611. return true;
  612. };
  613. exports.getWindowSize = function(){
  614. if ('innerHeight' in global) {
  615. return [global.innerHeight, global.innerWidth];
  616. } else {
  617. // In a Web Worker, the DOM Window is not available.
  618. return [640, 480];
  619. }
  620. };
  621. }); // module: browser/tty.js
  622. require.register("context.js", function(module, exports, require){
  623. /**
  624. * Expose `Context`.
  625. */
  626. module.exports = Context;
  627. /**
  628. * Initialize a new `Context`.
  629. *
  630. * @api private
  631. */
  632. function Context(){}
  633. /**
  634. * Set or get the context `Runnable` to `runnable`.
  635. *
  636. * @param {Runnable} runnable
  637. * @return {Context}
  638. * @api private
  639. */
  640. Context.prototype.runnable = function(runnable){
  641. if (0 == arguments.length) return this._runnable;
  642. this.test = this._runnable = runnable;
  643. return this;
  644. };
  645. /**
  646. * Set test timeout `ms`.
  647. *
  648. * @param {Number} ms
  649. * @return {Context} self
  650. * @api private
  651. */
  652. Context.prototype.timeout = function(ms){
  653. this.runnable().timeout(ms);
  654. return this;
  655. };
  656. /**
  657. * Set test slowness threshold `ms`.
  658. *
  659. * @param {Number} ms
  660. * @return {Context} self
  661. * @api private
  662. */
  663. Context.prototype.slow = function(ms){
  664. this.runnable().slow(ms);
  665. return this;
  666. };
  667. /**
  668. * Inspect the context void of `._runnable`.
  669. *
  670. * @return {String}
  671. * @api private
  672. */
  673. Context.prototype.inspect = function(){
  674. return JSON.stringify(this, function(key, val){
  675. if ('_runnable' == key) return;
  676. if ('test' == key) return;
  677. return val;
  678. }, 2);
  679. };
  680. }); // module: context.js
  681. require.register("hook.js", function(module, exports, require){
  682. /**
  683. * Module dependencies.
  684. */
  685. var Runnable = require('./runnable');
  686. /**
  687. * Expose `Hook`.
  688. */
  689. module.exports = Hook;
  690. /**
  691. * Initialize a new `Hook` with the given `title` and callback `fn`.
  692. *
  693. * @param {String} title
  694. * @param {Function} fn
  695. * @api private
  696. */
  697. function Hook(title, fn) {
  698. Runnable.call(this, title, fn);
  699. this.type = 'hook';
  700. }
  701. /**
  702. * Inherit from `Runnable.prototype`.
  703. */
  704. function F(){};
  705. F.prototype = Runnable.prototype;
  706. Hook.prototype = new F;
  707. Hook.prototype.constructor = Hook;
  708. /**
  709. * Get or set the test `err`.
  710. *
  711. * @param {Error} err
  712. * @return {Error}
  713. * @api public
  714. */
  715. Hook.prototype.error = function(err){
  716. if (0 == arguments.length) {
  717. var err = this._error;
  718. this._error = null;
  719. return err;
  720. }
  721. this._error = err;
  722. };
  723. }); // module: hook.js
  724. require.register("interfaces/bdd.js", function(module, exports, require){
  725. /**
  726. * Module dependencies.
  727. */
  728. var Suite = require('../suite')
  729. , Test = require('../test')
  730. , utils = require('../utils');
  731. /**
  732. * BDD-style interface:
  733. *
  734. * describe('Array', function(){
  735. * describe('#indexOf()', function(){
  736. * it('should return -1 when not present', function(){
  737. *
  738. * });
  739. *
  740. * it('should return the index when present', function(){
  741. *
  742. * });
  743. * });
  744. * });
  745. *
  746. */
  747. module.exports = function(suite){
  748. var suites = [suite];
  749. suite.on('pre-require', function(context, file, mocha){
  750. /**
  751. * Execute before running tests.
  752. */
  753. context.before = function(fn){
  754. suites[0].beforeAll(fn);
  755. };
  756. /**
  757. * Execute after running tests.
  758. */
  759. context.after = function(fn){
  760. suites[0].afterAll(fn);
  761. };
  762. /**
  763. * Execute before each test case.
  764. */
  765. context.beforeEach = function(fn){
  766. suites[0].beforeEach(fn);
  767. };
  768. /**
  769. * Execute after each test case.
  770. */
  771. context.afterEach = function(fn){
  772. suites[0].afterEach(fn);
  773. };
  774. /**
  775. * Describe a "suite" with the given `title`
  776. * and callback `fn` containing nested suites
  777. * and/or tests.
  778. */
  779. context.describe = context.context = function(title, fn){
  780. var suite = Suite.create(suites[0], title);
  781. suites.unshift(suite);
  782. fn.call(suite);
  783. suites.shift();
  784. return suite;
  785. };
  786. /**
  787. * Pending describe.
  788. */
  789. context.xdescribe =
  790. context.xcontext =
  791. context.describe.skip = function(title, fn){
  792. var suite = Suite.create(suites[0], title);
  793. suite.pending = true;
  794. suites.unshift(suite);
  795. fn.call(suite);
  796. suites.shift();
  797. };
  798. /**
  799. * Exclusive suite.
  800. */
  801. context.describe.only = function(title, fn){
  802. var suite = context.describe(title, fn);
  803. mocha.grep(suite.fullTitle());
  804. return suite;
  805. };
  806. /**
  807. * Describe a specification or test-case
  808. * with the given `title` and callback `fn`
  809. * acting as a thunk.
  810. */
  811. context.it = context.specify = function(title, fn){
  812. var suite = suites[0];
  813. if (suite.pending) var fn = null;
  814. var test = new Test(title, fn);
  815. suite.addTest(test);
  816. return test;
  817. };
  818. /**
  819. * Exclusive test-case.
  820. */
  821. context.it.only = function(title, fn){
  822. var test = context.it(title, fn);
  823. var reString = '^' + utils.escapeRegexp(test.fullTitle()) + '$';
  824. mocha.grep(new RegExp(reString));
  825. return test;
  826. };
  827. /**
  828. * Pending test case.
  829. */
  830. context.xit =
  831. context.xspecify =
  832. context.it.skip = function(title){
  833. context.it(title);
  834. };
  835. });
  836. };
  837. }); // module: interfaces/bdd.js
  838. require.register("interfaces/exports.js", function(module, exports, require){
  839. /**
  840. * Module dependencies.
  841. */
  842. var Suite = require('../suite')
  843. , Test = require('../test');
  844. /**
  845. * TDD-style interface:
  846. *
  847. * exports.Array = {
  848. * '#indexOf()': {
  849. * 'should return -1 when the value is not present': function(){
  850. *
  851. * },
  852. *
  853. * 'should return the correct index when the value is present': function(){
  854. *
  855. * }
  856. * }
  857. * };
  858. *
  859. */
  860. module.exports = function(suite){
  861. var suites = [suite];
  862. suite.on('require', visit);
  863. function visit(obj) {
  864. var suite;
  865. for (var key in obj) {
  866. if ('function' == typeof obj[key]) {
  867. var fn = obj[key];
  868. switch (key) {
  869. case 'before':
  870. suites[0].beforeAll(fn);
  871. break;
  872. case 'after':
  873. suites[0].afterAll(fn);
  874. break;
  875. case 'beforeEach':
  876. suites[0].beforeEach(fn);
  877. break;
  878. case 'afterEach':
  879. suites[0].afterEach(fn);
  880. break;
  881. default:
  882. suites[0].addTest(new Test(key, fn));
  883. }
  884. } else {
  885. var suite = Suite.create(suites[0], key);
  886. suites.unshift(suite);
  887. visit(obj[key]);
  888. suites.shift();
  889. }
  890. }
  891. }
  892. };
  893. }); // module: interfaces/exports.js
  894. require.register("interfaces/index.js", function(module, exports, require){
  895. exports.bdd = require('./bdd');
  896. exports.tdd = require('./tdd');
  897. exports.qunit = require('./qunit');
  898. exports.exports = require('./exports');
  899. }); // module: interfaces/index.js
  900. require.register("interfaces/qunit.js", function(module, exports, require){
  901. /**
  902. * Module dependencies.
  903. */
  904. var Suite = require('../suite')
  905. , Test = require('../test')
  906. , utils = require('../utils');
  907. /**
  908. * QUnit-style interface:
  909. *
  910. * suite('Array');
  911. *
  912. * test('#length', function(){
  913. * var arr = [1,2,3];
  914. * ok(arr.length == 3);
  915. * });
  916. *
  917. * test('#indexOf()', function(){
  918. * var arr = [1,2,3];
  919. * ok(arr.indexOf(1) == 0);
  920. * ok(arr.indexOf(2) == 1);
  921. * ok(arr.indexOf(3) == 2);
  922. * });
  923. *
  924. * suite('String');
  925. *
  926. * test('#length', function(){
  927. * ok('foo'.length == 3);
  928. * });
  929. *
  930. */
  931. module.exports = function(suite){
  932. var suites = [suite];
  933. suite.on('pre-require', function(context, file, mocha){
  934. /**
  935. * Execute before running tests.
  936. */
  937. context.before = function(fn){
  938. suites[0].beforeAll(fn);
  939. };
  940. /**
  941. * Execute after running tests.
  942. */
  943. context.after = function(fn){
  944. suites[0].afterAll(fn);
  945. };
  946. /**
  947. * Execute before each test case.
  948. */
  949. context.beforeEach = function(fn){
  950. suites[0].beforeEach(fn);
  951. };
  952. /**
  953. * Execute after each test case.
  954. */
  955. context.afterEach = function(fn){
  956. suites[0].afterEach(fn);
  957. };
  958. /**
  959. * Describe a "suite" with the given `title`.
  960. */
  961. context.suite = function(title){
  962. if (suites.length > 1) suites.shift();
  963. var suite = Suite.create(suites[0], title);
  964. suites.unshift(suite);
  965. return suite;
  966. };
  967. /**
  968. * Exclusive test-case.
  969. */
  970. context.suite.only = function(title, fn){
  971. var suite = context.suite(title, fn);
  972. mocha.grep(suite.fullTitle());
  973. };
  974. /**
  975. * Describe a specification or test-case
  976. * with the given `title` and callback `fn`
  977. * acting as a thunk.
  978. */
  979. context.test = function(title, fn){
  980. var test = new Test(title, fn);
  981. suites[0].addTest(test);
  982. return test;
  983. };
  984. /**
  985. * Exclusive test-case.
  986. */
  987. context.test.only = function(title, fn){
  988. var test = context.test(title, fn);
  989. var reString = '^' + utils.escapeRegexp(test.fullTitle()) + '$';
  990. mocha.grep(new RegExp(reString));
  991. };
  992. /**
  993. * Pending test case.
  994. */
  995. context.test.skip = function(title){
  996. context.test(title);
  997. };
  998. });
  999. };
  1000. }); // module: interfaces/qunit.js
  1001. require.register("interfaces/tdd.js", function(module, exports, require){
  1002. /**
  1003. * Module dependencies.
  1004. */
  1005. var Suite = require('../suite')
  1006. , Test = require('../test')
  1007. , utils = require('../utils');;
  1008. /**
  1009. * TDD-style interface:
  1010. *
  1011. * suite('Array', function(){
  1012. * suite('#indexOf()', function(){
  1013. * suiteSetup(function(){
  1014. *
  1015. * });
  1016. *
  1017. * test('should return -1 when not present', function(){
  1018. *
  1019. * });
  1020. *
  1021. * test('should return the index when present', function(){
  1022. *
  1023. * });
  1024. *
  1025. * suiteTeardown(function(){
  1026. *
  1027. * });
  1028. * });
  1029. * });
  1030. *
  1031. */
  1032. module.exports = function(suite){
  1033. var suites = [suite];
  1034. suite.on('pre-require', function(context, file, mocha){
  1035. /**
  1036. * Execute before each test case.
  1037. */
  1038. context.setup = function(fn){
  1039. suites[0].beforeEach(fn);
  1040. };
  1041. /**
  1042. * Execute after each test case.
  1043. */
  1044. context.teardown = function(fn){
  1045. suites[0].afterEach(fn);
  1046. };
  1047. /**
  1048. * Execute before the suite.
  1049. */
  1050. context.suiteSetup = function(fn){
  1051. suites[0].beforeAll(fn);
  1052. };
  1053. /**
  1054. * Execute after the suite.
  1055. */
  1056. context.suiteTeardown = function(fn){
  1057. suites[0].afterAll(fn);
  1058. };
  1059. /**
  1060. * Describe a "suite" with the given `title`
  1061. * and callback `fn` containing nested suites
  1062. * and/or tests.
  1063. */
  1064. context.suite = function(title, fn){
  1065. var suite = Suite.create(suites[0], title);
  1066. suites.unshift(suite);
  1067. fn.call(suite);
  1068. suites.shift();
  1069. return suite;
  1070. };
  1071. /**
  1072. * Pending suite.
  1073. */
  1074. context.suite.skip = function(title, fn) {
  1075. var suite = Suite.create(suites[0], title);
  1076. suite.pending = true;
  1077. suites.unshift(suite);
  1078. fn.call(suite);
  1079. suites.shift();
  1080. };
  1081. /**
  1082. * Exclusive test-case.
  1083. */
  1084. context.suite.only = function(title, fn){
  1085. var suite = context.suite(title, fn);
  1086. mocha.grep(suite.fullTitle());
  1087. };
  1088. /**
  1089. * Describe a specification or test-case
  1090. * with the given `title` and callback `fn`
  1091. * acting as a thunk.
  1092. */
  1093. context.test = function(title, fn){
  1094. var suite = suites[0];
  1095. if (suite.pending) var fn = null;
  1096. var test = new Test(title, fn);
  1097. suite.addTest(test);
  1098. return test;
  1099. };
  1100. /**
  1101. * Exclusive test-case.
  1102. */
  1103. context.test.only = function(title, fn){
  1104. var test = context.test(title, fn);
  1105. var reString = '^' + utils.escapeRegexp(test.fullTitle()) + '$';
  1106. mocha.grep(new RegExp(reString));
  1107. };
  1108. /**
  1109. * Pending test case.
  1110. */
  1111. context.test.skip = function(title){
  1112. context.test(title);
  1113. };
  1114. });
  1115. };
  1116. }); // module: interfaces/tdd.js
  1117. require.register("mocha.js", function(module, exports, require){
  1118. /*!
  1119. * mocha
  1120. * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>
  1121. * MIT Licensed
  1122. */
  1123. /**
  1124. * Module dependencies.
  1125. */
  1126. var path = require('browser/path')
  1127. , utils = require('./utils');
  1128. /**
  1129. * Expose `Mocha`.
  1130. */
  1131. exports = module.exports = Mocha;
  1132. /**
  1133. * Expose internals.
  1134. */
  1135. exports.utils = utils;
  1136. exports.interfaces = require('./interfaces');
  1137. exports.reporters = require('./reporters');
  1138. exports.Runnable = require('./runnable');
  1139. exports.Context = require('./context');
  1140. exports.Runner = require('./runner');
  1141. exports.Suite = require('./suite');
  1142. exports.Hook = require('./hook');
  1143. exports.Test = require('./test');
  1144. /**
  1145. * Return image `name` path.
  1146. *
  1147. * @param {String} name
  1148. * @return {String}
  1149. * @api private
  1150. */
  1151. function image(name) {
  1152. return __dirname + '/../images/' + name + '.png';
  1153. }
  1154. /**
  1155. * Setup mocha with `options`.
  1156. *
  1157. * Options:
  1158. *
  1159. * - `ui` name "bdd", "tdd", "exports" etc
  1160. * - `reporter` reporter instance, defaults to `mocha.reporters.Dot`
  1161. * - `globals` array of accepted globals
  1162. * - `timeout` timeout in milliseconds
  1163. * - `bail` bail on the first test failure
  1164. * - `slow` milliseconds to wait before considering a test slow
  1165. * - `ignoreLeaks` ignore global leaks
  1166. * - `grep` string or regexp to filter tests with
  1167. *
  1168. * @param {Object} options
  1169. * @api public
  1170. */
  1171. function Mocha(options) {
  1172. options = options || {};
  1173. this.files = [];
  1174. this.options = options;
  1175. this.grep(options.grep);
  1176. this.suite = new exports.Suite('', new exports.Context);
  1177. this.ui(options.ui);
  1178. this.bail(options.bail);
  1179. this.reporter(options.reporter);
  1180. if (null != options.timeout) this.timeout(options.timeout);
  1181. this.useColors(options.useColors)
  1182. if (options.slow) this.slow(options.slow);
  1183. this.suite.on('pre-require', function (context) {
  1184. exports.afterEach = context.afterEach || context.teardown;
  1185. exports.after = context.after || context.suiteTeardown;
  1186. exports.beforeEach = context.beforeEach || context.setup;
  1187. exports.before = context.before || context.suiteSetup;
  1188. exports.describe = context.describe || context.suite;
  1189. exports.it = context.it || context.test;
  1190. exports.setup = context.setup || context.beforeEach;
  1191. exports.suiteSetup = context.suiteSetup || context.before;
  1192. exports.suiteTeardown = context.suiteTeardown || context.after;
  1193. exports.suite = context.suite || context.describe;
  1194. exports.teardown = context.teardown || context.afterEach;
  1195. exports.test = context.test || context.it;
  1196. });
  1197. }
  1198. /**
  1199. * Enable or disable bailing on the first failure.
  1200. *
  1201. * @param {Boolean} [bail]
  1202. * @api public
  1203. */
  1204. Mocha.prototype.bail = function(bail){
  1205. if (0 == arguments.length) bail = true;
  1206. this.suite.bail(bail);
  1207. return this;
  1208. };
  1209. /**
  1210. * Add test `file`.
  1211. *
  1212. * @param {String} file
  1213. * @api public
  1214. */
  1215. Mocha.prototype.addFile = function(file){
  1216. this.files.push(file);
  1217. return this;
  1218. };
  1219. /**
  1220. * Set reporter to `reporter`, defaults to "dot".
  1221. *
  1222. * @param {String|Function} reporter name or constructor
  1223. * @api public
  1224. */
  1225. Mocha.prototype.reporter = function(reporter){
  1226. if ('function' == typeof reporter) {
  1227. this._reporter = reporter;
  1228. } else {
  1229. reporter = reporter || 'dot';
  1230. var _reporter;
  1231. try { _reporter = require('./reporters/' + reporter); } catch (err) {};
  1232. if (!_reporter) try { _reporter = require(reporter); } catch (err) {};
  1233. if (!_reporter && reporter === 'teamcity')
  1234. console.warn('The Teamcity reporter was moved to a package named ' +
  1235. 'mocha-teamcity-reporter ' +
  1236. '(https://npmjs.org/package/mocha-teamcity-reporter).');
  1237. if (!_reporter) throw new Error('invalid reporter "' + reporter + '"');
  1238. this._reporter = _reporter;
  1239. }
  1240. return this;
  1241. };
  1242. /**
  1243. * Set test UI `name`, defaults to "bdd".
  1244. *
  1245. * @param {String} bdd
  1246. * @api public
  1247. */
  1248. Mocha.prototype.ui = function(name){
  1249. name = name || 'bdd';
  1250. this._ui = exports.interfaces[name];
  1251. if (!this._ui) try { this._ui = require(name); } catch (err) {};
  1252. if (!this._ui) throw new Error('invalid interface "' + name + '"');
  1253. this._ui = this._ui(this.suite);
  1254. return this;
  1255. };
  1256. /**
  1257. * Load registered files.
  1258. *
  1259. * @api private
  1260. */
  1261. Mocha.prototype.loadFiles = function(fn){
  1262. var self = this;
  1263. var suite = this.suite;
  1264. var pending = this.files.length;
  1265. this.files.forEach(function(file){
  1266. file = path.resolve(file);
  1267. suite.emit('pre-require', global, file, self);
  1268. suite.emit('require', require(file), file, self);
  1269. suite.emit('post-require', global, file, self);
  1270. --pending || (fn && fn());
  1271. });
  1272. };
  1273. /**
  1274. * Enable growl support.
  1275. *
  1276. * @api private
  1277. */
  1278. Mocha.prototype._growl = function(runner, reporter) {
  1279. var notify = require('growl');
  1280. runner.on('end', function(){
  1281. var stats = reporter.stats;
  1282. if (stats.failures) {
  1283. var msg = stats.failures + ' of ' + runner.total + ' tests failed';
  1284. notify(msg, { name: 'mocha', title: 'Failed', image: image('error') });
  1285. } else {
  1286. notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', {
  1287. name: 'mocha'
  1288. , title: 'Passed'
  1289. , image: image('ok')
  1290. });
  1291. }
  1292. });
  1293. };
  1294. /**
  1295. * Add regexp to grep, if `re` is a string it is escaped.
  1296. *
  1297. * @param {RegExp|String} re
  1298. * @return {Mocha}
  1299. * @api public
  1300. */
  1301. Mocha.prototype.grep = function(re){
  1302. this.options.grep = 'string' == typeof re
  1303. ? new RegExp(utils.escapeRegexp(re))
  1304. : re;
  1305. return this;
  1306. };
  1307. /**
  1308. * Invert `.grep()` matches.
  1309. *
  1310. * @return {Mocha}
  1311. * @api public
  1312. */
  1313. Mocha.prototype.invert = function(){
  1314. this.options.invert = true;
  1315. return this;
  1316. };
  1317. /**
  1318. * Ignore global leaks.
  1319. *
  1320. * @param {Boolean} ignore
  1321. * @return {Mocha}
  1322. * @api public
  1323. */
  1324. Mocha.prototype.ignoreLeaks = function(ignore){
  1325. this.options.ignoreLeaks = !!ignore;
  1326. return this;
  1327. };
  1328. /**
  1329. * Enable global leak checking.
  1330. *
  1331. * @return {Mocha}
  1332. * @api public
  1333. */
  1334. Mocha.prototype.checkLeaks = function(){
  1335. this.options.ignoreLeaks = false;
  1336. return this;
  1337. };
  1338. /**
  1339. * Enable growl support.
  1340. *
  1341. * @return {Mocha}
  1342. * @api public
  1343. */
  1344. Mocha.prototype.growl = function(){
  1345. this.options.growl = true;
  1346. return this;
  1347. };
  1348. /**
  1349. * Ignore `globals` array or string.
  1350. *
  1351. * @param {Array|String} globals
  1352. * @return {Mocha}
  1353. * @api public
  1354. */
  1355. Mocha.prototype.globals = function(globals){
  1356. this.options.globals = (this.options.globals || []).concat(globals);
  1357. return this;
  1358. };
  1359. /**
  1360. * Emit color output.
  1361. *
  1362. * @param {Boolean} colors
  1363. * @return {Mocha}
  1364. * @api public
  1365. */
  1366. Mocha.prototype.useColors = function(colors){
  1367. this.options.useColors = arguments.length && colors != undefined
  1368. ? colors
  1369. : true;
  1370. return this;
  1371. };
  1372. /**
  1373. * Use inline diffs rather than +/-.
  1374. *
  1375. * @param {Boolean} inlineDiffs
  1376. * @return {Mocha}
  1377. * @api public
  1378. */
  1379. Mocha.prototype.useInlineDiffs = function(inlineDiffs) {
  1380. this.options.useInlineDiffs = arguments.length && inlineDiffs != undefined
  1381. ? inlineDiffs
  1382. : false;
  1383. return this;
  1384. };
  1385. /**
  1386. * Set the timeout in milliseconds.
  1387. *
  1388. * @param {Number} timeout
  1389. * @return {Mocha}
  1390. * @api public
  1391. */
  1392. Mocha.prototype.timeout = function(timeout){
  1393. this.suite.timeout(timeout);
  1394. return this;
  1395. };
  1396. /**
  1397. * Set slowness threshold in milliseconds.
  1398. *
  1399. * @param {Number} slow
  1400. * @return {Mocha}
  1401. * @api public
  1402. */
  1403. Mocha.prototype.slow = function(slow){
  1404. this.suite.slow(slow);
  1405. return this;
  1406. };
  1407. /**
  1408. * Makes all tests async (accepting a callback)
  1409. *
  1410. * @return {Mocha}
  1411. * @api public
  1412. */
  1413. Mocha.prototype.asyncOnly = function(){
  1414. this.options.asyncOnly = true;
  1415. return this;
  1416. };
  1417. /**
  1418. * Run tests and invoke `fn()` when complete.
  1419. *
  1420. * @param {Function} fn
  1421. * @return {Runner}
  1422. * @api public
  1423. */
  1424. Mocha.prototype.run = function(fn){
  1425. if (this.files.length) this.loadFiles();
  1426. var suite = this.suite;
  1427. var options = this.options;
  1428. var runner = new exports.Runner(suite);
  1429. var reporter = new this._reporter(runner);
  1430. runner.ignoreLeaks = false !== options.ignoreLeaks;
  1431. runner.asyncOnly = options.asyncOnly;
  1432. if (options.grep) runner.grep(options.grep, options.invert);
  1433. if (options.globals) runner.globals(options.globals);
  1434. if (options.growl) this._growl(runner, reporter);
  1435. exports.reporters.Base.useColors = options.useColors;
  1436. exports.reporters.Base.inlineDiffs = options.useInlineDiffs;
  1437. return runner.run(fn);
  1438. };
  1439. }); // module: mocha.js
  1440. require.register("ms.js", function(module, exports, require){
  1441. /**
  1442. * Helpers.
  1443. */
  1444. var s = 1000;
  1445. var m = s * 60;
  1446. var h = m * 60;
  1447. var d = h * 24;
  1448. var y = d * 365.25;
  1449. /**
  1450. * Parse or format the given `val`.
  1451. *
  1452. * Options:
  1453. *
  1454. * - `long` verbose formatting [false]
  1455. *
  1456. * @param {String|Number} val
  1457. * @param {Object} options
  1458. * @return {String|Number}
  1459. * @api public
  1460. */
  1461. module.exports = function(val, options){
  1462. options = options || {};
  1463. if ('string' == typeof val) return parse(val);
  1464. return options.long ? longFormat(val) : shortFormat(val);
  1465. };
  1466. /**
  1467. * Parse the given `str` and return milliseconds.
  1468. *
  1469. * @param {String} str
  1470. * @return {Number}
  1471. * @api private
  1472. */
  1473. function parse(str) {
  1474. var match = /^((?:\d+)?\.?\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i.exec(str);
  1475. if (!match) return;
  1476. var n = parseFloat(match[1]);
  1477. var type = (match[2] || 'ms').toLowerCase();
  1478. switch (type) {
  1479. case 'years':
  1480. case 'year':
  1481. case 'y':
  1482. return n * y;
  1483. case 'days':
  1484. case 'day':
  1485. case 'd':
  1486. return n * d;
  1487. case 'hours':
  1488. case 'hour':
  1489. case 'h':
  1490. return n * h;
  1491. case 'minutes':
  1492. case 'minute':
  1493. case 'm':
  1494. return n * m;
  1495. case 'seconds':
  1496. case 'second':
  1497. case 's':
  1498. return n * s;
  1499. case 'ms':
  1500. return n;
  1501. }
  1502. }
  1503. /**
  1504. * Short format for `ms`.
  1505. *
  1506. * @param {Number} ms
  1507. * @return {String}
  1508. * @api private
  1509. */
  1510. function shortFormat(ms) {
  1511. if (ms >= d) return Math.round(ms / d) + 'd';
  1512. if (ms >= h) return Math.round(ms / h) + 'h';
  1513. if (ms >= m) return Math.round(ms / m) + 'm';
  1514. if (ms >= s) return Math.round(ms / s) + 's';
  1515. return ms + 'ms';
  1516. }
  1517. /**
  1518. * Long format for `ms`.
  1519. *
  1520. * @param {Number} ms
  1521. * @return {String}
  1522. * @api private
  1523. */
  1524. function longFormat(ms) {
  1525. return plural(ms, d, 'day')
  1526. || plural(ms, h, 'hour')
  1527. || plural(ms, m, 'minute')
  1528. || plural(ms, s, 'second')
  1529. || ms + ' ms';
  1530. }
  1531. /**
  1532. * Pluralization helper.
  1533. */
  1534. function plural(ms, n, name) {
  1535. if (ms < n) return;
  1536. if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name;
  1537. return Math.ceil(ms / n) + ' ' + name + 's';
  1538. }
  1539. }); // module: ms.js
  1540. require.register("reporters/base.js", function(module, exports, require){
  1541. /**
  1542. * Module dependencies.
  1543. */
  1544. var tty = require('browser/tty')
  1545. , diff = require('browser/diff')
  1546. , ms = require('../ms')
  1547. , utils = require('../utils');
  1548. /**
  1549. * Save timer references to avoid Sinon interfering (see GH-237).
  1550. */
  1551. var Date = global.Date
  1552. , setTimeout = global.setTimeout
  1553. , setInterval = global.setInterval
  1554. , clearTimeout = global.clearTimeout
  1555. , clearInterval = global.clearInterval;
  1556. /**
  1557. * Check if both stdio streams are associated with a tty.
  1558. */
  1559. var isatty = tty.isatty(1) && tty.isatty(2);
  1560. /**
  1561. * Expose `Base`.
  1562. */
  1563. exports = module.exports = Base;
  1564. /**
  1565. * Enable coloring by default.
  1566. */
  1567. exports.useColors = isatty || (process.env.MOCHA_COLORS !== undefined);
  1568. /**
  1569. * Inline diffs instead of +/-
  1570. */
  1571. exports.inlineDiffs = false;
  1572. /**
  1573. * Default color map.
  1574. */
  1575. exports.colors = {
  1576. 'pass': 90
  1577. , 'fail': 31
  1578. , 'bright pass': 92
  1579. , 'bright fail': 91
  1580. , 'bright yellow': 93
  1581. , 'pending': 36
  1582. , 'suite': 0
  1583. , 'error title': 0
  1584. , 'error message': 31
  1585. , 'error stack': 90
  1586. , 'checkmark': 32
  1587. , 'fast': 90
  1588. , 'medium': 33
  1589. , 'slow': 31
  1590. , 'green': 32
  1591. , 'light': 90
  1592. , 'diff gutter': 90
  1593. , 'diff added': 42
  1594. , 'diff removed': 41
  1595. };
  1596. /**
  1597. * Default symbol map.
  1598. */
  1599. exports.symbols = {
  1600. ok: '✓',
  1601. err: '✖',
  1602. dot: '․'
  1603. };
  1604. // With node.js on Windows: use symbols available in terminal default fonts
  1605. if ('win32' == process.platform) {
  1606. exports.symbols.ok = '\u221A';
  1607. exports.symbols.err = '\u00D7';
  1608. exports.symbols.dot = '.';
  1609. }
  1610. /**
  1611. * Color `str` with the given `type`,
  1612. * allowing colors to be disabled,
  1613. * as well as user-defined color
  1614. * schemes.
  1615. *
  1616. * @param {String} type
  1617. * @param {String} str
  1618. * @return {String}
  1619. * @api private
  1620. */
  1621. var color = exports.color = function(type, str) {
  1622. if (!exports.useColors) return str;
  1623. return '\u001b[' + exports.colors[type] + 'm' + str + '\u001b[0m';
  1624. };
  1625. /**
  1626. * Expose term window size, with some
  1627. * defaults for when stderr is not a tty.
  1628. */
  1629. exports.window = {
  1630. width: isatty
  1631. ? process.stdout.getWindowSize
  1632. ? process.stdout.getWindowSize(1)[0]
  1633. : tty.getWindowSize()[1]
  1634. : 75
  1635. };
  1636. /**
  1637. * Expose some basic cursor interactions
  1638. * that are common among reporters.
  1639. */
  1640. exports.cursor = {
  1641. hide: function(){
  1642. isatty && process.stdout.write('\u001b[?25l');
  1643. },
  1644. show: function(){
  1645. isatty && process.stdout.write('\u001b[?25h');
  1646. },
  1647. deleteLine: function(){
  1648. isatty && process.stdout.write('\u001b[2K');
  1649. },
  1650. beginningOfLine: function(){
  1651. isatty && process.stdout.write('\u001b[0G');
  1652. },
  1653. CR: function(){
  1654. if (isatty) {
  1655. exports.cursor.deleteLine();
  1656. exports.cursor.beginningOfLine();
  1657. } else {
  1658. process.stdout.write('\r');
  1659. }
  1660. }
  1661. };
  1662. /**
  1663. * Outut the given `failures` as a list.
  1664. *
  1665. * @param {Array} failures
  1666. * @api public
  1667. */
  1668. exports.list = function(failures){
  1669. console.error();
  1670. failures.forEach(function(test, i){
  1671. // format
  1672. var fmt = color('error title', ' %s) %s:\n')
  1673. + color('error message', ' %s')
  1674. + color('error stack', '\n%s\n');
  1675. // msg
  1676. var err = test.err
  1677. , message = err.message || ''
  1678. , stack = err.stack || message
  1679. , index = stack.indexOf(message) + message.length
  1680. , msg = stack.slice(0, index)
  1681. , actual = err.actual
  1682. , expected = err.expected
  1683. , escape = true;
  1684. // uncaught
  1685. if (err.uncaught) {
  1686. msg = 'Uncaught ' + msg;
  1687. }
  1688. // explicitly show diff
  1689. if (err.showDiff && sameType(actual, expected)) {
  1690. escape = false;
  1691. err.actual = actual = stringify(canonicalize(actual));
  1692. err.expected = expected = stringify(canonicalize(expected));
  1693. }
  1694. // actual / expected diff
  1695. if ('string' == typeof actual && 'string' == typeof expected) {
  1696. fmt = color('error title', ' %s) %s:\n%s') + color('error stack', '\n%s\n');
  1697. var match = message.match(/^([^:]+): expected/);
  1698. msg = '\n ' + color('error message', match ? match[1] : msg);
  1699. if (exports.inlineDiffs) {
  1700. msg += inlineDiff(err, escape);
  1701. } else {
  1702. msg += unifiedDiff(err, escape);
  1703. }
  1704. }
  1705. // indent stack trace without msg
  1706. stack = stack.slice(index ? index + 1 : index)
  1707. .replace(/^/gm, ' ');
  1708. console.error(fmt, (i + 1), test.fullTitle(), msg, stack);
  1709. });
  1710. };
  1711. /**
  1712. * Initialize a new `Base` reporter.
  1713. *
  1714. * All other reporters generally
  1715. * inherit from this reporter, providing
  1716. * stats such as test duration, number
  1717. * of tests passed / failed etc.
  1718. *
  1719. * @param {Runner} runner
  1720. * @api public
  1721. */
  1722. function Base(runner) {
  1723. var self = this
  1724. , stats = this.stats = { suites: 0, tests: 0, passes: 0, pending: 0, failures: 0 }
  1725. , failures = this.failures = [];
  1726. if (!runner) return;
  1727. this.runner = runner;
  1728. runner.stats = stats;
  1729. runner.on('start', function(){
  1730. stats.start = new Date;
  1731. });
  1732. runner.on('suite', function(suite){
  1733. stats.suites = stats.suites || 0;
  1734. suite.root || stats.suites++;
  1735. });
  1736. runner.on('test end', function(test){
  1737. stats.tests = stats.tests || 0;
  1738. stats.tests++;
  1739. });
  1740. runner.on('pass', function(test){
  1741. stats.passes = stats.passes || 0;
  1742. var medium = test.slow() / 2;
  1743. test.speed = test.duration > test.slow()
  1744. ? 'slow'
  1745. : test.duration > medium
  1746. ? 'medium'
  1747. : 'fast';
  1748. stats.passes++;
  1749. });
  1750. runner.on('fail', function(test, err){
  1751. stats.failures = stats.failures || 0;
  1752. stats.failures++;
  1753. test.err = err;
  1754. failures.push(test);
  1755. });
  1756. runner.on('end', function(){
  1757. stats.end = new Date;
  1758. stats.duration = new Date - stats.start;
  1759. });
  1760. runner.on('pending', function(){
  1761. stats.pending++;
  1762. });
  1763. }
  1764. /**
  1765. * Output common epilogue used by many of
  1766. * the bundled reporters.
  1767. *
  1768. * @api public
  1769. */
  1770. Base.prototype.epilogue = function(){
  1771. var stats = this.stats;
  1772. var tests;
  1773. var fmt;
  1774. console.log();
  1775. // passes
  1776. fmt = color('bright pass', ' ')
  1777. + color('green', ' %d passing')
  1778. + color('light', ' (%s)');
  1779. console.log(fmt,
  1780. stats.passes || 0,
  1781. ms(stats.duration));
  1782. // pending
  1783. if (stats.pending) {
  1784. fmt = color('pending', ' ')
  1785. + color('pending', ' %d pending');
  1786. console.log(fmt, stats.pending);
  1787. }
  1788. // failures
  1789. if (stats.failures) {
  1790. fmt = color('fail', ' %d failing');
  1791. console.error(fmt,
  1792. stats.failures);
  1793. Base.list(this.failures);
  1794. console.error();
  1795. }
  1796. console.log();
  1797. };
  1798. /**
  1799. * Pad the given `str` to `len`.
  1800. *
  1801. * @param {String} str
  1802. * @param {String} len
  1803. * @return {String}
  1804. * @api private
  1805. */
  1806. function pad(str, len) {
  1807. str = String(str);
  1808. return Array(len - str.length + 1).join(' ') + str;
  1809. }
  1810. /**
  1811. * Returns an inline diff between 2 strings with coloured ANSI output
  1812. *
  1813. * @param {Error} Error with actual/expected
  1814. * @return {String} Diff
  1815. * @api private
  1816. */
  1817. function inlineDiff(err, escape) {
  1818. var msg = errorDiff(err, 'WordsWithSpace', escape);
  1819. // linenos
  1820. var lines = msg.split('\n');
  1821. if (lines.length > 4) {
  1822. var width = String(lines.length).length;
  1823. msg = lines.map(function(str, i){
  1824. return pad(++i, width) + ' |' + ' ' + str;
  1825. }).join('\n');
  1826. }
  1827. // legend
  1828. msg = '\n'
  1829. + color('diff removed', 'actual')
  1830. + ' '
  1831. + color('diff added', 'expected')
  1832. + '\n\n'
  1833. + msg
  1834. + '\n';
  1835. // indent
  1836. msg = msg.replace(/^/gm, ' ');
  1837. return msg;
  1838. }
  1839. /**
  1840. * Returns a unified diff between 2 strings
  1841. *
  1842. * @param {Error} Error with actual/expected
  1843. * @return {String} Diff
  1844. * @api private
  1845. */
  1846. function unifiedDiff(err, escape) {
  1847. var indent = ' ';
  1848. function cleanUp(line) {
  1849. if (escape) {
  1850. line = escapeInvisibles(line);
  1851. }
  1852. if (line[0] === '+') return indent + colorLines('diff added', line);
  1853. if (line[0] === '-') return indent + colorLines('diff removed', line);
  1854. if (line.match(/\@\@/)) return null;
  1855. if (line.match(/\\ No newline/)) return null;
  1856. else return indent + line;
  1857. }
  1858. function notBlank(line) {
  1859. return line != null;
  1860. }
  1861. msg = diff.createPatch('string', err.actual, err.expected);
  1862. var lines = msg.split('\n').splice(4);
  1863. return '\n '
  1864. + colorLines('diff added', '+ expected') + ' '
  1865. + colorLines('diff removed', '- actual')
  1866. + '\n\n'
  1867. + lines.map(cleanUp).filter(notBlank).join('\n');
  1868. }
  1869. /**
  1870. * Return a character diff for `err`.
  1871. *
  1872. * @param {Error} err
  1873. * @return {String}
  1874. * @api private
  1875. */
  1876. function errorDiff(err, type, escape) {
  1877. var actual = escape ? escapeInvisibles(err.actual) : err.actual;
  1878. var expected = escape ? escapeInvisibles(err.expected) : err.expected;
  1879. return diff['diff' + type](actual, expected).map(function(str){
  1880. if (str.added) return colorLines('diff added', str.value);
  1881. if (str.removed) return colorLines('diff removed', str.value);
  1882. return str.value;
  1883. }).join('');
  1884. }
  1885. /**
  1886. * Returns a string with all invisible characters in plain text
  1887. *
  1888. * @param {String} line
  1889. * @return {String}
  1890. * @api private
  1891. */
  1892. function escapeInvisibles(line) {
  1893. return line.replace(/\t/g, '<tab>')
  1894. .replace(/\r/g, '<CR>')
  1895. .replace(/\n/g, '<LF>\n');
  1896. }
  1897. /**
  1898. * Color lines for `str`, using the color `name`.
  1899. *
  1900. * @param {String} name
  1901. * @param {String} str
  1902. * @return {String}
  1903. * @api private
  1904. */
  1905. function colorLines(name, str) {
  1906. return str.split('\n').map(function(str){
  1907. return color(name, str);
  1908. }).join('\n');
  1909. }
  1910. /**
  1911. * Stringify `obj`.
  1912. *
  1913. * @param {Object} obj
  1914. * @return {String}
  1915. * @api private
  1916. */
  1917. function stringify(obj) {
  1918. if (obj instanceof RegExp) return obj.toString();
  1919. return JSON.stringify(obj, null, 2);
  1920. }
  1921. /**
  1922. * Return a new object that has the keys in sorted order.
  1923. * @param {Object} obj
  1924. * @return {Object}
  1925. * @api private
  1926. */
  1927. function canonicalize(obj, stack) {
  1928. stack = stack || [];
  1929. if (utils.indexOf(stack, obj) !== -1) return obj;
  1930. var canonicalizedObj;
  1931. if ('[object Array]' == {}.toString.call(obj)) {
  1932. stack.push(obj);
  1933. canonicalizedObj = utils.map(obj, function(item) {
  1934. return canonicalize(item, stack);
  1935. });
  1936. stack.pop();
  1937. } else if (typeof obj === 'object' && obj !== null) {
  1938. stack.push(obj);
  1939. canonicalizedObj = {};
  1940. utils.forEach(utils.keys(obj).sort(), function(key) {
  1941. canonicalizedObj[key] = canonicalize(obj[key], stack);
  1942. });
  1943. stack.pop();
  1944. } else {
  1945. canonicalizedObj = obj;
  1946. }
  1947. return canonicalizedObj;
  1948. }
  1949. /**
  1950. * Check that a / b have the same type.
  1951. *
  1952. * @param {Object} a
  1953. * @param {Object} b
  1954. * @return {Boolean}
  1955. * @api private
  1956. */
  1957. function sameType(a, b) {
  1958. a = Object.prototype.toString.call(a);
  1959. b = Object.prototype.toString.call(b);
  1960. return a == b;
  1961. }
  1962. }); // module: reporters/base.js
  1963. require.register("reporters/doc.js", function(module, exports, require){
  1964. /**
  1965. * Module dependencies.
  1966. */
  1967. var Base = require('./base')
  1968. , utils = require('../utils');
  1969. /**
  1970. * Expose `Doc`.
  1971. */
  1972. exports = module.exports = Doc;
  1973. /**
  1974. * Initialize a new `Doc` reporter.
  1975. *
  1976. * @param {Runner} runner
  1977. * @api public
  1978. */
  1979. function Doc(runner) {
  1980. Base.call(this, runner);
  1981. var self = this
  1982. , stats = this.stats
  1983. , total = runner.total
  1984. , indents = 2;
  1985. function indent() {
  1986. return Array(indents).join(' ');
  1987. }
  1988. runner.on('suite', function(suite){
  1989. if (suite.root) return;
  1990. ++indents;
  1991. console.log('%s<section class="suite">', indent());
  1992. ++indents;
  1993. console.log('%s<h1>%s</h1>', indent(), utils.escape(suite.title));
  1994. console.log('%s<dl>', indent());
  1995. });
  1996. runner.on('suite end', function(suite){
  1997. if (suite.root) return;
  1998. console.log('%s</dl>', indent());
  1999. --indents;
  2000. console.log('%s</section>', indent());
  2001. --indents;
  2002. });
  2003. runner.on('pass', function(test){
  2004. console.log('%s <dt>%s</dt>', indent(), utils.escape(test.title));
  2005. var code = utils.escape(utils.clean(test.fn.toString()));
  2006. console.log('%s <dd><pre><code>%s</code></pre></dd>', indent(), code);
  2007. });
  2008. }
  2009. }); // module: reporters/doc.js
  2010. require.register("reporters/dot.js", function(module, exports, require){
  2011. /**
  2012. * Module dependencies.
  2013. */
  2014. var Base = require('./base')
  2015. , color = Base.color;
  2016. /**
  2017. * Expose `Dot`.
  2018. */
  2019. exports = module.exports = Dot;
  2020. /**
  2021. * Initialize a new `Dot` matrix test reporter.
  2022. *
  2023. * @param {Runner} runner
  2024. * @api public
  2025. */
  2026. function Dot(runner) {
  2027. Base.call(this, runner);
  2028. var self = this
  2029. , stats = this.stats
  2030. , width = Base.window.width * .75 | 0
  2031. , n = 0;
  2032. runner.on('start', function(){
  2033. process.stdout.write('\n ');
  2034. });
  2035. runner.on('pending', function(test){
  2036. process.stdout.write(color('pending', Base.symbols.dot));
  2037. });
  2038. runner.on('pass', function(test){
  2039. if (++n % width == 0) process.stdout.write('\n ');
  2040. if ('slow' == test.speed) {
  2041. process.stdout.write(color('bright yellow', Base.symbols.dot));
  2042. } else {
  2043. process.stdout.write(color(test.speed, Base.symbols.dot));
  2044. }
  2045. });
  2046. runner.on('fail', function(test, err){
  2047. if (++n % width == 0) process.stdout.write('\n ');
  2048. process.stdout.write(color('fail', Base.symbols.dot));
  2049. });
  2050. runner.on('end', function(){
  2051. console.log();
  2052. self.epilogue();
  2053. });
  2054. }
  2055. /**
  2056. * Inherit from `Base.prototype`.
  2057. */
  2058. function F(){};
  2059. F.prototype = Base.prototype;
  2060. Dot.prototype = new F;
  2061. Dot.prototype.constructor = Dot;
  2062. }); // module: reporters/dot.js
  2063. require.register("reporters/html-cov.js", function(module, exports, require){
  2064. /**
  2065. * Module dependencies.
  2066. */
  2067. var JSONCov = require('./json-cov')
  2068. , fs = require('browser/fs');
  2069. /**
  2070. * Expose `HTMLCov`.
  2071. */
  2072. exports = module.exports = HTMLCov;
  2073. /**
  2074. * Initialize a new `JsCoverage` reporter.
  2075. *
  2076. * @param {Runner} runner
  2077. * @api public
  2078. */
  2079. function HTMLCov(runner) {
  2080. var jade = require('jade')
  2081. , file = __dirname + '/templates/coverage.jade'
  2082. , str = fs.readFileSync(file, 'utf8')
  2083. , fn = jade.compile(str, { filename: file })
  2084. , self = this;
  2085. JSONCov.call(this, runner, false);
  2086. runner.on('end', function(){
  2087. process.stdout.write(fn({
  2088. cov: self.cov
  2089. , coverageClass: coverageClass
  2090. }));
  2091. });
  2092. }
  2093. /**
  2094. * Return coverage class for `n`.
  2095. *
  2096. * @return {String}
  2097. * @api private
  2098. */
  2099. function coverageClass(n) {
  2100. if (n >= 75) return 'high';
  2101. if (n >= 50) return 'medium';
  2102. if (n >= 25) return 'low';
  2103. return 'terrible';
  2104. }
  2105. }); // module: reporters/html-cov.js
  2106. require.register("reporters/html.js", function(module, exports, require){
  2107. /**
  2108. * Module dependencies.
  2109. */
  2110. var Base = require('./base')
  2111. , utils = require('../utils')
  2112. , Progress = require('../browser/progress')
  2113. , escape = utils.escape;
  2114. /**
  2115. * Save timer references to avoid Sinon interfering (see GH-237).
  2116. */
  2117. var Date = global.Date
  2118. , setTimeout = global.setTimeout
  2119. , setInterval = global.setInterval
  2120. , clearTimeout = global.clearTimeout
  2121. , clearInterval = global.clearInterval;
  2122. /**
  2123. * Expose `HTML`.
  2124. */
  2125. exports = module.exports = HTML;
  2126. /**
  2127. * Stats template.
  2128. */
  2129. var statsTemplate = '<ul id="mocha-stats">'
  2130. + '<li class="progress"><canvas width="40" height="40"></canvas></li>'
  2131. + '<li class="passes"><a href="#">passes:</a> <em>0</em></li>'
  2132. + '<li class="failures"><a href="#">failures:</a> <em>0</em></li>'
  2133. + '<li class="duration">duration: <em>0</em>s</li>'
  2134. + '</ul>';
  2135. /**
  2136. * Initialize a new `HTML` reporter.
  2137. *
  2138. * @param {Runner} runner
  2139. * @api public
  2140. */
  2141. function HTML(runner, root) {
  2142. Base.call(this, runner);
  2143. var self = this
  2144. , stats = this.stats
  2145. , total = runner.total
  2146. , stat = fragment(statsTemplate)
  2147. , items = stat.getElementsByTagName('li')
  2148. , passes = items[1].getElementsByTagName('em')[0]
  2149. , passesLink = items[1].getElementsByTagName('a')[0]
  2150. , failures = items[2].getElementsByTagName('em')[0]
  2151. , failuresLink = items[2].getElementsByTagName('a')[0]
  2152. , duration = items[3].getElementsByTagName('em')[0]
  2153. , canvas = stat.getElementsByTagName('canvas')[0]
  2154. , report = fragment('<ul id="mocha-report"></ul>')
  2155. , stack = [report]
  2156. , progress
  2157. , ctx
  2158. root = root || document.getElementById('mocha');
  2159. if (canvas.getContext) {
  2160. var ratio = window.devicePixelRatio || 1;
  2161. canvas.style.width = canvas.width;
  2162. canvas.style.height = canvas.height;
  2163. canvas.width *= ratio;
  2164. canvas.height *= ratio;
  2165. ctx = canvas.getContext('2d');
  2166. ctx.scale(ratio, ratio);
  2167. progress = new Progress;
  2168. }
  2169. if (!root) return error('#mocha div missing, add it to your document');
  2170. // pass toggle
  2171. on(passesLink, 'click', function(){
  2172. unhide();
  2173. var name = /pass/.test(report.className) ? '' : ' pass';
  2174. report.className = report.className.replace(/fail|pass/g, '') + name;
  2175. if (report.className.trim()) hideSuitesWithout('test pass');
  2176. });
  2177. // failure toggle
  2178. on(failuresLink, 'click', function(){
  2179. unhide();
  2180. var name = /fail/.test(report.className) ? '' : ' fail';
  2181. report.className = report.className.replace(/fail|pass/g, '') + name;
  2182. if (report.className.trim()) hideSuitesWithout('test fail');
  2183. });
  2184. root.appendChild(stat);
  2185. root.appendChild(report);
  2186. if (progress) progress.size(40);
  2187. runner.on('suite', function(suite){
  2188. if (suite.root) return;
  2189. // suite
  2190. var url = self.suiteURL(suite);
  2191. var el = fragment('<li class="suite"><h1><a href="%s">%s</a></h1></li>', url, escape(suite.title));
  2192. // container
  2193. stack[0].appendChild(el);
  2194. stack.unshift(document.createElement('ul'));
  2195. el.appendChild(stack[0]);
  2196. });
  2197. runner.on('suite end', function(suite){
  2198. if (suite.root) return;
  2199. stack.shift();
  2200. });
  2201. runner.on('fail', function(test, err){
  2202. if ('hook' == test.type) runner.emit('test end', test);
  2203. });
  2204. runner.on('test end', function(test){
  2205. // TODO: add to stats
  2206. var percent = stats.tests / this.total * 100 | 0;
  2207. if (progress) progress.update(percent).draw(ctx);
  2208. // update stats
  2209. var ms = new Date - stats.start;
  2210. text(passes, stats.passes);
  2211. text(failures, stats.failures);
  2212. text(duration, (ms / 1000).toFixed(2));
  2213. // test
  2214. if ('passed' == test.state) {
  2215. var url = self.testURL(test);
  2216. var el = fragment('<li class="test pass %e"><h2>%e<span class="duration">%ems</span> <a href="%s" class="replay">‣</a></h2></li>', test.speed, test.title, test.duration, url);
  2217. } else if (test.pending) {
  2218. var el = fragment('<li class="test pass pending"><h2>%e</h2></li>', test.title);
  2219. } else {
  2220. var el = fragment('<li class="test fail"><h2>%e <a href="?grep=%e" class="replay">‣</a></h2></li>', test.title, encodeURIComponent(test.fullTitle()));
  2221. var str = test.err.stack || test.err.toString();
  2222. // FF / Opera do not add the message
  2223. if (!~str.indexOf(test.err.message)) {
  2224. str = test.err.message + '\n' + str;
  2225. }
  2226. // <=IE7 stringifies to [Object Error]. Since it can be overloaded, we
  2227. // check for the result of the stringifying.
  2228. if ('[object Error]' == str) str = test.err.message;
  2229. // Safari doesn't give you a stack. Let's at least provide a source line.
  2230. if (!test.err.stack && test.err.sourceURL && test.err.line !== undefined) {
  2231. str += "\n(" + test.err.sourceURL + ":" + test.err.line + ")";
  2232. }
  2233. el.appendChild(fragment('<pre class="error">%e</pre>', str));
  2234. }
  2235. // toggle code
  2236. // TODO: defer
  2237. if (!test.pending) {
  2238. var h2 = el.getElementsByTagName('h2')[0];
  2239. on(h2, 'click', function(){
  2240. pre.style.display = 'none' == pre.style.display
  2241. ? 'block'
  2242. : 'none';
  2243. });
  2244. var pre = fragment('<pre><code>%e</code></pre>', utils.clean(test.fn.toString()));
  2245. el.appendChild(pre);
  2246. pre.style.display = 'none';
  2247. }
  2248. // Don't call .appendChild if #mocha-report was already .shift()'ed off the stack.
  2249. if (stack[0]) stack[0].appendChild(el);
  2250. });
  2251. }
  2252. /**
  2253. * Provide suite URL
  2254. *
  2255. * @param {Object} [suite]
  2256. */
  2257. HTML.prototype.suiteURL = function(suite){
  2258. return '?grep=' + encodeURIComponent(suite.fullTitle());
  2259. };
  2260. /**
  2261. * Provide test URL
  2262. *
  2263. * @param {Object} [test]
  2264. */
  2265. HTML.prototype.testURL = function(test){
  2266. return '?grep=' + encodeURIComponent(test.fullTitle());
  2267. };
  2268. /**
  2269. * Display error `msg`.
  2270. */
  2271. function error(msg) {
  2272. document.body.appendChild(fragment('<div id="mocha-error">%s</div>', msg));
  2273. }
  2274. /**
  2275. * Return a DOM fragment from `html`.
  2276. */
  2277. function fragment(html) {
  2278. var args = arguments
  2279. , div = document.createElement('div')
  2280. , i = 1;
  2281. div.innerHTML = html.replace(/%([se])/g, function(_, type){
  2282. switch (type) {
  2283. case 's': return String(args[i++]);
  2284. case 'e': return escape(args[i++]);
  2285. }
  2286. });
  2287. return div.firstChild;
  2288. }
  2289. /**
  2290. * Check for suites that do not have elements
  2291. * with `classname`, and hide them.
  2292. */
  2293. function hideSuitesWithout(classname) {
  2294. var suites = document.getElementsByClassName('suite');
  2295. for (var i = 0; i < suites.length; i++) {
  2296. var els = suites[i].getElementsByClassName(classname);
  2297. if (0 == els.length) suites[i].className += ' hidden';
  2298. }
  2299. }
  2300. /**
  2301. * Unhide .hidden suites.
  2302. */
  2303. function unhide() {
  2304. var els = document.getElementsByClassName('suite hidden');
  2305. for (var i = 0; i < els.length; ++i) {
  2306. els[i].className = els[i].className.replace('suite hidden', 'suite');
  2307. }
  2308. }
  2309. /**
  2310. * Set `el` text to `str`.
  2311. */
  2312. function text(el, str) {
  2313. if (el.textContent) {
  2314. el.textContent = str;
  2315. } else {
  2316. el.innerText = str;
  2317. }
  2318. }
  2319. /**
  2320. * Listen on `event` with callback `fn`.
  2321. */
  2322. function on(el, event, fn) {
  2323. if (el.addEventListener) {
  2324. el.addEventListener(event, fn, false);
  2325. } else {
  2326. el.attachEvent('on' + event, fn);
  2327. }
  2328. }
  2329. }); // module: reporters/html.js
  2330. require.register("reporters/index.js", function(module, exports, require){
  2331. exports.Base = require('./base');
  2332. exports.Dot = require('./dot');
  2333. exports.Doc = require('./doc');
  2334. exports.TAP = require('./tap');
  2335. exports.JSON = require('./json');
  2336. exports.HTML = require('./html');
  2337. exports.List = require('./list');
  2338. exports.Min = require('./min');
  2339. exports.Spec = require('./spec');
  2340. exports.Nyan = require('./nyan');
  2341. exports.XUnit = require('./xunit');
  2342. exports.Markdown = require('./markdown');
  2343. exports.Progress = require('./progress');
  2344. exports.Landing = require('./landing');
  2345. exports.JSONCov = require('./json-cov');
  2346. exports.HTMLCov = require('./html-cov');
  2347. exports.JSONStream = require('./json-stream');
  2348. }); // module: reporters/index.js
  2349. require.register("reporters/json-cov.js", function(module, exports, require){
  2350. /**
  2351. * Module dependencies.
  2352. */
  2353. var Base = require('./base');
  2354. /**
  2355. * Expose `JSONCov`.
  2356. */
  2357. exports = module.exports = JSONCov;
  2358. /**
  2359. * Initialize a new `JsCoverage` reporter.
  2360. *
  2361. * @param {Runner} runner
  2362. * @param {Boolean} output
  2363. * @api public
  2364. */
  2365. function JSONCov(runner, output) {
  2366. var self = this
  2367. , output = 1 == arguments.length ? true : output;
  2368. Base.call(this, runner);
  2369. var tests = []
  2370. , failures = []
  2371. , passes = [];
  2372. runner.on('test end', function(test){
  2373. tests.push(test);
  2374. });
  2375. runner.on('pass', function(test){
  2376. passes.push(test);
  2377. });
  2378. runner.on('fail', function(test){
  2379. failures.push(test);
  2380. });
  2381. runner.on('end', function(){
  2382. var cov = global._$jscoverage || {};
  2383. var result = self.cov = map(cov);
  2384. result.stats = self.stats;
  2385. result.tests = tests.map(clean);
  2386. result.failures = failures.map(clean);
  2387. result.passes = passes.map(clean);
  2388. if (!output) return;
  2389. process.stdout.write(JSON.stringify(result, null, 2 ));
  2390. });
  2391. }
  2392. /**
  2393. * Map jscoverage data to a JSON structure
  2394. * suitable for reporting.
  2395. *
  2396. * @param {Object} cov
  2397. * @return {Object}
  2398. * @api private
  2399. */
  2400. function map(cov) {
  2401. var ret = {
  2402. instrumentation: 'node-jscoverage'
  2403. , sloc: 0
  2404. , hits: 0
  2405. , misses: 0
  2406. , coverage: 0
  2407. , files: []
  2408. };
  2409. for (var filename in cov) {
  2410. var data = coverage(filename, cov[filename]);
  2411. ret.files.push(data);
  2412. ret.hits += data.hits;
  2413. ret.misses += data.misses;
  2414. ret.sloc += data.sloc;
  2415. }
  2416. ret.files.sort(function(a, b) {
  2417. return a.filename.localeCompare(b.filename);
  2418. });
  2419. if (ret.sloc > 0) {
  2420. ret.coverage = (ret.hits / ret.sloc) * 100;
  2421. }
  2422. return ret;
  2423. };
  2424. /**
  2425. * Map jscoverage data for a single source file
  2426. * to a JSON structure suitable for reporting.
  2427. *
  2428. * @param {String} filename name of the source file
  2429. * @param {Object} data jscoverage coverage data
  2430. * @return {Object}
  2431. * @api private
  2432. */
  2433. function coverage(filename, data) {
  2434. var ret = {
  2435. filename: filename,
  2436. coverage: 0,
  2437. hits: 0,
  2438. misses: 0,
  2439. sloc: 0,
  2440. source: {}
  2441. };
  2442. data.source.forEach(function(line, num){
  2443. num++;
  2444. if (data[num] === 0) {
  2445. ret.misses++;
  2446. ret.sloc++;
  2447. } else if (data[num] !== undefined) {
  2448. ret.hits++;
  2449. ret.sloc++;
  2450. }
  2451. ret.source[num] = {
  2452. source: line
  2453. , coverage: data[num] === undefined
  2454. ? ''
  2455. : data[num]
  2456. };
  2457. });
  2458. ret.coverage = ret.hits / ret.sloc * 100;
  2459. return ret;
  2460. }
  2461. /**
  2462. * Return a plain-object representation of `test`
  2463. * free of cyclic properties etc.
  2464. *
  2465. * @param {Object} test
  2466. * @return {Object}
  2467. * @api private
  2468. */
  2469. function clean(test) {
  2470. return {
  2471. title: test.title
  2472. , fullTitle: test.fullTitle()
  2473. , duration: test.duration
  2474. }
  2475. }
  2476. }); // module: reporters/json-cov.js
  2477. require.register("reporters/json-stream.js", function(module, exports, require){
  2478. /**
  2479. * Module dependencies.
  2480. */
  2481. var Base = require('./base')
  2482. , color = Base.color;
  2483. /**
  2484. * Expose `List`.
  2485. */
  2486. exports = module.exports = List;
  2487. /**
  2488. * Initialize a new `List` test reporter.
  2489. *
  2490. * @param {Runner} runner
  2491. * @api public
  2492. */
  2493. function List(runner) {
  2494. Base.call(this, runner);
  2495. var self = this
  2496. , stats = this.stats
  2497. , total = runner.total;
  2498. runner.on('start', function(){
  2499. console.log(JSON.stringify(['start', { total: total }]));
  2500. });
  2501. runner.on('pass', function(test){
  2502. console.log(JSON.stringify(['pass', clean(test)]));
  2503. });
  2504. runner.on('fail', function(test, err){
  2505. console.log(JSON.stringify(['fail', clean(test)]));
  2506. });
  2507. runner.on('end', function(){
  2508. process.stdout.write(JSON.stringify(['end', self.stats]));
  2509. });
  2510. }
  2511. /**
  2512. * Return a plain-object representation of `test`
  2513. * free of cyclic properties etc.
  2514. *
  2515. * @param {Object} test
  2516. * @return {Object}
  2517. * @api private
  2518. */
  2519. function clean(test) {
  2520. return {
  2521. title: test.title
  2522. , fullTitle: test.fullTitle()
  2523. , duration: test.duration
  2524. }
  2525. }
  2526. }); // module: reporters/json-stream.js
  2527. require.register("reporters/json.js", function(module, exports, require){
  2528. /**
  2529. * Module dependencies.
  2530. */
  2531. var Base = require('./base')
  2532. , cursor = Base.cursor
  2533. , color = Base.color;
  2534. /**
  2535. * Expose `JSON`.
  2536. */
  2537. exports = module.exports = JSONReporter;
  2538. /**
  2539. * Initialize a new `JSON` reporter.
  2540. *
  2541. * @param {Runner} runner
  2542. * @api public
  2543. */
  2544. function JSONReporter(runner) {
  2545. var self = this;
  2546. Base.call(this, runner);
  2547. var tests = []
  2548. , failures = []
  2549. , passes = [];
  2550. runner.on('test end', function(test){
  2551. tests.push(test);
  2552. });
  2553. runner.on('pass', function(test){
  2554. passes.push(test);
  2555. });
  2556. runner.on('fail', function(test){
  2557. failures.push(test);
  2558. });
  2559. runner.on('end', function(){
  2560. var obj = {
  2561. stats: self.stats
  2562. , tests: tests.map(clean)
  2563. , failures: failures.map(clean)
  2564. , passes: passes.map(clean)
  2565. };
  2566. process.stdout.write(JSON.stringify(obj, null, 2));
  2567. });
  2568. }
  2569. /**
  2570. * Return a plain-object representation of `test`
  2571. * free of cyclic properties etc.
  2572. *
  2573. * @param {Object} test
  2574. * @return {Object}
  2575. * @api private
  2576. */
  2577. function clean(test) {
  2578. return {
  2579. title: test.title
  2580. , fullTitle: test.fullTitle()
  2581. , duration: test.duration
  2582. }
  2583. }
  2584. }); // module: reporters/json.js
  2585. require.register("reporters/landing.js", function(module, exports, require){
  2586. /**
  2587. * Module dependencies.
  2588. */
  2589. var Base = require('./base')
  2590. , cursor = Base.cursor
  2591. , color = Base.color;
  2592. /**
  2593. * Expose `Landing`.
  2594. */
  2595. exports = module.exports = Landing;
  2596. /**
  2597. * Airplane color.
  2598. */
  2599. Base.colors.plane = 0;
  2600. /**
  2601. * Airplane crash color.
  2602. */
  2603. Base.colors['plane crash'] = 31;
  2604. /**
  2605. * Runway color.
  2606. */
  2607. Base.colors.runway = 90;
  2608. /**
  2609. * Initialize a new `Landing` reporter.
  2610. *
  2611. * @param {Runner} runner
  2612. * @api public
  2613. */
  2614. function Landing(runner) {
  2615. Base.call(this, runner);
  2616. var self = this
  2617. , stats = this.stats
  2618. , width = Base.window.width * .75 | 0
  2619. , total = runner.total
  2620. , stream = process.stdout
  2621. , plane = color('plane', '✈')
  2622. , crashed = -1
  2623. , n = 0;
  2624. function runway() {
  2625. var buf = Array(width).join('-');
  2626. return ' ' + color('runway', buf);
  2627. }
  2628. runner.on('start', function(){
  2629. stream.write('\n ');
  2630. cursor.hide();
  2631. });
  2632. runner.on('test end', function(test){
  2633. // check if the plane crashed
  2634. var col = -1 == crashed
  2635. ? width * ++n / total | 0
  2636. : crashed;
  2637. // show the crash
  2638. if ('failed' == test.state) {
  2639. plane = color('plane crash', '✈');
  2640. crashed = col;
  2641. }
  2642. // render landing strip
  2643. stream.write('\u001b[4F\n\n');
  2644. stream.write(runway());
  2645. stream.write('\n ');
  2646. stream.write(color('runway', Array(col).join('⋅')));
  2647. stream.write(plane)
  2648. stream.write(color('runway', Array(width - col).join('⋅') + '\n'));
  2649. stream.write(runway());
  2650. stream.write('\u001b[0m');
  2651. });
  2652. runner.on('end', function(){
  2653. cursor.show();
  2654. console.log();
  2655. self.epilogue();
  2656. });
  2657. }
  2658. /**
  2659. * Inherit from `Base.prototype`.
  2660. */
  2661. function F(){};
  2662. F.prototype = Base.prototype;
  2663. Landing.prototype = new F;
  2664. Landing.prototype.constructor = Landing;
  2665. }); // module: reporters/landing.js
  2666. require.register("reporters/list.js", function(module, exports, require){
  2667. /**
  2668. * Module dependencies.
  2669. */
  2670. var Base = require('./base')
  2671. , cursor = Base.cursor
  2672. , color = Base.color;
  2673. /**
  2674. * Expose `List`.
  2675. */
  2676. exports = module.exports = List;
  2677. /**
  2678. * Initialize a new `List` test reporter.
  2679. *
  2680. * @param {Runner} runner
  2681. * @api public
  2682. */
  2683. function List(runner) {
  2684. Base.call(this, runner);
  2685. var self = this
  2686. , stats = this.stats
  2687. , n = 0;
  2688. runner.on('start', function(){
  2689. console.log();
  2690. });
  2691. runner.on('test', function(test){
  2692. process.stdout.write(color('pass', ' ' + test.fullTitle() + ': '));
  2693. });
  2694. runner.on('pending', function(test){
  2695. var fmt = color('checkmark', ' -')
  2696. + color('pending', ' %s');
  2697. console.log(fmt, test.fullTitle());
  2698. });
  2699. runner.on('pass', function(test){
  2700. var fmt = color('checkmark', ' '+Base.symbols.dot)
  2701. + color('pass', ' %s: ')
  2702. + color(test.speed, '%dms');
  2703. cursor.CR();
  2704. console.log(fmt, test.fullTitle(), test.duration);
  2705. });
  2706. runner.on('fail', function(test, err){
  2707. cursor.CR();
  2708. console.log(color('fail', ' %d) %s'), ++n, test.fullTitle());
  2709. });
  2710. runner.on('end', self.epilogue.bind(self));
  2711. }
  2712. /**
  2713. * Inherit from `Base.prototype`.
  2714. */
  2715. function F(){};
  2716. F.prototype = Base.prototype;
  2717. List.prototype = new F;
  2718. List.prototype.constructor = List;
  2719. }); // module: reporters/list.js
  2720. require.register("reporters/markdown.js", function(module, exports, require){
  2721. /**
  2722. * Module dependencies.
  2723. */
  2724. var Base = require('./base')
  2725. , utils = require('../utils');
  2726. /**
  2727. * Expose `Markdown`.
  2728. */
  2729. exports = module.exports = Markdown;
  2730. /**
  2731. * Initialize a new `Markdown` reporter.
  2732. *
  2733. * @param {Runner} runner
  2734. * @api public
  2735. */
  2736. function Markdown(runner) {
  2737. Base.call(this, runner);
  2738. var self = this
  2739. , stats = this.stats
  2740. , level = 0
  2741. , buf = '';
  2742. function title(str) {
  2743. return Array(level).join('#') + ' ' + str;
  2744. }
  2745. function indent() {
  2746. return Array(level).join(' ');
  2747. }
  2748. function mapTOC(suite, obj) {
  2749. var ret = obj;
  2750. obj = obj[suite.title] = obj[suite.title] || { suite: suite };
  2751. suite.suites.forEach(function(suite){
  2752. mapTOC(suite, obj);
  2753. });
  2754. return ret;
  2755. }
  2756. function stringifyTOC(obj, level) {
  2757. ++level;
  2758. var buf = '';
  2759. var link;
  2760. for (var key in obj) {
  2761. if ('suite' == key) continue;
  2762. if (key) link = ' - [' + key + '](#' + utils.slug(obj[key].suite.fullTitle()) + ')\n';
  2763. if (key) buf += Array(level).join(' ') + link;
  2764. buf += stringifyTOC(obj[key], level);
  2765. }
  2766. --level;
  2767. return buf;
  2768. }
  2769. function generateTOC(suite) {
  2770. var obj = mapTOC(suite, {});
  2771. return stringifyTOC(obj, 0);
  2772. }
  2773. generateTOC(runner.suite);
  2774. runner.on('suite', function(suite){
  2775. ++level;
  2776. var slug = utils.slug(suite.fullTitle());
  2777. buf += '<a name="' + slug + '"></a>' + '\n';
  2778. buf += title(suite.title) + '\n';
  2779. });
  2780. runner.on('suite end', function(suite){
  2781. --level;
  2782. });
  2783. runner.on('pass', function(test){
  2784. var code = utils.clean(test.fn.toString());
  2785. buf += test.title + '.\n';
  2786. buf += '\n```js\n';
  2787. buf += code + '\n';
  2788. buf += '```\n\n';
  2789. });
  2790. runner.on('end', function(){
  2791. process.stdout.write('# TOC\n');
  2792. process.stdout.write(generateTOC(runner.suite));
  2793. process.stdout.write(buf);
  2794. });
  2795. }
  2796. }); // module: reporters/markdown.js
  2797. require.register("reporters/min.js", function(module, exports, require){
  2798. /**
  2799. * Module dependencies.
  2800. */
  2801. var Base = require('./base');
  2802. /**
  2803. * Expose `Min`.
  2804. */
  2805. exports = module.exports = Min;
  2806. /**
  2807. * Initialize a new `Min` minimal test reporter (best used with --watch).
  2808. *
  2809. * @param {Runner} runner
  2810. * @api public
  2811. */
  2812. function Min(runner) {
  2813. Base.call(this, runner);
  2814. runner.on('start', function(){
  2815. // clear screen
  2816. process.stdout.write('\u001b[2J');
  2817. // set cursor position
  2818. process.stdout.write('\u001b[1;3H');
  2819. });
  2820. runner.on('end', this.epilogue.bind(this));
  2821. }
  2822. /**
  2823. * Inherit from `Base.prototype`.
  2824. */
  2825. function F(){};
  2826. F.prototype = Base.prototype;
  2827. Min.prototype = new F;
  2828. Min.prototype.constructor = Min;
  2829. }); // module: reporters/min.js
  2830. require.register("reporters/nyan.js", function(module, exports, require){
  2831. /**
  2832. * Module dependencies.
  2833. */
  2834. var Base = require('./base')
  2835. , color = Base.color;
  2836. /**
  2837. * Expose `Dot`.
  2838. */
  2839. exports = module.exports = NyanCat;
  2840. /**
  2841. * Initialize a new `Dot` matrix test reporter.
  2842. *
  2843. * @param {Runner} runner
  2844. * @api public
  2845. */
  2846. function NyanCat(runner) {
  2847. Base.call(this, runner);
  2848. var self = this
  2849. , stats = this.stats
  2850. , width = Base.window.width * .75 | 0
  2851. , rainbowColors = this.rainbowColors = self.generateColors()
  2852. , colorIndex = this.colorIndex = 0
  2853. , numerOfLines = this.numberOfLines = 4
  2854. , trajectories = this.trajectories = [[], [], [], []]
  2855. , nyanCatWidth = this.nyanCatWidth = 11
  2856. , trajectoryWidthMax = this.trajectoryWidthMax = (width - nyanCatWidth)
  2857. , scoreboardWidth = this.scoreboardWidth = 5
  2858. , tick = this.tick = 0
  2859. , n = 0;
  2860. runner.on('start', function(){
  2861. Base.cursor.hide();
  2862. self.draw();
  2863. });
  2864. runner.on('pending', function(test){
  2865. self.draw();
  2866. });
  2867. runner.on('pass', function(test){
  2868. self.draw();
  2869. });
  2870. runner.on('fail', function(test, err){
  2871. self.draw();
  2872. });
  2873. runner.on('end', function(){
  2874. Base.cursor.show();
  2875. for (var i = 0; i < self.numberOfLines; i++) write('\n');
  2876. self.epilogue();
  2877. });
  2878. }
  2879. /**
  2880. * Draw the nyan cat
  2881. *
  2882. * @api private
  2883. */
  2884. NyanCat.prototype.draw = function(){
  2885. this.appendRainbow();
  2886. this.drawScoreboard();
  2887. this.drawRainbow();
  2888. this.drawNyanCat();
  2889. this.tick = !this.tick;
  2890. };
  2891. /**
  2892. * Draw the "scoreboard" showing the number
  2893. * of passes, failures and pending tests.
  2894. *
  2895. * @api private
  2896. */
  2897. NyanCat.prototype.drawScoreboard = function(){
  2898. var stats = this.stats;
  2899. var colors = Base.colors;
  2900. function draw(color, n) {
  2901. write(' ');
  2902. write('\u001b[' + color + 'm' + n + '\u001b[0m');
  2903. write('\n');
  2904. }
  2905. draw(colors.green, stats.passes);
  2906. draw(colors.fail, stats.failures);
  2907. draw(colors.pending, stats.pending);
  2908. write('\n');
  2909. this.cursorUp(this.numberOfLines);
  2910. };
  2911. /**
  2912. * Append the rainbow.
  2913. *
  2914. * @api private
  2915. */
  2916. NyanCat.prototype.appendRainbow = function(){
  2917. var segment = this.tick ? '_' : '-';
  2918. var rainbowified = this.rainbowify(segment);
  2919. for (var index = 0; index < this.numberOfLines; index++) {
  2920. var trajectory = this.trajectories[index];
  2921. if (trajectory.length >= this.trajectoryWidthMax) trajectory.shift();
  2922. trajectory.push(rainbowified);
  2923. }
  2924. };
  2925. /**
  2926. * Draw the rainbow.
  2927. *
  2928. * @api private
  2929. */
  2930. NyanCat.prototype.drawRainbow = function(){
  2931. var self = this;
  2932. this.trajectories.forEach(function(line, index) {
  2933. write('\u001b[' + self.scoreboardWidth + 'C');
  2934. write(line.join(''));
  2935. write('\n');
  2936. });
  2937. this.cursorUp(this.numberOfLines);
  2938. };
  2939. /**
  2940. * Draw the nyan cat
  2941. *
  2942. * @api private
  2943. */
  2944. NyanCat.prototype.drawNyanCat = function() {
  2945. var self = this;
  2946. var startWidth = this.scoreboardWidth + this.trajectories[0].length;
  2947. var color = '\u001b[' + startWidth + 'C';
  2948. var padding = '';
  2949. write(color);
  2950. write('_,------,');
  2951. write('\n');
  2952. write(color);
  2953. padding = self.tick ? ' ' : ' ';
  2954. write('_|' + padding + '/\\_/\\ ');
  2955. write('\n');
  2956. write(color);
  2957. padding = self.tick ? '_' : '__';
  2958. var tail = self.tick ? '~' : '^';
  2959. var face;
  2960. write(tail + '|' + padding + this.face() + ' ');
  2961. write('\n');
  2962. write(color);
  2963. padding = self.tick ? ' ' : ' ';
  2964. write(padding + '"" "" ');
  2965. write('\n');
  2966. this.cursorUp(this.numberOfLines);
  2967. };
  2968. /**
  2969. * Draw nyan cat face.
  2970. *
  2971. * @return {String}
  2972. * @api private
  2973. */
  2974. NyanCat.prototype.face = function() {
  2975. var stats = this.stats;
  2976. if (stats.failures) {
  2977. return '( x .x)';
  2978. } else if (stats.pending) {
  2979. return '( o .o)';
  2980. } else if(stats.passes) {
  2981. return '( ^ .^)';
  2982. } else {
  2983. return '( - .-)';
  2984. }
  2985. }
  2986. /**
  2987. * Move cursor up `n`.
  2988. *
  2989. * @param {Number} n
  2990. * @api private
  2991. */
  2992. NyanCat.prototype.cursorUp = function(n) {
  2993. write('\u001b[' + n + 'A');
  2994. };
  2995. /**
  2996. * Move cursor down `n`.
  2997. *
  2998. * @param {Number} n
  2999. * @api private
  3000. */
  3001. NyanCat.prototype.cursorDown = function(n) {
  3002. write('\u001b[' + n + 'B');
  3003. };
  3004. /**
  3005. * Generate rainbow colors.
  3006. *
  3007. * @return {Array}
  3008. * @api private
  3009. */
  3010. NyanCat.prototype.generateColors = function(){
  3011. var colors = [];
  3012. for (var i = 0; i < (6 * 7); i++) {
  3013. var pi3 = Math.floor(Math.PI / 3);
  3014. var n = (i * (1.0 / 6));
  3015. var r = Math.floor(3 * Math.sin(n) + 3);
  3016. var g = Math.floor(3 * Math.sin(n + 2 * pi3) + 3);
  3017. var b = Math.floor(3 * Math.sin(n + 4 * pi3) + 3);
  3018. colors.push(36 * r + 6 * g + b + 16);
  3019. }
  3020. return colors;
  3021. };
  3022. /**
  3023. * Apply rainbow to the given `str`.
  3024. *
  3025. * @param {String} str
  3026. * @return {String}
  3027. * @api private
  3028. */
  3029. NyanCat.prototype.rainbowify = function(str){
  3030. var color = this.rainbowColors[this.colorIndex % this.rainbowColors.length];
  3031. this.colorIndex += 1;
  3032. return '\u001b[38;5;' + color + 'm' + str + '\u001b[0m';
  3033. };
  3034. /**
  3035. * Stdout helper.
  3036. */
  3037. function write(string) {
  3038. process.stdout.write(string);
  3039. }
  3040. /**
  3041. * Inherit from `Base.prototype`.
  3042. */
  3043. function F(){};
  3044. F.prototype = Base.prototype;
  3045. NyanCat.prototype = new F;
  3046. NyanCat.prototype.constructor = NyanCat;
  3047. }); // module: reporters/nyan.js
  3048. require.register("reporters/progress.js", function(module, exports, require){
  3049. /**
  3050. * Module dependencies.
  3051. */
  3052. var Base = require('./base')
  3053. , cursor = Base.cursor
  3054. , color = Base.color;
  3055. /**
  3056. * Expose `Progress`.
  3057. */
  3058. exports = module.exports = Progress;
  3059. /**
  3060. * General progress bar color.
  3061. */
  3062. Base.colors.progress = 90;
  3063. /**
  3064. * Initialize a new `Progress` bar test reporter.
  3065. *
  3066. * @param {Runner} runner
  3067. * @param {Object} options
  3068. * @api public
  3069. */
  3070. function Progress(runner, options) {
  3071. Base.call(this, runner);
  3072. var self = this
  3073. , options = options || {}
  3074. , stats = this.stats
  3075. , width = Base.window.width * .50 | 0
  3076. , total = runner.total
  3077. , complete = 0
  3078. , max = Math.max;
  3079. // default chars
  3080. options.open = options.open || '[';
  3081. options.complete = options.complete || '▬';
  3082. options.incomplete = options.incomplete || Base.symbols.dot;
  3083. options.close = options.close || ']';
  3084. options.verbose = false;
  3085. // tests started
  3086. runner.on('start', function(){
  3087. console.log();
  3088. cursor.hide();
  3089. });
  3090. // tests complete
  3091. runner.on('test end', function(){
  3092. complete++;
  3093. var incomplete = total - complete
  3094. , percent = complete / total
  3095. , n = width * percent | 0
  3096. , i = width - n;
  3097. cursor.CR();
  3098. process.stdout.write('\u001b[J');
  3099. process.stdout.write(color('progress', ' ' + options.open));
  3100. process.stdout.write(Array(n).join(options.complete));
  3101. process.stdout.write(Array(i).join(options.incomplete));
  3102. process.stdout.write(color('progress', options.close));
  3103. if (options.verbose) {
  3104. process.stdout.write(color('progress', ' ' + complete + ' of ' + total));
  3105. }
  3106. });
  3107. // tests are complete, output some stats
  3108. // and the failures if any
  3109. runner.on('end', function(){
  3110. cursor.show();
  3111. console.log();
  3112. self.epilogue();
  3113. });
  3114. }
  3115. /**
  3116. * Inherit from `Base.prototype`.
  3117. */
  3118. function F(){};
  3119. F.prototype = Base.prototype;
  3120. Progress.prototype = new F;
  3121. Progress.prototype.constructor = Progress;
  3122. }); // module: reporters/progress.js
  3123. require.register("reporters/spec.js", function(module, exports, require){
  3124. /**
  3125. * Module dependencies.
  3126. */
  3127. var Base = require('./base')
  3128. , cursor = Base.cursor
  3129. , color = Base.color;
  3130. /**
  3131. * Expose `Spec`.
  3132. */
  3133. exports = module.exports = Spec;
  3134. /**
  3135. * Initialize a new `Spec` test reporter.
  3136. *
  3137. * @param {Runner} runner
  3138. * @api public
  3139. */
  3140. function Spec(runner) {
  3141. Base.call(this, runner);
  3142. var self = this
  3143. , stats = this.stats
  3144. , indents = 0
  3145. , n = 0;
  3146. function indent() {
  3147. return Array(indents).join(' ')
  3148. }
  3149. runner.on('start', function(){
  3150. console.log();
  3151. });
  3152. runner.on('suite', function(suite){
  3153. ++indents;
  3154. console.log(color('suite', '%s%s'), indent(), suite.title);
  3155. });
  3156. runner.on('suite end', function(suite){
  3157. --indents;
  3158. if (1 == indents) console.log();
  3159. });
  3160. runner.on('pending', function(test){
  3161. var fmt = indent() + color('pending', ' - %s');
  3162. console.log(fmt, test.title);
  3163. });
  3164. runner.on('pass', function(test){
  3165. if ('fast' == test.speed) {
  3166. var fmt = indent()
  3167. + color('checkmark', ' ' + Base.symbols.ok)
  3168. + color('pass', ' %s ');
  3169. cursor.CR();
  3170. console.log(fmt, test.title);
  3171. } else {
  3172. var fmt = indent()
  3173. + color('checkmark', ' ' + Base.symbols.ok)
  3174. + color('pass', ' %s ')
  3175. + color(test.speed, '(%dms)');
  3176. cursor.CR();
  3177. console.log(fmt, test.title, test.duration);
  3178. }
  3179. });
  3180. runner.on('fail', function(test, err){
  3181. cursor.CR();
  3182. console.log(indent() + color('fail', ' %d) %s'), ++n, test.title);
  3183. });
  3184. runner.on('end', self.epilogue.bind(self));
  3185. }
  3186. /**
  3187. * Inherit from `Base.prototype`.
  3188. */
  3189. function F(){};
  3190. F.prototype = Base.prototype;
  3191. Spec.prototype = new F;
  3192. Spec.prototype.constructor = Spec;
  3193. }); // module: reporters/spec.js
  3194. require.register("reporters/tap.js", function(module, exports, require){
  3195. /**
  3196. * Module dependencies.
  3197. */
  3198. var Base = require('./base')
  3199. , cursor = Base.cursor
  3200. , color = Base.color;
  3201. /**
  3202. * Expose `TAP`.
  3203. */
  3204. exports = module.exports = TAP;
  3205. /**
  3206. * Initialize a new `TAP` reporter.
  3207. *
  3208. * @param {Runner} runner
  3209. * @api public
  3210. */
  3211. function TAP(runner) {
  3212. Base.call(this, runner);
  3213. var self = this
  3214. , stats = this.stats
  3215. , n = 1
  3216. , passes = 0
  3217. , failures = 0;
  3218. runner.on('start', function(){
  3219. var total = runner.grepTotal(runner.suite);
  3220. console.log('%d..%d', 1, total);
  3221. });
  3222. runner.on('test end', function(){
  3223. ++n;
  3224. });
  3225. runner.on('pending', function(test){
  3226. console.log('ok %d %s # SKIP -', n, title(test));
  3227. });
  3228. runner.on('pass', function(test){
  3229. passes++;
  3230. console.log('ok %d %s', n, title(test));
  3231. });
  3232. runner.on('fail', function(test, err){
  3233. failures++;
  3234. console.log('not ok %d %s', n, title(test));
  3235. if (err.stack) console.log(err.stack.replace(/^/gm, ' '));
  3236. });
  3237. runner.on('end', function(){
  3238. console.log('# tests ' + (passes + failures));
  3239. console.log('# pass ' + passes);
  3240. console.log('# fail ' + failures);
  3241. });
  3242. }
  3243. /**
  3244. * Return a TAP-safe title of `test`
  3245. *
  3246. * @param {Object} test
  3247. * @return {String}
  3248. * @api private
  3249. */
  3250. function title(test) {
  3251. return test.fullTitle().replace(/#/g, '');
  3252. }
  3253. }); // module: reporters/tap.js
  3254. require.register("reporters/xunit.js", function(module, exports, require){
  3255. /**
  3256. * Module dependencies.
  3257. */
  3258. var Base = require('./base')
  3259. , utils = require('../utils')
  3260. , escape = utils.escape;
  3261. /**
  3262. * Save timer references to avoid Sinon interfering (see GH-237).
  3263. */
  3264. var Date = global.Date
  3265. , setTimeout = global.setTimeout
  3266. , setInterval = global.setInterval
  3267. , clearTimeout = global.clearTimeout
  3268. , clearInterval = global.clearInterval;
  3269. /**
  3270. * Expose `XUnit`.
  3271. */
  3272. exports = module.exports = XUnit;
  3273. /**
  3274. * Initialize a new `XUnit` reporter.
  3275. *
  3276. * @param {Runner} runner
  3277. * @api public
  3278. */
  3279. function XUnit(runner) {
  3280. Base.call(this, runner);
  3281. var stats = this.stats
  3282. , tests = []
  3283. , self = this;
  3284. runner.on('pending', function(test){
  3285. tests.push(test);
  3286. });
  3287. runner.on('pass', function(test){
  3288. tests.push(test);
  3289. });
  3290. runner.on('fail', function(test){
  3291. tests.push(test);
  3292. });
  3293. runner.on('end', function(){
  3294. console.log(tag('testsuite', {
  3295. name: 'Mocha Tests'
  3296. , tests: stats.tests
  3297. , failures: stats.failures
  3298. , errors: stats.failures
  3299. , skipped: stats.tests - stats.failures - stats.passes
  3300. , timestamp: (new Date).toUTCString()
  3301. , time: (stats.duration / 1000) || 0
  3302. }, false));
  3303. tests.forEach(test);
  3304. console.log('</testsuite>');
  3305. });
  3306. }
  3307. /**
  3308. * Inherit from `Base.prototype`.
  3309. */
  3310. function F(){};
  3311. F.prototype = Base.prototype;
  3312. XUnit.prototype = new F;
  3313. XUnit.prototype.constructor = XUnit;
  3314. /**
  3315. * Output tag for the given `test.`
  3316. */
  3317. function test(test) {
  3318. var attrs = {
  3319. classname: test.parent.fullTitle()
  3320. , name: test.title
  3321. , time: (test.duration / 1000) || 0
  3322. };
  3323. if ('failed' == test.state) {
  3324. var err = test.err;
  3325. attrs.message = escape(err.message);
  3326. console.log(tag('testcase', attrs, false, tag('failure', attrs, false, cdata(err.stack))));
  3327. } else if (test.pending) {
  3328. console.log(tag('testcase', attrs, false, tag('skipped', {}, true)));
  3329. } else {
  3330. console.log(tag('testcase', attrs, true) );
  3331. }
  3332. }
  3333. /**
  3334. * HTML tag helper.
  3335. */
  3336. function tag(name, attrs, close, content) {
  3337. var end = close ? '/>' : '>'
  3338. , pairs = []
  3339. , tag;
  3340. for (var key in attrs) {
  3341. pairs.push(key + '="' + escape(attrs[key]) + '"');
  3342. }
  3343. tag = '<' + name + (pairs.length ? ' ' + pairs.join(' ') : '') + end;
  3344. if (content) tag += content + '</' + name + end;
  3345. return tag;
  3346. }
  3347. /**
  3348. * Return cdata escaped CDATA `str`.
  3349. */
  3350. function cdata(str) {
  3351. return '<![CDATA[' + escape(str) + ']]>';
  3352. }
  3353. }); // module: reporters/xunit.js
  3354. require.register("runnable.js", function(module, exports, require){
  3355. /**
  3356. * Module dependencies.
  3357. */
  3358. var EventEmitter = require('browser/events').EventEmitter
  3359. , debug = require('browser/debug')('mocha:runnable')
  3360. , milliseconds = require('./ms');
  3361. /**
  3362. * Save timer references to avoid Sinon interfering (see GH-237).
  3363. */
  3364. var Date = global.Date
  3365. , setTimeout = global.setTimeout
  3366. , setInterval = global.setInterval
  3367. , clearTimeout = global.clearTimeout
  3368. , clearInterval = global.clearInterval;
  3369. /**
  3370. * Object#toString().
  3371. */
  3372. var toString = Object.prototype.toString;
  3373. /**
  3374. * Expose `Runnable`.
  3375. */
  3376. module.exports = Runnable;
  3377. /**
  3378. * Initialize a new `Runnable` with the given `title` and callback `fn`.
  3379. *
  3380. * @param {String} title
  3381. * @param {Function} fn
  3382. * @api private
  3383. */
  3384. function Runnable(title, fn) {
  3385. this.title = title;
  3386. this.fn = fn;
  3387. this.async = fn && fn.length;
  3388. this.sync = ! this.async;
  3389. this._timeout = 2000;
  3390. this._slow = 75;
  3391. this.timedOut = false;
  3392. }
  3393. /**
  3394. * Inherit from `EventEmitter.prototype`.
  3395. */
  3396. function F(){};
  3397. F.prototype = EventEmitter.prototype;
  3398. Runnable.prototype = new F;
  3399. Runnable.prototype.constructor = Runnable;
  3400. /**
  3401. * Set & get timeout `ms`.
  3402. *
  3403. * @param {Number|String} ms
  3404. * @return {Runnable|Number} ms or self
  3405. * @api private
  3406. */
  3407. Runnable.prototype.timeout = function(ms){
  3408. if (0 == arguments.length) return this._timeout;
  3409. if ('string' == typeof ms) ms = milliseconds(ms);
  3410. debug('timeout %d', ms);
  3411. this._timeout = ms;
  3412. if (this.timer) this.resetTimeout();
  3413. return this;
  3414. };
  3415. /**
  3416. * Set & get slow `ms`.
  3417. *
  3418. * @param {Number|String} ms
  3419. * @return {Runnable|Number} ms or self
  3420. * @api private
  3421. */
  3422. Runnable.prototype.slow = function(ms){
  3423. if (0 === arguments.length) return this._slow;
  3424. if ('string' == typeof ms) ms = milliseconds(ms);
  3425. debug('timeout %d', ms);
  3426. this._slow = ms;
  3427. return this;
  3428. };
  3429. /**
  3430. * Return the full title generated by recursively
  3431. * concatenating the parent's full title.
  3432. *
  3433. * @return {String}
  3434. * @api public
  3435. */
  3436. Runnable.prototype.fullTitle = function(){
  3437. return this.parent.fullTitle() + ' ' + this.title;
  3438. };
  3439. /**
  3440. * Clear the timeout.
  3441. *
  3442. * @api private
  3443. */
  3444. Runnable.prototype.clearTimeout = function(){
  3445. clearTimeout(this.timer);
  3446. };
  3447. /**
  3448. * Inspect the runnable void of private properties.
  3449. *
  3450. * @return {String}
  3451. * @api private
  3452. */
  3453. Runnable.prototype.inspect = function(){
  3454. return JSON.stringify(this, function(key, val){
  3455. if ('_' == key[0]) return;
  3456. if ('parent' == key) return '#<Suite>';
  3457. if ('ctx' == key) return '#<Context>';
  3458. return val;
  3459. }, 2);
  3460. };
  3461. /**
  3462. * Reset the timeout.
  3463. *
  3464. * @api private
  3465. */
  3466. Runnable.prototype.resetTimeout = function(){
  3467. var self = this;
  3468. var ms = this.timeout() || 1e9;
  3469. this.clearTimeout();
  3470. this.timer = setTimeout(function(){
  3471. self.callback(new Error('timeout of ' + ms + 'ms exceeded'));
  3472. self.timedOut = true;
  3473. }, ms);
  3474. };
  3475. /**
  3476. * Whitelist these globals for this test run
  3477. *
  3478. * @api private
  3479. */
  3480. Runnable.prototype.globals = function(arr){
  3481. var self = this;
  3482. this._allowedGlobals = arr;
  3483. };
  3484. /**
  3485. * Run the test and invoke `fn(err)`.
  3486. *
  3487. * @param {Function} fn
  3488. * @api private
  3489. */
  3490. Runnable.prototype.run = function(fn){
  3491. var self = this
  3492. , ms = this.timeout()
  3493. , start = new Date
  3494. , ctx = this.ctx
  3495. , finished
  3496. , emitted;
  3497. if (ctx) ctx.runnable(this);
  3498. // timeout
  3499. if (this.async) {
  3500. if (ms) {
  3501. this.timer = setTimeout(function(){
  3502. done(new Error('timeout of ' + ms + 'ms exceeded'));
  3503. self.timedOut = true;
  3504. }, ms);
  3505. }
  3506. }
  3507. // called multiple times
  3508. function multiple(err) {
  3509. if (emitted) return;
  3510. emitted = true;
  3511. self.emit('error', err || new Error('done() called multiple times'));
  3512. }
  3513. // finished
  3514. function done(err) {
  3515. if (self.timedOut) return;
  3516. if (finished) return multiple(err);
  3517. self.clearTimeout();
  3518. self.duration = new Date - start;
  3519. finished = true;
  3520. fn(err);
  3521. }
  3522. // for .resetTimeout()
  3523. this.callback = done;
  3524. // async
  3525. if (this.async) {
  3526. try {
  3527. this.fn.call(ctx, function(err){
  3528. if (err instanceof Error || toString.call(err) === "[object Error]") return done(err);
  3529. if (null != err) return done(new Error('done() invoked with non-Error: ' + err));
  3530. done();
  3531. });
  3532. } catch (err) {
  3533. done(err);
  3534. }
  3535. return;
  3536. }
  3537. if (this.asyncOnly) {
  3538. return done(new Error('--async-only option in use without declaring `done()`'));
  3539. }
  3540. // sync
  3541. try {
  3542. if (!this.pending) this.fn.call(ctx);
  3543. this.duration = new Date - start;
  3544. fn();
  3545. } catch (err) {
  3546. fn(err);
  3547. }
  3548. };
  3549. }); // module: runnable.js
  3550. require.register("runner.js", function(module, exports, require){
  3551. /**
  3552. * Module dependencies.
  3553. */
  3554. var EventEmitter = require('browser/events').EventEmitter
  3555. , debug = require('browser/debug')('mocha:runner')
  3556. , Test = require('./test')
  3557. , utils = require('./utils')
  3558. , filter = utils.filter
  3559. , keys = utils.keys;
  3560. /**
  3561. * Non-enumerable globals.
  3562. */
  3563. var globals = [
  3564. 'setTimeout',
  3565. 'clearTimeout',
  3566. 'setInterval',
  3567. 'clearInterval',
  3568. 'XMLHttpRequest',
  3569. 'Date'
  3570. ];
  3571. /**
  3572. * Expose `Runner`.
  3573. */
  3574. module.exports = Runner;
  3575. /**
  3576. * Initialize a `Runner` for the given `suite`.
  3577. *
  3578. * Events:
  3579. *
  3580. * - `start` execution started
  3581. * - `end` execution complete
  3582. * - `suite` (suite) test suite execution started
  3583. * - `suite end` (suite) all tests (and sub-suites) have finished
  3584. * - `test` (test) test execution started
  3585. * - `test end` (test) test completed
  3586. * - `hook` (hook) hook execution started
  3587. * - `hook end` (hook) hook complete
  3588. * - `pass` (test) test passed
  3589. * - `fail` (test, err) test failed
  3590. * - `pending` (test) test pending
  3591. *
  3592. * @api public
  3593. */
  3594. function Runner(suite) {
  3595. var self = this;
  3596. this._globals = [];
  3597. this._abort = false;
  3598. this.suite = suite;
  3599. this.total = suite.total();
  3600. this.failures = 0;
  3601. this.on('test end', function(test){ self.checkGlobals(test); });
  3602. this.on('hook end', function(hook){ self.checkGlobals(hook); });
  3603. this.grep(/.*/);
  3604. this.globals(this.globalProps().concat(extraGlobals()));
  3605. }
  3606. /**
  3607. * Wrapper for setImmediate, process.nextTick, or browser polyfill.
  3608. *
  3609. * @param {Function} fn
  3610. * @api private
  3611. */
  3612. Runner.immediately = global.setImmediate || process.nextTick;
  3613. /**
  3614. * Inherit from `EventEmitter.prototype`.
  3615. */
  3616. function F(){};
  3617. F.prototype = EventEmitter.prototype;
  3618. Runner.prototype = new F;
  3619. Runner.prototype.constructor = Runner;
  3620. /**
  3621. * Run tests with full titles matching `re`. Updates runner.total
  3622. * with number of tests matched.
  3623. *
  3624. * @param {RegExp} re
  3625. * @param {Boolean} invert
  3626. * @return {Runner} for chaining
  3627. * @api public
  3628. */
  3629. Runner.prototype.grep = function(re, invert){
  3630. debug('grep %s', re);
  3631. this._grep = re;
  3632. this._invert = invert;
  3633. this.total = this.grepTotal(this.suite);
  3634. return this;
  3635. };
  3636. /**
  3637. * Returns the number of tests matching the grep search for the
  3638. * given suite.
  3639. *
  3640. * @param {Suite} suite
  3641. * @return {Number}
  3642. * @api public
  3643. */
  3644. Runner.prototype.grepTotal = function(suite) {
  3645. var self = this;
  3646. var total = 0;
  3647. suite.eachTest(function(test){
  3648. var match = self._grep.test(test.fullTitle());
  3649. if (self._invert) match = !match;
  3650. if (match) total++;
  3651. });
  3652. return total;
  3653. };
  3654. /**
  3655. * Return a list of global properties.
  3656. *
  3657. * @return {Array}
  3658. * @api private
  3659. */
  3660. Runner.prototype.globalProps = function() {
  3661. var props = utils.keys(global);
  3662. // non-enumerables
  3663. for (var i = 0; i < globals.length; ++i) {
  3664. if (~utils.indexOf(props, globals[i])) continue;
  3665. props.push(globals[i]);
  3666. }
  3667. return props;
  3668. };
  3669. /**
  3670. * Allow the given `arr` of globals.
  3671. *
  3672. * @param {Array} arr
  3673. * @return {Runner} for chaining
  3674. * @api public
  3675. */
  3676. Runner.prototype.globals = function(arr){
  3677. if (0 == arguments.length) return this._globals;
  3678. debug('globals %j', arr);
  3679. this._globals = this._globals.concat(arr);
  3680. return this;
  3681. };
  3682. /**
  3683. * Check for global variable leaks.
  3684. *
  3685. * @api private
  3686. */
  3687. Runner.prototype.checkGlobals = function(test){
  3688. if (this.ignoreLeaks) return;
  3689. var ok = this._globals;
  3690. var globals = this.globalProps();
  3691. var isNode = process.kill;
  3692. var leaks;
  3693. if (test) {
  3694. ok = ok.concat(test._allowedGlobals || []);
  3695. }
  3696. if(this.prevGlobalsLength == globals.length) return;
  3697. this.prevGlobalsLength = globals.length;
  3698. leaks = filterLeaks(ok, globals);
  3699. this._globals = this._globals.concat(leaks);
  3700. if (leaks.length > 1) {
  3701. this.fail(test, new Error('global leaks detected: ' + leaks.join(', ') + ''));
  3702. } else if (leaks.length) {
  3703. this.fail(test, new Error('global leak detected: ' + leaks[0]));
  3704. }
  3705. };
  3706. /**
  3707. * Fail the given `test`.
  3708. *
  3709. * @param {Test} test
  3710. * @param {Error} err
  3711. * @api private
  3712. */
  3713. Runner.prototype.fail = function(test, err){
  3714. ++this.failures;
  3715. test.state = 'failed';
  3716. if ('string' == typeof err) {
  3717. err = new Error('the string "' + err + '" was thrown, throw an Error :)');
  3718. }
  3719. this.emit('fail', test, err);
  3720. };
  3721. /**
  3722. * Fail the given `hook` with `err`.
  3723. *
  3724. * Hook failures work in the following pattern:
  3725. * - If bail, then exit
  3726. * - Failed `before` hook skips all tests in a suite and subsuites,
  3727. * but jumps to corresponding `after` hook
  3728. * - Failed `before each` hook skips remaining tests in a
  3729. * suite and jumps to corresponding `after each` hook,
  3730. * which is run only once
  3731. * - Failed `after` hook does not alter
  3732. * execution order
  3733. * - Failed `after each` hook skips remaining tests in a
  3734. * suite and subsuites, but executes other `after each`
  3735. * hooks
  3736. *
  3737. * @param {Hook} hook
  3738. * @param {Error} err
  3739. * @api private
  3740. */
  3741. Runner.prototype.failHook = function(hook, err){
  3742. this.fail(hook, err);
  3743. if (this.suite.bail()) {
  3744. this.emit('end');
  3745. }
  3746. };
  3747. /**
  3748. * Run hook `name` callbacks and then invoke `fn()`.
  3749. *
  3750. * @param {String} name
  3751. * @param {Function} function
  3752. * @api private
  3753. */
  3754. Runner.prototype.hook = function(name, fn){
  3755. var suite = this.suite
  3756. , hooks = suite['_' + name]
  3757. , self = this
  3758. , timer;
  3759. function next(i) {
  3760. var hook = hooks[i];
  3761. if (!hook) return fn();
  3762. if (self.failures && suite.bail()) return fn();
  3763. self.currentRunnable = hook;
  3764. hook.ctx.currentTest = self.test;
  3765. self.emit('hook', hook);
  3766. hook.on('error', function(err){
  3767. self.failHook(hook, err);
  3768. });
  3769. hook.run(function(err){
  3770. hook.removeAllListeners('error');
  3771. var testError = hook.error();
  3772. if (testError) self.fail(self.test, testError);
  3773. if (err) {
  3774. self.failHook(hook, err);
  3775. // stop executing hooks, notify callee of hook err
  3776. return fn(err);
  3777. }
  3778. self.emit('hook end', hook);
  3779. delete hook.ctx.currentTest;
  3780. next(++i);
  3781. });
  3782. }
  3783. Runner.immediately(function(){
  3784. next(0);
  3785. });
  3786. };
  3787. /**
  3788. * Run hook `name` for the given array of `suites`
  3789. * in order, and callback `fn(err, errSuite)`.
  3790. *
  3791. * @param {String} name
  3792. * @param {Array} suites
  3793. * @param {Function} fn
  3794. * @api private
  3795. */
  3796. Runner.prototype.hooks = function(name, suites, fn){
  3797. var self = this
  3798. , orig = this.suite;
  3799. function next(suite) {
  3800. self.suite = suite;
  3801. if (!suite) {
  3802. self.suite = orig;
  3803. return fn();
  3804. }
  3805. self.hook(name, function(err){
  3806. if (err) {
  3807. var errSuite = self.suite;
  3808. self.suite = orig;
  3809. return fn(err, errSuite);
  3810. }
  3811. next(suites.pop());
  3812. });
  3813. }
  3814. next(suites.pop());
  3815. };
  3816. /**
  3817. * Run hooks from the top level down.
  3818. *
  3819. * @param {String} name
  3820. * @param {Function} fn
  3821. * @api private
  3822. */
  3823. Runner.prototype.hookUp = function(name, fn){
  3824. var suites = [this.suite].concat(this.parents()).reverse();
  3825. this.hooks(name, suites, fn);
  3826. };
  3827. /**
  3828. * Run hooks from the bottom up.
  3829. *
  3830. * @param {String} name
  3831. * @param {Function} fn
  3832. * @api private
  3833. */
  3834. Runner.prototype.hookDown = function(name, fn){
  3835. var suites = [this.suite].concat(this.parents());
  3836. this.hooks(name, suites, fn);
  3837. };
  3838. /**
  3839. * Return an array of parent Suites from
  3840. * closest to furthest.
  3841. *
  3842. * @return {Array}
  3843. * @api private
  3844. */
  3845. Runner.prototype.parents = function(){
  3846. var suite = this.suite
  3847. , suites = [];
  3848. while (suite = suite.parent) suites.push(suite);
  3849. return suites;
  3850. };
  3851. /**
  3852. * Run the current test and callback `fn(err)`.
  3853. *
  3854. * @param {Function} fn
  3855. * @api private
  3856. */
  3857. Runner.prototype.runTest = function(fn){
  3858. var test = this.test
  3859. , self = this;
  3860. if (this.asyncOnly) test.asyncOnly = true;
  3861. try {
  3862. test.on('error', function(err){
  3863. self.fail(test, err);
  3864. });
  3865. test.run(fn);
  3866. } catch (err) {
  3867. fn(err);
  3868. }
  3869. };
  3870. /**
  3871. * Run tests in the given `suite` and invoke
  3872. * the callback `fn()` when complete.
  3873. *
  3874. * @param {Suite} suite
  3875. * @param {Function} fn
  3876. * @api private
  3877. */
  3878. Runner.prototype.runTests = function(suite, fn){
  3879. var self = this
  3880. , tests = suite.tests.slice()
  3881. , test;
  3882. function hookErr(err, errSuite, after) {
  3883. // before/after Each hook for errSuite failed:
  3884. var orig = self.suite;
  3885. // for failed 'after each' hook start from errSuite parent,
  3886. // otherwise start from errSuite itself
  3887. self.suite = after ? errSuite.parent : errSuite;
  3888. if (self.suite) {
  3889. // call hookUp afterEach
  3890. self.hookUp('afterEach', function(err2, errSuite2) {
  3891. self.suite = orig;
  3892. // some hooks may fail even now
  3893. if (err2) return hookErr(err2, errSuite2, true);
  3894. // report error suite
  3895. fn(errSuite);
  3896. });
  3897. } else {
  3898. // there is no need calling other 'after each' hooks
  3899. self.suite = orig;
  3900. fn(errSuite);
  3901. }
  3902. }
  3903. function next(err, errSuite) {
  3904. // if we bail after first err
  3905. if (self.failures && suite._bail) return fn();
  3906. if (self._abort) return fn();
  3907. if (err) return hookErr(err, errSuite, true);
  3908. // next test
  3909. test = tests.shift();
  3910. // all done
  3911. if (!test) return fn();
  3912. // grep
  3913. var match = self._grep.test(test.fullTitle());
  3914. if (self._invert) match = !match;
  3915. if (!match) return next();
  3916. // pending
  3917. if (test.pending) {
  3918. self.emit('pending', test);
  3919. self.emit('test end', test);
  3920. return next();
  3921. }
  3922. // execute test and hook(s)
  3923. self.emit('test', self.test = test);
  3924. self.hookDown('beforeEach', function(err, errSuite){
  3925. if (err) return hookErr(err, errSuite, false);
  3926. self.currentRunnable = self.test;
  3927. self.runTest(function(err){
  3928. test = self.test;
  3929. if (err) {
  3930. self.fail(test, err);
  3931. self.emit('test end', test);
  3932. return self.hookUp('afterEach', next);
  3933. }
  3934. test.state = 'passed';
  3935. self.emit('pass', test);
  3936. self.emit('test end', test);
  3937. self.hookUp('afterEach', next);
  3938. });
  3939. });
  3940. }
  3941. this.next = next;
  3942. next();
  3943. };
  3944. /**
  3945. * Run the given `suite` and invoke the
  3946. * callback `fn()` when complete.
  3947. *
  3948. * @param {Suite} suite
  3949. * @param {Function} fn
  3950. * @api private
  3951. */
  3952. Runner.prototype.runSuite = function(suite, fn){
  3953. var total = this.grepTotal(suite)
  3954. , self = this
  3955. , i = 0;
  3956. debug('run suite %s', suite.fullTitle());
  3957. if (!total) return fn();
  3958. this.emit('suite', this.suite = suite);
  3959. function next(errSuite) {
  3960. if (errSuite) {
  3961. // current suite failed on a hook from errSuite
  3962. if (errSuite == suite) {
  3963. // if errSuite is current suite
  3964. // continue to the next sibling suite
  3965. return done();
  3966. } else {
  3967. // errSuite is among the parents of current suite
  3968. // stop execution of errSuite and all sub-suites
  3969. return done(errSuite);
  3970. }
  3971. }
  3972. if (self._abort) return done();
  3973. var curr = suite.suites[i++];
  3974. if (!curr) return done();
  3975. self.runSuite(curr, next);
  3976. }
  3977. function done(errSuite) {
  3978. self.suite = suite;
  3979. self.hook('afterAll', function(){
  3980. self.emit('suite end', suite);
  3981. fn(errSuite);
  3982. });
  3983. }
  3984. this.hook('beforeAll', function(err){
  3985. if (err) return done();
  3986. self.runTests(suite, next);
  3987. });
  3988. };
  3989. /**
  3990. * Handle uncaught exceptions.
  3991. *
  3992. * @param {Error} err
  3993. * @api private
  3994. */
  3995. Runner.prototype.uncaught = function(err){
  3996. debug('uncaught exception %s', err.message);
  3997. var runnable = this.currentRunnable;
  3998. if (!runnable || 'failed' == runnable.state) return;
  3999. runnable.clearTimeout();
  4000. err.uncaught = true;
  4001. this.fail(runnable, err);
  4002. // recover from test
  4003. if ('test' == runnable.type) {
  4004. this.emit('test end', runnable);
  4005. this.hookUp('afterEach', this.next);
  4006. return;
  4007. }
  4008. // bail on hooks
  4009. this.emit('end');
  4010. };
  4011. /**
  4012. * Run the root suite and invoke `fn(failures)`
  4013. * on completion.
  4014. *
  4015. * @param {Function} fn
  4016. * @return {Runner} for chaining
  4017. * @api public
  4018. */
  4019. Runner.prototype.run = function(fn){
  4020. var self = this
  4021. , fn = fn || function(){};
  4022. function uncaught(err){
  4023. self.uncaught(err);
  4024. }
  4025. debug('start');
  4026. // callback
  4027. this.on('end', function(){
  4028. debug('end');
  4029. process.removeListener('uncaughtException', uncaught);
  4030. fn(self.failures);
  4031. });
  4032. // run suites
  4033. this.emit('start');
  4034. this.runSuite(this.suite, function(){
  4035. debug('finished running');
  4036. self.emit('end');
  4037. });
  4038. // uncaught exception
  4039. process.on('uncaughtException', uncaught);
  4040. return this;
  4041. };
  4042. /**
  4043. * Cleanly abort execution
  4044. *
  4045. * @return {Runner} for chaining
  4046. * @api public
  4047. */
  4048. Runner.prototype.abort = function(){
  4049. debug('aborting');
  4050. this._abort = true;
  4051. }
  4052. /**
  4053. * Filter leaks with the given globals flagged as `ok`.
  4054. *
  4055. * @param {Array} ok
  4056. * @param {Array} globals
  4057. * @return {Array}
  4058. * @api private
  4059. */
  4060. function filterLeaks(ok, globals) {
  4061. return filter(globals, function(key){
  4062. // Firefox and Chrome exposes iframes as index inside the window object
  4063. if (/^d+/.test(key)) return false;
  4064. // in firefox
  4065. // if runner runs in an iframe, this iframe's window.getInterface method not init at first
  4066. // it is assigned in some seconds
  4067. if (global.navigator && /^getInterface/.test(key)) return false;
  4068. // an iframe could be approached by window[iframeIndex]
  4069. // in ie6,7,8 and opera, iframeIndex is enumerable, this could cause leak
  4070. if (global.navigator && /^\d+/.test(key)) return false;
  4071. // Opera and IE expose global variables for HTML element IDs (issue #243)
  4072. if (/^mocha-/.test(key)) return false;
  4073. var matched = filter(ok, function(ok){
  4074. if (~ok.indexOf('*')) return 0 == key.indexOf(ok.split('*')[0]);
  4075. return key == ok;
  4076. });
  4077. return matched.length == 0 && (!global.navigator || 'onerror' !== key);
  4078. });
  4079. }
  4080. /**
  4081. * Array of globals dependent on the environment.
  4082. *
  4083. * @return {Array}
  4084. * @api private
  4085. */
  4086. function extraGlobals() {
  4087. if (typeof(process) === 'object' &&
  4088. typeof(process.version) === 'string') {
  4089. var nodeVersion = process.version.split('.').reduce(function(a, v) {
  4090. return a << 8 | v;
  4091. });
  4092. // 'errno' was renamed to process._errno in v0.9.11.
  4093. if (nodeVersion < 0x00090B) {
  4094. return ['errno'];
  4095. }
  4096. }
  4097. return [];
  4098. }
  4099. }); // module: runner.js
  4100. require.register("suite.js", function(module, exports, require){
  4101. /**
  4102. * Module dependencies.
  4103. */
  4104. var EventEmitter = require('browser/events').EventEmitter
  4105. , debug = require('browser/debug')('mocha:suite')
  4106. , milliseconds = require('./ms')
  4107. , utils = require('./utils')
  4108. , Hook = require('./hook');
  4109. /**
  4110. * Expose `Suite`.
  4111. */
  4112. exports = module.exports = Suite;
  4113. /**
  4114. * Create a new `Suite` with the given `title`
  4115. * and parent `Suite`. When a suite with the
  4116. * same title is already present, that suite
  4117. * is returned to provide nicer reporter
  4118. * and more flexible meta-testing.
  4119. *
  4120. * @param {Suite} parent
  4121. * @param {String} title
  4122. * @return {Suite}
  4123. * @api public
  4124. */
  4125. exports.create = function(parent, title){
  4126. var suite = new Suite(title, parent.ctx);
  4127. suite.parent = parent;
  4128. if (parent.pending) suite.pending = true;
  4129. title = suite.fullTitle();
  4130. parent.addSuite(suite);
  4131. return suite;
  4132. };
  4133. /**
  4134. * Initialize a new `Suite` with the given
  4135. * `title` and `ctx`.
  4136. *
  4137. * @param {String} title
  4138. * @param {Context} ctx
  4139. * @api private
  4140. */
  4141. function Suite(title, ctx) {
  4142. this.title = title;
  4143. this.ctx = ctx;
  4144. this.suites = [];
  4145. this.tests = [];
  4146. this.pending = false;
  4147. this._beforeEach = [];
  4148. this._beforeAll = [];
  4149. this._afterEach = [];
  4150. this._afterAll = [];
  4151. this.root = !title;
  4152. this._timeout = 2000;
  4153. this._slow = 75;
  4154. this._bail = false;
  4155. }
  4156. /**
  4157. * Inherit from `EventEmitter.prototype`.
  4158. */
  4159. function F(){};
  4160. F.prototype = EventEmitter.prototype;
  4161. Suite.prototype = new F;
  4162. Suite.prototype.constructor = Suite;
  4163. /**
  4164. * Return a clone of this `Suite`.
  4165. *
  4166. * @return {Suite}
  4167. * @api private
  4168. */
  4169. Suite.prototype.clone = function(){
  4170. var suite = new Suite(this.title);
  4171. debug('clone');
  4172. suite.ctx = this.ctx;
  4173. suite.timeout(this.timeout());
  4174. suite.slow(this.slow());
  4175. suite.bail(this.bail());
  4176. return suite;
  4177. };
  4178. /**
  4179. * Set timeout `ms` or short-hand such as "2s".
  4180. *
  4181. * @param {Number|String} ms
  4182. * @return {Suite|Number} for chaining
  4183. * @api private
  4184. */
  4185. Suite.prototype.timeout = function(ms){
  4186. if (0 == arguments.length) return this._timeout;
  4187. if ('string' == typeof ms) ms = milliseconds(ms);
  4188. debug('timeout %d', ms);
  4189. this._timeout = parseInt(ms, 10);
  4190. return this;
  4191. };
  4192. /**
  4193. * Set slow `ms` or short-hand such as "2s".
  4194. *
  4195. * @param {Number|String} ms
  4196. * @return {Suite|Number} for chaining
  4197. * @api private
  4198. */
  4199. Suite.prototype.slow = function(ms){
  4200. if (0 === arguments.length) return this._slow;
  4201. if ('string' == typeof ms) ms = milliseconds(ms);
  4202. debug('slow %d', ms);
  4203. this._slow = ms;
  4204. return this;
  4205. };
  4206. /**
  4207. * Sets whether to bail after first error.
  4208. *
  4209. * @parma {Boolean} bail
  4210. * @return {Suite|Number} for chaining
  4211. * @api private
  4212. */
  4213. Suite.prototype.bail = function(bail){
  4214. if (0 == arguments.length) return this._bail;
  4215. debug('bail %s', bail);
  4216. this._bail = bail;
  4217. return this;
  4218. };
  4219. /**
  4220. * Run `fn(test[, done])` before running tests.
  4221. *
  4222. * @param {Function} fn
  4223. * @return {Suite} for chaining
  4224. * @api private
  4225. */
  4226. Suite.prototype.beforeAll = function(fn){
  4227. if (this.pending) return this;
  4228. var hook = new Hook('"before all" hook', fn);
  4229. hook.parent = this;
  4230. hook.timeout(this.timeout());
  4231. hook.slow(this.slow());
  4232. hook.ctx = this.ctx;
  4233. this._beforeAll.push(hook);
  4234. this.emit('beforeAll', hook);
  4235. return this;
  4236. };
  4237. /**
  4238. * Run `fn(test[, done])` after running tests.
  4239. *
  4240. * @param {Function} fn
  4241. * @return {Suite} for chaining
  4242. * @api private
  4243. */
  4244. Suite.prototype.afterAll = function(fn){
  4245. if (this.pending) return this;
  4246. var hook = new Hook('"after all" hook', fn);
  4247. hook.parent = this;
  4248. hook.timeout(this.timeout());
  4249. hook.slow(this.slow());
  4250. hook.ctx = this.ctx;
  4251. this._afterAll.push(hook);
  4252. this.emit('afterAll', hook);
  4253. return this;
  4254. };
  4255. /**
  4256. * Run `fn(test[, done])` before each test case.
  4257. *
  4258. * @param {Function} fn
  4259. * @return {Suite} for chaining
  4260. * @api private
  4261. */
  4262. Suite.prototype.beforeEach = function(fn){
  4263. if (this.pending) return this;
  4264. var hook = new Hook('"before each" hook', fn);
  4265. hook.parent = this;
  4266. hook.timeout(this.timeout());
  4267. hook.slow(this.slow());
  4268. hook.ctx = this.ctx;
  4269. this._beforeEach.push(hook);
  4270. this.emit('beforeEach', hook);
  4271. return this;
  4272. };
  4273. /**
  4274. * Run `fn(test[, done])` after each test case.
  4275. *
  4276. * @param {Function} fn
  4277. * @return {Suite} for chaining
  4278. * @api private
  4279. */
  4280. Suite.prototype.afterEach = function(fn){
  4281. if (this.pending) return this;
  4282. var hook = new Hook('"after each" hook', fn);
  4283. hook.parent = this;
  4284. hook.timeout(this.timeout());
  4285. hook.slow(this.slow());
  4286. hook.ctx = this.ctx;
  4287. this._afterEach.push(hook);
  4288. this.emit('afterEach', hook);
  4289. return this;
  4290. };
  4291. /**
  4292. * Add a test `suite`.
  4293. *
  4294. * @param {Suite} suite
  4295. * @return {Suite} for chaining
  4296. * @api private
  4297. */
  4298. Suite.prototype.addSuite = function(suite){
  4299. suite.parent = this;
  4300. suite.timeout(this.timeout());
  4301. suite.slow(this.slow());
  4302. suite.bail(this.bail());
  4303. this.suites.push(suite);
  4304. this.emit('suite', suite);
  4305. return this;
  4306. };
  4307. /**
  4308. * Add a `test` to this suite.
  4309. *
  4310. * @param {Test} test
  4311. * @return {Suite} for chaining
  4312. * @api private
  4313. */
  4314. Suite.prototype.addTest = function(test){
  4315. test.parent = this;
  4316. test.timeout(this.timeout());
  4317. test.slow(this.slow());
  4318. test.ctx = this.ctx;
  4319. this.tests.push(test);
  4320. this.emit('test', test);
  4321. return this;
  4322. };
  4323. /**
  4324. * Return the full title generated by recursively
  4325. * concatenating the parent's full title.
  4326. *
  4327. * @return {String}
  4328. * @api public
  4329. */
  4330. Suite.prototype.fullTitle = function(){
  4331. if (this.parent) {
  4332. var full = this.parent.fullTitle();
  4333. if (full) return full + ' ' + this.title;
  4334. }
  4335. return this.title;
  4336. };
  4337. /**
  4338. * Return the total number of tests.
  4339. *
  4340. * @return {Number}
  4341. * @api public
  4342. */
  4343. Suite.prototype.total = function(){
  4344. return utils.reduce(this.suites, function(sum, suite){
  4345. return sum + suite.total();
  4346. }, 0) + this.tests.length;
  4347. };
  4348. /**
  4349. * Iterates through each suite recursively to find
  4350. * all tests. Applies a function in the format
  4351. * `fn(test)`.
  4352. *
  4353. * @param {Function} fn
  4354. * @return {Suite}
  4355. * @api private
  4356. */
  4357. Suite.prototype.eachTest = function(fn){
  4358. utils.forEach(this.tests, fn);
  4359. utils.forEach(this.suites, function(suite){
  4360. suite.eachTest(fn);
  4361. });
  4362. return this;
  4363. };
  4364. }); // module: suite.js
  4365. require.register("test.js", function(module, exports, require){
  4366. /**
  4367. * Module dependencies.
  4368. */
  4369. var Runnable = require('./runnable');
  4370. /**
  4371. * Expose `Test`.
  4372. */
  4373. module.exports = Test;
  4374. /**
  4375. * Initialize a new `Test` with the given `title` and callback `fn`.
  4376. *
  4377. * @param {String} title
  4378. * @param {Function} fn
  4379. * @api private
  4380. */
  4381. function Test(title, fn) {
  4382. Runnable.call(this, title, fn);
  4383. this.pending = !fn;
  4384. this.type = 'test';
  4385. }
  4386. /**
  4387. * Inherit from `Runnable.prototype`.
  4388. */
  4389. function F(){};
  4390. F.prototype = Runnable.prototype;
  4391. Test.prototype = new F;
  4392. Test.prototype.constructor = Test;
  4393. }); // module: test.js
  4394. require.register("utils.js", function(module, exports, require){
  4395. /**
  4396. * Module dependencies.
  4397. */
  4398. var fs = require('browser/fs')
  4399. , path = require('browser/path')
  4400. , join = path.join
  4401. , debug = require('browser/debug')('mocha:watch');
  4402. /**
  4403. * Ignored directories.
  4404. */
  4405. var ignore = ['node_modules', '.git'];
  4406. /**
  4407. * Escape special characters in the given string of html.
  4408. *
  4409. * @param {String} html
  4410. * @return {String}
  4411. * @api private
  4412. */
  4413. exports.escape = function(html){
  4414. return String(html)
  4415. .replace(/&/g, '&amp;')
  4416. .replace(/"/g, '&quot;')
  4417. .replace(/</g, '&lt;')
  4418. .replace(/>/g, '&gt;');
  4419. };
  4420. /**
  4421. * Array#forEach (<=IE8)
  4422. *
  4423. * @param {Array} array
  4424. * @param {Function} fn
  4425. * @param {Object} scope
  4426. * @api private
  4427. */
  4428. exports.forEach = function(arr, fn, scope){
  4429. for (var i = 0, l = arr.length; i < l; i++)
  4430. fn.call(scope, arr[i], i);
  4431. };
  4432. /**
  4433. * Array#map (<=IE8)
  4434. *
  4435. * @param {Array} array
  4436. * @param {Function} fn
  4437. * @param {Object} scope
  4438. * @api private
  4439. */
  4440. exports.map = function(arr, fn, scope){
  4441. var result = [];
  4442. for (var i = 0, l = arr.length; i < l; i++)
  4443. result.push(fn.call(scope, arr[i], i));
  4444. return result;
  4445. };
  4446. /**
  4447. * Array#indexOf (<=IE8)
  4448. *
  4449. * @parma {Array} arr
  4450. * @param {Object} obj to find index of
  4451. * @param {Number} start
  4452. * @api private
  4453. */
  4454. exports.indexOf = function(arr, obj, start){
  4455. for (var i = start || 0, l = arr.length; i < l; i++) {
  4456. if (arr[i] === obj)
  4457. return i;
  4458. }
  4459. return -1;
  4460. };
  4461. /**
  4462. * Array#reduce (<=IE8)
  4463. *
  4464. * @param {Array} array
  4465. * @param {Function} fn
  4466. * @param {Object} initial value
  4467. * @api private
  4468. */
  4469. exports.reduce = function(arr, fn, val){
  4470. var rval = val;
  4471. for (var i = 0, l = arr.length; i < l; i++) {
  4472. rval = fn(rval, arr[i], i, arr);
  4473. }
  4474. return rval;
  4475. };
  4476. /**
  4477. * Array#filter (<=IE8)
  4478. *
  4479. * @param {Array} array
  4480. * @param {Function} fn
  4481. * @api private
  4482. */
  4483. exports.filter = function(arr, fn){
  4484. var ret = [];
  4485. for (var i = 0, l = arr.length; i < l; i++) {
  4486. var val = arr[i];
  4487. if (fn(val, i, arr)) ret.push(val);
  4488. }
  4489. return ret;
  4490. };
  4491. /**
  4492. * Object.keys (<=IE8)
  4493. *
  4494. * @param {Object} obj
  4495. * @return {Array} keys
  4496. * @api private
  4497. */
  4498. exports.keys = Object.keys || function(obj) {
  4499. var keys = []
  4500. , has = Object.prototype.hasOwnProperty // for `window` on <=IE8
  4501. for (var key in obj) {
  4502. if (has.call(obj, key)) {
  4503. keys.push(key);
  4504. }
  4505. }
  4506. return keys;
  4507. };
  4508. /**
  4509. * Watch the given `files` for changes
  4510. * and invoke `fn(file)` on modification.
  4511. *
  4512. * @param {Array} files
  4513. * @param {Function} fn
  4514. * @api private
  4515. */
  4516. exports.watch = function(files, fn){
  4517. var options = { interval: 100 };
  4518. files.forEach(function(file){
  4519. debug('file %s', file);
  4520. fs.watchFile(file, options, function(curr, prev){
  4521. if (prev.mtime < curr.mtime) fn(file);
  4522. });
  4523. });
  4524. };
  4525. /**
  4526. * Ignored files.
  4527. */
  4528. function ignored(path){
  4529. return !~ignore.indexOf(path);
  4530. }
  4531. /**
  4532. * Lookup files in the given `dir`.
  4533. *
  4534. * @return {Array}
  4535. * @api private
  4536. */
  4537. exports.files = function(dir, ret){
  4538. ret = ret || [];
  4539. fs.readdirSync(dir)
  4540. .filter(ignored)
  4541. .forEach(function(path){
  4542. path = join(dir, path);
  4543. if (fs.statSync(path).isDirectory()) {
  4544. exports.files(path, ret);
  4545. } else if (path.match(/\.(js|coffee|litcoffee|coffee.md)$/)) {
  4546. ret.push(path);
  4547. }
  4548. });
  4549. return ret;
  4550. };
  4551. /**
  4552. * Compute a slug from the given `str`.
  4553. *
  4554. * @param {String} str
  4555. * @return {String}
  4556. * @api private
  4557. */
  4558. exports.slug = function(str){
  4559. return str
  4560. .toLowerCase()
  4561. .replace(/ +/g, '-')
  4562. .replace(/[^-\w]/g, '');
  4563. };
  4564. /**
  4565. * Strip the function definition from `str`,
  4566. * and re-indent for pre whitespace.
  4567. */
  4568. exports.clean = function(str) {
  4569. str = str
  4570. .replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/^\uFEFF/, '')
  4571. .replace(/^function *\(.*\) *{/, '')
  4572. .replace(/\s+\}$/, '');
  4573. var spaces = str.match(/^\n?( *)/)[1].length
  4574. , tabs = str.match(/^\n?(\t*)/)[1].length
  4575. , re = new RegExp('^\n?' + (tabs ? '\t' : ' ') + '{' + (tabs ? tabs : spaces) + '}', 'gm');
  4576. str = str.replace(re, '');
  4577. return exports.trim(str);
  4578. };
  4579. /**
  4580. * Escape regular expression characters in `str`.
  4581. *
  4582. * @param {String} str
  4583. * @return {String}
  4584. * @api private
  4585. */
  4586. exports.escapeRegexp = function(str){
  4587. return str.replace(/[-\\^$*+?.()|[\]{}]/g, "\\$&");
  4588. };
  4589. /**
  4590. * Trim the given `str`.
  4591. *
  4592. * @param {String} str
  4593. * @return {String}
  4594. * @api private
  4595. */
  4596. exports.trim = function(str){
  4597. return str.replace(/^\s+|\s+$/g, '');
  4598. };
  4599. /**
  4600. * Parse the given `qs`.
  4601. *
  4602. * @param {String} qs
  4603. * @return {Object}
  4604. * @api private
  4605. */
  4606. exports.parseQuery = function(qs){
  4607. return exports.reduce(qs.replace('?', '').split('&'), function(obj, pair){
  4608. var i = pair.indexOf('=')
  4609. , key = pair.slice(0, i)
  4610. , val = pair.slice(++i);
  4611. obj[key] = decodeURIComponent(val);
  4612. return obj;
  4613. }, {});
  4614. };
  4615. /**
  4616. * Highlight the given string of `js`.
  4617. *
  4618. * @param {String} js
  4619. * @return {String}
  4620. * @api private
  4621. */
  4622. function highlight(js) {
  4623. return js
  4624. .replace(/</g, '&lt;')
  4625. .replace(/>/g, '&gt;')
  4626. .replace(/\/\/(.*)/gm, '<span class="comment">//$1</span>')
  4627. .replace(/('.*?')/gm, '<span class="string">$1</span>')
  4628. .replace(/(\d+\.\d+)/gm, '<span class="number">$1</span>')
  4629. .replace(/(\d+)/gm, '<span class="number">$1</span>')
  4630. .replace(/\bnew *(\w+)/gm, '<span class="keyword">new</span> <span class="init">$1</span>')
  4631. .replace(/\b(function|new|throw|return|var|if|else)\b/gm, '<span class="keyword">$1</span>')
  4632. }
  4633. /**
  4634. * Highlight the contents of tag `name`.
  4635. *
  4636. * @param {String} name
  4637. * @api private
  4638. */
  4639. exports.highlightTags = function(name) {
  4640. var code = document.getElementsByTagName(name);
  4641. for (var i = 0, len = code.length; i < len; ++i) {
  4642. code[i].innerHTML = highlight(code[i].innerHTML);
  4643. }
  4644. };
  4645. }); // module: utils.js
  4646. // The global object is "self" in Web Workers.
  4647. global = (function() { return this; })();
  4648. /**
  4649. * Save timer references to avoid Sinon interfering (see GH-237).
  4650. */
  4651. var Date = global.Date;
  4652. var setTimeout = global.setTimeout;
  4653. var setInterval = global.setInterval;
  4654. var clearTimeout = global.clearTimeout;
  4655. var clearInterval = global.clearInterval;
  4656. /**
  4657. * Node shims.
  4658. *
  4659. * These are meant only to allow
  4660. * mocha.js to run untouched, not
  4661. * to allow running node code in
  4662. * the browser.
  4663. */
  4664. var process = {};
  4665. process.exit = function(status){};
  4666. process.stdout = {};
  4667. var uncaughtExceptionHandlers = [];
  4668. /**
  4669. * Remove uncaughtException listener.
  4670. */
  4671. process.removeListener = function(e, fn){
  4672. if ('uncaughtException' == e) {
  4673. global.onerror = function() {};
  4674. var i = Mocha.utils.indexOf(uncaughtExceptionHandlers, fn);
  4675. if (i != -1) { uncaughtExceptionHandlers.splice(i, 1); }
  4676. }
  4677. };
  4678. /**
  4679. * Implements uncaughtException listener.
  4680. */
  4681. process.on = function(e, fn){
  4682. if ('uncaughtException' == e) {
  4683. global.onerror = function(err, url, line){
  4684. fn(new Error(err + ' (' + url + ':' + line + ')'));
  4685. return true;
  4686. };
  4687. uncaughtExceptionHandlers.push(fn);
  4688. }
  4689. };
  4690. /**
  4691. * Expose mocha.
  4692. */
  4693. var Mocha = global.Mocha = require('mocha'),
  4694. mocha = global.mocha = new Mocha({ reporter: 'html' });
  4695. // The BDD UI is registered by default, but no UI will be functional in the
  4696. // browser without an explicit call to the overridden `mocha.ui` (see below).
  4697. // Ensure that this default UI does not expose its methods to the global scope.
  4698. mocha.suite.removeAllListeners('pre-require');
  4699. var immediateQueue = []
  4700. , immediateTimeout;
  4701. function timeslice() {
  4702. var immediateStart = new Date().getTime();
  4703. while (immediateQueue.length && (new Date().getTime() - immediateStart) < 100) {
  4704. immediateQueue.shift()();
  4705. }
  4706. if (immediateQueue.length) {
  4707. immediateTimeout = setTimeout(timeslice, 0);
  4708. } else {
  4709. immediateTimeout = null;
  4710. }
  4711. }
  4712. /**
  4713. * High-performance override of Runner.immediately.
  4714. */
  4715. Mocha.Runner.immediately = function(callback) {
  4716. immediateQueue.push(callback);
  4717. if (!immediateTimeout) {
  4718. immediateTimeout = setTimeout(timeslice, 0);
  4719. }
  4720. };
  4721. /**
  4722. * Function to allow assertion libraries to throw errors directly into mocha.
  4723. * This is useful when running tests in a browser because window.onerror will
  4724. * only receive the 'message' attribute of the Error.
  4725. */
  4726. mocha.throwError = function(err) {
  4727. Mocha.utils.forEach(uncaughtExceptionHandlers, function (fn) {
  4728. fn(err);
  4729. });
  4730. throw err;
  4731. };
  4732. /**
  4733. * Override ui to ensure that the ui functions are initialized.
  4734. * Normally this would happen in Mocha.prototype.loadFiles.
  4735. */
  4736. mocha.ui = function(ui){
  4737. Mocha.prototype.ui.call(this, ui);
  4738. this.suite.emit('pre-require', global, null, this);
  4739. return this;
  4740. };
  4741. /**
  4742. * Setup mocha with the given setting options.
  4743. */
  4744. mocha.setup = function(opts){
  4745. if ('string' == typeof opts) opts = { ui: opts };
  4746. for (var opt in opts) this[opt](opts[opt]);
  4747. return this;
  4748. };
  4749. /**
  4750. * Run mocha, returning the Runner.
  4751. */
  4752. mocha.run = function(fn){
  4753. var options = mocha.options;
  4754. mocha.globals('location');
  4755. var query = Mocha.utils.parseQuery(global.location.search || '');
  4756. if (query.grep) mocha.grep(query.grep);
  4757. if (query.invert) mocha.invert();
  4758. return Mocha.prototype.run.call(mocha, function(){
  4759. // The DOM Document is not available in Web Workers.
  4760. if (global.document) {
  4761. Mocha.utils.highlightTags('code');
  4762. }
  4763. if (fn) fn();
  4764. });
  4765. };
  4766. /**
  4767. * Expose the process shim.
  4768. */
  4769. Mocha.process = process;
  4770. })();