Tizen 2.0 Release
[platform/framework/web/web-ui-fw.git] / libs / js / jquery-mobile-1.2.0 / node_modules / grunt / node_modules / nodeunit / examples / browser / nodeunit.js
1 /*!
2  * Nodeunit
3  * https://github.com/caolan/nodeunit
4  * Copyright (c) 2010 Caolan McMahon
5  * MIT Licensed
6  *
7  * json2.js
8  * http://www.JSON.org/json2.js
9  * Public Domain.
10  * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
11  */
12 nodeunit = (function(){
13 /*
14     http://www.JSON.org/json2.js
15     2010-11-17
16
17     Public Domain.
18
19     NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
20
21     See http://www.JSON.org/js.html
22
23
24     This code should be minified before deployment.
25     See http://javascript.crockford.com/jsmin.html
26
27     USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
28     NOT CONTROL.
29
30
31     This file creates a global JSON object containing two methods: stringify
32     and parse.
33
34         JSON.stringify(value, replacer, space)
35             value       any JavaScript value, usually an object or array.
36
37             replacer    an optional parameter that determines how object
38                         values are stringified for objects. It can be a
39                         function or an array of strings.
40
41             space       an optional parameter that specifies the indentation
42                         of nested structures. If it is omitted, the text will
43                         be packed without extra whitespace. If it is a number,
44                         it will specify the number of spaces to indent at each
45                         level. If it is a string (such as '\t' or ' '),
46                         it contains the characters used to indent at each level.
47
48             This method produces a JSON text from a JavaScript value.
49
50             When an object value is found, if the object contains a toJSON
51             method, its toJSON method will be called and the result will be
52             stringified. A toJSON method does not serialize: it returns the
53             value represented by the name/value pair that should be serialized,
54             or undefined if nothing should be serialized. The toJSON method
55             will be passed the key associated with the value, and this will be
56             bound to the value
57
58             For example, this would serialize Dates as ISO strings.
59
60                 Date.prototype.toJSON = function (key) {
61                     function f(n) {
62                         // Format integers to have at least two digits.
63                         return n < 10 ? '0' + n : n;
64                     }
65
66                     return this.getUTCFullYear()   + '-' +
67                          f(this.getUTCMonth() + 1) + '-' +
68                          f(this.getUTCDate())      + 'T' +
69                          f(this.getUTCHours())     + ':' +
70                          f(this.getUTCMinutes())   + ':' +
71                          f(this.getUTCSeconds())   + 'Z';
72                 };
73
74             You can provide an optional replacer method. It will be passed the
75             key and value of each member, with this bound to the containing
76             object. The value that is returned from your method will be
77             serialized. If your method returns undefined, then the member will
78             be excluded from the serialization.
79
80             If the replacer parameter is an array of strings, then it will be
81             used to select the members to be serialized. It filters the results
82             such that only members with keys listed in the replacer array are
83             stringified.
84
85             Values that do not have JSON representations, such as undefined or
86             functions, will not be serialized. Such values in objects will be
87             dropped; in arrays they will be replaced with null. You can use
88             a replacer function to replace those with JSON values.
89             JSON.stringify(undefined) returns undefined.
90
91             The optional space parameter produces a stringification of the
92             value that is filled with line breaks and indentation to make it
93             easier to read.
94
95             If the space parameter is a non-empty string, then that string will
96             be used for indentation. If the space parameter is a number, then
97             the indentation will be that many spaces.
98
99             Example:
100
101             text = JSON.stringify(['e', {pluribus: 'unum'}]);
102             // text is '["e",{"pluribus":"unum"}]'
103
104
105             text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
106             // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
107
108             text = JSON.stringify([new Date()], function (key, value) {
109                 return this[key] instanceof Date ?
110                     'Date(' + this[key] + ')' : value;
111             });
112             // text is '["Date(---current time---)"]'
113
114
115         JSON.parse(text, reviver)
116             This method parses a JSON text to produce an object or array.
117             It can throw a SyntaxError exception.
118
119             The optional reviver parameter is a function that can filter and
120             transform the results. It receives each of the keys and values,
121             and its return value is used instead of the original value.
122             If it returns what it received, then the structure is not modified.
123             If it returns undefined then the member is deleted.
124
125             Example:
126
127             // Parse the text. Values that look like ISO date strings will
128             // be converted to Date objects.
129
130             myData = JSON.parse(text, function (key, value) {
131                 var a;
132                 if (typeof value === 'string') {
133                     a =
134 /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
135                     if (a) {
136                         return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
137                             +a[5], +a[6]));
138                     }
139                 }
140                 return value;
141             });
142
143             myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
144                 var d;
145                 if (typeof value === 'string' &&
146                         value.slice(0, 5) === 'Date(' &&
147                         value.slice(-1) === ')') {
148                     d = new Date(value.slice(5, -1));
149                     if (d) {
150                         return d;
151                     }
152                 }
153                 return value;
154             });
155
156
157     This is a reference implementation. You are free to copy, modify, or
158     redistribute.
159 */
160
161 /*jslint evil: true, strict: false, regexp: false */
162
163 /*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
164     call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
165     getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
166     lastIndex, length, parse, prototype, push, replace, slice, stringify,
167     test, toJSON, toString, valueOf
168 */
169
170
171 // Create a JSON object only if one does not already exist. We create the
172 // methods in a closure to avoid creating global variables.
173
174 var JSON = {};
175
176 (function () {
177     "use strict";
178
179     function f(n) {
180         // Format integers to have at least two digits.
181         return n < 10 ? '0' + n : n;
182     }
183
184     if (typeof Date.prototype.toJSON !== 'function') {
185
186         Date.prototype.toJSON = function (key) {
187
188             return isFinite(this.valueOf()) ?
189                    this.getUTCFullYear()   + '-' +
190                  f(this.getUTCMonth() + 1) + '-' +
191                  f(this.getUTCDate())      + 'T' +
192                  f(this.getUTCHours())     + ':' +
193                  f(this.getUTCMinutes())   + ':' +
194                  f(this.getUTCSeconds())   + 'Z' : null;
195         };
196
197         String.prototype.toJSON =
198         Number.prototype.toJSON =
199         Boolean.prototype.toJSON = function (key) {
200             return this.valueOf();
201         };
202     }
203
204     var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
205         escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
206         gap,
207         indent,
208         meta = {    // table of character substitutions
209             '\b': '\\b',
210             '\t': '\\t',
211             '\n': '\\n',
212             '\f': '\\f',
213             '\r': '\\r',
214             '"' : '\\"',
215             '\\': '\\\\'
216         },
217         rep;
218
219
220     function quote(string) {
221
222 // If the string contains no control characters, no quote characters, and no
223 // backslash characters, then we can safely slap some quotes around it.
224 // Otherwise we must also replace the offending characters with safe escape
225 // sequences.
226
227         escapable.lastIndex = 0;
228         return escapable.test(string) ?
229             '"' + string.replace(escapable, function (a) {
230                 var c = meta[a];
231                 return typeof c === 'string' ? c :
232                     '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
233             }) + '"' :
234             '"' + string + '"';
235     }
236
237
238     function str(key, holder) {
239
240 // Produce a string from holder[key].
241
242         var i,          // The loop counter.
243             k,          // The member key.
244             v,          // The member value.
245             length,
246             mind = gap,
247             partial,
248             value = holder[key];
249
250 // If the value has a toJSON method, call it to obtain a replacement value.
251
252         if (value && typeof value === 'object' &&
253                 typeof value.toJSON === 'function') {
254             value = value.toJSON(key);
255         }
256
257 // If we were called with a replacer function, then call the replacer to
258 // obtain a replacement value.
259
260         if (typeof rep === 'function') {
261             value = rep.call(holder, key, value);
262         }
263
264 // What happens next depends on the value's type.
265
266         switch (typeof value) {
267         case 'string':
268             return quote(value);
269
270         case 'number':
271
272 // JSON numbers must be finite. Encode non-finite numbers as null.
273
274             return isFinite(value) ? String(value) : 'null';
275
276         case 'boolean':
277         case 'null':
278
279 // If the value is a boolean or null, convert it to a string. Note:
280 // typeof null does not produce 'null'. The case is included here in
281 // the remote chance that this gets fixed someday.
282
283             return String(value);
284
285 // If the type is 'object', we might be dealing with an object or an array or
286 // null.
287
288         case 'object':
289
290 // Due to a specification blunder in ECMAScript, typeof null is 'object',
291 // so watch out for that case.
292
293             if (!value) {
294                 return 'null';
295             }
296
297 // Make an array to hold the partial results of stringifying this object value.
298
299             gap += indent;
300             partial = [];
301
302 // Is the value an array?
303
304             if (Object.prototype.toString.apply(value) === '[object Array]') {
305
306 // The value is an array. Stringify every element. Use null as a placeholder
307 // for non-JSON values.
308
309                 length = value.length;
310                 for (i = 0; i < length; i += 1) {
311                     partial[i] = str(i, value) || 'null';
312                 }
313
314 // Join all of the elements together, separated with commas, and wrap them in
315 // brackets.
316
317                 v = partial.length === 0 ? '[]' :
318                     gap ? '[\n' + gap +
319                             partial.join(',\n' + gap) + '\n' +
320                                 mind + ']' :
321                           '[' + partial.join(',') + ']';
322                 gap = mind;
323                 return v;
324             }
325
326 // If the replacer is an array, use it to select the members to be stringified.
327
328             if (rep && typeof rep === 'object') {
329                 length = rep.length;
330                 for (i = 0; i < length; i += 1) {
331                     k = rep[i];
332                     if (typeof k === 'string') {
333                         v = str(k, value);
334                         if (v) {
335                             partial.push(quote(k) + (gap ? ': ' : ':') + v);
336                         }
337                     }
338                 }
339             } else {
340
341 // Otherwise, iterate through all of the keys in the object.
342
343                 for (k in value) {
344                     if (Object.hasOwnProperty.call(value, k)) {
345                         v = str(k, value);
346                         if (v) {
347                             partial.push(quote(k) + (gap ? ': ' : ':') + v);
348                         }
349                     }
350                 }
351             }
352
353 // Join all of the member texts together, separated with commas,
354 // and wrap them in braces.
355
356             v = partial.length === 0 ? '{}' :
357                 gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
358                         mind + '}' : '{' + partial.join(',') + '}';
359             gap = mind;
360             return v;
361         }
362     }
363
364 // If the JSON object does not yet have a stringify method, give it one.
365
366     if (typeof JSON.stringify !== 'function') {
367         JSON.stringify = function (value, replacer, space) {
368
369 // The stringify method takes a value and an optional replacer, and an optional
370 // space parameter, and returns a JSON text. The replacer can be a function
371 // that can replace values, or an array of strings that will select the keys.
372 // A default replacer method can be provided. Use of the space parameter can
373 // produce text that is more easily readable.
374
375             var i;
376             gap = '';
377             indent = '';
378
379 // If the space parameter is a number, make an indent string containing that
380 // many spaces.
381
382             if (typeof space === 'number') {
383                 for (i = 0; i < space; i += 1) {
384                     indent += ' ';
385                 }
386
387 // If the space parameter is a string, it will be used as the indent string.
388
389             } else if (typeof space === 'string') {
390                 indent = space;
391             }
392
393 // If there is a replacer, it must be a function or an array.
394 // Otherwise, throw an error.
395
396             rep = replacer;
397             if (replacer && typeof replacer !== 'function' &&
398                     (typeof replacer !== 'object' ||
399                      typeof replacer.length !== 'number')) {
400                 throw new Error('JSON.stringify');
401             }
402
403 // Make a fake root object containing our value under the key of ''.
404 // Return the result of stringifying the value.
405
406             return str('', {'': value});
407         };
408     }
409
410
411 // If the JSON object does not yet have a parse method, give it one.
412
413     if (typeof JSON.parse !== 'function') {
414         JSON.parse = function (text, reviver) {
415
416 // The parse method takes a text and an optional reviver function, and returns
417 // a JavaScript value if the text is a valid JSON text.
418
419             var j;
420
421             function walk(holder, key) {
422
423 // The walk method is used to recursively walk the resulting structure so
424 // that modifications can be made.
425
426                 var k, v, value = holder[key];
427                 if (value && typeof value === 'object') {
428                     for (k in value) {
429                         if (Object.hasOwnProperty.call(value, k)) {
430                             v = walk(value, k);
431                             if (v !== undefined) {
432                                 value[k] = v;
433                             } else {
434                                 delete value[k];
435                             }
436                         }
437                     }
438                 }
439                 return reviver.call(holder, key, value);
440             }
441
442
443 // Parsing happens in four stages. In the first stage, we replace certain
444 // Unicode characters with escape sequences. JavaScript handles many characters
445 // incorrectly, either silently deleting them, or treating them as line endings.
446
447             text = String(text);
448             cx.lastIndex = 0;
449             if (cx.test(text)) {
450                 text = text.replace(cx, function (a) {
451                     return '\\u' +
452                         ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
453                 });
454             }
455
456 // In the second stage, we run the text against regular expressions that look
457 // for non-JSON patterns. We are especially concerned with '()' and 'new'
458 // because they can cause invocation, and '=' because it can cause mutation.
459 // But just to be safe, we want to reject all unexpected forms.
460
461 // We split the second stage into 4 regexp operations in order to work around
462 // crippling inefficiencies in IE's and Safari's regexp engines. First we
463 // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
464 // replace all simple value tokens with ']' characters. Third, we delete all
465 // open brackets that follow a colon or comma or that begin the text. Finally,
466 // we look to see that the remaining characters are only whitespace or ']' or
467 // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
468
469             if (/^[\],:{}\s]*$/
470 .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
471 .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
472 .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
473
474 // In the third stage we use the eval function to compile the text into a
475 // JavaScript structure. The '{' operator is subject to a syntactic ambiguity
476 // in JavaScript: it can begin a block or an object literal. We wrap the text
477 // in parens to eliminate the ambiguity.
478
479                 j = eval('(' + text + ')');
480
481 // In the optional fourth stage, we recursively walk the new structure, passing
482 // each name/value pair to a reviver function for possible transformation.
483
484                 return typeof reviver === 'function' ?
485                     walk({'': j}, '') : j;
486             }
487
488 // If the text is not JSON parseable, then a SyntaxError is thrown.
489
490             throw new SyntaxError('JSON.parse');
491         };
492     }
493 }());
494 var assert = this.assert = {};
495 var types = {};
496 var core = {};
497 var nodeunit = {};
498 var reporter = {};
499 /*global setTimeout: false, console: false */
500 (function () {
501
502     var async = {};
503
504     // global on the server, window in the browser
505     var root = this,
506         previous_async = root.async;
507
508     if (typeof module !== 'undefined' && module.exports) {
509         module.exports = async;
510     }
511     else {
512         root.async = async;
513     }
514
515     async.noConflict = function () {
516         root.async = previous_async;
517         return async;
518     };
519
520     //// cross-browser compatiblity functions ////
521
522     var _forEach = function (arr, iterator) {
523         if (arr.forEach) {
524             return arr.forEach(iterator);
525         }
526         for (var i = 0; i < arr.length; i += 1) {
527             iterator(arr[i], i, arr);
528         }
529     };
530
531     var _map = function (arr, iterator) {
532         if (arr.map) {
533             return arr.map(iterator);
534         }
535         var results = [];
536         _forEach(arr, function (x, i, a) {
537             results.push(iterator(x, i, a));
538         });
539         return results;
540     };
541
542     var _reduce = function (arr, iterator, memo) {
543         if (arr.reduce) {
544             return arr.reduce(iterator, memo);
545         }
546         _forEach(arr, function (x, i, a) {
547             memo = iterator(memo, x, i, a);
548         });
549         return memo;
550     };
551
552     var _keys = function (obj) {
553         if (Object.keys) {
554             return Object.keys(obj);
555         }
556         var keys = [];
557         for (var k in obj) {
558             if (obj.hasOwnProperty(k)) {
559                 keys.push(k);
560             }
561         }
562         return keys;
563     };
564
565     var _indexOf = function (arr, item) {
566         if (arr.indexOf) {
567             return arr.indexOf(item);
568         }
569         for (var i = 0; i < arr.length; i += 1) {
570             if (arr[i] === item) {
571                 return i;
572             }
573         }
574         return -1;
575     };
576
577     //// exported async module functions ////
578
579     //// nextTick implementation with browser-compatible fallback ////
580     if (typeof process === 'undefined' || !(process.nextTick)) {
581         async.nextTick = function (fn) {
582             setTimeout(fn, 0);
583         };
584     }
585     else {
586         async.nextTick = process.nextTick;
587     }
588
589     async.forEach = function (arr, iterator, callback) {
590         if (!arr.length) {
591             return callback();
592         }
593         var completed = 0;
594         _forEach(arr, function (x) {
595             iterator(x, function (err) {
596                 if (err) {
597                     callback(err);
598                     callback = function () {};
599                 }
600                 else {
601                     completed += 1;
602                     if (completed === arr.length) {
603                         callback();
604                     }
605                 }
606             });
607         });
608     };
609
610     async.forEachSeries = function (arr, iterator, callback) {
611         if (!arr.length) {
612             return callback();
613         }
614         var completed = 0;
615         var iterate = function () {
616             iterator(arr[completed], function (err) {
617                 if (err) {
618                     callback(err);
619                     callback = function () {};
620                 }
621                 else {
622                     completed += 1;
623                     if (completed === arr.length) {
624                         callback();
625                     }
626                     else {
627                         iterate();
628                     }
629                 }
630             });
631         };
632         iterate();
633     };
634
635
636     var doParallel = function (fn) {
637         return function () {
638             var args = Array.prototype.slice.call(arguments);
639             return fn.apply(null, [async.forEach].concat(args));
640         };
641     };
642     var doSeries = function (fn) {
643         return function () {
644             var args = Array.prototype.slice.call(arguments);
645             return fn.apply(null, [async.forEachSeries].concat(args));
646         };
647     };
648
649
650     var _asyncMap = function (eachfn, arr, iterator, callback) {
651         var results = [];
652         arr = _map(arr, function (x, i) {
653             return {index: i, value: x};
654         });
655         eachfn(arr, function (x, callback) {
656             iterator(x.value, function (err, v) {
657                 results[x.index] = v;
658                 callback(err);
659             });
660         }, function (err) {
661             callback(err, results);
662         });
663     };
664     async.map = doParallel(_asyncMap);
665     async.mapSeries = doSeries(_asyncMap);
666
667
668     // reduce only has a series version, as doing reduce in parallel won't
669     // work in many situations.
670     async.reduce = function (arr, memo, iterator, callback) {
671         async.forEachSeries(arr, function (x, callback) {
672             iterator(memo, x, function (err, v) {
673                 memo = v;
674                 callback(err);
675             });
676         }, function (err) {
677             callback(err, memo);
678         });
679     };
680     // inject alias
681     async.inject = async.reduce;
682     // foldl alias
683     async.foldl = async.reduce;
684
685     async.reduceRight = function (arr, memo, iterator, callback) {
686         var reversed = _map(arr, function (x) {
687             return x;
688         }).reverse();
689         async.reduce(reversed, memo, iterator, callback);
690     };
691     // foldr alias
692     async.foldr = async.reduceRight;
693
694     var _filter = function (eachfn, arr, iterator, callback) {
695         var results = [];
696         arr = _map(arr, function (x, i) {
697             return {index: i, value: x};
698         });
699         eachfn(arr, function (x, callback) {
700             iterator(x.value, function (v) {
701                 if (v) {
702                     results.push(x);
703                 }
704                 callback();
705             });
706         }, function (err) {
707             callback(_map(results.sort(function (a, b) {
708                 return a.index - b.index;
709             }), function (x) {
710                 return x.value;
711             }));
712         });
713     };
714     async.filter = doParallel(_filter);
715     async.filterSeries = doSeries(_filter);
716     // select alias
717     async.select = async.filter;
718     async.selectSeries = async.filterSeries;
719
720     var _reject = function (eachfn, arr, iterator, callback) {
721         var results = [];
722         arr = _map(arr, function (x, i) {
723             return {index: i, value: x};
724         });
725         eachfn(arr, function (x, callback) {
726             iterator(x.value, function (v) {
727                 if (!v) {
728                     results.push(x);
729                 }
730                 callback();
731             });
732         }, function (err) {
733             callback(_map(results.sort(function (a, b) {
734                 return a.index - b.index;
735             }), function (x) {
736                 return x.value;
737             }));
738         });
739     };
740     async.reject = doParallel(_reject);
741     async.rejectSeries = doSeries(_reject);
742
743     var _detect = function (eachfn, arr, iterator, main_callback) {
744         eachfn(arr, function (x, callback) {
745             iterator(x, function (result) {
746                 if (result) {
747                     main_callback(x);
748                 }
749                 else {
750                     callback();
751                 }
752             });
753         }, function (err) {
754             main_callback();
755         });
756     };
757     async.detect = doParallel(_detect);
758     async.detectSeries = doSeries(_detect);
759
760     async.some = function (arr, iterator, main_callback) {
761         async.forEach(arr, function (x, callback) {
762             iterator(x, function (v) {
763                 if (v) {
764                     main_callback(true);
765                     main_callback = function () {};
766                 }
767                 callback();
768             });
769         }, function (err) {
770             main_callback(false);
771         });
772     };
773     // any alias
774     async.any = async.some;
775
776     async.every = function (arr, iterator, main_callback) {
777         async.forEach(arr, function (x, callback) {
778             iterator(x, function (v) {
779                 if (!v) {
780                     main_callback(false);
781                     main_callback = function () {};
782                 }
783                 callback();
784             });
785         }, function (err) {
786             main_callback(true);
787         });
788     };
789     // all alias
790     async.all = async.every;
791
792     async.sortBy = function (arr, iterator, callback) {
793         async.map(arr, function (x, callback) {
794             iterator(x, function (err, criteria) {
795                 if (err) {
796                     callback(err);
797                 }
798                 else {
799                     callback(null, {value: x, criteria: criteria});
800                 }
801             });
802         }, function (err, results) {
803             if (err) {
804                 return callback(err);
805             }
806             else {
807                 var fn = function (left, right) {
808                     var a = left.criteria, b = right.criteria;
809                     return a < b ? -1 : a > b ? 1 : 0;
810                 };
811                 callback(null, _map(results.sort(fn), function (x) {
812                     return x.value;
813                 }));
814             }
815         });
816     };
817
818     async.auto = function (tasks, callback) {
819         callback = callback || function () {};
820         var keys = _keys(tasks);
821         if (!keys.length) {
822             return callback(null);
823         }
824
825         var completed = [];
826
827         var listeners = [];
828         var addListener = function (fn) {
829             listeners.unshift(fn);
830         };
831         var removeListener = function (fn) {
832             for (var i = 0; i < listeners.length; i += 1) {
833                 if (listeners[i] === fn) {
834                     listeners.splice(i, 1);
835                     return;
836                 }
837             }
838         };
839         var taskComplete = function () {
840             _forEach(listeners, function (fn) {
841                 fn();
842             });
843         };
844
845         addListener(function () {
846             if (completed.length === keys.length) {
847                 callback(null);
848             }
849         });
850
851         _forEach(keys, function (k) {
852             var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k];
853             var taskCallback = function (err) {
854                 if (err) {
855                     callback(err);
856                     // stop subsequent errors hitting callback multiple times
857                     callback = function () {};
858                 }
859                 else {
860                     completed.push(k);
861                     taskComplete();
862                 }
863             };
864             var requires = task.slice(0, Math.abs(task.length - 1)) || [];
865             var ready = function () {
866                 return _reduce(requires, function (a, x) {
867                     return (a && _indexOf(completed, x) !== -1);
868                 }, true);
869             };
870             if (ready()) {
871                 task[task.length - 1](taskCallback);
872             }
873             else {
874                 var listener = function () {
875                     if (ready()) {
876                         removeListener(listener);
877                         task[task.length - 1](taskCallback);
878                     }
879                 };
880                 addListener(listener);
881             }
882         });
883     };
884
885     async.waterfall = function (tasks, callback) {
886         if (!tasks.length) {
887             return callback();
888         }
889         callback = callback || function () {};
890         var wrapIterator = function (iterator) {
891             return function (err) {
892                 if (err) {
893                     callback(err);
894                     callback = function () {};
895                 }
896                 else {
897                     var args = Array.prototype.slice.call(arguments, 1);
898                     var next = iterator.next();
899                     if (next) {
900                         args.push(wrapIterator(next));
901                     }
902                     else {
903                         args.push(callback);
904                     }
905                     async.nextTick(function () {
906                         iterator.apply(null, args);
907                     });
908                 }
909             };
910         };
911         wrapIterator(async.iterator(tasks))();
912     };
913
914     async.parallel = function (tasks, callback) {
915         callback = callback || function () {};
916         if (tasks.constructor === Array) {
917             async.map(tasks, function (fn, callback) {
918                 if (fn) {
919                     fn(function (err) {
920                         var args = Array.prototype.slice.call(arguments, 1);
921                         if (args.length <= 1) {
922                             args = args[0];
923                         }
924                         callback.call(null, err, args || null);
925                     });
926                 }
927             }, callback);
928         }
929         else {
930             var results = {};
931             async.forEach(_keys(tasks), function (k, callback) {
932                 tasks[k](function (err) {
933                     var args = Array.prototype.slice.call(arguments, 1);
934                     if (args.length <= 1) {
935                         args = args[0];
936                     }
937                     results[k] = args;
938                     callback(err);
939                 });
940             }, function (err) {
941                 callback(err, results);
942             });
943         }
944     };
945
946     async.series = function (tasks, callback) {
947         callback = callback || function () {};
948         if (tasks.constructor === Array) {
949             async.mapSeries(tasks, function (fn, callback) {
950                 if (fn) {
951                     fn(function (err) {
952                         var args = Array.prototype.slice.call(arguments, 1);
953                         if (args.length <= 1) {
954                             args = args[0];
955                         }
956                         callback.call(null, err, args || null);
957                     });
958                 }
959             }, callback);
960         }
961         else {
962             var results = {};
963             async.forEachSeries(_keys(tasks), function (k, callback) {
964                 tasks[k](function (err) {
965                     var args = Array.prototype.slice.call(arguments, 1);
966                     if (args.length <= 1) {
967                         args = args[0];
968                     }
969                     results[k] = args;
970                     callback(err);
971                 });
972             }, function (err) {
973                 callback(err, results);
974             });
975         }
976     };
977
978     async.iterator = function (tasks) {
979         var makeCallback = function (index) {
980             var fn = function () {
981                 if (tasks.length) {
982                     tasks[index].apply(null, arguments);
983                 }
984                 return fn.next();
985             };
986             fn.next = function () {
987                 return (index < tasks.length - 1) ? makeCallback(index + 1): null;
988             };
989             return fn;
990         };
991         return makeCallback(0);
992     };
993
994     async.apply = function (fn) {
995         var args = Array.prototype.slice.call(arguments, 1);
996         return function () {
997             return fn.apply(
998                 null, args.concat(Array.prototype.slice.call(arguments))
999             );
1000         };
1001     };
1002
1003     var _concat = function (eachfn, arr, fn, callback) {
1004         var r = [];
1005         eachfn(arr, function (x, cb) {
1006             fn(x, function (err, y) {
1007                 r = r.concat(y || []);
1008                 cb(err);
1009             });
1010         }, function (err) {
1011             callback(err, r);
1012         });
1013     };
1014     async.concat = doParallel(_concat);
1015     async.concatSeries = doSeries(_concat);
1016
1017     async.whilst = function (test, iterator, callback) {
1018         if (test()) {
1019             iterator(function (err) {
1020                 if (err) {
1021                     return callback(err);
1022                 }
1023                 async.whilst(test, iterator, callback);
1024             });
1025         }
1026         else {
1027             callback();
1028         }
1029     };
1030
1031     async.until = function (test, iterator, callback) {
1032         if (!test()) {
1033             iterator(function (err) {
1034                 if (err) {
1035                     return callback(err);
1036                 }
1037                 async.until(test, iterator, callback);
1038             });
1039         }
1040         else {
1041             callback();
1042         }
1043     };
1044
1045     async.queue = function (worker, concurrency) {
1046         var workers = 0;
1047         var tasks = [];
1048         var q = {
1049             concurrency: concurrency,
1050             push: function (data, callback) {
1051                 tasks.push({data: data, callback: callback});
1052                 async.nextTick(q.process);
1053             },
1054             process: function () {
1055                 if (workers < q.concurrency && tasks.length) {
1056                     var task = tasks.splice(0, 1)[0];
1057                     workers += 1;
1058                     worker(task.data, function () {
1059                         workers -= 1;
1060                         if (task.callback) {
1061                             task.callback.apply(task, arguments);
1062                         }
1063                         q.process();
1064                     });
1065                 }
1066             },
1067             length: function () {
1068                 return tasks.length;
1069             }
1070         };
1071         return q;
1072     };
1073
1074     var _console_fn = function (name) {
1075         return function (fn) {
1076             var args = Array.prototype.slice.call(arguments, 1);
1077             fn.apply(null, args.concat([function (err) {
1078                 var args = Array.prototype.slice.call(arguments, 1);
1079                 if (typeof console !== 'undefined') {
1080                     if (err) {
1081                         if (console.error) {
1082                             console.error(err);
1083                         }
1084                     }
1085                     else if (console[name]) {
1086                         _forEach(args, function (x) {
1087                             console[name](x);
1088                         });
1089                     }
1090                 }
1091             }]));
1092         };
1093     };
1094     async.log = _console_fn('log');
1095     async.dir = _console_fn('dir');
1096     /*async.info = _console_fn('info');
1097     async.warn = _console_fn('warn');
1098     async.error = _console_fn('error');*/
1099
1100     async.memoize = function (fn, hasher) {
1101         var memo = {};
1102         hasher = hasher || function (x) {
1103             return x;
1104         };
1105         return function () {
1106             var args = Array.prototype.slice.call(arguments);
1107             var callback = args.pop();
1108             var key = hasher.apply(null, args);
1109             if (key in memo) {
1110                 callback.apply(null, memo[key]);
1111             }
1112             else {
1113                 fn.apply(null, args.concat([function () {
1114                     memo[key] = arguments;
1115                     callback.apply(null, arguments);
1116                 }]));
1117             }
1118         };
1119     };
1120
1121 }());
1122 (function(exports){
1123 /**
1124  * This file is based on the node.js assert module, but with some small
1125  * changes for browser-compatibility
1126  * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS!
1127  */
1128
1129
1130 /**
1131  * Added for browser compatibility
1132  */
1133
1134 var _keys = function(obj){
1135     if(Object.keys) return Object.keys(obj);
1136     if (typeof obj != 'object' && typeof obj != 'function') {
1137         throw new TypeError('-');
1138     }
1139     var keys = [];
1140     for(var k in obj){
1141         if(obj.hasOwnProperty(k)) keys.push(k);
1142     }
1143     return keys;
1144 };
1145
1146
1147
1148 // http://wiki.commonjs.org/wiki/Unit_Testing/1.0
1149 //
1150 // THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!
1151 //
1152 // Originally from narwhal.js (http://narwhaljs.org)
1153 // Copyright (c) 2009 Thomas Robinson <280north.com>
1154 //
1155 // Permission is hereby granted, free of charge, to any person obtaining a copy
1156 // of this software and associated documentation files (the 'Software'), to
1157 // deal in the Software without restriction, including without limitation the
1158 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
1159 // sell copies of the Software, and to permit persons to whom the Software is
1160 // furnished to do so, subject to the following conditions:
1161 //
1162 // The above copyright notice and this permission notice shall be included in
1163 // all copies or substantial portions of the Software.
1164 //
1165 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1166 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1167 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1168 // AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
1169 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
1170 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1171
1172
1173 var pSlice = Array.prototype.slice;
1174
1175 // 1. The assert module provides functions that throw
1176 // AssertionError's when particular conditions are not met. The
1177 // assert module must conform to the following interface.
1178
1179 var assert = exports;
1180
1181 // 2. The AssertionError is defined in assert.
1182 // new assert.AssertionError({message: message, actual: actual, expected: expected})
1183
1184 assert.AssertionError = function AssertionError (options) {
1185   this.name = "AssertionError";
1186   this.message = options.message;
1187   this.actual = options.actual;
1188   this.expected = options.expected;
1189   this.operator = options.operator;
1190   var stackStartFunction = options.stackStartFunction || fail;
1191
1192   if (Error.captureStackTrace) {
1193     Error.captureStackTrace(this, stackStartFunction);
1194   }
1195 };
1196 // code from util.inherits in node
1197 assert.AssertionError.super_ = Error;
1198
1199
1200 // EDITED FOR BROWSER COMPATIBILITY: replaced Object.create call
1201 // TODO: test what effect this may have
1202 var ctor = function () { this.constructor = assert.AssertionError; };
1203 ctor.prototype = Error.prototype;
1204 assert.AssertionError.prototype = new ctor();
1205
1206
1207 assert.AssertionError.prototype.toString = function() {
1208   if (this.message) {
1209     return [this.name+":", this.message].join(' ');
1210   } else {
1211     return [ this.name+":"
1212            , JSON.stringify(this.expected )
1213            , this.operator
1214            , JSON.stringify(this.actual)
1215            ].join(" ");
1216   }
1217 };
1218
1219 // assert.AssertionError instanceof Error
1220
1221 assert.AssertionError.__proto__ = Error.prototype;
1222
1223 // At present only the three keys mentioned above are used and
1224 // understood by the spec. Implementations or sub modules can pass
1225 // other keys to the AssertionError's constructor - they will be
1226 // ignored.
1227
1228 // 3. All of the following functions must throw an AssertionError
1229 // when a corresponding condition is not met, with a message that
1230 // may be undefined if not provided.  All assertion methods provide
1231 // both the actual and expected values to the assertion error for
1232 // display purposes.
1233
1234 function fail(actual, expected, message, operator, stackStartFunction) {
1235   throw new assert.AssertionError({
1236     message: message,
1237     actual: actual,
1238     expected: expected,
1239     operator: operator,
1240     stackStartFunction: stackStartFunction
1241   });
1242 }
1243
1244 // EXTENSION! allows for well behaved errors defined elsewhere.
1245 assert.fail = fail;
1246
1247 // 4. Pure assertion tests whether a value is truthy, as determined
1248 // by !!guard.
1249 // assert.ok(guard, message_opt);
1250 // This statement is equivalent to assert.equal(true, guard,
1251 // message_opt);. To test strictly for the value true, use
1252 // assert.strictEqual(true, guard, message_opt);.
1253
1254 assert.ok = function ok(value, message) {
1255   if (!!!value) fail(value, true, message, "==", assert.ok);
1256 };
1257
1258 // 5. The equality assertion tests shallow, coercive equality with
1259 // ==.
1260 // assert.equal(actual, expected, message_opt);
1261
1262 assert.equal = function equal(actual, expected, message) {
1263   if (actual != expected) fail(actual, expected, message, "==", assert.equal);
1264 };
1265
1266 // 6. The non-equality assertion tests for whether two objects are not equal
1267 // with != assert.notEqual(actual, expected, message_opt);
1268
1269 assert.notEqual = function notEqual(actual, expected, message) {
1270   if (actual == expected) {
1271     fail(actual, expected, message, "!=", assert.notEqual);
1272   }
1273 };
1274
1275 // 7. The equivalence assertion tests a deep equality relation.
1276 // assert.deepEqual(actual, expected, message_opt);
1277
1278 assert.deepEqual = function deepEqual(actual, expected, message) {
1279   if (!_deepEqual(actual, expected)) {
1280     fail(actual, expected, message, "deepEqual", assert.deepEqual);
1281   }
1282 };
1283
1284 function _deepEqual(actual, expected) {
1285   // 7.1. All identical values are equivalent, as determined by ===.
1286   if (actual === expected) {
1287     return true;
1288   // 7.2. If the expected value is a Date object, the actual value is
1289   // equivalent if it is also a Date object that refers to the same time.
1290   } else if (actual instanceof Date && expected instanceof Date) {
1291     return actual.getTime() === expected.getTime();
1292
1293   // 7.3. Other pairs that do not both pass typeof value == "object",
1294   // equivalence is determined by ==.
1295   } else if (typeof actual != 'object' && typeof expected != 'object') {
1296     return actual == expected;
1297
1298   // 7.4. For all other Object pairs, including Array objects, equivalence is
1299   // determined by having the same number of owned properties (as verified
1300   // with Object.prototype.hasOwnProperty.call), the same set of keys
1301   // (although not necessarily the same order), equivalent values for every
1302   // corresponding key, and an identical "prototype" property. Note: this
1303   // accounts for both named and indexed properties on Arrays.
1304   } else {
1305     return objEquiv(actual, expected);
1306   }
1307 }
1308
1309 function isUndefinedOrNull (value) {
1310   return value === null || value === undefined;
1311 }
1312
1313 function isArguments (object) {
1314   return Object.prototype.toString.call(object) == '[object Arguments]';
1315 }
1316
1317 function objEquiv (a, b) {
1318   if (isUndefinedOrNull(a) || isUndefinedOrNull(b))
1319     return false;
1320   // an identical "prototype" property.
1321   if (a.prototype !== b.prototype) return false;
1322   //~~~I've managed to break Object.keys through screwy arguments passing.
1323   //   Converting to array solves the problem.
1324   if (isArguments(a)) {
1325     if (!isArguments(b)) {
1326       return false;
1327     }
1328     a = pSlice.call(a);
1329     b = pSlice.call(b);
1330     return _deepEqual(a, b);
1331   }
1332   try{
1333     var ka = _keys(a),
1334       kb = _keys(b),
1335       key, i;
1336   } catch (e) {//happens when one is a string literal and the other isn't
1337     return false;
1338   }
1339   // having the same number of owned properties (keys incorporates hasOwnProperty)
1340   if (ka.length != kb.length)
1341     return false;
1342   //the same set of keys (although not necessarily the same order),
1343   ka.sort();
1344   kb.sort();
1345   //~~~cheap key test
1346   for (i = ka.length - 1; i >= 0; i--) {
1347     if (ka[i] != kb[i])
1348       return false;
1349   }
1350   //equivalent values for every corresponding key, and
1351   //~~~possibly expensive deep test
1352   for (i = ka.length - 1; i >= 0; i--) {
1353     key = ka[i];
1354     if (!_deepEqual(a[key], b[key] ))
1355        return false;
1356   }
1357   return true;
1358 }
1359
1360 // 8. The non-equivalence assertion tests for any deep inequality.
1361 // assert.notDeepEqual(actual, expected, message_opt);
1362
1363 assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
1364   if (_deepEqual(actual, expected)) {
1365     fail(actual, expected, message, "notDeepEqual", assert.notDeepEqual);
1366   }
1367 };
1368
1369 // 9. The strict equality assertion tests strict equality, as determined by ===.
1370 // assert.strictEqual(actual, expected, message_opt);
1371
1372 assert.strictEqual = function strictEqual(actual, expected, message) {
1373   if (actual !== expected) {
1374     fail(actual, expected, message, "===", assert.strictEqual);
1375   }
1376 };
1377
1378 // 10. The strict non-equality assertion tests for strict inequality, as determined by !==.
1379 // assert.notStrictEqual(actual, expected, message_opt);
1380
1381 assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
1382   if (actual === expected) {
1383     fail(actual, expected, message, "!==", assert.notStrictEqual);
1384   }
1385 };
1386
1387 function _throws (shouldThrow, block, err, message) {
1388   var exception = null,
1389       threw = false,
1390       typematters = true;
1391
1392   message = message || "";
1393
1394   //handle optional arguments
1395   if (arguments.length == 3) {
1396     if (typeof(err) == "string") {
1397       message = err;
1398       typematters = false;
1399     }
1400   } else if (arguments.length == 2) {
1401     typematters = false;
1402   }
1403
1404   try {
1405     block();
1406   } catch (e) {
1407     threw = true;
1408     exception = e;
1409   }
1410
1411   if (shouldThrow && !threw) {
1412     fail( "Missing expected exception"
1413         + (err && err.name ? " ("+err.name+")." : '.')
1414         + (message ? " " + message : "")
1415         );
1416   }
1417   if (!shouldThrow && threw && typematters && exception instanceof err) {
1418     fail( "Got unwanted exception"
1419         + (err && err.name ? " ("+err.name+")." : '.')
1420         + (message ? " " + message : "")
1421         );
1422   }
1423   if ((shouldThrow && threw && typematters && !(exception instanceof err)) ||
1424       (!shouldThrow && threw)) {
1425     throw exception;
1426   }
1427 };
1428
1429 // 11. Expected to throw an error:
1430 // assert.throws(block, Error_opt, message_opt);
1431
1432 assert.throws = function(block, /*optional*/error, /*optional*/message) {
1433   _throws.apply(this, [true].concat(pSlice.call(arguments)));
1434 };
1435
1436 // EXTENSION! This is annoying to write outside this module.
1437 assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) {
1438   _throws.apply(this, [false].concat(pSlice.call(arguments)));
1439 };
1440
1441 assert.ifError = function (err) { if (err) {throw err;}};
1442 })(assert);
1443 (function(exports){
1444 /*!
1445  * Nodeunit
1446  * Copyright (c) 2010 Caolan McMahon
1447  * MIT Licensed
1448  *
1449  * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS!
1450  * You can use @REMOVE_LINE_FOR_BROWSER to remove code from the browser build.
1451  * Only code on that line will be removed, its mostly to avoid requiring code
1452  * that is node specific
1453  */
1454
1455 /**
1456  * Module dependencies
1457  */
1458
1459 //var assert = require('./assert'),     //@REMOVE_LINE_FOR_BROWSER
1460 //    async = require('../deps/async'); //@REMOVE_LINE_FOR_BROWSER
1461
1462
1463 /**
1464  * Creates assertion objects representing the result of an assert call.
1465  * Accepts an object or AssertionError as its argument.
1466  *
1467  * @param {object} obj
1468  * @api public
1469  */
1470
1471 exports.assertion = function (obj) {
1472     return {
1473         method: obj.method || '',
1474         message: obj.message || (obj.error && obj.error.message) || '',
1475         error: obj.error,
1476         passed: function () {
1477             return !this.error;
1478         },
1479         failed: function () {
1480             return Boolean(this.error);
1481         }
1482     };
1483 };
1484
1485 /**
1486  * Creates an assertion list object representing a group of assertions.
1487  * Accepts an array of assertion objects.
1488  *
1489  * @param {Array} arr
1490  * @param {Number} duration
1491  * @api public
1492  */
1493
1494 exports.assertionList = function (arr, duration) {
1495     var that = arr || [];
1496     that.failures = function () {
1497         var failures = 0;
1498         for (var i = 0; i < this.length; i += 1) {
1499             if (this[i].failed()) {
1500                 failures += 1;
1501             }
1502         }
1503         return failures;
1504     };
1505     that.passes = function () {
1506         return that.length - that.failures();
1507     };
1508     that.duration = duration || 0;
1509     return that;
1510 };
1511
1512 /**
1513  * Create a wrapper function for assert module methods. Executes a callback
1514  * after the it's complete with an assertion object representing the result.
1515  *
1516  * @param {Function} callback
1517  * @api private
1518  */
1519
1520 var assertWrapper = function (callback) {
1521     return function (new_method, assert_method, arity) {
1522         return function () {
1523             var message = arguments[arity - 1];
1524             var a = exports.assertion({method: new_method, message: message});
1525             try {
1526                 assert[assert_method].apply(null, arguments);
1527             }
1528             catch (e) {
1529                 a.error = e;
1530             }
1531             callback(a);
1532         };
1533     };
1534 };
1535
1536 /**
1537  * Creates the 'test' object that gets passed to every test function.
1538  * Accepts the name of the test function as its first argument, followed by
1539  * the start time in ms, the options object and a callback function.
1540  *
1541  * @param {String} name
1542  * @param {Number} start
1543  * @param {Object} options
1544  * @param {Function} callback
1545  * @api public
1546  */
1547
1548 exports.test = function (name, start, options, callback) {
1549     var expecting;
1550     var a_list = [];
1551
1552     var wrapAssert = assertWrapper(function (a) {
1553         a_list.push(a);
1554         if (options.log) {
1555             async.nextTick(function () {
1556                 options.log(a);
1557             });
1558         }
1559     });
1560
1561     var test = {
1562         done: function (err) {
1563             if (expecting !== undefined && expecting !== a_list.length) {
1564                 var e = new Error(
1565                     'Expected ' + expecting + ' assertions, ' +
1566                     a_list.length + ' ran'
1567                 );
1568                 var a1 = exports.assertion({method: 'expect', error: e});
1569                 a_list.push(a1);
1570                 if (options.log) {
1571                     async.nextTick(function () {
1572                         options.log(a1);
1573                     });
1574                 }
1575             }
1576             if (err) {
1577                 var a2 = exports.assertion({error: err});
1578                 a_list.push(a2);
1579                 if (options.log) {
1580                     async.nextTick(function () {
1581                         options.log(a2);
1582                     });
1583                 }
1584             }
1585             var end = new Date().getTime();
1586             async.nextTick(function () {
1587                 var assertion_list = exports.assertionList(a_list, end - start);
1588                 options.testDone(name, assertion_list);
1589                 callback(null, a_list);
1590             });
1591         },
1592         ok: wrapAssert('ok', 'ok', 2),
1593         same: wrapAssert('same', 'deepEqual', 3),
1594         equals: wrapAssert('equals', 'equal', 3),
1595         expect: function (num) {
1596             expecting = num;
1597         },
1598         _assertion_list: a_list
1599     };
1600     // add all functions from the assert module
1601     for (var k in assert) {
1602         if (assert.hasOwnProperty(k)) {
1603             test[k] = wrapAssert(k, k, assert[k].length);
1604         }
1605     }
1606     return test;
1607 };
1608
1609 /**
1610  * Ensures an options object has all callbacks, adding empty callback functions
1611  * if any are missing.
1612  *
1613  * @param {Object} opt
1614  * @return {Object}
1615  * @api public
1616  */
1617
1618 exports.options = function (opt) {
1619     var optionalCallback = function (name) {
1620         opt[name] = opt[name] || function () {};
1621     };
1622
1623     optionalCallback('moduleStart');
1624     optionalCallback('moduleDone');
1625     optionalCallback('testStart');
1626     optionalCallback('testDone');
1627     //optionalCallback('log');
1628
1629     // 'done' callback is not optional.
1630
1631     return opt;
1632 };
1633 })(types);
1634 (function(exports){
1635 /*!
1636  * Nodeunit
1637  * Copyright (c) 2010 Caolan McMahon
1638  * MIT Licensed
1639  *
1640  * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS!
1641  * You can use @REMOVE_LINE_FOR_BROWSER to remove code from the browser build.
1642  * Only code on that line will be removed, its mostly to avoid requiring code
1643  * that is node specific
1644  */
1645
1646 /**
1647  * Module dependencies
1648  */
1649
1650 //var async = require('../deps/async'), //@REMOVE_LINE_FOR_BROWSER
1651 //    types = require('./types');       //@REMOVE_LINE_FOR_BROWSER
1652
1653
1654 /**
1655  * Added for browser compatibility
1656  */
1657
1658 var _keys = function (obj) {
1659     if (Object.keys) {
1660         return Object.keys(obj);
1661     }
1662     var keys = [];
1663     for (var k in obj) {
1664         if (obj.hasOwnProperty(k)) {
1665             keys.push(k);
1666         }
1667     }
1668     return keys;
1669 };
1670
1671
1672 var _copy = function (obj) {
1673     var nobj = {};
1674     var keys = _keys(obj);
1675     for (var i = 0; i <  keys.length; i += 1) {
1676         nobj[keys[i]] = obj[keys[i]];
1677     }
1678     return nobj;
1679 };
1680
1681
1682 /**
1683  * Runs a test function (fn) from a loaded module. After the test function
1684  * calls test.done(), the callback is executed with an assertionList as its
1685  * second argument.
1686  *
1687  * @param {String} name
1688  * @param {Function} fn
1689  * @param {Object} opt
1690  * @param {Function} callback
1691  * @api public
1692  */
1693
1694 exports.runTest = function (name, fn, opt, callback) {
1695     var options = types.options(opt);
1696
1697     options.testStart(name);
1698     var start = new Date().getTime();
1699     var test = types.test(name, start, options, callback);
1700
1701     try {
1702         fn(test);
1703     }
1704     catch (e) {
1705         test.done(e);
1706     }
1707 };
1708
1709 /**
1710  * Takes an object containing test functions or other test suites as properties
1711  * and runs each in series. After all tests have completed, the callback is
1712  * called with a list of all assertions as the second argument.
1713  *
1714  * If a name is passed to this function it is prepended to all test and suite
1715  * names that run within it.
1716  *
1717  * @param {String} name
1718  * @param {Object} suite
1719  * @param {Object} opt
1720  * @param {Function} callback
1721  * @api public
1722  */
1723
1724 exports.runSuite = function (name, suite, opt, callback) {
1725     var keys = _keys(suite);
1726
1727     async.concatSeries(keys, function (k, cb) {
1728         var prop = suite[k], _name;
1729
1730         _name = name ? [].concat(name, k) : [k];
1731
1732         _name.toString = function () {
1733             // fallback for old one
1734             return this.join(' - ');
1735         };
1736
1737         if (typeof prop === 'function') {
1738             var in_name = false;
1739             for (var i = 0; i < _name.length; i += 1) {
1740                 if (_name[i] === opt.testspec) {
1741                     in_name = true;
1742                 }
1743             }
1744             if (!opt.testspec || in_name) {
1745                 if (opt.moduleStart) {
1746                     opt.moduleStart();
1747                 }
1748                 exports.runTest(_name, suite[k], opt, cb);
1749             }
1750             else {
1751                 return cb();
1752             }
1753         }
1754         else {
1755             exports.runSuite(_name, suite[k], opt, cb);
1756         }
1757     }, callback);
1758 };
1759
1760 /**
1761  * Run each exported test function or test suite from a loaded module.
1762  *
1763  * @param {String} name
1764  * @param {Object} mod
1765  * @param {Object} opt
1766  * @param {Function} callback
1767  * @api public
1768  */
1769
1770 exports.runModule = function (name, mod, opt, callback) {
1771     var options = _copy(types.options(opt));
1772
1773     var _run = false;
1774     var _moduleStart = options.moduleStart;
1775     function run_once() {
1776         if (!_run) {
1777             _run = true;
1778             _moduleStart(name);
1779         }
1780     }
1781     options.moduleStart = run_once;
1782
1783     var start = new Date().getTime();
1784
1785     exports.runSuite(null, mod, options, function (err, a_list) {
1786         var end = new Date().getTime();
1787         var assertion_list = types.assertionList(a_list, end - start);
1788         options.moduleDone(name, assertion_list);
1789         callback(null, a_list);
1790     });
1791 };
1792
1793 /**
1794  * Treats an object literal as a list of modules keyed by name. Runs each
1795  * module and finished with calling 'done'. You can think of this as a browser
1796  * safe alternative to runFiles in the nodeunit module.
1797  *
1798  * @param {Object} modules
1799  * @param {Object} opt
1800  * @api public
1801  */
1802
1803 // TODO: add proper unit tests for this function
1804 exports.runModules = function (modules, opt) {
1805     var all_assertions = [];
1806     var options = types.options(opt);
1807     var start = new Date().getTime();
1808
1809     async.concatSeries(_keys(modules), function (k, cb) {
1810         exports.runModule(k, modules[k], options, cb);
1811     },
1812     function (err, all_assertions) {
1813         var end = new Date().getTime();
1814         options.done(types.assertionList(all_assertions, end - start));
1815     });
1816 };
1817
1818
1819 /**
1820  * Wraps a test function with setUp and tearDown functions.
1821  * Used by testCase.
1822  *
1823  * @param {Function} setUp
1824  * @param {Function} tearDown
1825  * @param {Function} fn
1826  * @api private
1827  */
1828
1829 var wrapTest = function (setUp, tearDown, fn) {
1830     return function (test) {
1831         var context = {};
1832         if (tearDown) {
1833             var done = test.done;
1834             test.done = function (err) {
1835                 try {
1836                     tearDown.call(context, function (err2) {
1837                         if (err && err2) {
1838                             test._assertion_list.push(
1839                                 types.assertion({error: err})
1840                             );
1841                             return done(err2);
1842                         }
1843                         done(err || err2);
1844                     });
1845                 }
1846                 catch (e) {
1847                     done(e);
1848                 }
1849             };
1850         }
1851         if (setUp) {
1852             setUp.call(context, function (err) {
1853                 if (err) {
1854                     return test.done(err);
1855                 }
1856                 fn.call(context, test);
1857             });
1858         }
1859         else {
1860             fn.call(context, test);
1861         }
1862     };
1863 };
1864
1865
1866 /**
1867  * Wraps a group of tests with setUp and tearDown functions.
1868  * Used by testCase.
1869  *
1870  * @param {Function} setUp
1871  * @param {Function} tearDown
1872  * @param {Object} group
1873  * @api private
1874  */
1875
1876 var wrapGroup = function (setUp, tearDown, group) {
1877     var tests = {};
1878     var keys = _keys(group);
1879     for (var i = 0; i < keys.length; i += 1) {
1880         var k = keys[i];
1881         if (typeof group[k] === 'function') {
1882             tests[k] = wrapTest(setUp, tearDown, group[k]);
1883         }
1884         else if (typeof group[k] === 'object') {
1885             tests[k] = wrapGroup(setUp, tearDown, group[k]);
1886         }
1887     }
1888     return tests;
1889 };
1890
1891
1892 /**
1893  * Utility for wrapping a suite of test functions with setUp and tearDown
1894  * functions.
1895  *
1896  * @param {Object} suite
1897  * @return {Object}
1898  * @api public
1899  */
1900
1901 exports.testCase = function (suite) {
1902     var setUp = suite.setUp;
1903     var tearDown = suite.tearDown;
1904     delete suite.setUp;
1905     delete suite.tearDown;
1906     return wrapGroup(setUp, tearDown, suite);
1907 };
1908 })(core);
1909 (function(exports){
1910 /*!
1911  * Nodeunit
1912  * Copyright (c) 2010 Caolan McMahon
1913  * MIT Licensed
1914  *
1915  * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS!
1916  * You can use @REMOVE_LINE_FOR_BROWSER to remove code from the browser build.
1917  * Only code on that line will be removed, its mostly to avoid requiring code
1918  * that is node specific
1919  */
1920
1921
1922 /**
1923  * NOTE: this test runner is not listed in index.js because it cannot be
1924  * used with the command-line tool, only inside the browser.
1925  */
1926
1927
1928 /**
1929  * Reporter info string
1930  */
1931
1932 exports.info = "Browser-based test reporter";
1933
1934
1935 /**
1936  * Run all tests within each module, reporting the results
1937  *
1938  * @param {Array} files
1939  * @api public
1940  */
1941
1942 exports.run = function (modules, options) {
1943     var start = new Date().getTime();
1944
1945     function setText(el, txt) {
1946         if ('innerText' in el) {
1947             el.innerText = txt;
1948         }
1949         else if ('textContent' in el){
1950             el.textContent = txt;
1951         }
1952     }
1953
1954     function getOrCreate(tag, id) {
1955         var el = document.getElementById(id);
1956         if (!el) {
1957             el = document.createElement(tag);
1958             el.id = id;
1959             document.body.appendChild(el);
1960         }
1961         return el;
1962     };
1963
1964     var header = getOrCreate('h1', 'nodeunit-header');
1965     var banner = getOrCreate('h2', 'nodeunit-banner');
1966     var userAgent = getOrCreate('h2', 'nodeunit-userAgent');
1967     var tests = getOrCreate('ol', 'nodeunit-tests');
1968     var result = getOrCreate('p', 'nodeunit-testresult');
1969
1970     setText(userAgent, navigator.userAgent);
1971
1972     nodeunit.runModules(modules, {
1973         moduleStart: function (name) {
1974             /*var mheading = document.createElement('h2');
1975             mheading.innerText = name;
1976             results.appendChild(mheading);
1977             module = document.createElement('ol');
1978             results.appendChild(module);*/
1979         },
1980         testDone: function (name, assertions) {
1981             var test = document.createElement('li');
1982             var strong = document.createElement('strong');
1983             strong.innerHTML = name + ' <b style="color: black;">(' +
1984                 '<b class="fail">' + assertions.failures() + '</b>, ' +
1985                 '<b class="pass">' + assertions.passes() + '</b>, ' +
1986                 assertions.length +
1987             ')</b>';
1988             test.className = assertions.failures() ? 'fail': 'pass';
1989             test.appendChild(strong);
1990
1991             var aList = document.createElement('ol');
1992             aList.style.display = 'none';
1993             test.onclick = function () {
1994                 var d = aList.style.display;
1995                 aList.style.display = (d == 'none') ? 'block': 'none';
1996             };
1997             for (var i=0; i<assertions.length; i++) {
1998                 var li = document.createElement('li');
1999                 var a = assertions[i];
2000                 if (a.failed()) {
2001                     li.innerHTML = (a.message || a.method || 'no message') +
2002                         '<pre>' + (a.error.stack || a.error) + '</pre>';
2003                     li.className = 'fail';
2004                 }
2005                 else {
2006                     li.innerHTML = a.message || a.method || 'no message';
2007                     li.className = 'pass';
2008                 }
2009                 aList.appendChild(li);
2010             }
2011             test.appendChild(aList);
2012             tests.appendChild(test);
2013         },
2014         done: function (assertions) {
2015             var end = new Date().getTime();
2016             var duration = end - start;
2017
2018             var failures = assertions.failures();
2019             banner.className = failures ? 'fail': 'pass';
2020
2021             result.innerHTML = 'Tests completed in ' + duration +
2022                 ' milliseconds.<br/><span class="passed">' +
2023                 assertions.passes() + '</span> assertions of ' +
2024                 '<span class="all">' + assertions.length + '<span> passed, ' +
2025                 assertions.failures() + ' failed.';
2026         }
2027     });
2028 };
2029 })(reporter);
2030 nodeunit = core;
2031 nodeunit.assert = assert;
2032 nodeunit.reporter = reporter;
2033 nodeunit.run = reporter.run;
2034 return nodeunit; })();