teaspoon 0.7.9 → 0.8.0

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 (163) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +382 -260
  3. data/app/assets/javascripts/teaspoon-angular.js +108 -26241
  4. data/app/assets/javascripts/teaspoon-jasmine.js +103 -2642
  5. data/app/assets/javascripts/teaspoon-mocha.js +109 -5416
  6. data/app/assets/javascripts/teaspoon-qunit.js +107 -2255
  7. data/app/assets/javascripts/teaspoon-teaspoon.js +0 -1
  8. data/app/assets/javascripts/teaspoon/angular.coffee +3 -1
  9. data/app/assets/javascripts/teaspoon/base/hook.coffee +21 -0
  10. data/app/assets/javascripts/teaspoon/base/reporters/html.coffee +26 -14
  11. data/app/assets/javascripts/teaspoon/base/reporters/html/progress_view.coffee +1 -1
  12. data/app/assets/javascripts/teaspoon/base/reporters/html/template.coffee +3 -3
  13. data/app/assets/javascripts/teaspoon/base/teaspoon.coffee +10 -1
  14. data/app/assets/javascripts/teaspoon/jasmine.coffee +3 -1
  15. data/app/assets/javascripts/teaspoon/mocha.coffee +3 -1
  16. data/app/assets/javascripts/teaspoon/mocha/reporters/html.coffee +1 -1
  17. data/app/assets/javascripts/teaspoon/qunit.coffee +3 -1
  18. data/app/assets/javascripts/teaspoon/qunit/reporters/html.coffee +1 -1
  19. data/app/assets/javascripts/teaspoon/teaspoon.coffee +0 -1
  20. data/app/assets/stylesheets/teaspoon.css +12 -8
  21. data/app/controllers/teaspoon/suite_controller.rb +32 -0
  22. data/app/views/teaspoon/suite/_body.html.erb +0 -0
  23. data/app/views/teaspoon/suite/_boot.html.erb +4 -0
  24. data/app/views/teaspoon/suite/_boot_require_js.html.erb +19 -0
  25. data/app/views/teaspoon/{spec/suites.html.erb → suite/index.html.erb} +6 -7
  26. data/app/views/teaspoon/suite/show.html.erb +19 -0
  27. data/bin/teaspoon +1 -1
  28. data/config/routes.rb +14 -4
  29. data/lib/generators/teaspoon/install/POST_INSTALL +2 -2
  30. data/lib/generators/teaspoon/install/install_generator.rb +22 -11
  31. data/lib/generators/teaspoon/install/templates/_body.html.erb +0 -0
  32. data/lib/generators/teaspoon/install/templates/_boot.html.erb +4 -0
  33. data/lib/generators/teaspoon/install/templates/jasmine/env.rb +11 -0
  34. data/lib/generators/teaspoon/install/templates/jasmine/env_comments.rb +182 -0
  35. data/lib/generators/teaspoon/install/templates/jasmine/spec_helper.coffee +8 -6
  36. data/lib/generators/teaspoon/install/templates/jasmine/spec_helper.js +8 -7
  37. data/lib/generators/teaspoon/install/templates/mocha/env.rb +11 -0
  38. data/lib/generators/teaspoon/install/templates/mocha/env_comments.rb +182 -0
  39. data/lib/generators/teaspoon/install/templates/mocha/spec_helper.coffee +13 -13
  40. data/lib/generators/teaspoon/install/templates/mocha/spec_helper.js +13 -13
  41. data/lib/generators/teaspoon/install/templates/qunit/env.rb +11 -0
  42. data/lib/generators/teaspoon/install/templates/qunit/env_comments.rb +182 -0
  43. data/lib/generators/teaspoon/install/templates/qunit/test_helper.coffee +6 -5
  44. data/lib/generators/teaspoon/install/templates/qunit/test_helper.js +6 -5
  45. data/lib/tasks/teaspoon.rake +9 -2
  46. data/lib/teaspoon.rb +4 -6
  47. data/lib/teaspoon/command_line.rb +116 -134
  48. data/lib/teaspoon/configuration.rb +144 -66
  49. data/lib/teaspoon/console.rb +70 -37
  50. data/lib/teaspoon/coverage.rb +42 -15
  51. data/lib/teaspoon/deprecated.rb +65 -0
  52. data/lib/teaspoon/drivers/base.rb +10 -0
  53. data/lib/teaspoon/drivers/phantomjs/runner.js +9 -11
  54. data/lib/teaspoon/drivers/phantomjs_driver.rb +21 -21
  55. data/lib/teaspoon/drivers/selenium_driver.rb +32 -13
  56. data/lib/teaspoon/engine.rb +32 -12
  57. data/lib/teaspoon/environment.rb +16 -12
  58. data/lib/teaspoon/exceptions.rb +41 -5
  59. data/lib/teaspoon/exporter.rb +52 -0
  60. data/lib/teaspoon/formatters/base.rb +171 -0
  61. data/lib/teaspoon/formatters/clean_formatter.rb +2 -4
  62. data/lib/teaspoon/formatters/documentation_formatter.rb +60 -0
  63. data/lib/teaspoon/formatters/dot_formatter.rb +12 -90
  64. data/lib/teaspoon/formatters/json_formatter.rb +36 -0
  65. data/lib/teaspoon/formatters/junit_formatter.rb +51 -32
  66. data/lib/teaspoon/formatters/modules/report_module.rb +76 -0
  67. data/lib/teaspoon/formatters/pride_formatter.rb +23 -27
  68. data/lib/teaspoon/formatters/snowday_formatter.rb +7 -11
  69. data/lib/teaspoon/formatters/swayze_or_oprah_formatter.rb +88 -64
  70. data/lib/teaspoon/formatters/tap_formatter.rb +18 -27
  71. data/lib/teaspoon/formatters/tap_y_formatter.rb +35 -45
  72. data/lib/teaspoon/formatters/teamcity_formatter.rb +69 -31
  73. data/lib/teaspoon/instrumentation.rb +33 -33
  74. data/lib/teaspoon/result.rb +2 -1
  75. data/lib/teaspoon/runner.rb +40 -28
  76. data/lib/teaspoon/server.rb +23 -25
  77. data/lib/teaspoon/suite.rb +52 -72
  78. data/lib/teaspoon/utility.rb +3 -14
  79. data/lib/teaspoon/version.rb +1 -1
  80. data/spec/dummy/app/assets/javascripts/integration/integration_spec.coffee +3 -0
  81. data/spec/dummy/app/assets/javascripts/integration/spec_helper.coffee +2 -0
  82. data/spec/dummy/config/application.rb +3 -0
  83. data/spec/features/console_reporter_spec.rb +48 -18
  84. data/spec/features/hooks_spec.rb +23 -41
  85. data/spec/features/html_reporter_spec.rb +38 -21
  86. data/spec/features/install_generator_spec.rb +34 -20
  87. data/spec/features/instrumentation_spec.rb +3 -2
  88. data/spec/fixtures/coverage.json +243 -0
  89. data/spec/javascripts/fixtures/_body.html.erb +1 -0
  90. data/spec/javascripts/jasmine_helper.coffee +1 -1
  91. data/spec/javascripts/teaspoon/base/fixture_spec.coffee +4 -4
  92. data/spec/javascripts/teaspoon/base/reporters/html_spec.coffee +9 -10
  93. data/spec/javascripts/teaspoon/mocha/reporters/html_mspec.coffee +0 -6
  94. data/spec/javascripts/teaspoon/phantomjs/runner_spec.coffee +5 -6
  95. data/spec/javascripts/turbolinks_helper.coffee +1 -1
  96. data/spec/spec_helper.rb +3 -4
  97. data/spec/teaspoon/command_line_spec.rb +139 -23
  98. data/spec/teaspoon/configuration_spec.rb +164 -46
  99. data/spec/teaspoon/console_spec.rb +142 -47
  100. data/spec/teaspoon/coverage_spec.rb +98 -28
  101. data/spec/teaspoon/drivers/base_spec.rb +5 -0
  102. data/spec/teaspoon/drivers/phantomjs_driver_spec.rb +32 -14
  103. data/spec/teaspoon/drivers/selenium_driver_spec.rb +32 -24
  104. data/spec/teaspoon/engine_spec.rb +8 -5
  105. data/spec/teaspoon/environment_spec.rb +56 -33
  106. data/spec/teaspoon/exceptions_spec.rb +57 -0
  107. data/spec/teaspoon/exporter_spec.rb +96 -0
  108. data/spec/teaspoon/formatters/base_spec.rb +259 -0
  109. data/spec/teaspoon/formatters/clean_formatter_spec.rb +37 -0
  110. data/spec/teaspoon/formatters/documentation_formatter_spec.rb +127 -0
  111. data/spec/teaspoon/formatters/dot_formatter_spec.rb +52 -56
  112. data/spec/teaspoon/formatters/json_formatter_spec.rb +77 -0
  113. data/spec/teaspoon/formatters/junit_formatter_spec.rb +72 -35
  114. data/spec/teaspoon/formatters/pride_formatter_spec.rb +37 -0
  115. data/spec/teaspoon/formatters/snowday_formatter_spec.rb +35 -0
  116. data/spec/teaspoon/formatters/tap_formatter_spec.rb +29 -81
  117. data/spec/teaspoon/formatters/tap_y_formatter_spec.rb +31 -141
  118. data/spec/teaspoon/formatters/teamcity_formatter_spec.rb +99 -42
  119. data/spec/teaspoon/instrumentation_spec.rb +44 -44
  120. data/spec/teaspoon/result_spec.rb +37 -0
  121. data/spec/teaspoon/runner_spec.rb +70 -59
  122. data/spec/teaspoon/server_spec.rb +34 -52
  123. data/spec/teaspoon/suite_spec.rb +42 -188
  124. data/spec/teaspoon_env.rb +39 -28
  125. data/vendor/assets/javascripts/{angular-scenario-1.0.5.js → angular/1.0.5.js} +0 -0
  126. data/vendor/assets/javascripts/{angular-scenario-1.0.5.MIT-LICENSE → angular/MIT-LICENSE} +0 -0
  127. data/vendor/assets/javascripts/{jasmine-1.3.1.js → jasmine/1.3.1.js} +0 -0
  128. data/vendor/assets/javascripts/jasmine/2.0.0.js +2412 -0
  129. data/vendor/assets/javascripts/{jasmine-1.3.1.MIT.LICENSE → jasmine/MIT.LICENSE} +0 -0
  130. data/vendor/assets/javascripts/{mocha-1.10.0.js → mocha/1.10.0.js} +1 -0
  131. data/vendor/assets/javascripts/mocha/1.17.1.js +5813 -0
  132. data/vendor/assets/javascripts/{mocha-1.10.1.MIT.LICENSE → mocha/MIT.LICENSE} +0 -0
  133. data/vendor/assets/javascripts/{qunit-1.12.0.js → qunit/1.12.0.js} +1 -1
  134. data/vendor/assets/javascripts/qunit/1.14.0.js +2288 -0
  135. data/vendor/assets/javascripts/{qunit-1.12.0.MIT.LICENSE → qunit/MIT.LICENSE} +0 -0
  136. data/vendor/assets/javascripts/support/chai.js +827 -385
  137. data/vendor/assets/javascripts/support/jasmine-jquery-1.7.0.js +720 -0
  138. data/vendor/assets/javascripts/support/jasmine-jquery-2.0.0.js +812 -0
  139. data/vendor/assets/javascripts/support/sinon-chai.js +17 -0
  140. data/vendor/assets/javascripts/support/sinon.js +1138 -643
  141. metadata +57 -36
  142. data/app/controllers/teaspoon/spec_controller.rb +0 -38
  143. data/app/helpers/teaspoon/spec_helper.rb +0 -36
  144. data/app/views/teaspoon/spec/_require_js.html.erb +0 -21
  145. data/app/views/teaspoon/spec/_standard.html.erb +0 -4
  146. data/app/views/teaspoon/spec/runner.html.erb +0 -19
  147. data/lib/generators/teaspoon/install/templates/env.rb +0 -38
  148. data/lib/generators/teaspoon/install/templates/jasmine/initializer.rb +0 -64
  149. data/lib/generators/teaspoon/install/templates/mocha/initializer.rb +0 -64
  150. data/lib/generators/teaspoon/install/templates/qunit/initializer.rb +0 -64
  151. data/lib/teaspoon/check_coverage.rb +0 -33
  152. data/lib/teaspoon/drivers/base_driver.rb +0 -10
  153. data/lib/teaspoon/exception_handling.rb +0 -18
  154. data/lib/teaspoon/formatters/base_formatter.rb +0 -63
  155. data/spec/dummy/config/initializers/teaspoon.rb +0 -41
  156. data/spec/teaspoon/check_coverage_spec.rb +0 -50
  157. data/spec/teaspoon/formatters/base_formatter_spec.rb +0 -45
  158. data/vendor/assets/javascripts/support/chai.MIT.LICENSE +0 -22
  159. data/vendor/assets/javascripts/support/expect.MIT.LICENSE +0 -22
  160. data/vendor/assets/javascripts/support/jasmine-jquery.MIT.LICENSE +0 -20
  161. data/vendor/assets/javascripts/support/jasmine-jquery.js +0 -659
  162. data/vendor/assets/javascripts/support/sinon-chai.MIT-ISH.LICENSE +0 -13
  163. data/vendor/assets/javascripts/support/sinon.BSD.LICENSE +0 -27
