mocha.js 86 KB

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