teaspoon 1.1.2 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +47 -0
  3. data/MIT.LICENSE +2 -2
  4. data/README.md +56 -35
  5. data/app/assets/javascripts/teaspoon/hook.coffee +1 -1
  6. data/app/assets/javascripts/teaspoon/teaspoon.coffee +13 -1
  7. data/app/controllers/teaspoon/suite_controller.rb +25 -11
  8. data/app/views/teaspoon/suite/index.html.erb +1 -1
  9. data/lib/generators/teaspoon/install/install_generator.rb +34 -34
  10. data/lib/generators/teaspoon/install/templates/MISSING_FRAMEWORK +1 -1
  11. data/lib/generators/teaspoon/install/templates/POST_INSTALL +1 -1
  12. data/lib/generators/teaspoon/install/templates/_boot.html.erb +1 -1
  13. data/lib/generators/teaspoon/install/templates/env_comments.rb.tt +9 -7
  14. data/lib/tasks/teaspoon/info.rake +1 -1
  15. data/lib/teaspoon/command_line.rb +76 -76
  16. data/lib/teaspoon/configuration.rb +4 -4
  17. data/lib/teaspoon/console.rb +41 -40
  18. data/lib/teaspoon/coverage.rb +29 -25
  19. data/lib/teaspoon/deprecated.rb +1 -1
  20. data/lib/teaspoon/driver.rb +1 -1
  21. data/lib/teaspoon/driver/browserstack.rb +111 -0
  22. data/lib/teaspoon/driver/phantomjs.rb +25 -26
  23. data/lib/teaspoon/driver/phantomjs/runner.js +31 -3
  24. data/lib/teaspoon/driver/selenium.rb +13 -9
  25. data/lib/teaspoon/engine.rb +32 -16
  26. data/lib/teaspoon/environment.rb +28 -28
  27. data/lib/teaspoon/exceptions.rb +7 -7
  28. data/lib/teaspoon/exporter.rb +23 -23
  29. data/lib/teaspoon/formatter/base.rb +64 -46
  30. data/lib/teaspoon/formatter/clean.rb +2 -2
  31. data/lib/teaspoon/formatter/documentation.rb +40 -40
  32. data/lib/teaspoon/formatter/dot.rb +12 -12
  33. data/lib/teaspoon/formatter/json.rb +21 -21
  34. data/lib/teaspoon/formatter/junit.rb +52 -51
  35. data/lib/teaspoon/formatter/modules/report_module.rb +34 -32
  36. data/lib/teaspoon/formatter/pride.rb +21 -21
  37. data/lib/teaspoon/formatter/rspec_html.rb +31 -31
  38. data/lib/teaspoon/formatter/snowday.rb +6 -5
  39. data/lib/teaspoon/formatter/swayze_or_oprah.rb +91 -91
  40. data/lib/teaspoon/formatter/tap.rb +29 -29
  41. data/lib/teaspoon/formatter/tap_y.rb +57 -57
  42. data/lib/teaspoon/formatter/teamcity.rb +63 -63
  43. data/lib/teaspoon/framework/base.rb +1 -1
  44. data/lib/teaspoon/instrumentation.rb +18 -18
  45. data/lib/teaspoon/registry.rb +9 -9
  46. data/lib/teaspoon/registry/has_default.rb +2 -2
  47. data/lib/teaspoon/runner.rb +37 -37
  48. data/lib/teaspoon/server.rb +30 -29
  49. data/lib/teaspoon/suite.rb +68 -57
  50. data/lib/teaspoon/utility.rb +6 -0
  51. data/lib/teaspoon/version.rb +1 -1
  52. metadata +10 -17
  53. data/lib/teaspoon/driver/capybara_webkit.rb +0 -40
@@ -10,5 +10,5 @@ Add one or more of the following to your gemfile:
10
10
  gem "teaspoon-mocha"
11
11
  gem "teaspoon-qunit"
12
12
 
13
- More information can be found at: https://github.com/modeset/teaspoon
13
+ More information can be found at: https://github.com/jejacks0n/teaspoon
14
14
 
@@ -1,4 +1,4 @@
1
1
  +============================================================================+
