teaspoon 1.1.3 → 1.2.2

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 (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 +18 -13
  8. data/app/views/teaspoon/suite/_boot.html.erb +1 -1
  9. data/app/views/teaspoon/suite/index.html.erb +1 -1
  10. data/lib/generators/teaspoon/install/install_generator.rb +34 -34
  11. data/lib/generators/teaspoon/install/templates/MISSING_FRAMEWORK +1 -1
  12. data/lib/generators/teaspoon/install/templates/POST_INSTALL +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 -27
  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 +22 -15
  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
 
@@ -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