@@ -1,111 +1,206 @@
1
1
  require "spec_helper"
2
2
  require "teaspoon/console"
3
+ require "teaspoon/server"
4
+ require "teaspoon/runner"
5
+ require "teaspoon/exporter"
3
6
 
4
7
  describe Teaspoon::Console do
5
8
 
9
+ let(:driver) { double(run_specs: 0) }
6
10
  let(:server) { double(start: nil, url: "http://url.com") }
7
- subject {
8
- Teaspoon::Console.any_instance.stub(:start_server)
9
- instance = Teaspoon::Console.new
10
- instance.instance_variable_set(:@server, server)
11
- instance
12
- }
11
+ let(:runner) { double(failure_count: 2) }
13
12
 
14
13
  before do
15
- subject.instance_variable_set(:@server, server)
16
14
  Teaspoon::Environment.stub(:load)
15
+ Teaspoon::Server.stub(:new).and_return(server)
16
+ Teaspoon::Runner.stub(:new).and_return(runner)
17
+
18
+ Teaspoon::Console.any_instance.stub(:driver).and_return(driver)
19
+ Teaspoon::Console.any_instance.stub(:log)
17
20
  end
18
21
 
19
22
  describe "#initialize" do
20
23
 
21
24
  it "assigns @options" do
22
- options = {foo: "bar"}
23
- instance = Teaspoon::Console.new(options)
24
- expect(instance.instance_variable_get(:@options)).to eql(options)
25
+ subject = Teaspoon::Console.new(foo: "bar")
26
+ expect(subject.instance_variable_get(:@options)).to eql(foo: "bar")
25
27
  end