2
2
  Congratulations! Teaspoon was successfully installed. Documentation and more
3
- can be found at: https://github.com/modeset/teaspoon
3
+ can be found at: https://github.com/jejacks0n/teaspoon
4
4
 
@@ -1,4 +1,4 @@
1
- <%= javascript_include_tag *@suite.spec_assets, debug: @suite.config.expand_assets %>
1
+ <%= javascript_include_tag *@suite.spec_assets, debug: @suite.config.expand_assets, allow_non_precompiled: true %>
2
2
  <script type="text/javascript">
3
3
  Teaspoon.onWindowLoad(Teaspoon.execute);
4
4
  </script>
@@ -91,19 +91,21 @@ Teaspoon.configure do |config|
91
91
  # Rake:
92
92
  # teaspoon DRIVER=phantomjs SERVER_PORT=31337 FAIL_FAST=true FORMATTERS=junit suite=my_suite
93
93
 
94
- # Specify which headless driver to use. Supports PhantomJS and Selenium Webdriver.
94
+ # Specify which headless driver to use. Supports PhantomJS, Selenium Webdriver and BrowserStack Webdriver.
95
95
  #
96
96
  # Available: <%= Teaspoon::Driver.available.keys.map{|f| ":#{f}"}.join(", ") %>
97
- # PhantomJS: https://github.com/modeset/teaspoon/wiki/Using-PhantomJS
98
- # Selenium Webdriver: https://github.com/modeset/teaspoon/wiki/Using-Selenium-WebDriver
99
- # Capybara Webkit: https://github.com/modeset/teaspoon/wiki/Using-Capybara-Webkit
97
+ # PhantomJS: https://github.com/jejacks0n/teaspoon/wiki/Using-PhantomJS
98
+ # Selenium Webdriver: https://github.com/jejacks0n/teaspoon/wiki/Using-Selenium-WebDriver
99
+ # BrowserStack Webdriver: https://github.com/jejacks0n/teaspoon/wiki/Using-BrowserStack-WebDriver
100
+ # Capybara Webkit: https://github.com/jejacks0n/teaspoon/wiki/Using-Capybara-Webkit
100
101
  #config.driver = :<%= Teaspoon::Driver.default %>
101
102
 
102
103
  # Specify additional options for the driver.
103
104
  #
104
- # PhantomJS: https://github.com/modeset/teaspoon/wiki/Using-PhantomJS
105
- # Selenium Webdriver: https://github.com/modeset/teaspoon/wiki/Using-Selenium-WebDriver
106
- # Capybara Webkit: https://github.com/modeset/teaspoon/wiki/Using-Capybara-Webkit
105
+ # PhantomJS: https://github.com/jejacks0n/teaspoon/wiki/Using-PhantomJS
106
+ # Selenium Webdriver: https://github.com/jejacks0n/teaspoon/wiki/Using-Selenium-WebDriver
107
+ # BrowserStack Webdriver: https://github.com/jejacks0n/teaspoon/wiki/Using-BrowserStack-WebDriver
108
+ # Capybara Webkit: https://github.com/jejacks0n/teaspoon/wiki/Using-Capybara-Webkit
107
109
  #config.driver_options = nil
108
110
 
109
111
  # Specify the timeout for the driver. Specs are expected to complete within this time frame or the run will be
@@ -14,4 +14,4 @@ namespace :teaspoon do
14
14
  STDOUT.print("\n")
15
15
  end
16
16
  end
17
- end
17
+ end
@@ -32,113 +32,113 @@ module Teaspoon
32
32
 
33
33
  protected
34
34
 
35
- def opts_for_general
36
- opt :environment, "-r", "--require FILE",
37
- "Require Teaspoon environment file."
35
+ def opts_for_general
36
+ opt :environment, "-r", "--require FILE",
37
+ "Require Teaspoon environment file."
38
38
 
39
- # opt :custom_options_file,
40
- # "-O", "--options PATH",
41
- # "Specify the path to a custom options file."
39
+ # opt :custom_options_file,
40
+ # "-O", "--options PATH",
41
+ # "Specify the path to a custom options file."
42
42
 
