jasmine 1.0.2.0 → 1.0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. data/HOW_TO_TEST.markdown +4 -6
  2. data/generators/jasmine/templates/lib/tasks/jasmine.rake +8 -2
  3. data/generators/jasmine/templates/spec/javascripts/support/jasmine-rails.yml +1 -1
  4. data/jasmine.gemspec +4 -5
  5. data/jasmine/Gemfile +2 -2
  6. data/jasmine/HowToRelease.markdown +29 -0
  7. data/jasmine/MIT.LICENSE +1 -1
  8. data/jasmine/README.markdown +37 -15
  9. data/jasmine/Rakefile +42 -58
  10. data/jasmine/example/spec/SpecHelper.js +3 -3
  11. data/jasmine/images/jasmine_favicon.png +0 -0
  12. data/jasmine/jshint/jshint.js +5919 -0
  13. data/jasmine/jshint/run.js +98 -0
  14. data/jasmine/lib/jasmine-html.js +5 -3
  15. data/jasmine/lib/jasmine.js +56 -32
  16. data/jasmine/spec/node_suite.js +233 -0
  17. data/jasmine/spec/runner.html +4 -2
  18. data/jasmine/spec/suites/EnvSpec.js +1 -1
  19. data/jasmine/spec/suites/ExceptionsSpec.js +2 -2
  20. data/jasmine/spec/suites/JsApiReporterSpec.js +1 -1
  21. data/jasmine/spec/suites/MatchersSpec.js +9 -9
  22. data/jasmine/spec/suites/MultiReporterSpec.js +3 -3
  23. data/jasmine/spec/suites/SpecRunningSpec.js +1 -1
  24. data/jasmine/spec/suites/SpecSpec.js +1 -1
  25. data/jasmine/spec/suites/TrivialConsoleReporterSpec.js +431 -0
  26. data/jasmine/spec/suites/UtilSpec.js +0 -1
  27. data/jasmine/spec/suites/WaitsForBlockSpec.js +32 -1
  28. data/jasmine/src/Env.js +2 -2
  29. data/jasmine/src/Matchers.js +3 -3
  30. data/jasmine/src/PrettyPrinter.js +2 -1
  31. data/jasmine/src/WaitsBlock.js +3 -1
  32. data/jasmine/src/WaitsForBlock.js +4 -2
  33. data/jasmine/src/base.js +39 -20
  34. data/jasmine/src/console/TrivialConsoleReporter.js +144 -0
  35. data/jasmine/src/html/TrivialReporter.js +5 -3
  36. data/jasmine/src/util.js +1 -1
  37. data/jasmine/src/version.json +2 -2
  38. data/lib/generators/jasmine/install/templates/spec/javascripts/support/jasmine.yml +1 -1
  39. data/lib/generators/jasmine/templates/spec/javascripts/support/jasmine-rails.yml +1 -1
  40. data/lib/jasmine.rb +1 -20
  41. data/lib/jasmine/railtie.rb +20 -0
  42. data/lib/jasmine/run.html.erb +2 -1
  43. data/lib/jasmine/version.rb +2 -2
  44. data/spec/spec_helper.rb +0 -2
  45. metadata +16 -58
  46. data/install.rb +0 -2
  47. data/jasmine/images/fail-16.png +0 -0
  48. data/jasmine/images/fail.png +0 -0
  49. data/jasmine/images/go-16.png +0 -0
  50. data/jasmine/images/go.png +0 -0
  51. data/jasmine/images/pending-16.png +0 -0
  52. data/jasmine/images/pending.png +0 -0
  53. data/jasmine/images/question-bk.png +0 -0
  54. data/jasmine/images/questionbk-16.png +0 -0
  55. data/jasmine/images/spinner.gif +0 -0
  56. data/lib/jasmine/generator.rb +0 -9