26
28
 
27
29
  it "loads the environment" do
28
- Teaspoon::Environment.should_receive(:load).once
29
- Teaspoon::Console.new()
30
+ Teaspoon::Environment.should_receive(:load)
31
+ Teaspoon::Console.new
30
32
  end
31
33
 
32
34
  it "starts the server" do
35
+ Teaspoon::Console.any_instance.should_receive(:log).with("Starting the Teaspoon server...")
33
36
  Teaspoon::Console.any_instance.should_receive(:start_server).and_call_original
34
37
  Teaspoon::Server.should_receive(:new).and_return(server)
35
38
  server.should_receive(:start)
36
- subject.start_server
37
- Teaspoon::Console.new()
39
+ Teaspoon::Console.new
38
40
  end
39
41
 
40
- it "resolves the files" do
41
- files = ["file1"]
42
- Teaspoon::Console.any_instance.should_receive(:resolve).with(files)
43
- Teaspoon::Console.new(nil, files)
42
+ it "aborts (displaying a message) on Teaspoon::ServerException" do
43
+ STDOUT.should_receive(:print).with("_message_\n")
44
+ Teaspoon::Console.any_instance.should_receive(:log).and_call_original
45
+ Teaspoon::Console.any_instance.should_receive(:start_server).and_raise(Teaspoon::ServerException, "_message_")
46
+ Teaspoon::Console.any_instance.should_receive(:abort).with("_message_").and_call_original
47
+ expect{ Teaspoon::Console.new }.to raise_error SystemExit
48
+ end
49
+
50
+ end
51
+
52
+ describe "#failures?" do
53
+
54
+ it "calls #execute and returns the inverse of #executes return value" do
55
+ subject.should_receive(:execute).and_return(false)
56
+ expect(subject.failures?).to be_true
57
+
58
+ subject.should_receive(:execute).and_return(true)
59
+ expect(subject.failures?).to be_false
44
60
  end