43
- opt :driver, "-d", "--driver DRIVER",
44
- "Specify driver:",
45
- *driver_details
43
+ opt :driver, "-d", "--driver DRIVER",
44
+ "Specify driver:",
45
+ *driver_details
46
46
 
47
- opt :driver_options, "--driver-options OPTIONS",
48
- "Specify driver-specific options to pass into the driver.",
49
- " e.g. \"--ssl-protocol=any --ssl-certificates-path=/path/to/certs\".",
50
- " Driver options are only supported with phantomjs."
47
+ opt :driver_options, "--driver-options OPTIONS",
48
+ "Specify driver-specific options to pass into the driver.",
49
+ " e.g. \"--ssl-protocol=any --ssl-certificates-path=/path/to/certs\".",
50
+ " Driver options are only supported with phantomjs."
51
51
 
52
- opt :driver_timeout, "--driver-timeout SECONDS",
53
- "Sets the timeout for the driver to wait before exiting."
52
+ opt :driver_timeout, "--driver-timeout SECONDS",
53
+ "Sets the timeout for the driver to wait before exiting."
54
54
 
55
- opt :server, "--server SERVER",
56
- "Sets server to use with Rack.",
57
- " e.g. webrick, thin"
55
+ opt :server, "--server SERVER",
56
+ "Sets server to use with Rack.",
57
+ " e.g. webrick, thin"
58
58
 
59
- opt :server_host, "--server-host HOST",
60
- "Sets the server to use a specific host."
59
+ opt :server_host, "--server-host HOST",
60
+ "Sets the server to use a specific host."
61
61
 
62
- opt :server_port, "--server-port PORT",
63
- "Sets the server to use a specific port."
62
+ opt :server_port, "--server-port PORT",
63
+ "Sets the server to use a specific port."
64
64
 
65
- opt :server_timeout, "--server-timeout SECONDS",
66
- "Sets the timeout that the server must start within."
65
+ opt :server_timeout, "--server-timeout SECONDS",
66
+ "Sets the timeout that the server must start within."
67
67
 
68
- opt :fail_fast, "-F", "--[no-]fail-fast",
69
- "Abort after the first failing suite."
70
- end
68
+ opt :fail_fast, "-F", "--[no-]fail-fast",
69
+ "Abort after the first failing suite."
70
+ end
71
71
 
72
- def opts_for_filtering
73
- separator("Filtering")
72
+ def opts_for_filtering
73
+ separator("Filtering")
74
74
 
75
- opt :suite, "-s", "--suite SUITE",
76
- "Focus to a specific suite."
75
+ opt :suite, "-s", "--suite SUITE",
76
+ "Focus to a specific suite."
77
77
 
78
- opt :filter, "-g", "--filter FILTER",
79
- "Filter tests matching a specific filter."
80
- end
78
+ opt :filter, "-g", "--filter FILTER",
79
+ "Filter tests matching a specific filter."
80
+ end
81
81
 
82
- def opts_for_output
83
- separator("Output")
82
+ def opts_for_output
83
+ separator("Output")
84
84
 
85
- opt :suppress_log, "-q", "--[no-]suppress-log",
86
- "Suppress logs coming from console[log/debug/error]."
85
+ opt :suppress_log, "-q", "--[no-]suppress-log",
86
+ "Suppress logs coming from console[log/debug/error]."
87
87
 
88
- opt :color, "-c", "--[no-]color",
89
- "Enable/Disable color output."
88
+ opt :color, "-c", "--[no-]color",
89
+ "Enable/Disable color output."
90
90
 
91
- opt :export, "-e", "--export [OUTPUT_PATH]",
92
- "Exports the test suite as the full HTML (requires wget)."
91
+ opt :export, "-e", "--export [OUTPUT_PATH]",
92
+ "Exports the test suite as the full HTML (requires wget)."
93
93
 
94
- opt :formatters, "-f", "--format FORMATTERS",
95
- "Specify formatters (comma separated)",
96
- *formatter_details
97
- end
94
+ opt :formatters, "-f", "--format FORMATTERS",
95
+ "Specify formatters (comma separated)",
96
+ *formatter_details
97
+ end
98
98
 
