jasmine-core 2.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/lib/console/console.js +27 -22
  3. data/lib/jasmine-core.js +2 -0
  4. data/lib/jasmine-core.rb +6 -2
  5. data/lib/jasmine-core/__init__.py +1 -0
  6. data/lib/jasmine-core/boot.js +1 -1
  7. data/lib/jasmine-core/boot/node_boot.js +71 -0
  8. data/lib/jasmine-core/core.py +60 -0
  9. data/lib/jasmine-core/example/node_example/spec/PlayerSpec.js +60 -0
  10. data/lib/jasmine-core/example/node_example/spec/SpecHelper.js +15 -0
  11. data/lib/jasmine-core/example/node_example/src/Player.js +24 -0
  12. data/lib/jasmine-core/example/node_example/src/Song.js +9 -0
  13. data/lib/jasmine-core/jasmine-html.js +104 -73
  14. data/lib/jasmine-core/jasmine.css +58 -54
  15. data/lib/jasmine-core/jasmine.js +368 -254
  16. data/lib/jasmine-core/node_boot.js +93 -0
  17. data/lib/jasmine-core/spec/console/ConsoleReporterSpec.js +12 -0
  18. data/lib/jasmine-core/spec/core/AnySpec.js +1 -0
  19. data/lib/jasmine-core/spec/core/ClockSpec.js +103 -17
  20. data/lib/jasmine-core/spec/core/DelayedFunctionSchedulerSpec.js +1 -1
  21. data/lib/jasmine-core/spec/core/EnvSpec.js +14 -14
  22. data/lib/jasmine-core/spec/core/ExceptionFormatterSpec.js +7 -0
  23. data/lib/jasmine-core/spec/core/ExceptionsSpec.js +2 -2
  24. data/lib/jasmine-core/spec/core/ExpectationSpec.js +34 -0
  25. data/lib/jasmine-core/spec/core/MockDateSpec.js +179 -0
  26. data/lib/jasmine-core/spec/core/ObjectContainingSpec.js +6 -0
  27. data/lib/jasmine-core/spec/core/PrettyPrintSpec.js +41 -10
  28. data/lib/jasmine-core/spec/core/QueueRunnerSpec.js +130 -31
  29. data/lib/jasmine-core/spec/core/SpecSpec.js +27 -88
  30. data/lib/jasmine-core/spec/core/TimerSpec.js +18 -0
  31. data/lib/jasmine-core/spec/core/integration/EnvSpec.js +20 -2
  32. data/lib/jasmine-core/spec/core/matchers/matchersUtilSpec.js +8 -0
  33. data/lib/jasmine-core/spec/core/matchers/toBeGreaterThanSpec.js +2 -1
  34. data/lib/jasmine-core/spec/core/matchers/toBeNaNSpec.js +3 -2
  35. data/lib/jasmine-core/spec/core/matchers/toBeUndefinedSpec.js +2 -1
  36. data/lib/jasmine-core/spec/core/matchers/toContainSpec.js +4 -2
  37. data/lib/jasmine-core/spec/core/matchers/toHaveBeenCalledSpec.js +2 -1
  38. data/lib/jasmine-core/spec/core/matchers/toHaveBeenCalledWithSpec.js +17 -3
  39. data/lib/jasmine-core/spec/core/matchers/toThrowErrorSpec.js +11 -11
  40. data/lib/jasmine-core/spec/core/matchers/toThrowSpec.js +5 -5
  41. data/lib/jasmine-core/spec/helpers/defineJasmineUnderTest.js +7 -0
  42. data/lib/jasmine-core/spec/helpers/nodeDefineJasmineUnderTest.js +33 -0
  43. data/lib/jasmine-core/spec/html/HtmlReporterSpec.js +155 -35
  44. data/lib/jasmine-core/spec/html/PrettyPrintHtmlSpec.js +1 -1
  45. data/lib/jasmine-core/spec/performance/large_object_test.js +36 -0
  46. data/lib/jasmine-core/version.rb +1 -1
  47. metadata +34 -23
  48. data/lib/jasmine-core/spec/node_suite.js +0 -187
  49. data/lib/jasmine-core/spec/support/dev_boot.js +0 -124
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 64fc08a60b942909e10f43cd7568374e95e0ccda
4
- data.tar.gz: f6cc9a58eeb24163496fb22903321b73d97cd3fd
3
+ metadata.gz: 31f38e6d9ef7197809f9bb2444b834cfb3e6659d
4
+ data.tar.gz: ae0c370c39a2e8bae6512766894f35e753959e62
5
5
  SHA512:
6
- metadata.gz: 24d62c7f7aea8cc8b640f562a77ba219d25b203e587df68b2b29245d22e98e0475ca27fbf2f994f031b89b35b4c8e08c1ba402f1dc8eb81281c90ee27a909daf
7
- data.tar.gz: d2ee9eacc009ce20f427baf2a13d61b69abb814d1a40788986d393322ccad3347d2f00b57c5c2feb57ccb88231fa6d5e49049aa8c99c1268566a798ddb9aa60a
6
+ metadata.gz: a180ed071f5468dd122a0d4cb8ae4a0583596ac0c3f92768e05106b787dc6e8bbd2c4180e897a1cc539ae1de58419c24fe226284c51e928f2949fdbceaa81007
7
+ data.tar.gz: 2e655020347e0e1e6af8a6158c08e209dd201615370f82422de66328672d083aa3df92f8eab2f7734ccc1711e7a4a894bac3fdbd9a631e201b0fa7f9ac4f7418
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright (c) 2008-2013 Pivotal Labs
2
+ Copyright (c) 2008-2014 Pivotal Labs
3
3
 
4
4
  Permission is hereby granted, free of charge, to any person obtaining
5
5
  a copy of this software and associated documentation files (the
@@ -21,7 +21,7 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
21
  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
22
  */
23
23
  function getJasmineRequireObj() {
24
- if (typeof module !== "undefined" && module.exports) {
24
+ if (typeof module !== 'undefined' && module.exports) {
25
25
  return exports;
26
26
  } else {
27
27
  window.jasmineRequire = window.jasmineRequire || {};
@@ -60,7 +60,7 @@ getJasmineRequireObj().ConsoleReporter = function() {
60
60
  specCount = 0;
61
61
  failureCount = 0;
62
62
  pendingCount = 0;
63
- print("Started");
63
+ print('Started');
64
64
  printNewline();
65
65
  timer.start();
66
66
  };
@@ -71,19 +71,24 @@ getJasmineRequireObj().ConsoleReporter = function() {
71
71
  specFailureDetails(failedSpecs[i]);
72
72
  }
73
73
 
74
- printNewline();
75
- var specCounts = specCount + " " + plural("spec", specCount) + ", " +
76
- failureCount + " " + plural("failure", failureCount);
74
+ if(specCount > 0) {
75
+ printNewline();
77
76
 
78
- if (pendingCount) {
79
- specCounts += ", " + pendingCount + " pending " + plural("spec", pendingCount);
80
- }
77
+ var specCounts = specCount + ' ' + plural('spec', specCount) + ', ' +
78
+ failureCount + ' ' + plural('failure', failureCount);
81
79
 
82
- print(specCounts);
80
+ if (pendingCount) {
81
+ specCounts += ', ' + pendingCount + ' pending ' + plural('spec', pendingCount);
82
+ }
83
+
84
+ print(specCounts);
85
+ } else {
86
+ print('No specs found');
87
+ }
83
88
 
84
89
  printNewline();
85
90
  var seconds = timer.elapsed() / 1000;
86
- print("Finished in " + seconds + " " + plural("second", seconds));
91
+ print('Finished in ' + seconds + ' ' + plural('second', seconds));
87
92
 
88
93
  printNewline();
89
94
 
@@ -93,28 +98,28 @@ getJasmineRequireObj().ConsoleReporter = function() {
93
98
  this.specDone = function(result) {
94
99
  specCount++;
95
100
 
96
- if (result.status == "pending") {
101
+ if (result.status == 'pending') {
97
102
  pendingCount++;
98
- print(colored("yellow", "*"));
103
+ print(colored('yellow', '*'));
99
104
  return;
100
105
  }
101
106
 
102
- if (result.status == "passed") {
103
- print(colored("green", '.'));
107
+ if (result.status == 'passed') {
108
+ print(colored('green', '.'));
104
109
  return;
105
110
  }
106
111
 
107
- if (result.status == "failed") {
112
+ if (result.status == 'failed') {
108
113
  failureCount++;
109
114
  failedSpecs.push(result);
110
- print(colored("red", 'F'));
115
+ print(colored('red', 'F'));
111
116
  }
112
117
  };
113
118
 
114
119
  return this;
115
120
 
116
121
  function printNewline() {
117
- print("\n");
122
+ print('\n');
118
123
  }
119
124
 
120
125
  function colored(color, str) {
@@ -122,7 +127,7 @@ getJasmineRequireObj().ConsoleReporter = function() {
122
127
  }
123
128
 
124
129
  function plural(str, count) {
125
- return count == 1 ? str : str + "s";
130
+ return count == 1 ? str : str + 's';
126
131
  }
127
132
 
128
133
  function repeat(thing, times) {
@@ -134,12 +139,12 @@ getJasmineRequireObj().ConsoleReporter = function() {
134
139
  }
135
140
 
136
141
  function indent(str, spaces) {
137
- var lines = (str || '').split("\n");
142
+ var lines = (str || '').split('\n');
138
143
  var newArr = [];
139
144
  for (var i = 0; i < lines.length; i++) {
140
- newArr.push(repeat(" ", spaces).join("") + lines[i]);
145
+ newArr.push(repeat(' ', spaces).join('') + lines[i]);
141
146
  }
142
- return newArr.join("\n");
147
+ return newArr.join('\n');
143
148
  }
144
149
 
145
150
  function specFailureDetails(result) {
@@ -0,0 +1,2 @@
1
+ module.exports = require("./jasmine-core/jasmine.js");
2
+ module.exports.boot = require('./jasmine-core/node_boot.js');
@@ -6,7 +6,7 @@ module Jasmine
6
6
  end
7
7
 
8
8
  def js_files
9
- (["jasmine.js"] + Dir.glob(File.join(path, "*.js"))).map { |f| File.basename(f) }.uniq - boot_files
9
+ (["jasmine.js"] + Dir.glob(File.join(path, "*.js"))).map { |f| File.basename(f) }.uniq - boot_files - node_boot_files
10
10
  end
11
11
 
12
12
  SPEC_TYPES = ["core", "html", "node"]
@@ -27,8 +27,12 @@ module Jasmine
27
27
  ["boot.js"]
28
28
  end
29
29
 
30
+ def node_boot_files
31
+ ["node_boot.js"]
32
+ end
33
+
30
34
  def boot_dir
31
- File.join(path, 'boot')
35
+ path
32
36
  end
33
37
 
34
38
  def spec_files(type)
@@ -0,0 +1 @@
1
+ from .core import Core
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright (c) 2008-2013 Pivotal Labs
2
+ Copyright (c) 2008-2014 Pivotal Labs
3
3
 
4
4
  Permission is hereby granted, free of charge, to any person obtaining
5
5
  a copy of this software and associated documentation files (the
@@ -0,0 +1,71 @@
1
+ module.exports = function(jasmineRequire) {
2
+ var jasmine = jasmineRequire.core(jasmineRequire);
3
+
4
+ var consoleFns = require('../console/console.js');
5
+ consoleFns.console(consoleFns, jasmine);
6
+
7
+ var env = jasmine.getEnv();
8
+
9
+ var jasmineInterface = {
10
+ describe: function(description, specDefinitions) {
11
+ return env.describe(description, specDefinitions);
12
+ },
13
+
14
+ xdescribe: function(description, specDefinitions) {
15
+ return env.xdescribe(description, specDefinitions);
16
+ },
17
+
18
+ it: function(desc, func) {
19
+ return env.it(desc, func);
20
+ },
21
+
22
+ xit: function(desc, func) {
23
+ return env.xit(desc, func);
24
+ },
25
+
26
+ beforeEach: function(beforeEachFunction) {
27
+ return env.beforeEach(beforeEachFunction);
28
+ },
29
+
30
+ afterEach: function(afterEachFunction) {
31
+ return env.afterEach(afterEachFunction);
32
+ },
33
+
34
+ expect: function(actual) {
35
+ return env.expect(actual);
36
+ },
37
+
38
+ spyOn: function(obj, methodName) {
39
+ return env.spyOn(obj, methodName);
40
+ },
41
+
42
+ jsApiReporter: new jasmine.JsApiReporter({
43
+ timer: new jasmine.Timer()
44
+ }),
45
+
46
+
47
+ jasmine: jasmine
48
+ };
49
+
50
+ extend(global, jasmineInterface);
51
+
52
+ jasmine.addCustomEqualityTester = function(tester) {
53
+ env.addCustomEqualityTester(tester);
54
+ };
55
+
56
+ jasmine.addMatchers = function(matchers) {
57
+ return env.addMatchers(matchers);
58
+ };
59
+
60
+ jasmine.clock = function() {
61
+ return env.clock;
62
+ };
63
+
64
+ function extend(destination, source) {
65
+ for (var property in source) destination[property] = source[property];
66
+ return destination;
67
+ }
68
+
69
+
70
+ return jasmine;
71
+ };
@@ -0,0 +1,60 @@
1
+ import pkg_resources
2
+
3
+ try:
4
+ from collections import OrderedDict
5
+ except ImportError:
6
+ from ordereddict import OrderedDict
7
+
8
+ class Core(object):
9
+ @classmethod
10
+ def js_package(cls):
11
+ return __package__
12
+
13
+ @classmethod
14
+ def css_package(cls):
15
+ return __package__
16
+
17
+ @classmethod
18
+ def image_package(cls):
19
+ return __package__ + ".images"
20
+
21
+ @classmethod
22
+ def js_files(cls):
23
+ js_files = sorted(list(filter(lambda x: '.js' in x, pkg_resources.resource_listdir(cls.js_package(), '.'))))
24
+
25
+ # jasmine.js needs to be first
26
+ js_files.insert(0, 'jasmine.js')
27
+
28
+ # boot needs to be last
29
+ js_files.remove('boot.js')
30
+ js_files.append('boot.js')
31
+
32
+ return cls._uniq(js_files)
33
+
34
+ @classmethod
35
+ def css_files(cls):
36
+ return cls._uniq(sorted(filter(lambda x: '.css' in x, pkg_resources.resource_listdir(cls.css_package(), '.'))))
37
+
38
+ @classmethod
39
+ def favicon(cls):
40
+ return 'jasmine_favicon.png'
41
+
42
+ @classmethod
43
+ def _uniq(self, items, idfun=None):
44
+ # order preserving
45
+
46
+ if idfun is None:
47
+ def idfun(x): return x
48
+ seen = {}
49
+ result = []
50
+ for item in items:
51
+ marker = idfun(item)
52
+ # in old Python versions:
53
+ # if seen.has_key(marker)
54
+ # but in new ones:
55
+ if marker in seen:
56
+ continue
57
+
58
+ seen[marker] = 1
59
+ result.append(item)
60
+ return result
@@ -0,0 +1,60 @@
1
+ describe("Player", function() {
2
+ var Player = require('../../jasmine_examples/Player.js');
3
+ var Song = require('../../jasmine_examples/Song.js');
4
+ var player;
5
+ var song;
6
+
7
+ beforeEach(function() {
8
+ player = new Player();
9
+ song = new Song();
10
+ });
11
+
12
+ it("should be able to play a Song", function() {
13
+ player.play(song);
14
+ expect(player.currentlyPlayingSong).toEqual(song);
15
+
16
+ //demonstrates use of custom matcher
17
+ expect(player).toBePlaying(song);
18
+ });
19
+
20
+ describe("when song has been paused", function() {
21
+ beforeEach(function() {
22
+ player.play(song);
23
+ player.pause();
24
+ });
25
+
26
+ it("should indicate that the song is currently paused", function() {
27
+ expect(player.isPlaying).toBeFalsy();
28
+
29
+ // demonstrates use of 'not' with a custom matcher
30
+ expect(player).not.toBePlaying(song);
31
+ });
32
+
33
+ it("should be possible to resume", function() {
34
+ player.resume();
35
+ expect(player.isPlaying).toBeTruthy();
36
+ expect(player.currentlyPlayingSong).toEqual(song);
37
+ });
38
+ });
39
+
40
+ // demonstrates use of spies to intercept and test method calls
41
+ it("tells the current song if the user has made it a favorite", function() {
42
+ spyOn(song, 'persistFavoriteStatus');
43
+
44
+ player.play(song);
45
+ player.makeFavorite();
46
+
47
+ expect(song.persistFavoriteStatus).toHaveBeenCalledWith(true);
48
+ });
49
+
50
+ //demonstrates use of expected exceptions
51
+ describe("#resume", function() {
52
+ it("should throw an exception if song is already playing", function() {
53
+ player.play(song);
54
+
55
+ expect(function() {
56
+ player.resume();
57
+ }).toThrowError("song is already playing");
58
+ });
59
+ });
60
+ });
@@ -0,0 +1,15 @@
1
+ beforeEach(function () {
2
+ jasmine.addMatchers({
3
+ toBePlaying: function () {
4
+ return {
5
+ compare: function (actual, expected) {
6
+ var player = actual;
7
+
8
+ return {
9
+ pass: player.currentlyPlayingSong === expected && player.isPlaying
10
+ }
11
+ }
12
+ };
13
+ }
14
+ });
15
+ });
@@ -0,0 +1,24 @@
1
+ function Player() {
2
+ }
3
+ Player.prototype.play = function(song) {
4
+ this.currentlyPlayingSong = song;
5
+ this.isPlaying = true;
6
+ };
7
+
8
+ Player.prototype.pause = function() {
9
+ this.isPlaying = false;
10
+ };
11
+
12
+ Player.prototype.resume = function() {
13
+ if (this.isPlaying) {
14
+ throw new Error("song is already playing");
15
+ }
16
+
17
+ this.isPlaying = true;
18
+ };
19
+
20
+ Player.prototype.makeFavorite = function() {
21
+ this.currentlyPlayingSong.persistFavoriteStatus(true);
22
+ };
23
+
24
+ module.exports = Player;
@@ -0,0 +1,9 @@
1
+ function Song() {
2
+ }
3
+
4
+ Song.prototype.persistFavoriteStatus = function(value) {
5
+ // something complicated
6
+ throw new Error("not yet implemented");
7
+ };
8
+
9
+ module.exports = Song;
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright (c) 2008-2013 Pivotal Labs
2
+ Copyright (c) 2008-2014 Pivotal Labs
3
3
 
4
4
  Permission is hereby granted, free of charge, to any person obtaining
5
5
  a copy of this software and associated documentation files (the
@@ -49,20 +49,21 @@ jasmineRequire.HtmlReporter = function(j$) {
49
49
  symbols;
50
50
 
51
51
  this.initialize = function() {
52
- htmlReporterMain = createDom("div", {className: "html-reporter"},
53
- createDom("div", {className: "banner"},
54
- createDom("span", {className: "title"}, "Jasmine"),
55
- createDom("span", {className: "version"}, j$.version)
52
+ clearPrior();
53
+ htmlReporterMain = createDom('div', {className: 'jasmine_html-reporter'},
54
+ createDom('div', {className: 'banner'},
55
+ createDom('a', {className: 'title', href: 'http://jasmine.github.io/', target: '_blank'}),
56
+ createDom('span', {className: 'version'}, j$.version)
56
57
  ),
57
- createDom("ul", {className: "symbol-summary"}),
58
- createDom("div", {className: "alert"}),
59
- createDom("div", {className: "results"},
60
- createDom("div", {className: "failures"})
58
+ createDom('ul', {className: 'symbol-summary'}),
59
+ createDom('div', {className: 'alert'}),
60
+ createDom('div', {className: 'results'},
61
+ createDom('div', {className: 'failures'})
61
62
  )
62
63
  );
63
64
  getContainer().appendChild(htmlReporterMain);
64
65
 
65
- symbols = find(".symbol-summary");
66
+ symbols = find('.symbol-summary');
66
67
  };
67
68
 
68
69
  var totalSpecsDefined;
@@ -71,13 +72,13 @@ jasmineRequire.HtmlReporter = function(j$) {
71
72
  timer.start();
72
73
  };
73
74
 
74
- var summary = createDom("div", {className: "summary"});
75
+ var summary = createDom('div', {className: 'summary'});
75
76
 
76
- var topResults = new j$.ResultsNode({}, "", null),
77
+ var topResults = new j$.ResultsNode({}, '', null),
77
78
  currentParent = topResults;
78
79
 
79
80
  this.suiteStarted = function(result) {
80
- currentParent.addChild(result, "suite");
81
+ currentParent.addChild(result, 'suite');
81
82
  currentParent = currentParent.last();
82
83
  };
83
84
 
@@ -90,82 +91,94 @@ jasmineRequire.HtmlReporter = function(j$) {
90
91
  };
91
92
 
92
93
  this.specStarted = function(result) {
93
- currentParent.addChild(result, "spec");
94
+ currentParent.addChild(result, 'spec');
94
95
  };
95
96
 
96
97
  var failures = [];
97
98
  this.specDone = function(result) {
98
- if (result.status != "disabled") {
99
+ if(noExpectations(result) && console && console.error) {
100
+ console.error('Spec \'' + result.fullName + '\' has no expectations.');
101
+ }
102
+
103
+ if (result.status != 'disabled') {
99
104
  specsExecuted++;
100
105
  }
101
106
 
102
- symbols.appendChild(createDom("li", {
103
- className: result.status,
104
- id: "spec_" + result.id,
107
+ symbols.appendChild(createDom('li', {
108
+ className: noExpectations(result) ? 'empty' : result.status,
109
+ id: 'spec_' + result.id,
105
110
  title: result.fullName
106
111
  }
107
112
  ));
108
113
 
109
- if (result.status == "failed") {
114
+ if (result.status == 'failed') {
110
115
  failureCount++;
111
116
 
112
117
  var failure =
113
- createDom("div", {className: "spec-detail failed"},
114
- createDom("div", {className: "description"},
115
- createDom("a", {title: result.fullName, href: specHref(result)}, result.fullName)
118
+ createDom('div', {className: 'spec-detail failed'},
119
+ createDom('div', {className: 'description'},
120
+ createDom('a', {title: result.fullName, href: specHref(result)}, result.fullName)
116
121
  ),
117
- createDom("div", {className: "messages"})
122
+ createDom('div', {className: 'messages'})
118
123
  );
119
124
  var messages = failure.childNodes[1];
120
125
 
121
126
  for (var i = 0; i < result.failedExpectations.length; i++) {
122
127
  var expectation = result.failedExpectations[i];
123
- messages.appendChild(createDom("div", {className: "result-message"}, expectation.message));
124
- messages.appendChild(createDom("div", {className: "stack-trace"}, expectation.stack));
128
+ messages.appendChild(createDom('div', {className: 'result-message'}, expectation.message));
129
+ messages.appendChild(createDom('div', {className: 'stack-trace'}, expectation.stack));
125
130
  }
126
131
 
127
132
  failures.push(failure);
128
133
  }
129
134
 
130
- if (result.status == "pending") {
135
+ if (result.status == 'pending') {
131
136
  pendingSpecCount++;
132
137
  }
133
138
  };
134
139
 
135
140
  this.jasmineDone = function() {
136
- var banner = find(".banner");
137
- banner.appendChild(createDom("span", {className: "duration"}, "finished in " + timer.elapsed() / 1000 + "s"));
141
+ var banner = find('.banner');
142
+ banner.appendChild(createDom('span', {className: 'duration'}, 'finished in ' + timer.elapsed() / 1000 + 's'));
138
143
 
139
- var alert = find(".alert");
144
+ var alert = find('.alert');
140
145
 
141
- alert.appendChild(createDom("span", { className: "exceptions" },
142
- createDom("label", { className: "label", 'for': "raise-exceptions" }, "raise exceptions"),
143
- createDom("input", {
144
- className: "raise",
145
- id: "raise-exceptions",
146
- type: "checkbox"
146
+ alert.appendChild(createDom('span', { className: 'exceptions' },
147
+ createDom('label', { className: 'label', 'for': 'raise-exceptions' }, 'raise exceptions'),
148
+ createDom('input', {
149
+ className: 'raise',
150
+ id: 'raise-exceptions',
151
+ type: 'checkbox'
147
152
  })
148
153
  ));
149
- var checkbox = find("input");
154
+ var checkbox = find('#raise-exceptions');
150
155
 
151
156
  checkbox.checked = !env.catchingExceptions();
152
157
  checkbox.onclick = onRaiseExceptionsClick;
153
158
 
154
159
  if (specsExecuted < totalSpecsDefined) {
155
- var skippedMessage = "Ran " + specsExecuted + " of " + totalSpecsDefined + " specs - run all";
160
+ var skippedMessage = 'Ran ' + specsExecuted + ' of ' + totalSpecsDefined + ' specs - run all';
156
161
  alert.appendChild(
157
- createDom("span", {className: "bar skipped"},
158
- createDom("a", {href: "?", title: "Run all specs"}, skippedMessage)
162
+ createDom('span', {className: 'bar skipped'},
163
+ createDom('a', {href: '?', title: 'Run all specs'}, skippedMessage)
159
164
  )
160
165
  );
161
166
  }
162
- var statusBarMessage = "" + pluralize("spec", specsExecuted) + ", " + pluralize("failure", failureCount);
163
- if (pendingSpecCount) { statusBarMessage += ", " + pluralize("pending spec", pendingSpecCount); }
167
+ var statusBarMessage = '';
168
+ var statusBarClassName = 'bar ';
169
+
170
+ if (totalSpecsDefined > 0) {
171
+ statusBarMessage += pluralize('spec', specsExecuted) + ', ' + pluralize('failure', failureCount);
172
+ if (pendingSpecCount) { statusBarMessage += ', ' + pluralize('pending spec', pendingSpecCount); }
173
+ statusBarClassName += (failureCount > 0) ? 'failed' : 'passed';
174
+ } else {
175
+ statusBarClassName += 'skipped';
176
+ statusBarMessage += 'No specs found';
177
+ }
164
178
 
165
- var statusBarClassName = "bar " + ((failureCount > 0) ? "failed" : "passed");
166
- alert.appendChild(createDom("span", {className: statusBarClassName}, statusBarMessage));
179
+ alert.appendChild(createDom('span', {className: statusBarClassName}, statusBarMessage));
167
180
 
168
- var results = find(".results");
181
+ var results = find('.results');
169
182
  results.appendChild(summary);
170
183
 
171
184
  summaryList(topResults, summary);
@@ -174,27 +187,31 @@ jasmineRequire.HtmlReporter = function(j$) {
174
187
  var specListNode;
175
188
  for (var i = 0; i < resultsTree.children.length; i++) {
176
189
  var resultNode = resultsTree.children[i];
177
- if (resultNode.type == "suite") {
178
- var suiteListNode = createDom("ul", {className: "suite", id: "suite-" + resultNode.result.id},
179
- createDom("li", {className: "suite-detail"},
180
- createDom("a", {href: specHref(resultNode.result)}, resultNode.result.description)
190
+ if (resultNode.type == 'suite') {
191
+ var suiteListNode = createDom('ul', {className: 'suite', id: 'suite-' + resultNode.result.id},
192
+ createDom('li', {className: 'suite-detail'},
193
+ createDom('a', {href: specHref(resultNode.result)}, resultNode.result.description)
181
194
  )
182
195
  );
183
196
 
184
197
  summaryList(resultNode, suiteListNode);
185
198
  domParent.appendChild(suiteListNode);
186
199
  }
187
- if (resultNode.type == "spec") {
188
- if (domParent.getAttribute("class") != "specs") {
189
- specListNode = createDom("ul", {className: "specs"});
200
+ if (resultNode.type == 'spec') {
201
+ if (domParent.getAttribute('class') != 'specs') {
202
+ specListNode = createDom('ul', {className: 'specs'});
190
203
  domParent.appendChild(specListNode);
191
204
  }
205
+ var specDescription = resultNode.result.description;
206
+ if(noExpectations(resultNode.result)) {
207
+ specDescription = 'SPEC HAS NO EXPECTATIONS ' + specDescription;
208
+ }
192
209
  specListNode.appendChild(
193
- createDom("li", {
210
+ createDom('li', {
194
211
  className: resultNode.result.status,
195
- id: "spec-" + resultNode.result.id
212
+ id: 'spec-' + resultNode.result.id
196
213
  },
197
- createDom("a", {href: specHref(resultNode.result)}, resultNode.result.description)
214
+ createDom('a', {href: specHref(resultNode.result)}, specDescription)
198
215
  )
199
216
  );
200
217
  }
@@ -203,24 +220,24 @@ jasmineRequire.HtmlReporter = function(j$) {
203
220
 
204
221
  if (failures.length) {
205
222
  alert.appendChild(
206
- createDom('span', {className: "menu bar spec-list"},
207
- createDom("span", {}, "Spec List | "),
208
- createDom('a', {className: "failures-menu", href: "#"}, "Failures")));
223
+ createDom('span', {className: 'menu bar spec-list'},
224
+ createDom('span', {}, 'Spec List | '),
225
+ createDom('a', {className: 'failures-menu', href: '#'}, 'Failures')));
209
226
  alert.appendChild(
210
- createDom('span', {className: "menu bar failure-list"},
211
- createDom('a', {className: "spec-list-menu", href: "#"}, "Spec List"),
212
- createDom("span", {}, " | Failures ")));
227
+ createDom('span', {className: 'menu bar failure-list'},
228
+ createDom('a', {className: 'spec-list-menu', href: '#'}, 'Spec List'),
229
+ createDom('span', {}, ' | Failures ')));
213
230
 
214
- find(".failures-menu").onclick = function() {
231
+ find('.failures-menu').onclick = function() {
215
232
  setMenuModeTo('failure-list');
216
233
  };
217
- find(".spec-list-menu").onclick = function() {
234
+ find('.spec-list-menu').onclick = function() {
218
235
  setMenuModeTo('spec-list');
219
236
  };
220
237
 
221
238
  setMenuModeTo('failure-list');
222
239
 
223
- var failureNode = find(".failures");
240
+ var failureNode = find('.failures');
224
241
  for (var i = 0; i < failures.length; i++) {
225
242
  failureNode.appendChild(failures[i]);
226
243
  }
@@ -230,7 +247,16 @@ jasmineRequire.HtmlReporter = function(j$) {
230
247
  return this;
231
248
 
232
249
  function find(selector) {
233
- return getContainer().querySelector(selector);
250
+ return getContainer().querySelector('.jasmine_html-reporter ' + selector);
251
+ }
252
+
253
+ function clearPrior() {
254
+ // return the reporter
255
+ var oldReporter = find('');
256
+
257
+ if(oldReporter) {
258
+ getContainer().removeChild(oldReporter);
259
+ }
234
260
  }
235
261
 
236
262
  function createDom(type, attrs, childrenVarArgs) {
@@ -249,7 +275,7 @@ jasmineRequire.HtmlReporter = function(j$) {
249
275
  }
250
276
 
251
277
  for (var attr in attrs) {
252
- if (attr == "className") {
278
+ if (attr == 'className') {
253
279
  el[attr] = attrs[attr];
254
280
  } else {
255
281
  el.setAttribute(attr, attrs[attr]);
@@ -260,17 +286,22 @@ jasmineRequire.HtmlReporter = function(j$) {
260
286
  }
261
287
 
262
288
  function pluralize(singular, count) {
263
- var word = (count == 1 ? singular : singular + "s");
289
+ var word = (count == 1 ? singular : singular + 's');
264
290
 
265
- return "" + count + " " + word;
291
+ return '' + count + ' ' + word;
266
292
  }
267
293
 
268
294
  function specHref(result) {
269
- return "?spec=" + encodeURIComponent(result.fullName);
295
+ return '?spec=' + encodeURIComponent(result.fullName);
270
296
  }
271
297
 
272
298
  function setMenuModeTo(mode) {
273
- htmlReporterMain.setAttribute("class", "html-reporter " + mode);
299
+ htmlReporterMain.setAttribute('class', 'jasmine_html-reporter ' + mode);
300
+ }
301
+
302
+ function noExpectations(result) {
303
+ return (result.failedExpectations.length + result.passedExpectations.length) === 0 &&
304
+ result.status === 'passed';
274
305
  }
275
306
  }
276
307
 
@@ -279,7 +310,7 @@ jasmineRequire.HtmlReporter = function(j$) {
279
310
 
280
311
  jasmineRequire.HtmlSpecFilter = function() {
281
312
  function HtmlSpecFilter(options) {
282
- var filterString = options && options.filterString() && options.filterString().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
313
+ var filterString = options && options.filterString() && options.filterString().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
283
314
  var filterPattern = new RegExp(filterString);
284
315
 
285
316
  this.matches = function(specName) {
@@ -328,9 +359,9 @@ jasmineRequire.QueryString = function() {
328
359
  function toQueryString(paramMap) {
329
360
  var qStrPairs = [];
330
361
  for (var prop in paramMap) {
331
- qStrPairs.push(encodeURIComponent(prop) + "=" + encodeURIComponent(paramMap[prop]));
362
+ qStrPairs.push(encodeURIComponent(prop) + '=' + encodeURIComponent(paramMap[prop]));
332
363
  }
333
- return "?" + qStrPairs.join('&');
364
+ return '?' + qStrPairs.join('&');
334
365
  }
335
366
 
336
367
  function queryStringToParamMap() {
@@ -343,7 +374,7 @@ jasmineRequire.QueryString = function() {
343
374
  for (var i = 0; i < params.length; i++) {
344
375
  var p = params[i].split('=');
345
376
  var value = decodeURIComponent(p[1]);
346
- if (value === "true" || value === "false") {
377
+ if (value === 'true' || value === 'false') {
347
378
  value = JSON.parse(value);
348
379
  }
349
380
  paramMap[decodeURIComponent(p[0])] = value;