45
61
 
46
62
  end
47
63
 
48
64
  describe "#execute" do
49
65
 
66
+ it "calls #execute_without_handling and returns its value" do
67
+ subject.should_receive(:execute_without_handling).with(foo: "bar").and_return(true)
68
+ expect(subject.execute(foo: "bar")).to be_true
69
+ end
70
+
71
+ it "handles Teaspoon::Error exceptions" do
72
+ subject.should_receive(:abort).with("_unknown_error_")
73
+ subject.should_receive(:execute_without_handling).and_raise(Teaspoon::Error, "_unknown_error_")
74
+ subject.execute
75
+ end
76
+
77
+ it "returns false on Teaspoon::Failure" do
78
+ subject.should_receive(:execute_without_handling).and_raise(Teaspoon::Failure)
79
+ expect(subject.execute).to be_false
80
+ end
81
+
82
+ end
83
+
84
+ describe "#execute_without_handling" do
85
+
50
86
  before do
51
- STDOUT.stub(:print)
52
87
  subject.stub(:run_specs).and_return(0)
88
+ subject.stub(:export)
53
89
  end
54
90
 
55
- it "assigns @options" do
56
- options = {foo: "bar"}
57
- instance = Teaspoon::Console.new(options)
58
- expect(instance.instance_variable_get(:@options)).to eql(options)
91
+ it "merges @options" do
92
+ subject.instance_variable_set(:@options, foo: "bar")
93
+ subject.execute_without_handling(bar: "baz")
94
+ expect(subject.instance_variable_get(:@options)).to eql(foo: "bar", bar: "baz")
95
+ end
96
+
97
+ it "clears any @suites" do
98
+ subject.instance_variable_set(:@suites, foo: "bar")
99
+ subject.execute_without_handling
100
+ expect(subject.instance_variable_get(:@suites)).to eql({})
59
101
  end