99
- def opts_for_coverage
100
- separator("Coverage")
99
+ def opts_for_coverage
100
+ separator("Coverage")
101
101
 
102
- opt :use_coverage, "-C", "--coverage CONFIG_NAME",
103
- "Generate coverage reports using a pre-defined coverage configuration."
104
- end
102
+ opt :use_coverage, "-C", "--coverage CONFIG_NAME",
103
+ "Generate coverage reports using a pre-defined coverage configuration."
104
+ end
105
105
 
106
- def opts_for_utility
107
- separator("Utility")
106
+ def opts_for_utility
107
+ separator("Utility")
108
108
 
109
- @parser.on "-v", "--version", "Display the version." do
110
- Teaspoon.abort(Teaspoon::VERSION, 0)
111
- end
109
+ @parser.on "-v", "--version", "Display the version." do
110
+ Teaspoon.abort(Teaspoon::VERSION, 0)
111
+ end
112
112
 
113
- @parser.on "-h", "--help", "You're looking at it." do
114
- Teaspoon.abort(@parser, 0)
113
+ @parser.on "-h", "--help", "You're looking at it." do
114
+ Teaspoon.abort(@parser, 0)
115
+ end
115
116
  end
116
- end
117
117
 
118
118
  private
119
119
 
120
- def separator(message)
121
- @parser.separator("\n **** #{message} ****\n\n")
122
- end
120
+ def separator(message)
121
+ @parser.separator("\n **** #{message} ****\n\n")
122
+ end
123
123
 
124
- def opt(config, *args)
125
- @parser.on(*args, proc { |value| @options[config] = value })
126
- end
124
+ def opt(config, *args)
125
+ @parser.on(*args, proc { |value| @options[config] = value })
126
+ end
127
127
 
128
- def require_console
129
- require "teaspoon/console"
130
- end
128
+ def require_console
129
+ require "teaspoon/console"
130
+ end
131
131
 
132
- def formatter_details
133
- Teaspoon::Formatter.available.map do |name, options|
134
- " #{name}#{' (default)' if options[:default]} - #{options[:description]}"
132
+ def formatter_details
133
+ Teaspoon::Formatter.available.map do |name, options|
134
+ " #{name}#{' (default)' if options[:default]} - #{options[:description]}"
135
+ end
135
136
  end
136
- end
137
137
 
138
- def driver_details
139
- Teaspoon::Driver.available.map do |name, options|
140
- " #{name}#{' (default)' if options[:default]}"
138
+ def driver_details
139
+ Teaspoon::Driver.available.map do |name, options|
140
+ " #{name}#{' (default)' if options[:default]}"
141
+ end
141
142
  end
142
- end
143
143
  end
144
144
  end
@@ -21,7 +21,7 @@ module Teaspoon
21
21
  @@asset_paths = ["spec/javascripts", "spec/javascripts/stylesheets",
22
22
  "test/javascripts", "test/javascripts/stylesheets"]
23
23
  @@fixture_paths = ["spec/javascripts/fixtures", "test/javascripts/fixtures"]
24
- @@asset_manifest = ["teaspoon.css", "teaspoon-filterer.js", "teaspoon/*.js", "support/*.js"]
24
+ @@asset_manifest = ["teaspoon.css", "teaspoon-filterer.js", "support/*.js"]
25
25
 
26
26
  # console runner specific
27
27
 
@@ -54,7 +54,7 @@ module Teaspoon
54
54
  # suite configurations
55
55
 
56
56
  cattr_accessor :suite_configs
57
- @@suite_configs = { "default" => { block: proc {} } }
57
+ @@suite_configs = { "default" => { block: proc { } } }
58
58
 
59
59
  def self.suite(name = :default, &block)
60
60
  @@suite_configs[name.to_s] = { block: block, instance: Suite.new(name, &block) }
@@ -66,7 +66,7 @@ module Teaspoon
66
66
  :hooks, :expand_assets, :js_extensions
67
67
 
68
68
  def initialize(name = nil)
