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.
- 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
|