jasmine-core 2.0.0 → 2.0.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 (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;