69
- @matcher = "{spec/javascripts,app/assets}/**/*_spec.{js,js.coffee,coffee}"
69
+ @matcher = "{spec/javascripts,app/assets}/**/*_spec.{js,js.coffee,coffee,es6,js.es6}"
70
70
  @helper = "spec_helper"
71
71
  @javascripts = []
72
72
  @stylesheets = ["teaspoon"]
@@ -104,7 +104,7 @@ module Teaspoon
104
104
  # coverage configurations
105
105
 
106
106
  cattr_accessor :coverage_configs
107
- @@coverage_configs = { "default" => { block: proc {} } }
107
+ @@coverage_configs = { "default" => { block: proc { } } }
108
108
 
109
109
  def self.coverage(name = :default, &block)
110
110
  @@coverage_configs[name.to_s] = { block: block, instance: Coverage.new(&block) }
@@ -1,4 +1,5 @@
1
1
  require "teaspoon/environment"
2
+ require "teaspoon/utility"
2
3
 
3
4
  module Teaspoon
4
5
  class Console
@@ -66,54 +67,54 @@ module Teaspoon
66
67
 
67
68
  protected
68
69
 
69
- def resolve(files = [])
70
- return if files.blank?
71
- files.uniq.each do |path|
72
- if result = Teaspoon::Suite.resolve_spec_for(path)
73
- suite = @suites[result[:suite]] ||= []
74
- suite << result[:path]
70
+ def resolve(files = [])
71
+ return if files.blank?
72
+ files.uniq.each do |path|
73
+ if result = Teaspoon::Suite.resolve_spec_for(path)
74
+ suite = @suites[result[:suite]] ||= []
75
+ suite << result[:path]
76
+ end
75
77
  end
76
78
  end
77
- end
78
79
 
79
- def start_server
80
- server = Teaspoon::Server.new
81
- log("Starting the Teaspoon server...") unless server.responsive?
82
- server.start
83
- server
84
- end
80
+ def start_server
81
+ server = Teaspoon::Server.new
82
+ log("Starting the Teaspoon server...") unless server.responsive?
83
+ server.start
84
+ server
85
+ end
85
86
 
86
- def suites
87
- return [options[:suite]] if options[:suite].present?
88
- return @suites.keys if @suites.present?
89
- Teaspoon.configuration.suite_configs.keys
90
- end
87
+ def suites
88
+ return [options[:suite]] if options[:suite].present?
89
+ return @suites.keys if @suites.present?
90
+ Teaspoon.configuration.suite_configs.keys
91
+ end
91
92
 
92
- def driver
93
- return @driver if @driver
94
- driver = Teaspoon::Driver.fetch(Teaspoon.configuration.driver)
95
- @driver = driver.new(Teaspoon.configuration.driver_options)
96
- end
93
+ def driver
94
+ return @driver if @driver
95
+ driver = Teaspoon::Driver.fetch(Teaspoon.configuration.driver)
96
+ @driver = driver.new(Teaspoon.configuration.driver_options)
97
+ end
97
98
 
98
- def base_url_for(suite)
99
- ["#{@server.url}#{Teaspoon.configuration.mount_at}", suite].join("/")
100
- end
99
+ def base_url_for(suite)
100
+ ["#{@server.url}#{Teaspoon.configuration.mount_at}", suite].join("/")
101
+ end
101
102
 
102
- def url_for(suite, console = true)
103
- url = [base_url_for(suite), filter(suite)].compact.join("?")
104
- url += "#{(url.include?('?') ? '&' : '?')}reporter=Console" if console
105
- url
106
- end
103
+ def url_for(suite, console = true)
104
+ url = [base_url_for(suite), filter(suite)].compact.join("?")
105
+ url += "#{(url.include?('?') ? '&' : '?')}reporter=Console" if console
106
+ url
107
+ end
107
108
 
108
- def filter(suite)
109
- parts = []
110
- parts << "grep=#{URI::encode(options[:filter])}" if options[:filter].present?
111
- (@suites[suite] || options[:files] || []).flatten.each { |file| parts << "file[]=#{URI::encode(file)}" }
112
- "#{parts.join('&')}" if parts.present?
113
- end
109
+ def filter(suite)
110
+ parts = []
111
+ parts << "grep=#{CGI.escape(options[:filter])}" if options[:filter].present?
112
+ (@suites[suite] || options[:files] || []).flatten.each { |file| parts << "file[]=#{CGI.escape(file)}" }
113
+ "#{parts.join('&')}" if parts.present?
114
+ end
114
115
 
