evergreen 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +15 -0
  2. data/README.rdoc +8 -6
  3. data/lib/evergreen.rb +8 -6
  4. data/lib/evergreen/application.rb +2 -5
  5. data/lib/evergreen/helper.rb +33 -0
  6. data/lib/evergreen/runner.rb +1 -1
  7. data/lib/evergreen/server.rb +1 -0
  8. data/lib/evergreen/suite.rb +6 -0
  9. data/lib/evergreen/version.rb +1 -1
  10. data/lib/evergreen/views/run.erb +16 -6
  11. data/lib/jasmine/Contribute.markdown +8 -7
  12. data/lib/jasmine/Gemfile +0 -1
  13. data/lib/jasmine/README.markdown +1 -8
  14. data/lib/jasmine/Rakefile +26 -15
  15. data/lib/jasmine/Release.markdown +8 -6
  16. data/lib/jasmine/config.rb +29 -0
  17. data/lib/jasmine/jasmine-core.gemspec +9 -2
  18. data/lib/jasmine/jasmine_dev.thor +1 -0
  19. data/lib/jasmine/jshint/run.js +1 -1
  20. data/lib/jasmine/lib/jasmine-core/jasmine-html.js +427 -1
  21. data/lib/jasmine/lib/jasmine-core/jasmine.css +81 -166
  22. data/lib/jasmine/lib/jasmine-core/jasmine.js +245 -192
  23. data/lib/jasmine/lib/jasmine-core/version.rb +1 -1
  24. data/lib/jasmine/spec/core/MatchersSpec.js +273 -0
  25. data/lib/jasmine/spec/core/PrettyPrintSpec.js +7 -0
  26. data/lib/jasmine/spec/html/HTMLReporterSpec.js +209 -0
  27. data/lib/jasmine/spec/node_suite.js +2 -2
  28. data/lib/jasmine/spec/runner.html +10 -3
  29. data/lib/jasmine/spec/spec_helper.rb +51 -0
  30. data/lib/jasmine/spec/tasks/build_distribution_spec.rb +33 -0
  31. data/lib/jasmine/spec/tasks/build_github_pages_spec.rb +69 -0
  32. data/lib/jasmine/spec/tasks/build_standalone_distribution_spec.rb +109 -0
  33. data/lib/jasmine/spec/tasks/build_standalone_runner_spec.rb +63 -0
  34. data/lib/jasmine/spec/tasks/count_specs_spec.rb +26 -0
  35. data/lib/jasmine/spec/tasks/execute_specs_spec.rb +81 -0
  36. data/lib/jasmine/spec/tasks/jshint_spec.rb +39 -0
  37. data/lib/jasmine/spec/tasks/release_spec.rb +39 -0
  38. data/lib/jasmine/spec/tasks/version_spec.rb +55 -0
  39. data/lib/jasmine/spec/templates/runner.html.erb +3 -3
  40. data/lib/jasmine/src/core/Env.js +10 -2
  41. data/lib/jasmine/src/core/Matchers.js +33 -4
  42. data/lib/jasmine/src/core/PrettyPrinter.js +2 -2
  43. data/lib/jasmine/src/core/base.js +15 -0
  44. data/lib/jasmine/src/core/mock-timeout.js +0 -0
  45. data/lib/jasmine/src/html/HtmlReporter.js +101 -0
  46. data/lib/jasmine/src/html/HtmlReporterHelpers.js +60 -0
  47. data/lib/jasmine/src/html/ReporterView.js +164 -0
  48. data/lib/jasmine/src/html/SpecView.js +79 -0
  49. data/lib/jasmine/src/html/SuiteView.js +22 -0
  50. data/lib/jasmine/src/html/TrivialReporter.js +3 -1
  51. data/lib/jasmine/src/html/_HTMLReporter.scss +302 -0
  52. data/lib/jasmine/src/html/_TrivialReporter.scss +169 -0
  53. data/lib/jasmine/src/html/jasmine.css +81 -166
  54. data/lib/jasmine/src/html/jasmine.scss +2 -0
  55. data/lib/jasmine/src/templates/version.js.erb +1 -0
  56. data/lib/jasmine/src/version.js +3 -2
  57. data/lib/jasmine/src/version.json +1 -1
  58. data/lib/jasmine/tasks/jasmine_dev.rb +18 -0
  59. data/lib/jasmine/tasks/jasmine_dev/base.rb +54 -0
  60. data/lib/jasmine/tasks/jasmine_dev/build_distribution.rb +53 -0
  61. data/lib/jasmine/tasks/jasmine_dev/build_github_pages.rb +31 -0
  62. data/lib/jasmine/tasks/jasmine_dev/build_standalone_distribution.rb +49 -0
  63. data/lib/jasmine/tasks/jasmine_dev/build_standalone_runner.rb +59 -0
  64. data/lib/jasmine/tasks/jasmine_dev/count_specs.rb +29 -0
  65. data/lib/jasmine/tasks/jasmine_dev/execute_specs.rb +52 -0
  66. data/lib/jasmine/tasks/jasmine_dev/js_hint.rb +13 -0
  67. data/lib/jasmine/tasks/jasmine_dev/release.rb +16 -0
  68. data/lib/jasmine/tasks/jasmine_dev/sources.rb +32 -0
  69. data/lib/jasmine/tasks/jasmine_dev/version.rb +62 -0
  70. data/spec/helper_spec.rb +25 -0
  71. data/spec/suite1/spec/javascripts/{spec_helper.coffee → helpers/spec_helper.coffee} +0 -0
  72. data/spec/suite1/spec/javascripts/{spec_helper.js → helpers/spec_helper.js} +0 -0
  73. data/spec/suite1/spec/javascripts/templates_spec.js +6 -6
  74. data/spec/suite2/spec/awesome_spec.js +1 -1
  75. data/spec/suite_spec.rb +6 -0
  76. metadata +116 -52
  77. data/lib/jasmine/src/SourcesList.json +0 -7
  78. data/lib/jasmine/tasks/build_dist.rb +0 -48
  79. data/lib/jasmine/tasks/build_specs.rb +0 -50
  80. data/lib/jasmine/tasks/helpers.rb +0 -50
  81. data/lib/jasmine/tasks/pages.rb +0 -13
  82. data/lib/jasmine/tasks/spec.rb +0 -37
  83. data/lib/jasmine/tasks/standalone.rb +0 -91
  84. data/lib/jasmine/tasks/version.rb +0 -5