60
102
 
61
103
  it "resolves the files" do
62
- files = ["file2"]
63
- Teaspoon::Suite.should_receive(:resolve_spec_for).with("file2").and_return(suite: "foo", path: "file2")
64
- subject.execute(nil, files)
65
- expect(subject.instance_variable_get(:@files)).to eq(files)
104
+ Teaspoon::Suite.should_receive(:resolve_spec_for).with("file").and_return(suite: "foo", path: "file2")
105
+ subject.execute_without_handling(files: ["file"])
66
106
 
67
- suites = subject.send(:suites)
68
- expect(suites).to eq(["foo"])
107
+ expect(subject.send(:suites)).to eq(["foo"])
69
108
  expect(subject.send(:filter, "foo")).to eq("file[]=file2")
70
109
  end
71
110
 
72
111
  it "resolves the files if a directory was given" do
73
- directory = [ "test/javascripts" ]
74
112
  resolve_spec_for_output = ['test/javascripts/foo.coffee', 'test/javascripts/bar.coffee']
75
- Teaspoon::Suite.should_receive(:resolve_spec_for).with("test/javascripts").and_return(suite: "foo", path: resolve_spec_for_output)
76
- subject.execute(nil, directory)
77
- expect(subject.instance_variable_get(:@files)).to eq(directory)
78
-
79
- suites = subject.send(:suites)
80
- expect(suites).to eq(["foo"])
113
+ Teaspoon::Suite.should_receive(:resolve_spec_for).with("full/path").and_return(suite: "foo", path: resolve_spec_for_output)
114
+ subject.execute_without_handling(files: ["full/path"])
115
+ expect(subject.send(:suites)).to eq(["foo"])
81
116
  expect(subject.send(:filter, "foo")).to eq("file[]=#{resolve_spec_for_output.join('&file[]=')}")
82
117
  end
83
118
 
84
119
  it "runs the tests" do
85
120
  subject.should_receive(:suites).and_return([:default, :foo])
86
- STDOUT.should_receive(:print).with("Teaspoon running default suite at http://url.com/teaspoon/default\n")
87
- STDOUT.should_receive(:print).with("Teaspoon running foo suite at http://url.com/teaspoon/foo\n")
88
121
  subject.should_receive(:run_specs).twice.and_return(2)
89
- result = subject.execute
90
- expect(result).to be(true)
122
+ expect(subject.execute_without_handling).to be_false
91
123
  end
92
124
 
93
- it "tracks the failure count" do
125
+ it "returns true if no failure count" do
94
126
  subject.should_receive(:suites).and_return([:default, :foo])
95
127
  subject.should_receive(:run_specs).twice.and_return(0)
96
- result = subject.execute
97
- expect(result).to be(false)
128
+ expect(subject.execute_without_handling).to be_true
129
+ end
130
+
131
+ it "returns true if there were failures" do
132
+ subject.should_receive(:suites).and_return([:default])
133
+ subject.should_receive(:run_specs).once.and_return(1)
134
+ expect(subject.execute_without_handling).to be_false
135
+ end
136
+
137
+ it "calls export if the options include :export" do
138
+ subject.should_receive(:suites).and_return([:default, :foo])
139
+ subject.instance_variable_set(:@options, export: true)
140
+ subject.should_receive(:export).with(:default)
141
+ subject.should_receive(:export).with(:foo)
142
+ subject.execute
98
143
  end
99
144
 
100
145
  end
101
146
 
102
147
  describe "#run_specs" do
103
148
 
104
- it "calls run_specs on the driver" do
105
- driver = double(run_specs: nil)
149
+ before do
150
+ Teaspoon.configuration.stub(:fail_fast).and_return(false)
151
+ Teaspoon.configuration.should_receive(:suite_configs).and_return("_suite_" => proc{}, "suite_name" => proc{})
152
+ end
153
+
154
+ it "raises a Teaspoon::UnknownSuite exception when the suite isn't known" do
155
+ expect { subject.run_specs("_unknown_") }.to raise_error Teaspoon::UnknownSuite
156
+ end
157
+
158
+ it "logs that the suite is being run" do
159
+ subject.should_receive(:log).with("Teaspoon running _suite_ suite at http://url.com/teaspoon/_suite_")
160
+ subject.run_specs("_suite_")
161
+ end
162
+
163
+ it "calls #run_specs on the driver" do
106
164
  subject.should_receive(:driver).and_return(driver)