@@ -25,7 +25,6 @@ describe("jasmine.util", function() {
25
25
  it("should return true if the argument is an array", function() {
26
26
  expect(jasmine.isArray_([])).toBe(true);
27
27
  expect(jasmine.isArray_(['a'])).toBe(true);
28
- expect(jasmine.isArray_(new Array())).toBe(true);
29
28
  });
30
29
 
31
30
  it("should return false if the argument is not an array", function() {
@@ -10,6 +10,37 @@ describe('WaitsForBlock', function () {
10
10
  onComplete = jasmine.createSpy("onComplete");
11
11
  });
12
12
 
13
+ describe("jasmine.VERBOSE", function() {
14
+ var jasmineVerboseOriginal;
15
+ beforeEach(function() {
16
+ jasmineVerboseOriginal = jasmine.VERBOSE;
17
+ spyOn(env.reporter, 'log');
18
+
19
+ });
20
+ it('do not show information if jasmine.VERBOSE is set to false', function () {
21
+ jasmine.VERBOSE = false;
22
+ var latchFunction = function() {
23
+ return true;
24
+ };
25
+ var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
26
+ expect(env.reporter.log).not.toHaveBeenCalled();
27
+ block.execute(onComplete);
28
+ expect(env.reporter.log).not.toHaveBeenCalled();
29
+ jasmine.VERBOSE = jasmineVerboseOriginal;
30
+ });
31
+ it('show information if jasmine.VERBOSE is set to true', function () {
32
+ jasmine.VERBOSE = true;
33
+ var latchFunction = function() {
34
+ return true;
35
+ };
36
+ var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
37
+ expect(env.reporter.log).not.toHaveBeenCalled();
38
+ block.execute(onComplete);
39
+ expect(env.reporter.log).toHaveBeenCalled();
40
+ jasmine.VERBOSE = jasmineVerboseOriginal;
41
+ });
42
+ });
43
+
13
44
  it('onComplete should be called if the latchFunction returns true', function () {
14
45
  var latchFunction = function() {
15
46
  return true;
@@ -84,4 +115,4 @@ describe('WaitsForBlock', function () {
84
115
  expect(onComplete).toHaveBeenCalled();
85
116
  });
86
117
  });
87
- });
118
+ });
data/jasmine/src/Env.js CHANGED
@@ -172,7 +172,7 @@ jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchVal
172
172
  b.__Jasmine_been_here_before__ = a;
173
173
 
174
174
  var hasKey = function(obj, keyName) {
175
- return obj != null && obj[keyName] !== jasmine.undefined;
175
+ return obj !== null && obj[keyName] !== jasmine.undefined;
176
176
  };
177
177
 
178
178
  for (var property in b) {
@@ -198,7 +198,7 @@ jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchVal
198
198
 
199
199
  delete a.__Jasmine_been_here_before__;
200
200
  delete b.__Jasmine_been_here_before__;
201
- return (mismatchKeys.length == 0 && mismatchValues.length == 0);
201
+ return (mismatchKeys.length === 0 && mismatchValues.length === 0);
202
202
  };
203
203
 
204
204
  jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {
@@ -227,7 +227,7 @@ jasmine.Matchers.prototype.toHaveBeenCalledWith = function() {
227
227
  throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
228
228
  }
229
229
  this.message = function() {
230
- if (this.actual.callCount == 0) {
230
+ if (this.actual.callCount === 0) {
231
231
  // todo: what should the failure message for .not.toHaveBeenCalledWith() be? is this right? test better. [xw]
232
232
  return [
233
233
  "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.",
@@ -258,7 +258,7 @@ jasmine.Matchers.prototype.wasNotCalledWith = function() {
258
258
  return [
259
259
  "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was",
260
260
  "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was"
261
- ]
261
+ ];
262
262
  };
263
263
 
264
264
  return !this.env.contains_(this.actual.argsForCall, expectedArgs);
@@ -315,7 +315,7 @@ jasmine.Matchers.prototype.toThrow = function(expected) {
315
315
 
316
316
  this.message = function() {
317
317
  if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) {
318
- return ["Expected function " + not + "to throw", expected ? expected.message || expected : " an exception", ", but it threw", exception.message || exception].join(' ');
318
+ return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' ');
319
319
  } else {
320
320
  return "Expected function to throw an exception.";
321
321
  }
@@ -58,7 +58,8 @@ jasmine.PrettyPrinter.prototype.format = function(value) {
58
58
  jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) {
59
59
  for (var property in obj) {
60
60
  if (property == '__Jasmine_been_here_before__') continue;
61
- fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) != null) : false);
61
+ fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined &&
62
+ obj.__lookupGetter__(property) !== null) : false);
62
63
  }
63
64
  };
64
65
 
@@ -6,7 +6,9 @@ jasmine.WaitsBlock = function(env, timeout, spec) {
6
6
  jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block);
7
7
 
8
8
  jasmine.WaitsBlock.prototype.execute = function (onComplete) {
9
- this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...');
9
+ if (jasmine.VERBOSE) {
10
+ this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...');
11
+ }
10
12
  this.env.setTimeout(function () {
11
13
  onComplete();
12
14
  }, this.timeout);
@@ -21,7 +21,9 @@ jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block);
21
21
  jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10;
22
22
 