@@ -1,6 +1,6 @@
1
1
  module Jasmine
2
2
  module Core
3
- VERSION = "1.1.0"
3
+ VERSION = "1.2.0"
4
4
  end
5
5
  end
6
6
 
@@ -352,6 +352,33 @@ describe("jasmine.Matchers", function() {
352
352
  }]).toEqual(["a", jasmine.any(Function)])).toPass();
353
353
  });
354
354
 
355
+ describe("toEqual with an object implementing jasmineMatches", function () {
356
+ var matcher;
357
+ beforeEach(function () {
358
+ matcher = {
359
+ jasmineMatches: jasmine.createSpy("jasmineMatches")
360
+ };
361
+ });
362
+
363
+ describe("on the left side", function () {
364
+ it("uses the jasmineMatches function", function () {
365
+ matcher.jasmineMatches.andReturn(false);
366
+ expect(match(matcher).toEqual("foo")).toFail();
367
+ matcher.jasmineMatches.andReturn(true);
368
+ expect(match(matcher).toEqual("foo")).toPass();
369
+ });
370
+ });
371
+
372
+ describe("on the right side", function () {
373
+ it("uses the jasmineMatches function", function () {
374
+ matcher.jasmineMatches.andReturn(false);
375
+ expect(match("foo").toEqual(matcher)).toFail();
376
+ matcher.jasmineMatches.andReturn(true);
377
+ expect(match("foo").toEqual(matcher)).toPass();
378
+ });
379
+ });
380
+ });
381
+
355
382
  it("toEqual handles circular objects ok", function() {
356
383
  expect(match({foo: "bar", baz: jasmine.undefined}).toEqual({foo: "bar", baz: jasmine.undefined})).toPass();
357
384
  expect(match({foo:['bar','baz','quux']}).toEqual({foo:['bar','baz','quux']})).toPass();
@@ -830,6 +857,252 @@ describe("jasmine.Matchers", function() {
830
857
  });
831
858
  });
832
859
 
