mocha.js 95 KB

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