115
- def log(str)
116
- STDOUT.print("#{str}\n") unless Teaspoon.configuration.suppress_log
117
- end
116
+ def log(str)
117
+ STDOUT.print("#{str}\n") unless Teaspoon.configuration.suppress_log
118
+ end
118
119
  end
119
120
  end
@@ -1,3 +1,5 @@
1
+ require "open3"
2
+
1
3
  module Teaspoon
2
4
  class Coverage
3
5
  def self.configuration(name = Teaspoon.configuration.use_coverage)
@@ -18,7 +20,6 @@ module Teaspoon
18
20
  end
19
21
 
20
22
  def generate_reports(&block)
21
-
22
23
  input_path do |input|
23
24
  results = []
24
25
  @config.reports.each do |format|
@@ -33,8 +34,8 @@ module Teaspoon
33
34
  args = threshold_args
34
35
  return if args.blank?
35
36
  input_path do |input|
36
- result = %x{#{@executable} check-coverage #{args.join(" ")} #{input.shellescape} 2>&1}
37
- return if $?.exitstatus == 0
37
+ result, st = Open3.capture2e(@executable, "check-coverage", *args, input.shellescape)
38
+ return if st.exitstatus.zero?
38
39
  result = result.scan(/ERROR: .*$/).join("\n").gsub("ERROR: ", "")
39
40
  block.call(result) unless result.blank?
40
41
  end
@@ -42,31 +43,34 @@ module Teaspoon
42
43
 
43
44
  private
44
45
 
45
- def self.normalize_config_name(name)
46
- return "default" if name == true
47
- name.to_s
48
- end
46
+ def self.normalize_config_name(name)
47
+ return "default" if name == true
48
+ name.to_s
49
+ end
49
50
 
50
- def input_path(&block)
51
- Dir.mktmpdir do |temp_path|
52
- input_path = File.join(temp_path, "coverage.json")
53
- File.open(input_path, "w") { |f| f.write(@data.to_json) }
54
- block.call(input_path)
51
+ def input_path(&block)
52
+ Dir.mktmpdir do |temp_path|
53
+ input_path = File.join(temp_path, "coverage.json")
54
+ File.open(input_path, "w") { |f| f.write(@data.to_json) }
55
+ block.call(input_path)
56
+ end
55
57
  end
56
- end
57
58
 
58
- def generate_report(input, format)
59
- output_path = File.join(@config.output_path, @suite_name)
60
- result = %x{#{@executable} report --include=#{input.shellescape} --dir #{output_path} #{format} 2>&1}
61
- return result.gsub("Done", "").gsub("Using reporter [#{format}]", "").strip if $?.exitstatus == 0
62
- raise Teaspoon::DependencyError.new("Unable to generate #{format} coverage report:\n#{result}")
63
- end
59
+ def generate_report(input, format)
60
+ output_path = File.join(@config.output_path, @suite_name)
61
+ result, st =
62
+ Open3.capture2e(
63
+ @executable, "report", "--include", input.shellescape, "--dir", output_path, format
64
+ )
65
+ return result.gsub("Done", "").gsub("Using reporter [#{format}]", "").strip if st.exitstatus.zero?
66
+ raise Teaspoon::DependencyError.new("Unable to generate #{format} coverage report:\n#{result}")
67
+ end
64
68
 
65
- def threshold_args
66
- %w{statements functions branches lines}.map do |assert|
67
- threshold = @config.send(:"#{assert}")
68
- "--#{assert}=#{threshold}" if threshold
69
- end.compact
70
- end
69
+ def threshold_args
70
+ %w{statements functions branches lines}.map do |assert|
71
+ threshold = @config.send(:"#{assert}")
72
+ "--#{assert}=#{threshold}" if threshold
73
+ end.compact
74
+ end
71
75
  end
72
76
  end