107
- driver.should_receive(:run_specs).with(:suite_name, "http://url.com/teaspoon/suite_name?reporter=Console", nil)
108
- subject.run_specs(:suite_name)
165
+ driver.should_receive(:run_specs).with(runner, "http://url.com/teaspoon/suite_name?reporter=Console")
166
+ expect(subject.run_specs(:suite_name)).to eq(2)
167
+ end
168
+
169
+ it "raises a Teaspoon::Failure exception on failures when set to fail_fast" do
170
+ Teaspoon.configuration.stub(:fail_fast).and_return(true)
171
+ expect { subject.run_specs(:suite_name) }.to raise_error Teaspoon::Failure
172
+ end
173
+
174
+ it "raises a Teaspoon:UnknownDriver when an unknown driver is being used" do
175
+ Teaspoon.configuration.should_receive(:driver).twice.and_return(:foo)
176
+ subject.should_receive(:driver).and_call_original
177
+ expect { subject.run_specs(:suite_name) }.to raise_error Teaspoon::UnknownDriver
178
+ end
179
+
180
+ end
181
+
182
+ describe "#export" do
183
+
184
+ before do
185
+ Teaspoon.configuration.should_receive(:suite_configs).and_return("_suite_" => proc{}, "suite_name" => proc{})
186
+ Teaspoon::Exporter.stub(:new).and_return(double(export: nil))
187
+ end
188
+
189
+ it "raises a Teaspoon::UnknownSuite exception when the suite isn't known" do
190
+ expect { subject.export("_unknown_") }.to raise_error Teaspoon::UnknownSuite
191
+ end
192
+
193
+ it "logs that the suite is being exported" do
194
+ subject.should_receive(:log).with("Teaspoon exporting _suite_ suite at http://url.com/teaspoon/_suite_")
195
+ subject.export("_suite_")
196
+ end
197
+
198
+ it "calls #export on the exporter" do
199
+ subject.instance_variable_set(:@options, export: "_output_path_")
200
+ exporter = double(export: nil)
201
+ Teaspoon::Exporter.should_receive(:new).with("_suite_", "http://url.com/teaspoon/_suite_", "_output_path_").and_return(exporter)
202
+ exporter.should_receive(:export)
203
+ subject.export("_suite_")
109
204
  end
110
205
 
111
206
  end
@@ -3,44 +3,114 @@ require "teaspoon/coverage"
3
3
 
4
4
  describe Teaspoon::Coverage do
5
5
 
6
- subject { Teaspoon::Coverage.new({"foo" => "bar"}, "default") }
6
+ subject { Teaspoon::Coverage.new("_suite_", "default", data) }
7
+ let(:data) { {foo: "bar"} }
8
+ let(:config) { double }
7
9
 
8
- describe "#reports" do
10
+ before do
11
+ Teaspoon::Instrumentation.stub(:executable).and_return("/path/to/executable")
12
+ subject.stub(:`).and_return("")
13
+ subject.stub(:input_path).and_yield("/temp_path/coverage.json")
14
+ subject.instance_variable_set(:@config, config)
15
+ end
9
16
 
10
- before do
11
- Teaspoon.configuration.should_receive(:coverage_reports).and_return(["text", "text-summary", "html"])
12
- subject.stub(:generate_report) { |i, f| "_#{f}_report_" }
13
- File.stub(:open)
17
+ describe "#initialize" do
18
+
19
+ it "sets @suite_name" do
20
+ expect(subject.instance_variable_get(:@suite_name)).to eq("_suite_")
21
+ end
22
+
23
+ it "finds the executable from instrumentation" do
24
+ expect(subject.instance_variable_get(:@executable)).to eq("/path/to/executable")
25
+ end
26
+
27
+ it "gets the coverage configuration" do
28
+ Teaspoon::Coverage.any_instance.should_receive(:coverage_configuration).with("default")
29
+ subject = Teaspoon::Coverage.new("_suite_", :default, data)
30
+ end
31
+
32
+ end
33
+
34
+ describe "#generate_reports" do
14
35
 
15
- @check_coverage = double('check_coverage')
16
- Teaspoon::CheckCoverage.stub(:new).and_return(@check_coverage)
36
+ let(:config) { double(reports: ["html", "text", "text-summary"], output_path: "output/path") }
17
37
 
18
- path = nil
19
- Dir.mktmpdir { |p| path = p }
20
- Dir.stub(:mktmpdir).and_yield(path)
21
- @output = File.join(path, "coverage.json")
38
+ it "generates reports using istanbul and passes them to the block provided" do
39
+ `(exit 0)`
40
+ html_report = "/path/to/executable report html /temp_path/coverage.json --dir output/path/_suite_ 2>&1"
41
+ text1_report = "/path/to/executable report text /temp_path/coverage.json --dir output/path/_suite_ 2>&1"
42
+ text2_report = "/path/to/executable report text-summary /temp_path/coverage.json --dir output/path/_suite_ 2>&1"
43
+ subject.should_receive(:`).with(html_report).and_return("_html_report_")
44
+ subject.should_receive(:`).with(text1_report).and_return("_text1_report_")
45
+ subject.should_receive(:`).with(text2_report).and_return("_text2_report_")
46
+ subject.generate_reports { |r| @result = r }
47
+ expect(@result).to eq("_text1_report_\n\n_text2_report_")
22
48
  end