860
+ describe("ObjectContaining", function () {
861
+ describe("with an empty object", function () {
862
+ var containing;
863
+ beforeEach(function () {
864
+ containing = new jasmine.Matchers.ObjectContaining({});
865
+ });
866
+ it("matches everything", function () {
867
+ expect(containing.jasmineMatches("foo", [], [])).toBe(true);
868
+ });
869
+
870
+ it("says it didn't expect to contain anything", function () {
871
+ expect(containing.jasmineToString()).toEqual("<jasmine.objectContaining({ })>");
872
+ });
873
+ });
874
+
875
+ describe("with an object with items in it", function () {
876
+ var containing, mismatchKeys, mismatchValues;
877
+ beforeEach(function () {
878
+ mismatchKeys = [];
879
+ mismatchValues = [];
880
+ containing = new jasmine.Matchers.ObjectContaining({foo: "fooVal", bar: "barVal"});
881
+ });
882
+
883
+ it("doesn't match an empty object", function () {
884
+ expect(containing.jasmineMatches({}, mismatchKeys, mismatchValues)).toBe(false);
885
+ });
886
+
887
+ it("doesn't match an object with none of the specified options", function () {
888
+ expect(containing.jasmineMatches({baz:"stuff"}, mismatchKeys, mismatchValues)).toBe(false);
889
+ });
890
+
891
+ it("adds a message for each missing key", function () {
892
+ containing.jasmineMatches({foo: "fooVal"}, mismatchKeys, mismatchValues);
893
+ expect(mismatchKeys.length).toEqual(1);
894
+ });
895
+
896
+ it("doesn't match an object when the values are different", function () {
897
+ expect(containing.jasmineMatches({foo:"notFoo", bar:"notBar"}, mismatchKeys, mismatchValues)).toBe(false);
898
+ });
899
+
900
+ it("adds a message when values don't match", function () {
901
+ containing.jasmineMatches({foo: "fooVal", bar: "notBar"}, mismatchKeys, mismatchValues);
902
+ expect(mismatchValues.length).toEqual(1);
903
+ });
904
+
905
+ it("doesn't match an object with only one of the values matching", function () {
906
+ expect(containing.jasmineMatches({foo:"notFoo", bar:"barVal"}, mismatchKeys, mismatchValues)).toBe(false);
907
+ });
908
+
909
+ it("matches when all the values are the same", function () {
910
+ expect(containing.jasmineMatches({foo: "fooVal", bar: "barVal"}, mismatchKeys, mismatchValues)).toBe(true);
911
+ });
912
+
913
+ it("matches when there are additional values", function () {
914
+ expect(containing.jasmineMatches({foo: "fooVal", bar: "barVal", baz: "bazVal"}, mismatchKeys, mismatchValues)).toBe(true);
915
+ });
916
+
917
+ it("doesn't modify missingKeys or missingValues when match is successful", function () {
918
+ containing.jasmineMatches({foo: "fooVal", bar: "barVal"}, mismatchKeys, mismatchValues);
919
+ expect(mismatchKeys.length).toEqual(0);
920
+ expect(mismatchValues.length).toEqual(0);
921
+ });
922
+
923
+ it("says what it expects to contain", function () {
924
+ expect(containing.jasmineToString()).toEqual("<jasmine.objectContaining(" + jasmine.pp({foo:"fooVal", bar:"barVal"}) + ")>");
925
+ });
926
+ });
927
+
928
+ describe("in real life", function () {
929
+ var method;
930
+ beforeEach(function () {
931
+ method = jasmine.createSpy("method");
932
+ method({a:"b", c:"d"});
933
+ });
934
+ it("works correctly for positive matches", function () {
935
+ expect(method).toHaveBeenCalledWith(jasmine.objectContaining({a:"b"}));
936
+ });
937
+
938
+ it("works correctly for negative matches", function () {
939
+ expect(method).not.toHaveBeenCalledWith(jasmine.objectContaining({z:"x"}));
940
+ });
941
+ });
942
+ });
943
+
944
+ describe("Matchers.Any", function () {
945
+ var any;
946
+ describe(".jasmineToString", function () {
947
+ describe("with Object", function () {
948
+ it("says it's looking for an object", function () {
949
+ any = jasmine.any(Object);
950
+ expect(any.jasmineToString().replace(/\n/g, "")).toMatch(/<jasmine\.any\(function Object.*\)>/);
951
+ });
952
+ });
953
+
954
+ describe("with Function", function () {
955
+ it("says it's looking for a function", function () {
956
+ any = jasmine.any(Function);
957
+ expect(any.jasmineToString().replace(/\n/g, "")).toMatch(/<jasmine\.any\(function Function.*\)>/);
958
+ });
959
+ });
960
+
961
+ describe("with String", function () {
962
+ it("says it's looking for a string", function () {
963
+ any = jasmine.any(String);
964
+ expect(any.jasmineToString().replace(/\n/g, "")).toMatch(/<jasmine\.any\(function String.*\)>/);
965
+ });
966
+ });
967
+
968
+ describe("with Number", function () {
969
+ it("says it's looking for a number", function () {
970
+ any = jasmine.any(Number);
971
+ expect(any.jasmineToString().replace(/\n/g, "")).toMatch(/<jasmine\.any\(function Number.*\)>/);
972
+ });
973
+ });
974
+
975
+ describe("with some other defined 'class'", function () {
976
+ it("says it's looking for an object", function () {
977
+ function MyClass () {}
978
+ any = jasmine.any(MyClass);
979
+ expect(any.jasmineToString().replace("\n", "")).toMatch(/<jasmine\.any\(function MyClass.*\)>/);
980
+ });
981
+ });
982
+ });
983
+
984
+ describe(".jasmineMatches", function () {
985
+ describe("with Object", function () {
986
+ beforeEach(function () {
987
+ any = jasmine.any(Object);
988
+ });
989
+
990
+ it("matches an empty object", function () {
991
+ expect(any.jasmineMatches({})).toEqual(true);
992
+ });
993
+
994
+ it("matches a newed up object", function () {
995
+ expect(any.jasmineMatches(new Object())).toEqual(true);
996
+ });
997
+
998
+ it("doesn't match a string", function () {
999
+ expect(any.jasmineMatches("")).toEqual(false);
1000
+ });
1001
+
1002
+ it("doesn't match a number", function () {
1003
+ expect(any.jasmineMatches(123)).toEqual(false);
1004
+ });
1005
+
1006
+ it("doesn't match a function", function () {
1007
+ expect(any.jasmineMatches(function () {})).toEqual(false);
1008
+ });
1009
+ });
1010
+
1011
+ describe("with Function", function () {
1012
+ beforeEach(function () {
1013
+ any = jasmine.any(Function);
1014
+ });
1015
+
1016
+ it("doesn't match an object", function () {
1017
+ expect(any.jasmineMatches({})).toEqual(false);
1018
+ });
1019
+
1020
+ it("doesn't match a string", function () {
1021
+ expect(any.jasmineMatches("")).toEqual(false);
1022
+ });
1023
+
1024
+ it("doesn't match a number", function () {
1025
+ expect(any.jasmineMatches(123)).toEqual(false);
1026
+ });
1027
+
1028
+ it("matches a function", function () {
1029
+ expect(any.jasmineMatches(function () {})).toEqual(true);
1030
+ });
1031
+ });
1032
+
1033
+ describe("with Number", function () {
1034
+ beforeEach(function () {
1035
+ any = jasmine.any(Number);
1036
+ });
1037
+
1038
+ it("doesn't match an object", function () {
1039
+ expect(any.jasmineMatches({})).toEqual(false);
1040
+ });
1041
+
1042
+ it("doesn't match a string", function () {
1043
+ expect(any.jasmineMatches("")).toEqual(false);
1044
+ });
1045
+
1046
+ it("matches a number", function () {
1047
+ expect(any.jasmineMatches(123)).toEqual(true);
1048
+ });
1049
+
1050
+ it("doesn't match a function", function () {
1051
+ expect(any.jasmineMatches(function () {})).toEqual(false);
1052
+ });
1053
+ });
1054
+
1055
+ describe("with String", function () {
1056
+ beforeEach(function () {
1057
+ any = jasmine.any(String);
1058
+ });
1059
+
1060
+ it("doesn't match an object", function () {
1061
+ expect(any.jasmineMatches({})).toEqual(false);
1062
+ });
1063
+
1064
+ it("matches a string", function () {
1065
+ expect(any.jasmineMatches("")).toEqual(true);
1066
+ });
1067
+
1068
+ it("doesn't match a number", function () {
1069
+ expect(any.jasmineMatches(123)).toEqual(false);
1070
+ });
1071
+
1072
+ it("doesn't match a function", function () {
1073
+ expect(any.jasmineMatches(function () {})).toEqual(false);
1074
+ });
1075
+ });
1076
+
1077
+ describe("with some defined 'class'", function () {
1078
+ function MyClass () {}
1079
+ beforeEach(function () {
1080
+ any = jasmine.any(MyClass);
1081
+ });
1082
+
1083
+ it("doesn't match an object", function () {
1084
+ expect(any.jasmineMatches({})).toEqual(false);
1085
+ });
1086
+
1087
+ it("doesn't match a string", function () {
1088
+ expect(any.jasmineMatches("")).toEqual(false);
1089
+ });
1090
+
1091
+ it("doesn't match a number", function () {
1092
+ expect(any.jasmineMatches(123)).toEqual(false);
1093
+ });
1094
+
1095
+ it("doesn't match a function", function () {
1096
+ expect(any.jasmineMatches(function () {})).toEqual(false);
1097
+ });
1098
+
1099
+ it("matches an instance of the defined class", function () {
1100
+ expect(any.jasmineMatches(new MyClass())).toEqual(true);
1101
+ });
1102
+ });
1103
+ });
1104
+ });
1105
+
833
1106
  describe("all matchers", function() {
834
1107
  it("should return null, for future-proofing, since we might eventually allow matcher chaining", function() {
835
1108
  expect(match(true).toBe(true)).toBeUndefined();
@@ -83,5 +83,12 @@ describe("jasmine.pp", function () {
83
83
  expect(jasmine.pp(jasmine.createSpy("something"))).toEqual("spy on something");
84
84
  });
85
85
 
86
+ it("should stringify objects that implement jasmineToString", function () {
87
+ var obj = {
88
+ jasmineToString: function () { return "strung"; }
89
+ };
90
+
91
+ expect(jasmine.pp(obj)).toEqual("strung");
92
+ });
86
93
  });
87
94
 
@@ -0,0 +1,209 @@
1
+ describe("HtmlReporter", function() {
2
+ var env;
3
+ var htmlReporter;
4
+ var body;
5
+ var fakeDocument;
6
+
7
+ beforeEach(function() {
8
+ env = new jasmine.Env();
9
+ env.updateInterval = 0;
10
+
11
+ body = document.createElement("body");
12
+ fakeDocument = { body: body, location: { search: "" } };
13
+ htmlReporter = new jasmine.HtmlReporter(fakeDocument);
14
+ });
15
+
16
+ function fakeSpec(name) {
17
+ return {
18
+ getFullName: function() {
19
+ return name;
20
+ }
21
+ };
22
+ }
23
+
24
+ function findElements(divs, withClass) {
25
+ var els = [];
26
+ for (var i = 0; i < divs.length; i++) {
27
+ if (divs[i].className == withClass) els.push(divs[i]);
28
+ }
29
+ return els;
30
+ }
31
+
32
+ function findElement(divs, withClass) {
33
+ var els = findElements(divs, withClass);
34
+ if (els.length > 0) {
35
+ return els[0];
36
+ }
37
+ throw new Error("couldn't find div with class " + withClass);
38
+ }
39
+
40
+ it("should run only specs beginning with spec parameter", function() {
41
+ fakeDocument.location.search = "?spec=run%20this";
42
+ expect(htmlReporter.specFilter(fakeSpec("run this"))).toBeTruthy();
43
+ expect(htmlReporter.specFilter(fakeSpec("not the right spec"))).toBeFalsy();
44
+ expect(htmlReporter.specFilter(fakeSpec("not run this"))).toBeFalsy();
45
+ });
46
+
47
+ describe("running without any specs", function() {
48
+ var runner;
49
+ beforeEach(function() {
50
+ runner = env.currentRunner();
51
+ env.addReporter(htmlReporter);
52
+ });
53
+
54
+ it("should not error", function() {
55
+ var exec = function() {
56
+ runner.execute();
57
+ };
58
+ expect(exec).not.toThrow();
59
+ });
60
+ });
61
+
62
+ describe('Matcher reporting', function() {
63
+ var getResultMessageDiv = function(body) {
64
+ var divs = body.getElementsByTagName("div");
65
+ for (var i = 0; i < divs.length; i++) {
66
+ if (divs[i].className.match(/resultMessage/)) {
67
+ return divs[i];
68
+ }
69
+ }
70
+ };
71
+
72
+ var runner, spec, fakeTimer;
73
+ beforeEach(function() {
74
+ fakeTimer = new jasmine.FakeTimer();
75
+ env.setTimeout = fakeTimer.setTimeout;
76
+ env.clearTimeout = fakeTimer.clearTimeout;
77
+ env.setInterval = fakeTimer.setInterval;
78
+ env.clearInterval = fakeTimer.clearInterval;
79
+ runner = env.currentRunner();
80
+ var suite = new jasmine.Suite(env, 'some suite');
81
+ runner.add(suite);
82
+ spec = new jasmine.Spec(env, suite, 'some spec');
83
+ suite.add(spec);
84
+ fakeDocument.location.search = "?";
85
+ env.addReporter(htmlReporter);
86
+ });
87
+
88
+ describe('toContain', function() {
89
+ it('should show actual and expected', function() {
90
+ spec.runs(function() {
91
+ this.expect('foo').toContain('bar');
92
+ });
93
+ runner.execute();
94
+ fakeTimer.tick(0);
95
+
96
+ var resultEl = getResultMessageDiv(body);
97
+ expect(resultEl.innerHTML).toMatch(/foo/);
98
+ expect(resultEl.innerHTML).toMatch(/bar/);
99
+ });
100
+ });
101
+ });
102
+
103
+ describe("failure messages (integration)", function() {
104
+ var spec, results, expectationResult;
105
+
106
+ it("should add the failure message to the DOM (non-toEquals matchers)", function() {
107
+ env.describe("suite", function() {
108
+ env.it("will have log messages", function() {
109
+ this.expect('a').toBeNull();
110
+ });
111
+ });
112
+
113
+ env.addReporter(htmlReporter);
114
+ env.execute();
115
+
116
+ var divs = body.getElementsByTagName("div");
117
+ var errorDiv = findElement(divs, 'resultMessage fail');
118
+ expect(errorDiv.innerHTML).toMatch(/Expected 'a' to be null/);
119
+ });
120
+
121
+ it("should add the failure message to the DOM (non-toEquals matchers) html escaping", function() {
122
+ env.describe("suite", function() {
123
+ env.it("will have log messages", function() {
124
+ this.expect('1 < 2').toBeNull();
125
+ });
126
+ });
127
+
128
+ env.addReporter(htmlReporter);
129
+ env.execute();
130
+
131
+ var divs = body.getElementsByTagName("div");
132
+ var errorDiv = findElement(divs, 'resultMessage fail');
133
+ expect(errorDiv.innerHTML).toMatch(/Expected '1 &lt; 2' to be null/);
134
+ });
135
+ });
136
+
137
+ describe("log messages", function() {
138
+ it("should appear in the report of a failed spec", function() {
139
+ env.describe("suite", function() {
140
+ env.it("will have log messages", function() {
141
+ this.log("this is a", "multipart log message");
142
+ this.expect(true).toBeFalsy();
143
+ });
144
+ });
145
+
146
+ env.addReporter(htmlReporter);
147
+ env.execute();
148
+
149
+ var divs = body.getElementsByTagName("div");
150
+ var errorDiv = findElement(divs, 'specDetail failed');
151
+ expect(errorDiv.innerHTML).toMatch("this is a multipart log message");
152
+ });
153
+
154
+ xit("should work on IE without console.log.apply", function() {
155
+ });
156
+ });
157
+
158
+ describe("duplicate example names", function() {
159
+ it("should report failures correctly", function() {
160
+ var suite1 = env.describe("suite", function() {
161
+ env.it("will have log messages", function() {
162
+ this.log("this one fails!");
163
+ this.expect(true).toBeFalsy();
164
+ });
165
+ });
166
+
167
+ var suite2 = env.describe("suite", function() {
168
+ env.it("will have log messages", function() {
169
+ this.log("this one passes!");
170
+ this.expect(true).toBeTruthy();
171
+ });
172
+ });
173
+
174
+ env.addReporter(htmlReporter);
175
+ env.execute();
176
+
177
+ var divs = body.getElementsByTagName("div");
178
+ var failedSpecDiv = findElement(divs, 'specDetail failed');
179
+ expect(failedSpecDiv.className).toEqual('specDetail failed');
180
+ expect(failedSpecDiv.innerHTML).toContain("this one fails!");
181
+ expect(failedSpecDiv.innerHTML).not.toContain("this one passes!");
182
+ });
183
+ });
184
+
185
+ describe('#reportSpecStarting', function() {
186
+ beforeEach(function() {
187
+ env.describe("suite 1", function() {
188
+ env.it("spec 1", function() {
189
+ });
190
+ });
191
+ spyOn(htmlReporter, 'log').andCallThrough();
192
+ });
193
+
194
+ it('DOES NOT log running specs by default', function() {
195
+ env.addReporter(htmlReporter);
196
+ env.execute();
197
+
198
+ expect(htmlReporter.log).not.toHaveBeenCalled();
199
+ });
200
+
201
+ it('logs running specs when log_running_specs is true', function() {
202
+ htmlReporter.logRunningSpecs = true;
203
+ env.addReporter(htmlReporter);
204
+ env.execute();
205
+
206
+ expect(htmlReporter.log).toHaveBeenCalledWith('>> Jasmine Running suite 1 spec 1...');
207
+ });
208
+ });
209
+ });