teaspoon 0.7.9 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +382 -260
- data/app/assets/javascripts/teaspoon-angular.js +108 -26241
- data/app/assets/javascripts/teaspoon-jasmine.js +103 -2642
- data/app/assets/javascripts/teaspoon-mocha.js +109 -5416
- data/app/assets/javascripts/teaspoon-qunit.js +107 -2255
- data/app/assets/javascripts/teaspoon-teaspoon.js +0 -1
- data/app/assets/javascripts/teaspoon/angular.coffee +3 -1
- data/app/assets/javascripts/teaspoon/base/hook.coffee +21 -0
- data/app/assets/javascripts/teaspoon/base/reporters/html.coffee +26 -14
- data/app/assets/javascripts/teaspoon/base/reporters/html/progress_view.coffee +1 -1
- data/app/assets/javascripts/teaspoon/base/reporters/html/template.coffee +3 -3
- data/app/assets/javascripts/teaspoon/base/teaspoon.coffee +10 -1
- data/app/assets/javascripts/teaspoon/jasmine.coffee +3 -1
- data/app/assets/javascripts/teaspoon/mocha.coffee +3 -1
- data/app/assets/javascripts/teaspoon/mocha/reporters/html.coffee +1 -1
- data/app/assets/javascripts/teaspoon/qunit.coffee +3 -1
- data/app/assets/javascripts/teaspoon/qunit/reporters/html.coffee +1 -1
- data/app/assets/javascripts/teaspoon/teaspoon.coffee +0 -1
- data/app/assets/stylesheets/teaspoon.css +12 -8
- data/app/controllers/teaspoon/suite_controller.rb +32 -0
- data/app/views/teaspoon/suite/_body.html.erb +0 -0
- data/app/views/teaspoon/suite/_boot.html.erb +4 -0
- data/app/views/teaspoon/suite/_boot_require_js.html.erb +19 -0
- data/app/views/teaspoon/{spec/suites.html.erb → suite/index.html.erb} +6 -7
- data/app/views/teaspoon/suite/show.html.erb +19 -0
- data/bin/teaspoon +1 -1
- data/config/routes.rb +14 -4
- data/lib/generators/teaspoon/install/POST_INSTALL +2 -2
- data/lib/generators/teaspoon/install/install_generator.rb +22 -11
- data/lib/generators/teaspoon/install/templates/_body.html.erb +0 -0
- data/lib/generators/teaspoon/install/templates/_boot.html.erb +4 -0
- data/lib/generators/teaspoon/install/templates/jasmine/env.rb +11 -0
- data/lib/generators/teaspoon/install/templates/jasmine/env_comments.rb +182 -0
- data/lib/generators/teaspoon/install/templates/jasmine/spec_helper.coffee +8 -6
- data/lib/generators/teaspoon/install/templates/jasmine/spec_helper.js +8 -7
- data/lib/generators/teaspoon/install/templates/mocha/env.rb +11 -0
- data/lib/generators/teaspoon/install/templates/mocha/env_comments.rb +182 -0
- data/lib/generators/teaspoon/install/templates/mocha/spec_helper.coffee +13 -13
- data/lib/generators/teaspoon/install/templates/mocha/spec_helper.js +13 -13
- data/lib/generators/teaspoon/install/templates/qunit/env.rb +11 -0
- data/lib/generators/teaspoon/install/templates/qunit/env_comments.rb +182 -0
- data/lib/generators/teaspoon/install/templates/qunit/test_helper.coffee +6 -5
- data/lib/generators/teaspoon/install/templates/qunit/test_helper.js +6 -5
- data/lib/tasks/teaspoon.rake +9 -2
- data/lib/teaspoon.rb +4 -6
- data/lib/teaspoon/command_line.rb +116 -134
- data/lib/teaspoon/configuration.rb +144 -66
- data/lib/teaspoon/console.rb +70 -37
- data/lib/teaspoon/coverage.rb +42 -15
- data/lib/teaspoon/deprecated.rb +65 -0
- data/lib/teaspoon/drivers/base.rb +10 -0
- data/lib/teaspoon/drivers/phantomjs/runner.js +9 -11
- data/lib/teaspoon/drivers/phantomjs_driver.rb +21 -21
- data/lib/teaspoon/drivers/selenium_driver.rb +32 -13
- data/lib/teaspoon/engine.rb +32 -12
- data/lib/teaspoon/environment.rb +16 -12
- data/lib/teaspoon/exceptions.rb +41 -5
- data/lib/teaspoon/exporter.rb +52 -0
- data/lib/teaspoon/formatters/base.rb +171 -0
- data/lib/teaspoon/formatters/clean_formatter.rb +2 -4
- data/lib/teaspoon/formatters/documentation_formatter.rb +60 -0
- data/lib/teaspoon/formatters/dot_formatter.rb +12 -90
- data/lib/teaspoon/formatters/json_formatter.rb +36 -0
- data/lib/teaspoon/formatters/junit_formatter.rb +51 -32
- data/lib/teaspoon/formatters/modules/report_module.rb +76 -0
- data/lib/teaspoon/formatters/pride_formatter.rb +23 -27
- data/lib/teaspoon/formatters/snowday_formatter.rb +7 -11
- data/lib/teaspoon/formatters/swayze_or_oprah_formatter.rb +88 -64
- data/lib/teaspoon/formatters/tap_formatter.rb +18 -27
- data/lib/teaspoon/formatters/tap_y_formatter.rb +35 -45
- data/lib/teaspoon/formatters/teamcity_formatter.rb +69 -31
- data/lib/teaspoon/instrumentation.rb +33 -33
- data/lib/teaspoon/result.rb +2 -1
- data/lib/teaspoon/runner.rb +40 -28
- data/lib/teaspoon/server.rb +23 -25
- data/lib/teaspoon/suite.rb +52 -72
- data/lib/teaspoon/utility.rb +3 -14
- data/lib/teaspoon/version.rb +1 -1
- data/spec/dummy/app/assets/javascripts/integration/integration_spec.coffee +3 -0
- data/spec/dummy/app/assets/javascripts/integration/spec_helper.coffee +2 -0
- data/spec/dummy/config/application.rb +3 -0
- data/spec/features/console_reporter_spec.rb +48 -18
- data/spec/features/hooks_spec.rb +23 -41
- data/spec/features/html_reporter_spec.rb +38 -21
- data/spec/features/install_generator_spec.rb +34 -20
- data/spec/features/instrumentation_spec.rb +3 -2
- data/spec/fixtures/coverage.json +243 -0
- data/spec/javascripts/fixtures/_body.html.erb +1 -0
- data/spec/javascripts/jasmine_helper.coffee +1 -1
- data/spec/javascripts/teaspoon/base/fixture_spec.coffee +4 -4
- data/spec/javascripts/teaspoon/base/reporters/html_spec.coffee +9 -10
- data/spec/javascripts/teaspoon/mocha/reporters/html_mspec.coffee +0 -6
- data/spec/javascripts/teaspoon/phantomjs/runner_spec.coffee +5 -6
- data/spec/javascripts/turbolinks_helper.coffee +1 -1
- data/spec/spec_helper.rb +3 -4
- data/spec/teaspoon/command_line_spec.rb +139 -23
- data/spec/teaspoon/configuration_spec.rb +164 -46
- data/spec/teaspoon/console_spec.rb +142 -47
- data/spec/teaspoon/coverage_spec.rb +98 -28
- data/spec/teaspoon/drivers/base_spec.rb +5 -0
- data/spec/teaspoon/drivers/phantomjs_driver_spec.rb +32 -14
- data/spec/teaspoon/drivers/selenium_driver_spec.rb +32 -24
- data/spec/teaspoon/engine_spec.rb +8 -5
- data/spec/teaspoon/environment_spec.rb +56 -33
- data/spec/teaspoon/exceptions_spec.rb +57 -0
- data/spec/teaspoon/exporter_spec.rb +96 -0
- data/spec/teaspoon/formatters/base_spec.rb +259 -0
- data/spec/teaspoon/formatters/clean_formatter_spec.rb +37 -0
- data/spec/teaspoon/formatters/documentation_formatter_spec.rb +127 -0
- data/spec/teaspoon/formatters/dot_formatter_spec.rb +52 -56
- data/spec/teaspoon/formatters/json_formatter_spec.rb +77 -0
- data/spec/teaspoon/formatters/junit_formatter_spec.rb +72 -35
- data/spec/teaspoon/formatters/pride_formatter_spec.rb +37 -0
- data/spec/teaspoon/formatters/snowday_formatter_spec.rb +35 -0
- data/spec/teaspoon/formatters/tap_formatter_spec.rb +29 -81
- data/spec/teaspoon/formatters/tap_y_formatter_spec.rb +31 -141
- data/spec/teaspoon/formatters/teamcity_formatter_spec.rb +99 -42
- data/spec/teaspoon/instrumentation_spec.rb +44 -44
- data/spec/teaspoon/result_spec.rb +37 -0
- data/spec/teaspoon/runner_spec.rb +70 -59
- data/spec/teaspoon/server_spec.rb +34 -52
- data/spec/teaspoon/suite_spec.rb +42 -188
- data/spec/teaspoon_env.rb +39 -28
- data/vendor/assets/javascripts/{angular-scenario-1.0.5.js → angular/1.0.5.js} +0 -0
- data/vendor/assets/javascripts/{angular-scenario-1.0.5.MIT-LICENSE → angular/MIT-LICENSE} +0 -0
- data/vendor/assets/javascripts/{jasmine-1.3.1.js → jasmine/1.3.1.js} +0 -0
- data/vendor/assets/javascripts/jasmine/2.0.0.js +2412 -0
- data/vendor/assets/javascripts/{jasmine-1.3.1.MIT.LICENSE → jasmine/MIT.LICENSE} +0 -0
- data/vendor/assets/javascripts/{mocha-1.10.0.js → mocha/1.10.0.js} +1 -0
- data/vendor/assets/javascripts/mocha/1.17.1.js +5813 -0
- data/vendor/assets/javascripts/{mocha-1.10.1.MIT.LICENSE → mocha/MIT.LICENSE} +0 -0
- data/vendor/assets/javascripts/{qunit-1.12.0.js → qunit/1.12.0.js} +1 -1
- data/vendor/assets/javascripts/qunit/1.14.0.js +2288 -0
- data/vendor/assets/javascripts/{qunit-1.12.0.MIT.LICENSE → qunit/MIT.LICENSE} +0 -0
- data/vendor/assets/javascripts/support/chai.js +827 -385
- data/vendor/assets/javascripts/support/jasmine-jquery-1.7.0.js +720 -0
- data/vendor/assets/javascripts/support/jasmine-jquery-2.0.0.js +812 -0
- data/vendor/assets/javascripts/support/sinon-chai.js +17 -0
- data/vendor/assets/javascripts/support/sinon.js +1138 -643
- metadata +57 -36
- data/app/controllers/teaspoon/spec_controller.rb +0 -38
- data/app/helpers/teaspoon/spec_helper.rb +0 -36
- data/app/views/teaspoon/spec/_require_js.html.erb +0 -21
- data/app/views/teaspoon/spec/_standard.html.erb +0 -4
- data/app/views/teaspoon/spec/runner.html.erb +0 -19
- data/lib/generators/teaspoon/install/templates/env.rb +0 -38
- data/lib/generators/teaspoon/install/templates/jasmine/initializer.rb +0 -64
- data/lib/generators/teaspoon/install/templates/mocha/initializer.rb +0 -64
- data/lib/generators/teaspoon/install/templates/qunit/initializer.rb +0 -64
- data/lib/teaspoon/check_coverage.rb +0 -33
- data/lib/teaspoon/drivers/base_driver.rb +0 -10
- data/lib/teaspoon/exception_handling.rb +0 -18
- data/lib/teaspoon/formatters/base_formatter.rb +0 -63
- data/spec/dummy/config/initializers/teaspoon.rb +0 -41
- data/spec/teaspoon/check_coverage_spec.rb +0 -50
- data/spec/teaspoon/formatters/base_formatter_spec.rb +0 -45
- data/vendor/assets/javascripts/support/chai.MIT.LICENSE +0 -22
- data/vendor/assets/javascripts/support/expect.MIT.LICENSE +0 -22
- data/vendor/assets/javascripts/support/jasmine-jquery.MIT.LICENSE +0 -20
- data/vendor/assets/javascripts/support/jasmine-jquery.js +0 -659
- data/vendor/assets/javascripts/support/sinon-chai.MIT-ISH.LICENSE +0 -13
- data/vendor/assets/javascripts/support/sinon.BSD.LICENSE +0 -27
@@ -1,77 +1,152 @@
|
|
1
1
|
require "singleton"
|
2
2
|
|
3
3
|
module Teaspoon
|
4
|
+
|
5
|
+
autoload :Formatters, "teaspoon/formatters/base"
|
6
|
+
autoload :Drivers, "teaspoon/drivers/base"
|
7
|
+
|
4
8
|
class Configuration
|
5
9
|
include Singleton
|
6
10
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
# CONTRIBUTORS:
|
12
|
+
# If you add a configuration option you should do the following before it will be considered for merging.
|
13
|
+
# - think about if it should be a suite, coverage, or global configuration
|
14
|
+
# - write specs for it, and add it to existing specs in spec/teaspoon/configuration_spec.rb
|
15
|
+
# - add it to the readme so it's documented
|
16
|
+
# - add it to the command_line.rb if appropriate (_only_ if it's appropriate)
|
17
|
+
# - add it to ENV_OVERRIDES if it can be overridden from ENV
|
18
|
+
# - add it to the initializers in /lib/generators/install/templates so it's documented there as well
|
19
|
+
|
20
|
+
cattr_accessor :mount_at, :root, :asset_paths, :fixture_paths
|
21
|
+
@@mount_at = "/teaspoon"
|
22
|
+
@@root = nil # will default to Rails.root
|
23
|
+
@@asset_paths = ["spec/javascripts", "spec/javascripts/stylesheets", "test/javascripts", "test/javascripts/stylesheets"]
|
24
|
+
@@fixture_paths = ["spec/javascripts/fixtures", "test/javascripts/fixtures"]
|
15
25
|
|
16
26
|
# console runner specific
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
@@
|
22
|
-
@@
|
23
|
-
@@
|
24
|
-
@@
|
25
|
-
@@
|
26
|
-
@@
|
27
|
-
@@
|
28
|
-
|
29
|
-
@@
|
30
|
-
@@
|
31
|
-
@@
|
32
|
-
|
27
|
+
|
28
|
+
cattr_accessor :driver, :driver_options, :driver_timeout, :server, :server_port, :server_timeout, :fail_fast,
|
29
|
+
:formatters, :color, :suppress_log,
|
30
|
+
:use_coverage
|
31
|
+
@@driver = "phantomjs"
|
32
|
+
@@driver_options = nil
|
33
|
+
@@driver_timeout = 180
|
34
|
+
@@server = nil
|
35
|
+
@@server_port = nil
|
36
|
+
@@server_timeout = 20
|
37
|
+
@@fail_fast = true
|
38
|
+
|
39
|
+
@@formatters = ["dot"]
|
40
|
+
@@color = true
|
41
|
+
@@suppress_log = false
|
42
|
+
|
43
|
+
@@use_coverage = nil
|
44
|
+
|
45
|
+
# options that can be specified in the ENV
|
46
|
+
|
47
|
+
ENV_OVERRIDES = {
|
48
|
+
boolean: %w(FAIL_FAST SUPPRESS_LOG COLOR),
|
49
|
+
integer: %w(DRIVER_TIMEOUT SERVER_TIMEOUT),
|
50
|
+
string: %w(DRIVER DRIVER_OPTIONS SERVER SERVER_PORT FORMATTERS USE_COVERAGE)
|
51
|
+
}
|
52
|
+
|
53
|
+
# suite configurations
|
54
|
+
|
55
|
+
cattr_accessor :suite_configs
|
56
|
+
@@suite_configs = {"default" => {block: proc{}}}
|
57
|
+
|
58
|
+
def self.suite(name = :default, &block)
|
59
|
+
@@suite_configs[name.to_s] = {block: block, instance: Suite.new(&block)}
|
60
|
+
end
|
33
61
|
|
34
62
|
class Suite
|
35
|
-
|
63
|
+
|
64
|
+
FRAMEWORKS = {
|
65
|
+
jasmine: ["1.3.1", "2.0.0"],
|
66
|
+
mocha: ["1.10.0", "1.17.1"],
|
67
|
+
qunit: ["1.12.0", "1.14.0"],
|
68
|
+
angular: ["1.0.5"],
|
69
|
+
}
|
70
|
+
|
71
|
+
attr_accessor :matcher, :helper, :javascripts, :stylesheets,
|
72
|
+
:boot_partial, :body_partial,
|
73
|
+
:no_coverage,
|
74
|
+
:hooks
|
36
75
|
|
37
76
|
def initialize
|
38
|
-
@matcher
|
39
|
-
@helper
|
40
|
-
@javascripts
|
41
|
-
@stylesheets
|
42
|
-
|
43
|
-
@boot_partial
|
44
|
-
@
|
45
|
-
|
46
|
-
@
|
47
|
-
|
48
|
-
|
49
|
-
|
77
|
+
@matcher = "{spec/javascripts,app/assets}/**/*_spec.{js,js.coffee,coffee}"
|
78
|
+
@helper = "spec_helper"
|
79
|
+
@javascripts = ["jasmine/1.3.1", "teaspoon-jasmine"]
|
80
|
+
@stylesheets = ["teaspoon"]
|
81
|
+
|
82
|
+
@boot_partial = "boot"
|
83
|
+
@body_partial = "body"
|
84
|
+
|
85
|
+
@no_coverage = [%r{/lib/ruby/gems/}, %r{/vendor/assets/}, %r{/support/}, %r{/(.+)_helper.}]
|
86
|
+
|
87
|
+
@hooks = Hash.new{ |h, k| h[k] = [] }
|
88
|
+
|
89
|
+
default = Teaspoon.configuration.suite_configs["default"]
|
90
|
+
self.instance_eval(&default[:block]) if default
|
50
91
|
yield self if block_given?
|
51
92
|
end
|
52
93
|
|
53
|
-
def
|
54
|
-
|
55
|
-
|
94
|
+
def use_framework(name, version = nil)
|
95
|
+
name = name.to_sym
|
96
|
+
version ||= FRAMEWORKS[name].last if FRAMEWORKS[name]
|
97
|
+
unless FRAMEWORKS[name] && FRAMEWORKS[name].include?(version)
|
98
|
+
message = "Unknown framework \"#{name}\""
|
99
|
+
message += " with version #{version} -- available versions #{FRAMEWORKS[name].join(", ")}" if FRAMEWORKS[name] && version
|
100
|
+
raise Teaspoon::UnknownFramework, message
|
101
|
+
end
|
102
|
+
|
103
|
+
@javascripts = [[name, version].join("/"), "teaspoon-#{name}"]
|
104
|
+
case name.to_sym
|
105
|
+
when :qunit
|
106
|
+
@matcher = "{test/javascripts,app/assets}/**/*_test.{js,js.coffee,coffee}"
|
107
|
+
@helper = "test_helper"
|
108
|
+
else
|
109
|
+
end
|
56
110
|
end
|
111
|
+
alias_method :use_framework=, :use_framework
|
57
112
|
|
58
113
|
def hook(group = :default, &block)
|
59
114
|
@hooks[group.to_s] << block
|
60
115
|
end
|
61
116
|
end
|
62
117
|
|
63
|
-
|
64
|
-
|
118
|
+
# coverage configurations
|
119
|
+
|
120
|
+
cattr_accessor :coverage_configs
|
121
|
+
@@coverage_configs = {"default" => {block: proc{}}}
|
122
|
+
|
123
|
+
def self.coverage(name = :default, &block)
|
124
|
+
@@coverage_configs[name.to_s] = {block: block, instance: Coverage.new(&block)}
|
65
125
|
end
|
66
126
|
|
67
|
-
|
68
|
-
|
127
|
+
class Coverage
|
128
|
+
attr_accessor :reports, :output_path,
|
129
|
+
:statements, :functions, :branches, :lines
|
130
|
+
|
131
|
+
def initialize
|
132
|
+
@reports = ["text-summary"]
|
133
|
+
@output_path = "coverage"
|
134
|
+
|
135
|
+
@statements = nil
|
136
|
+
@functions = nil
|
137
|
+
@branches = nil
|
138
|
+
@lines = nil
|
139
|
+
|
140
|
+
default = Teaspoon.configuration.coverage_configs["default"]
|
141
|
+
self.instance_eval(&default[:block]) if default
|
142
|
+
yield self if block_given?
|
143
|
+
end
|
69
144
|
end
|
70
145
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
@@
|
146
|
+
# custom getters / setters
|
147
|
+
|
148
|
+
def self.root=(path)
|
149
|
+
@@root = Pathname.new(path.to_s) if path.present?
|
75
150
|
end
|
76
151
|
|
77
152
|
def self.formatters
|
@@ -79,29 +154,32 @@ module Teaspoon
|
|
79
154
|
return @@formatters if @@formatters.is_a?(Array)
|
80
155
|
@@formatters.to_s.split(/,\s?/)
|
81
156
|
end
|
82
|
-
end
|
83
157
|
|
84
|
-
|
85
|
-
autoload :Drivers, "teaspoon/drivers/base_driver"
|
158
|
+
# override from env or options
|
86
159
|
|
87
|
-
|
88
|
-
|
160
|
+
def self.override_from_options(options)
|
161
|
+
options.each { |k, v| override(k, v) }
|
162
|
+
end
|
89
163
|
|
90
|
-
|
91
|
-
|
92
|
-
|
164
|
+
def self.override_from_env(env)
|
165
|
+
ENV_OVERRIDES[:boolean].each { |o| override(o, env[o] == "true") if env[o].present? }
|
166
|
+
ENV_OVERRIDES[:integer].each { |o| override(o, env[o].to_i) if env[o].present? }
|
167
|
+
ENV_OVERRIDES[:string].each { |o| override(o, env[o]) if env[o].present? }
|
168
|
+
end
|
169
|
+
|
170
|
+
def self.override(config, value)
|
171
|
+
setter = "#{config.to_s.downcase}="
|
172
|
+
send(setter, value) if respond_to?(setter)
|
173
|
+
end
|
93
174
|
end
|
94
175
|
|
95
|
-
|
176
|
+
mattr_accessor :configured, :configuration
|
177
|
+
@@configured = false
|
178
|
+
@@configuration = Configuration
|
96
179
|
|
97
|
-
def self.
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
end
|
102
|
-
%w(DRIVER DRIVER_CLI_OPTIONS SERVER SERVER_TIMEOUT SERVER_PORT FORMATTERS COVERAGE_REPORTS COVERAGE_OUTPUT_DIR).each do |directive|
|
103
|
-
next unless ENV[directive].present?
|
104
|
-
@@configuration.send("#{directive.downcase}=", ENV[directive])
|
105
|
-
end
|
180
|
+
def self.configure
|
181
|
+
yield @@configuration
|
182
|
+
@@configured = true
|
183
|
+
@@configuration.override_from_env(ENV)
|
106
184
|
end
|
107
185
|
end
|
data/lib/teaspoon/console.rb
CHANGED
@@ -1,49 +1,62 @@
|
|
1
|
-
require
|
2
|
-
require 'teaspoon/environment'
|
1
|
+
require "teaspoon/environment"
|
3
2
|
|
4
3
|
module Teaspoon
|
5
4
|
class Console
|
6
5
|
|
7
|
-
def initialize(options =
|
8
|
-
@options = options
|
6
|
+
def initialize(options = {})
|
7
|
+
@options = options
|
9
8
|
@suites = {}
|
10
|
-
@files = []
|
11
|
-
|
12
9
|
Teaspoon::Environment.load(@options)
|
13
10
|
|
14
|
-
start_server
|
15
|
-
|
11
|
+
@server = start_server
|
12
|
+
rescue Teaspoon::ServerException => e
|
13
|
+
abort(e.message)
|
16
14
|
end
|
17
15
|
|
18
|
-
def
|
19
|
-
|
20
|
-
|
16
|
+
def failures?
|
17
|
+
!execute
|
18
|
+
end
|
21
19
|
|
22
|
-
|
23
|
-
|
24
|
-
STDOUT.print "Teaspoon running #{suite} suite at #{url(suite)}\n" unless Teaspoon.configuration.suppress_log
|
25
|
-
failure_count += run_specs(suite, @options[:driver_cli_options] || Teaspoon.configuration.driver_cli_options)
|
26
|
-
end
|
27
|
-
failure_count > 0
|
20
|
+
def execute(options = {})
|
21
|
+
execute_without_handling(options)
|
28
22
|
rescue Teaspoon::Failure
|
29
|
-
|
30
|
-
rescue Teaspoon::
|
31
|
-
|
23
|
+
false
|
24
|
+
rescue Teaspoon::Error => e
|
25
|
+
abort(e.message)
|
32
26
|
end
|
33
27
|
|
34
|
-
def
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
28
|
+
def execute_without_handling(options = {})
|
29
|
+
@options.merge!(options)
|
30
|
+
@suites = {}
|
31
|
+
resolve(@options[:files])
|
32
|
+
|
33
|
+
0 == suites.inject(0) do |failures, suite|
|
34
|
+
export(suite) if @options.include?(:export)
|
35
|
+
failures += run_specs(suite)
|
36
|
+
log("") # empty line for space
|
37
|
+
failures
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def run_specs(suite)
|
42
|
+
raise Teaspoon::UnknownSuite, "Unknown suite: \"#{suite}\"" unless Teaspoon.configuration.suite_configs[suite.to_s]
|
43
|
+
log("Teaspoon running #{suite} suite at #{base_url_for(suite)}")
|
44
|
+
runner = Teaspoon::Runner.new(suite)
|
45
|
+
driver.run_specs(runner, url_for(suite))
|
46
|
+
raise Teaspoon::Failure if Teaspoon.configuration.fail_fast && runner.failure_count > 0
|
47
|
+
runner.failure_count
|
48
|
+
end
|
49
|
+
|
50
|
+
def export(suite)
|
51
|
+
raise Teaspoon::UnknownSuite, "Unknown suite: \"#{suite}\"" unless Teaspoon.configuration.suite_configs[suite.to_s]
|
52
|
+
log("Teaspoon exporting #{suite} suite at #{base_url_for(suite)}")
|
53
|
+
Teaspoon::Exporter.new(suite, url_for(suite, false), @options[:export]).export
|
39
54
|
end
|
40
55
|
|
41
56
|
protected
|
42
57
|
|
43
|
-
def resolve(files)
|
44
|
-
return if files.
|
45
|
-
@suites = {}
|
46
|
-
@files = files
|
58
|
+
def resolve(files = [])
|
59
|
+
return if files.blank?
|
47
60
|
files.uniq.each do |path|
|
48
61
|
if result = Teaspoon::Suite.resolve_spec_for(path)
|
49
62
|
suite = @suites[result[:suite]] ||= []
|
@@ -53,30 +66,50 @@ module Teaspoon
|
|
53
66
|
end
|
54
67
|
|
55
68
|
def start_server
|
56
|
-
|
57
|
-
|
69
|
+
log("Starting the Teaspoon server...")
|
70
|
+
server = Teaspoon::Server.new
|
71
|
+
server.start
|
72
|
+
server
|
58
73
|
end
|
59
74
|
|
60
75
|
def suites
|
61
76
|
return [@options[:suite]] if @options[:suite].present?
|
62
77
|
return @suites.keys if @suites.present?
|
63
|
-
Teaspoon.configuration.
|
78
|
+
Teaspoon.configuration.suite_configs.keys
|
64
79
|
end
|
65
80
|
|
66
81
|
def driver
|
67
|
-
@driver
|
82
|
+
return @driver if @driver
|
83
|
+
klass = "#{Teaspoon.configuration.driver.to_s.camelize}Driver"
|
84
|
+
@driver = Teaspoon::Drivers.const_get(klass).new(Teaspoon.configuration.driver_options)
|
85
|
+
rescue NameError
|
86
|
+
raise Teaspoon::UnknownDriver, "Unknown driver: \"#{Teaspoon.configuration.driver}\""
|
87
|
+
end
|
88
|
+
|
89
|
+
def base_url_for(suite)
|
90
|
+
["#{@server.url}#{Teaspoon.configuration.mount_at}", suite].join('/')
|
91
|
+
end
|
92
|
+
|
93
|
+
def url_for(suite, console = true)
|
94
|
+
url = [base_url_for(suite), filter(suite)].compact.join('?')
|
95
|
+
url += "#{(url.include?("?") ? "&" : "?")}reporter=Console" if console
|
96
|
+
url
|
68
97
|
end
|
69
98
|
|
70
99
|
def filter(suite)
|
71
100
|
parts = []
|
72
101
|
parts << "grep=#{URI::encode(@options[:filter])}" if @options[:filter].present?
|
73
|
-
(@suites[suite] || @files).flatten.each { |file| parts << "file[]=#{URI::encode(file)}" }
|
102
|
+
(@suites[suite] || @options[:files] || []).flatten.each { |file| parts << "file[]=#{URI::encode(file)}" }
|
74
103
|
"#{parts.join('&')}" if parts.present?
|
75
104
|
end
|
76
105
|
|
77
|
-
def
|
78
|
-
|
79
|
-
|
106
|
+
def log(str, force = false)
|
107
|
+
STDOUT.print("#{str}\n") if force || !Teaspoon.configuration.suppress_log
|
108
|
+
end
|
109
|
+
|
110
|
+
def abort(message = nil)
|
111
|
+
log(message, true) if message
|
112
|
+
exit(1)
|
80
113
|
end
|
81
114
|
end
|
82
115
|
end
|
data/lib/teaspoon/coverage.rb
CHANGED
@@ -1,36 +1,63 @@
|
|
1
1
|
module Teaspoon
|
2
2
|
class Coverage
|
3
|
-
include Teaspoon::Utility
|
4
3
|
|
5
|
-
def initialize(
|
6
|
-
@data = data
|
4
|
+
def initialize(suite_name, config_name, data)
|
7
5
|
@suite_name = suite_name
|
6
|
+
@data = data
|
7
|
+
@executable = Teaspoon::Instrumentation.executable
|
8
|
+
@config = coverage_configuration(config_name.to_s)
|
8
9
|
end
|
9
10
|
|
10
|
-
def
|
11
|
-
|
12
|
-
input = File.join(path, 'coverage.json')
|
13
|
-
File.open(input, 'w') { |file| file.write(@data.to_json) }
|
11
|
+
def generate_reports(&block)
|
12
|
+
input_path do |input|
|
14
13
|
results = []
|
15
|
-
for format in
|
14
|
+
for format in @config.reports
|
16
15
|
result = generate_report(input, format)
|
17
16
|
results << result if ["text", "text-summary"].include?(format.to_s)
|
18
17
|
end
|
19
|
-
|
20
|
-
|
18
|
+
block.call(results.join("\n\n")) unless results.blank?
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def check_thresholds(&block)
|
23
|
+
args = threshold_args
|
24
|
+
return if args.blank?
|
25
|
+
input_path do |input|
|
26
|
+
result = %x{#{@executable} check-coverage #{args.join(" ")} #{input.shellescape} 2>&1}
|
27
|
+
return if $?.exitstatus == 0
|
28
|
+
result = result.scan(/ERROR: .*$/).join("\n").gsub("ERROR: ", "")
|
29
|
+
block.call(result) unless result.blank?
|
21
30
|
end
|
22
31
|
end
|
23
32
|
|
24
33
|
private
|
25
34
|
|
35
|
+
def coverage_configuration(name)
|
36
|
+
config = Teaspoon.configuration.coverage_configs[name]
|
37
|
+
raise Teaspoon::UnknownCoverage, "Unknown coverage configuration \"#{name}\"" unless config.present?
|
38
|
+
config[:instance] ||= Teaspoon::Configuration::Coverage.new(&config[:block])
|
39
|
+
end
|
40
|
+
|
41
|
+
def input_path(&block)
|
42
|
+
Dir.mktmpdir do |temp_path|
|
43
|
+
input_path = File.join(temp_path, "coverage.json")
|
44
|
+
File.open(input_path, "w") { |f| f.write(@data.to_json) }
|
45
|
+
block.call(input_path)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
26
49
|
def generate_report(input, format)
|
27
|
-
|
28
|
-
|
29
|
-
result.gsub("Done", "").gsub("Using reporter [#{format}]", "").strip
|
50
|
+
output_path = File.join(@config.output_path, @suite_name)
|
51
|
+
result = %x{#{@executable} report #{format} #{input.shellescape} --dir #{output_path} 2>&1}
|
52
|
+
return result.gsub("Done", "").gsub("Using reporter [#{format}]", "").strip if $?.exitstatus == 0
|
53
|
+
raise Teaspoon::DependencyFailure, "Could not generate coverage report for #{format}"
|
30
54
|
end
|
31
55
|
|
32
|
-
def
|
33
|
-
|
56
|
+
def threshold_args
|
57
|
+
%w{statements functions branches lines}.map do |assert|
|
58
|
+
threshold = @config.send(:"#{assert}")
|
59
|
+
"--#{assert}=#{threshold}" if threshold
|
60
|
+
end.compact
|
34
61
|
end
|
35
62
|
end
|
36
63
|
end
|