23
23
  jasmine.WaitsForBlock.prototype.execute = function(onComplete) {
24
- this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen'));
24
+ if (jasmine.VERBOSE) {
25
+ this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen'));
26
+ }
25
27
  var latchFunctionResult;
26
28
  try {
27
29
  latchFunctionResult = this.latchFunction.apply(this.spec);
@@ -49,4 +51,4 @@ jasmine.WaitsForBlock.prototype.execute = function(onComplete) {
49
51
  self.execute(onComplete);
50
52
  }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT);
51
53
  }
52
- };
54
+ };
data/jasmine/src/base.js CHANGED
@@ -1,10 +1,12 @@
1
+ var isCommonJS = typeof window == "undefined";
2
+
1
3
  /**
2
4
  * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework.
3
5
  *
4
6
  * @namespace
5
7
  */
6
8
  var jasmine = {};
7
-
9
+ if (isCommonJS) exports.jasmine = jasmine;
8
10
  /**
9
11
  * @private
10
12
  */
@@ -20,6 +22,12 @@ jasmine.unimplementedMethod_ = function() {
20
22
  */
21
23
  jasmine.undefined = jasmine.___undefined___;
22
24
 
25
+ /**
26
+ * Show diagnostic messages in the console if set to true
27
+ *
28
+ */
29
+ jasmine.VERBOSE = false;
30
+
23
31
  /**
24
32
  * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed.
25
33
  *
@@ -106,7 +114,8 @@ jasmine.ExpectationResult.prototype.passed = function () {
106
114
  * Getter for the Jasmine environment. Ensures one gets created
107
115
  */
108
116
  jasmine.getEnv = function() {
109
- return jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env();
117
+ var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env();
118
+ return env;
110
119
  };
111
120
 
112
121
  /**
@@ -169,7 +178,7 @@ jasmine.pp = function(value) {
169
178
  * @returns {Boolean}
170
179
  */
171
180
  jasmine.isDomNode = function(obj) {
172
- return obj['nodeType'] > 0;
181
+ return obj.nodeType > 0;
173
182
  };
174
183
 
175
184
  /**
@@ -405,7 +414,7 @@ jasmine.isSpy = function(putativeSpy) {
405
414
  * @param {Array} methodNames array of names of methods to make spies
406
415
  */
407
416
  jasmine.createSpyObj = function(baseName, methodNames) {
408
- if (!jasmine.isArray_(methodNames) || methodNames.length == 0) {
417
+ if (!jasmine.isArray_(methodNames) || methodNames.length === 0) {
409
418
  throw new Error('createSpyObj requires a non-empty array of method names to create spies for');
410
419
  }
411
420
  var obj = {};
@@ -443,6 +452,7 @@ jasmine.log = function() {
443
452
  var spyOn = function(obj, methodName) {
444
453
  return jasmine.getEnv().currentSpec.spyOn(obj, methodName);
445
454
  };
455
+ if (isCommonJS) exports.spyOn = spyOn;
446
456
 
447
457
  /**
448
458
  * Creates a Jasmine spec that will be added to the current suite.
@@ -460,6 +470,7 @@ var spyOn = function(obj, methodName) {
460
470
  var it = function(desc, func) {
461
471
  return jasmine.getEnv().it(desc, func);
462
472
  };
473
+ if (isCommonJS) exports.it = it;
463
474
 
464
475
  /**
465
476
  * Creates a <em>disabled</em> Jasmine spec.
@@ -472,6 +483,7 @@ var it = function(desc, func) {
472
483
  var xit = function(desc, func) {
473
484
  return jasmine.getEnv().xit(desc, func);
474
485
  };
486
+ if (isCommonJS) exports.xit = xit;
475
487
 
476
488
  /**
477
489
  * Starts a chain for a Jasmine expectation.
@@ -484,6 +496,7 @@ var xit = function(desc, func) {
484
496
  var expect = function(actual) {
485
497
  return jasmine.getEnv().currentSpec.expect(actual);
486
498
  };
499
+ if (isCommonJS) exports.expect = expect;
487
500
 
488
501
  /**
489
502
  * Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs.
@@ -493,6 +506,7 @@ var expect = function(actual) {
493
506
  var runs = function(func) {
494
507
  jasmine.getEnv().currentSpec.runs(func);
495
508
  };
509
+ if (isCommonJS) exports.runs = runs;
496
510
 
497
511
  /**
498
512
  * Waits a fixed time period before moving to the next block.
@@ -503,6 +517,7 @@ var runs = function(func) {
503
517
  var waits = function(timeout) {
504
518
  jasmine.getEnv().currentSpec.waits(timeout);
505
519
  };
520
+ if (isCommonJS) exports.waits = waits;
506
521
 
507
522
  /**
508
523
  * Waits for the latchFunction to return true before proceeding to the next block.
@@ -514,6 +529,7 @@ var waits = function(timeout) {
514
529
  var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
515
530
  jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments);
516
531
  };
532
+ if (isCommonJS) exports.waitsFor = waitsFor;
517
533
 
518
534
  /**
519
535
  * A function that is called before each spec in a suite.
@@ -525,6 +541,7 @@ var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout
525
541
  var beforeEach = function(beforeEachFunction) {
526
542
  jasmine.getEnv().beforeEach(beforeEachFunction);
527
543
  };
544
+ if (isCommonJS) exports.beforeEach = beforeEach;
528
545
 
529
546
  /**
530
547
  * A function that is called after each spec in a suite.
@@ -536,6 +553,7 @@ var beforeEach = function(beforeEachFunction) {
536
553
  var afterEach = function(afterEachFunction) {
537
554
  jasmine.getEnv().afterEach(afterEachFunction);
538
555
  };
556
+ if (isCommonJS) exports.afterEach = afterEach;
539
557
 
540
558
  /**
541
559
  * Defines a suite of specifications.
@@ -555,6 +573,7 @@ var afterEach = function(afterEachFunction) {
555
573
  var describe = function(description, specDefinitions) {
556
574
  return jasmine.getEnv().describe(description, specDefinitions);
557
575
  };
576
+ if (isCommonJS) exports.describe = describe;
558
577
 
559
578
  /**
560
579
  * Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development.
@@ -565,25 +584,25 @@ var describe = function(description, specDefinitions) {
565
584
  var xdescribe = function(description, specDefinitions) {
566
585
  return jasmine.getEnv().xdescribe(description, specDefinitions);
567
586
  };
587
+ if (isCommonJS) exports.xdescribe = xdescribe;
568
588
 
569
589
 
570
590
  // Provide the XMLHttpRequest class for IE 5.x-6.x:
571
591
  jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() {
572
- try {
573
- return new ActiveXObject("Msxml2.XMLHTTP.6.0");
574
- } catch(e) {
575
- }
576
- try {
577
- return new ActiveXObject("Msxml2.XMLHTTP.3.0");
578
- } catch(e) {
579
- }
580
- try {
581
- return new ActiveXObject("Msxml2.XMLHTTP");
582
- } catch(e) {
583
- }
584
- try {
585
- return new ActiveXObject("Microsoft.XMLHTTP");
586
- } catch(e) {
592
+ function tryIt(f) {
593
+ try {
594
+ return f();
595
+ } catch(e) {
596
+ }
597
+ return null;
587
598
  }
588
- throw new Error("This browser does not support XMLHttpRequest.");
599
+
600
+ var xhr = tryIt(function(){return new ActiveXObject("Msxml2.XMLHTTP.6.0");}) ||
601
+ tryIt(function(){return new ActiveXObject("Msxml2.XMLHTTP.3.0");}) ||
602
+ tryIt(function(){return new ActiveXObject("Msxml2.XMLHTTP");}) ||
603
+ tryIt(function(){return new ActiveXObject("Microsoft.XMLHTTP");});
604
+
605
+ if (!xhr) throw new Error("This browser does not support XMLHttpRequest.");
606
+
607
+ return xhr;
589
608
  } : XMLHttpRequest;
@@ -0,0 +1,144 @@
1
+ jasmine.TrivialConsoleReporter = function(print, doneCallback) {
2
+ //inspired by mhevery's jasmine-node reporter
3
+ //https://github.com/mhevery/jasmine-node
4
+
5
+ doneCallback = doneCallback || function(){};
6
+
7
+ var defaultColumnsPerLine = 50,
8
+ ansi = { green: '\033[32m', red: '\033[31m', yellow: '\033[33m', none: '\033[0m' },
9
+ language = { spec:"spec", expectation:"expectation", failure:"failure" };
10
+
11
+ function coloredStr(color, str) { return ansi[color] + str + ansi.none; }
12
+
13
+ function greenStr(str) { return coloredStr("green", str); }
14
+ function redStr(str) { return coloredStr("red", str); }
15
+ function yellowStr(str) { return coloredStr("yellow", str); }
16
+
17
+ function newline() { print("\n"); }
18
+ function started() { print("Started");
19
+ newline(); }
20
+
21
+ function greenDot() { print(greenStr(".")); }
22
+ function redF() { print(redStr("F")); }
23
+ function yellowStar() { print(yellowStr("*")); }
24
+
25
+ function plural(str, count) { return count == 1 ? str : str + "s"; }
26
+
27
+ function repeat(thing, times) { var arr = [];
28
+ for(var i=0; i<times; i++) arr.push(thing);
29
+ return arr;
30
+ }
31
+
32
+ function indent(str, spaces) { var lines = str.split("\n");
33
+ var newArr = [];
34
+ for(var i=0; i<lines.length; i++) {
35
+ newArr.push(repeat(" ", spaces).join("") + lines[i]);
36
+ }
37
+ return newArr.join("\n");
38
+ }
39
+
40
+ function specFailureDetails(suiteDescription, specDescription, stackTraces) {
41
+ newline();
42
+ print(suiteDescription + " " + specDescription);
43
+ newline();
44
+ for(var i=0; i<stackTraces.length; i++) {
45
+ print(indent(stackTraces[i], 2));
46
+ newline();
47
+ }
48
+ }
49
+ function finished(elapsed) { newline();
50
+ print("Finished in " + elapsed/1000 + " seconds"); }
51
+ function summary(colorF, specs, expectations, failed) { newline();
52
+ print(colorF(specs + " " + plural(language.spec, specs) + ", " +
53
+ expectations + " " + plural(language.expectation, expectations) + ", " +
54
+ failed + " " + plural(language.failure, failed)));
55
+ newline();
56
+ newline(); }
57
+ function greenSummary(specs, expectations, failed){ summary(greenStr, specs, expectations, failed); }
58
+ function redSummary(specs, expectations, failed){ summary(redStr, specs, expectations, failed); }
59
+
60
+
61
+
62
+
63
+ function lineEnder(columnsPerLine) {
64
+ var columnsSoFar = 0;
65
+ return function() {
66
+ columnsSoFar += 1;
67
+ if (columnsSoFar == columnsPerLine) {
68
+ newline();
69
+ columnsSoFar = 0;
70
+ }
71
+ };
72
+ }
73
+
74
+ function fullSuiteDescription(suite) {
75
+ var fullDescription = suite.description;
76
+ if (suite.parentSuite) fullDescription = fullSuiteDescription(suite.parentSuite) + " " + fullDescription ;
77
+ return fullDescription;
78
+ }
79
+
80
+ var startNewLineIfNecessary = lineEnder(defaultColumnsPerLine);
81
+
82
+ this.now = function() { return new Date().getTime(); };
83
+
84
+ this.reportRunnerStarting = function() {
85
+ this.runnerStartTime = this.now();
86
+ started();
87
+ };
88
+
89
+ this.reportSpecStarting = function() { /* do nothing */ };
90
+
91
+ this.reportSpecResults = function(spec) {
92
+ var results = spec.results();
93
+ if (results.skipped) {
94
+ yellowStar();
95
+ } else if (results.passed()) {
96
+ greenDot();
97
+ } else {
98
+ redF();
99
+ }
100
+ startNewLineIfNecessary();
101
+ };
102
+
103
+ this.suiteResults = [];
104
+
105
+ this.reportSuiteResults = function(suite) {
106
+ var suiteResult = {
107
+ description: fullSuiteDescription(suite),
108
+ failedSpecResults: []
109
+ };
110
+
111
+ suite.results().items_.forEach(function(spec){
112
+ if (spec.failedCount > 0 && spec.description) suiteResult.failedSpecResults.push(spec);
113
+ });
114
+
115
+ this.suiteResults.push(suiteResult);
116
+ };
117
+
118
+ function eachSpecFailure(suiteResults, callback) {
119
+ for(var i=0; i<suiteResults.length; i++) {
120
+ var suiteResult = suiteResults[i];
121
+ for(var j=0; j<suiteResult.failedSpecResults.length; j++) {
122
+ var failedSpecResult = suiteResult.failedSpecResults[j];
123
+ var stackTraces = [];
124
+ for(var k=0; k<failedSpecResult.items_.length; k++) stackTraces.push(failedSpecResult.items_[k].trace.stack);
125
+ callback(suiteResult.description, failedSpecResult.description, stackTraces);
126
+ }
127
+ }
128
+ }
129
+
130
+ this.reportRunnerResults = function(runner) {
131
+ newline();
132
+
133
+ eachSpecFailure(this.suiteResults, function(suiteDescription, specDescription, stackTraces) {
134
+ specFailureDetails(suiteDescription, specDescription, stackTraces);
135
+ });
136
+
137
+ finished(this.now() - this.runnerStartTime);
138
+
139
+ var results = runner.results();
140
+ var summaryFunction = results.failedCount === 0 ? greenSummary : redSummary;
141
+ summaryFunction(results.items_.length, results.totalCount, results.failedCount);
142
+ doneCallback(runner);
143
+ };
144
+ };