23
49
 
24
- it "writes the data to a file" do
25
- file = double('file')
26
- File.should_receive(:open).with(@output, "w").and_yield(file)
27
- file.should_receive(:write).with('{"foo":"bar"}')
28
- @check_coverage.should_receive(:check_coverage)
29
- subject.reports
50
+ it "raises a Teaspoon::DependencyFailure if the command doesn't exit cleanly" do
51
+ `(exit 1)`
52
+ expect { subject.generate_reports }.to raise_error Teaspoon::DependencyFailure, "Could not generate coverage report for html"
30
53
  end
31
54
 
32
- it "collects the results and returns them" do
33
- subject.should_receive(:generate_report).with(@output, "text")
34
- subject.should_receive(:generate_report).with(@output, "text-summary")
35
- subject.should_receive(:generate_report).with(@output, "html")
36
- @check_coverage.should_receive(:check_coverage)
37
- expect(subject.reports).to eq("\n_text_report_\n\n_text-summary_report_\n")
55
+ end
56
+
57
+ describe "#check_thresholds" do
58
+
59
+ let(:config) { double(statements: 42, functions: 66.6, branches: 0, lines: 100) }
60
+
61
+ it "does nothing if there are no threshold checks to make" do
62
+ subject.should_receive(:threshold_args).and_return(nil)
63
+ subject.should_not_receive(:input_path)
64
+ subject.check_thresholds {}
65
+ end
66
+
67
+ it "checks the coverage using istanbul and passes them to the block provided" do
68
+ `(exit 1)`
69
+ check_coverage = "/path/to/executable check-coverage --statements=42 --functions=66.6 --branches=0 --lines=100 /temp_path/coverage.json 2>&1"
70
+ subject.should_receive(:`).with(check_coverage).and_return("some mumbo jumbo\nERROR: _failure1_\nmore garbage\nERROR: _failure2_")
71
+ subject.check_thresholds { |r| @result = r }
72
+ expect(@result).to eq("_failure1_\n_failure2_")
73
+ end
74
+
75
+ it "doesn't call the callback if the exit status is 0" do
76
+ `(exit 0)`
77
+ subject.should_receive(:`).and_return("ERROR: _failure1_")
78
+ subject.check_thresholds { |r| @called = true }
79
+ expect(@called).to be_false
80
+ end
81
+
82
+ end
83
+
84
+ describe "integration" do
85
+
86
+ let(:config) { double(reports: ["text", "text-summary"], output_path: "output/path") }
87
+
88
+ before do
89
+ Teaspoon::Instrumentation.instance_variable_set(:@executable, nil)
90
+ Teaspoon::Instrumentation.instance_variable_set(:@executable_checked, nil)
91
+ Teaspoon::Instrumentation.should_receive(:executable).and_call_original
92
+ subject.should_receive(:input_path).and_call_original
93
+ subject.should_receive(:`).and_call_original
94
+
95
+ executable = Teaspoon::Instrumentation.executable
96
+ pending('needs istanbul to be installed') unless executable
97
+ subject.instance_variable_set(:@executable, executable)
98
+ subject.instance_variable_set(:@data, JSON.parse(IO.read(Teaspoon::Engine.root.join('spec/fixtures/coverage.json'))))
38
99
  end
39
100
 
40
- it "executes coverage checks" do
41
- Teaspoon::CheckCoverage.should_receive(:new).with(@output)
42
- @check_coverage.should_receive(:check_coverage)
43
- subject.reports
101
+ it "generates coverage reports" do
102
+ subject.generate_reports { |r| @report = r }
103
+ expect(@report).to eq <<-RESULT.strip_heredoc + "\n"
104
+ -------------------------+-----------+-----------+-----------+-----------+
105
+ File | % Stmts |% Branches | % Funcs | % Lines |
106
+ -------------------------+-----------+-----------+-----------+-----------+
107
+ integration/ | 90.91 | 100 | 75 | 90.91 |
108
+ integration.coffee | 75 | 100 | 50 | 75 |
109
+ spec_helper.coffee | 100 | 100 | 100 | 100 |
110
+ -------------------------+-----------+-----------+-----------+-----------+
111
+ All files | 90.91 | 100 | 75 | 90.91 |
112
+ -------------------------+-----------+-----------+-----------+-----------+
113
+ RESULT
44
114
  end
45
115
 
46
116
  end
@@ -0,0 +1,5 @@
1
+ require "spec_helper"
2
+
3
+ describe Teaspoon::Drivers::Base do
4
+
5
+ end
@@ -1,28 +1,47 @@
1
1
  require "spec_helper"
2
- require "teaspoon/drivers/phantomjs_driver"
3
2
 
4
3
  describe Teaspoon::Drivers::PhantomjsDriver do
5
4
 
5
+ describe "#initialize" do
6
+
7
+ it "assigns @options" do
8
+ subject = Teaspoon::Drivers::PhantomjsDriver.new(foo: "bar")
9
+ expect(subject.instance_variable_get(:@options)).to eq(["--foo=bar"])
10
+ end
11
+
12
+ it "accepts a string for options" do
13
+ subject = Teaspoon::Drivers::PhantomjsDriver.new("--foo=bar --bar=baz")
14
+ expect(subject.instance_variable_get(:@options)).to eq(["--foo=bar", "--bar=baz"])
15
+ end
16
+
17
+ it "accepts an array for options" do
18
+ subject = Teaspoon::Drivers::PhantomjsDriver.new(["--foo=bar", "--bar=baz"])
19
+ expect(subject.instance_variable_get(:@options)).to eq(["--foo=bar", "--bar=baz"])
20
+ end
21
+
22
+ it "raises a Teaspoon::UnknownDriverOptions exception if the options aren't understood" do
23
+ expect { Teaspoon::Drivers::PhantomjsDriver.new(true) }.to raise_error(Teaspoon::UnknownDriverOptions)
24
+ end
25
+
26
+ end
27
+
6
28
  describe "#run_specs" do
7
29
 
8
30
  context "with phantomjs" do
9
31
 
32
+ let(:runner) { double }
33
+
10
34
  before do
11
35
  subject.stub(:run)
12
36
  end
13
37
 
14
- it "instantiates the runner" do
15
- runner = double(failure_count: nil)
16
- Teaspoon::Runner.should_receive(:new).and_return(runner)
17
- subject.run_specs(:default, "_url_")
18
- end
19
-
20
- it "calls run and logs the results of each line using the formatter" do
21
- args = [Teaspoon::Engine.root.join("lib/teaspoon/drivers/phantomjs/runner.js").to_s, "_url_"]
22
- Teaspoon::Runner.any_instance.should_receive(:process).with("_line_")
38
+ it "calls #run and calls runner.process with each line of output" do
39
+ subject.instance_variable_set(:@options, ["--foo", "--bar"])
40
+ args = ["--foo", "--bar", Teaspoon::Engine.root.join("lib/teaspoon/drivers/phantomjs/runner.js").to_s, "_url_", 180]
41
+ runner.should_receive(:process).with("_line_")
23
42
  @block = nil
24
43
  subject.should_receive(:run).with(*args) { |&b| @block = b }
25
- subject.run_specs(:default, "_url_")
44
+ subject.run_specs(runner, "_url_")
26
45
  @block.call("_line_")
27
46
  end
28
47
 
@@ -30,10 +49,9 @@ describe Teaspoon::Drivers::PhantomjsDriver do
30
49
 
31
50
  context "without phantomjs" do
32
51
 
33
- it "tells you that it couldn't find phantomjs and exits" do
52
+ it "raises a MissingDependency exception" do
34
53
  subject.should_receive(:which).and_return(nil)
35
- STDOUT.should_receive(:print).with("Could not find PhantomJS. Install phantomjs or try the phantomjs gem.")
36
- expect { subject.run_specs(:default, "_url_") }.to raise_error SystemExit
54
+ expect { subject.run_specs(:default, "_url_") }.to raise_error Teaspoon::MissingDependency
37
55
  end
38
56
 
39
57
  end