teaspoon 1.0.2 → 1.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c6947cdfc11c4b82dfb1c0db440b2effbcaa2b69
4
- data.tar.gz: 0d792be5439b2f8b55c458620556e0ee9030aca4
3
+ metadata.gz: d648d120a3291ff212bf062258587a21f1ac8108
4
+ data.tar.gz: 82a0bc09c853b64f7af62d41e83eab9f29bb9245
5
5
  SHA512:
6
- metadata.gz: eb2cc7fb2e22d878e9f6a5877ddc71b8c21c7b004d17b1dfc76e3d6ea8e2fad666f9927cfe9b532fec219963ed27d21a0abb0dc3d712007b0057bf0a7a42a544
7
- data.tar.gz: d7eab6abba8e2479aad8fe1551ea1e3c3358fe1b54b9cf8262acc7504f992e7df6ba392996b869f9458a6733eaf9d33160f6df4169695c713f65f5b20914280e
6
+ metadata.gz: 0d40d4cda9de76dd8c641af719e3c86b8c37b40b554c18415cbb583757552d6a6fda5fdb89a5e906638fab73c52aec66ff25677c43d78a120687bdbef51b4259
7
+ data.tar.gz: ed02beab78edf289befa77c321f46469dc1a777877c598b70def697dea0a033e782b21f88ce4fa5e25124293a41746506085b1127b5cca32fb4518371541b159
data/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  ### Unreleased
2
2
 
3
+ #### Bug Fixes
4
+
5
+
6
+ ### 1.1.0
7
+
8
+ #### Enhancements
9
+
10
+ * Support invalid HTML in fixtures (#387)
11
+ * Configurable JavaScript extensions via suite.js_extensions (#418)
12
+ * Fail build when Phantomjs fails (b34c4)
13
+ * Add new versions of test frameworks to the latest minor versions
14
+
15
+ #### Bug Fixes
16
+
17
+ * Retain file filter when navigating to specs (#327)
18
+ * Provide details when Istanbul fails (#368)
19
+ * Fix support for barebones Rails app (#372)
20
+ * Fix pending count and nested styles (#373)
21
+ * Fix total count in Jasmine 2 (#378)
22
+ * Deprecate and fix suite.use_framework= (#394)
23
+ * Fix capybara-webkit synchronization (#403)
24
+ * Fix reporting in IE8 (97cf6)
25
+ * Fix Jasmine's "fit" (f5e2a)
26
+
27
+
3
28
  ### 1.0.2 (5/5/15)
4
29
 
5
30
  #### Bug Fixes
@@ -20,8 +45,19 @@
20
45
  #### Upgrade Steps
21
46
 
22
47
  - **Update your Gemfile**<br>
23
- Change your Gemfile to use "teaspoon-framework" instead of "teaspoon".<br>
24
- eg: If you are using Mocha, this would be `gem 'teaspoon-mocha'`
48
+ Change your Gemfile to use `teaspoon-jasmine` instead of `teaspoon`, if you're using Jasmine. If you're using Mocha, this would be `teaspoon-mocha`. Use `teaspoon-qunit` for QUnit.<br>
49
+ eg: For Jasmine:
50
+ ```ruby
51
+ gem 'teaspoon-jasmine'
52
+ ```
53
+ For Mocha:
54
+ ```ruby
55
+ gem 'teaspoon-mocha'
56
+ ```
57
+ For QUnit:
58
+ ```ruby
59
+ gem 'teaspoon-qunit'
60
+ ```
25
61
 
26
62
  If you had Teaspoon locked at a specific version, kill the version. You'll now need to reference the version of the framework, instead of the version of Teaspoon.<br>
27
63
  eg: If your Gemfile has `gem 'teaspoon', '0.9.1'` and you're using Mocha, you'll want your Gemfile to reference the latest version of Mocha: `gem 'teaspoon-mocha', '2.2.4'`. The teaspoon-mocha gem contains previous versions of Mocha, so even if you're not using version 2.2.4 of Mocha in your `teaspoon_env.rb`, still reference the latest version in your Gemfile and the older version should still work.
data/README.md CHANGED
@@ -329,6 +329,31 @@ All files | 93.75 | 75 | 94.12 | 93.65 |
329
329
  --------------------+-----------+-----------+-----------+-----------+
330
330
  ```
331
331
 
332
+ ### Caveats
333
+
334
+ In order to provide accurate coverage and best performance, it is recommended that you require the implementation file directly from the spec file. For example:
335
+
336
+ ```js
337
+ //= require "my_class"
338
+ describe("MyClass", function() { ... });
339
+ ```
340
+
341
+ It is **not** recommended that you require the entirety of your assets from within your spec helper:
342
+
343
+ ***spec_helper.js***
344
+ ```js
345
+ //= require "application"
346
+ ```
347
+
348
+ If you must require `application` from your spec helper and you have `expand_assets` configuration set to `false`, you'll need to exclude the spec helper from ignored coverage files:
349
+
350
+ ***teaspoon_env.rb***
351
+ ```ruby
352
+ config.coverage do |coverage|
353
+ coverage.ignore = coverage.ignore.reject { |matcher| matcher.match('/spec_helper.') }
354
+ end
355
+ ```
356
+
332
357
  ### Thresholds
333
358
 
334
359
  Teaspoon allows defining coverage threshold requirements. If a threshold is not met, it will cause a test run failure.
@@ -63,18 +63,22 @@ class Teaspoon.Fixture
63
63
 
64
64
  putContent = (content) =>
65
65
  cleanup()
66
- create()
67
- window.fixture.el.innerHTML = content
66
+ addContent(content)
68
67
 
69
68
 
70
69
  addContent = (content) =>
71
70
  create() unless window.fixture.el
72
- window.fixture.el.innerHTML += content
71
+
72
+ if jQueryAvailable()
73
+ parsed = $($.parseHTML(content, document, true))
74
+ window.fixture.el.appendChild(parsed[i]) for i in [0...parsed.length]
75
+ else
76
+ window.fixture.el.innerHTML += content
73
77
 
74
78
 
75
79
  create = =>
76
80
  window.fixture.el = document.createElement("div")
77
- window.fixture.$el = $(window.fixture.el) if typeof(window.$) == 'function'
81
+ window.fixture.$el = $(window.fixture.el) if jQueryAvailable()
78
82
  window.fixture.el.id = "teaspoon-fixtures"
79
83
  document.body?.appendChild(window.fixture.el)
80
84
 
@@ -98,3 +102,7 @@ class Teaspoon.Fixture
98
102
  xhr.onreadystatechange = callback
99
103
  xhr.open("GET", "#{Teaspoon.root}/fixtures/#{url}", false)
100
104
  xhr.send()
105
+
106
+
107
+ jQueryAvailable = ->
108
+ typeof(window.$) == 'function'
@@ -0,0 +1 @@
1
+ Teaspoon.Mixins ||= {}
@@ -0,0 +1,6 @@
1
+ Teaspoon.Mixins.FilterUrl =
2
+ filterUrl: (grep) ->
3
+ params = []
4
+ params.push("grep=#{encodeURIComponent(grep)}")
5
+ params.push("file=#{Teaspoon.params.file}") if Teaspoon.params.file
6
+ "?#{params.join("&")}"
@@ -41,44 +41,57 @@ class Teaspoon.Reporters.Console
41
41
 
42
42
  reportSpecResults: (@spec) ->
43
43
  result = @spec.result()
44
- return if result.skipped
44
+
45
+ if result.status == "pending"
46
+ @trackPending(@spec)
47
+ else if result.status == "failed"
48
+ @trackFailed(@spec)
49
+ else if result.skipped
50
+ @trackDisabled(@spec)
51
+ else
52
+ @trackPassed(@spec)
53
+
54
+
55
+ trackPending: (spec) ->
45
56
  @reportSuites()
46
- switch result.status
47
- when "pending" then @trackPending()
48
- when "failed" then @trackFailure()
49
- else
50
- @log
51
- type: "spec"
52
- suite: @spec.suiteName
53
- label: @spec.description
54
- status: result.status
55
- skipped: result.skipped
56
-
57
-
58
- trackPending: ->
59
- result = @spec.result()
57
+ result = spec.result()
60
58
  @log
61
59
  type: "spec"
62
- suite: @spec.suiteName
63
- label: @spec.description
60
+ suite: spec.suiteName
61
+ label: spec.description
64
62
  status: result.status
65
63
  skipped: result.skipped
66
64
 
67
65
 
68
- trackFailure: ->
69
- result = @spec.result()
70
- for error in @spec.errors()
66
+ trackFailed: (spec) ->
67
+ @reportSuites()
68
+ result = spec.result()
69
+ for error in spec.errors()
71
70
  @log
72
71
  type: "spec"
73
- suite: @spec.suiteName
74
- label: @spec.description
72
+ suite: spec.suiteName
73
+ label: spec.description
75
74
  status: result.status
76
75
  skipped: result.skipped
77
- link: @spec.fullDescription
76
+ link: spec.fullDescription
78
77
  message: error.message
79
78
  trace: error.stack || error.message || "Stack Trace Unavailable"
80
79
 
81
80
 
81
+ trackDisabled: (spec) -> # noop
82
+
83
+
84
+ trackPassed: (spec, result) ->
85
+ @reportSuites()
86
+ result = spec.result()
87
+ @log
88
+ type: "spec"
89
+ suite: spec.suiteName
90
+ label: spec.description
91
+ status: result.status
92
+ skipped: result.skipped
93
+
94
+
82
95
  log: (obj = {}) ->
83
96
  obj["_teaspoon"] = true
84
97
  Teaspoon.log(JSON.stringify(obj))
@@ -43,8 +43,8 @@ class Teaspoon.Reporters.HTML extends Teaspoon.Reporters.BaseView
43
43
  @setStatus("passed") unless @total.failures
44
44
  @setText("stats-passes", @total.passes)
45
45
  @setText("stats-failures", @total.failures)
46
- if @total.run < @total.exist
47
- @total.skipped = @total.exist - @total.run
46
+ if @total.run < @total.exist # For frameworks that don't "run" skipped specs
47
+ @total.skipped = @total.exist - @total.run + @total.skipped
48
48
  @total.run = @total.exist
49
49
  @setText("stats-skipped", @total.skipped)
50
50
  @updateProgress()
@@ -65,6 +65,7 @@ class Teaspoon.Reporters.HTML extends Teaspoon.Reporters.BaseView
65
65
  @total.run += 1
66
66
  @updateProgress()
67
67
  @updateStatus(spec)
68
+ delete @reportView
68
69
 
69
70
 
70
71
  buildLayout: ->
@@ -106,25 +107,22 @@ class Teaspoon.Reporters.HTML extends Teaspoon.Reporters.BaseView
106
107
 
107
108
 
108
109
  updateStatus: (spec) ->
110
+ elapsed = new Teaspoon.Date().getTime() - @specStart
111
+ @reportView?.updateState(spec, elapsed)
112
+
109
113
  result = spec.result()
110
114
 
111
- if result.skipped
115
+ if result.status == "pending"
112
116
  @updateStat("skipped", @total.skipped += 1)
113
- return
114
-
115
- elapsed = new Teaspoon.Date().getTime() - @specStart
116
-
117
- if result.status == "passed"
118
- @updateStat("passes", @total.passes += 1)
119
- @reportView?.updateState("passed", elapsed)
120
- else if result.status == "pending"
121
- @reportView?.updateState("pending", elapsed)
122
- else
117
+ else if result.status == "failed"
123
118
  @updateStat("failures", @total.failures += 1)
124
- @reportView?.updateState("failed", elapsed)
125
119
  unless @config["build-full-report"]
126
120
  new (Teaspoon.resolveClass("Reporters.HTML.FailureView"))(spec).appendTo(@findEl("report-failures"))
127
121
  @setStatus("failed")
122
+ else if result.skipped
123
+ @updateStat("skipped", @total.skipped += 1)
124
+ else
125
+ @updateStat("passes", @total.passes += 1)
128
126
 
129
127
 
130
128
  updateProgress: ->
@@ -22,6 +22,7 @@ class Teaspoon.Reporters.HTML.SpecView extends Teaspoon.Reporters.BaseView
22
22
 
23
23
  buildParent: ->
24
24
  parent = @spec.parent
25
+ return @reporter unless parent
25
26
  if parent.viewId
26
27
  @views.suites[parent.viewId]
27
28
  else
@@ -38,11 +39,46 @@ class Teaspoon.Reporters.HTML.SpecView extends Teaspoon.Reporters.BaseView
38
39
  @append(div)
39
40
 
40
41
 
41
- updateState: (state, elapsed) ->
42
- result = @spec.result()
43
- classes = ["state-#{state}"]
44
- classes.push("slow") if elapsed > Teaspoon.slow
45
- @el.innerHTML += "<span>#{elapsed}ms</span>" if state == "passed"
46
- @el.className = classes.join(" ")
47
- @buildErrors() if result.status == "failed"
48
- @parentView.updateState?(state)
42
+ updateState: (spec, elapsed) ->
43
+ result = spec.result()
44
+ @clearClasses()
45
+
46
+ if result.status == "pending"
47
+ @updatePending(spec, elapsed)
48
+ else if result.status == "failed"
49
+ @updateFailed(spec, elapsed)
50
+ else if result.skipped
51
+ @updateDisabled(spec, elapsed)
52
+ else
53
+ @updatePassed(spec, elapsed)
54
+
55
+
56
+ updatePassed: (spec, elapsed) ->
57
+ @addStatusClass("passed")
58
+ @addClass("slow") if elapsed > Teaspoon.slow
59
+ @el.innerHTML += "<span>#{elapsed}ms</span>"
60
+
61
+
62
+ updateFailed: (spec, elapsed) ->
63
+ @addStatusClass("failed")
64
+ @buildErrors()
65
+ @parentView.updateState?("failed")
66
+
67
+
68
+ updatePending: (spec, elapsed) ->
69
+ @addStatusClass("pending")
70
+
71
+
72
+ updateDisabled: (spec, elapsed) -> # noop
73
+
74
+
75
+ clearClasses: ->
76
+ @el.className = ""
77
+
78
+
79
+ addStatusClass: (status) ->
80
+ @addClass("state-#{status}")
81
+
82
+
83
+ addClass: (name) ->
84
+ @el.className += " #{name}"
@@ -0,0 +1,2 @@
1
+ class Teaspoon.Spec
2
+ Teaspoon.Utility.include(@, Teaspoon.Mixins.FilterUrl)
@@ -0,0 +1,2 @@
1
+ class Teaspoon.Suite
2
+ Teaspoon.Utility.include(@, Teaspoon.Mixins.FilterUrl)
@@ -1,7 +1,11 @@
1
1
  #= require_self
2
+ #= require_tree ./mixins
3
+ #= require teaspoon/utility
2
4
  #= require teaspoon/runner
3
5
  #= require teaspoon/fixture
4
6
  #= require teaspoon/hook
7
+ #= require teaspoon/spec
8
+ #= require teaspoon/suite
5
9
  #= require teaspoon/reporters/html
6
10
  #= require teaspoon/reporters/console
7
11
 
@@ -53,7 +57,7 @@ class @Teaspoon
53
57
 
54
58
  @log: ->
55
59
  Teaspoon.messages.push(arguments[0])
56
- try console.log(arguments...)
60
+ try console?.log?(arguments...)
57
61
  catch e
58
62
  throw new Error("Unable to use console.log for logging")
59
63
 
@@ -0,0 +1,7 @@
1
+ class Teaspoon.Utility
2
+ @extend: (obj, mixin) ->
3
+ obj[name] = method for name, method of mixin
4
+ obj
5
+
6
+ @include: (klass, mixin) ->
7
+ @extend(klass.prototype, mixin)
@@ -117,13 +117,7 @@ html[xmlns] #teaspoon-interface .teaspoon-clearfix {
117
117
  width: 87px;
118
118
  height: 34px;
119
119
  -webkit-transform: rotate(-18deg);
120
- -moz-transform: rotate(-18deg);
121
120
  transform: rotate(-18deg);
122
- background: -moz-linear-gradient(top, rgba(255, 255, 255,0) 0%, rgba(255, 255, 255, 0.3) 100%);
123
- background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(100%, rgba(255, 255, 255, 0.3)));
124
- background: -webkit-linear-gradient(top, rgba(255,255,255,0) 0%, rgba(255, 255, 255, 0.3) 100%);
125
- background: -o-linear-gradient(top, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.3) 100%);
126
- background: -ms-linear-gradient(top, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.3) 100%);
127
121
  background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.3) 100%);
128
122
  content: "\00a0";
129
123
  }
@@ -176,21 +170,13 @@ html[xmlns] #teaspoon-interface .teaspoon-clearfix {
176
170
  outline: none;
177
171
  border-radius: 0.4em;
178
172
  background-color: #fff;
179
- background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.2), rgba(0, 0, 0, 0.05));
180
- background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.2), rgba(0, 0, 0, 0.05));
181
- background-image: -o-linear-gradient(rgba(255, 255, 255, 0.2), rgba(0, 0, 0, 0.05));
182
- background-image: -ms-linear-gradient(rgba(255, 255, 255, 0.2), rgba(0, 0, 0, 0.05));
183
173
  background-image: linear-gradient(rgba(255, 255, 255, 0.2), rgba(0, 0, 0, 0.05));
184
- -webkit-box-shadow: inset 0 1px 4px rgba(255, 255, 255, 0.5);
185
- -moz-box-shadow: inset 0 1px 4px rgba(255, 255, 255, 0.5);
186
174
  box-shadow: inset 0 1px 4px rgba(255, 255, 255, 0.5);
187
175
  text-align: center;
188
176
  cursor: pointer;
189
177
  }
190
178
  #teaspoon-controls button:active,
191
179
  #teaspoon-controls button.active {
192
- -webkit-box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.3);
193
- -moz-box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.3);
194
180
  box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.3);
195
181
  background: #D9D9D9;
196
182
  outline: 0;
@@ -68,6 +68,9 @@ Teaspoon.configure do |config|
68
68
  # into a single file. Similar to Rails' asset `debug: true` and `config.assets.debug = true` options. By default,
69
69
  # Teaspoon expands all assets to provide more valuable stack traces that reference individual source files.
70
70
  #suite.expand_assets = true
71
+
72
+ # Non-.js file extensions Teaspoon should consider JavaScript files
73
+ #suite.js_extensions = [/(\.js)?.coffee/, /(\.js)?.es6/, ".es6.js"]
71
74
  end
72
75
 
73
76
  # Example suite. Since we're just filtering to files already within the root test/javascripts, these files will also
@@ -9,5 +9,7 @@ task teaspoon: :environment do
9
9
  driver_options: ENV["driver_options"],
10
10
  }
11
11
 
12
+ options.delete_if { |k, v| v.nil? }
13
+
12
14
  abort("rake teaspoon failed") if Teaspoon::Console.new(options).failures?
13
15
  end
@@ -28,6 +28,7 @@ module Teaspoon
28
28
  framework_name = options[:framework_name]
29
29
  framework_const = options[:framework_const]
30
30
  framework_root = options[:framework_root]
31
+ framework_env = options[:framework_env]
31
32
  compile_assets = options[:compile_assets]
32
33
 
33
34
  namespace :teaspoon do
@@ -36,9 +37,20 @@ module Teaspoon
36
37
  RSpec::Core::RakeTask.new(:spec) do |t|
37
38
  t.pattern = File.expand_path("spec/**/*_spec.rb", framework_root)
38
39
  end
39
- end
40
40
 
41
- namespace framework do
41
+ desc "Run the #{framework_name} javascript tests"
42
+ task :jsspec do
43
+ rails_env = File.expand_path("spec/dummy/config/environment.rb", DEV_PATH)
44
+ cmd = "rake teaspoon TEASPOON_DEVELOPMENT=true TEASPOON_RAILS_ENV=#{rails_env} TEASPOON_ENV=#{framework_env}"
45
+
46
+ # we shell out to another command so that it creates a pristine runtime environment
47
+ IO.popen(cmd).each do |line|
48
+ STDOUT.print(line)
49
+ end.close
50
+
51
+ exit(1) unless $?.success?
52
+ end
53
+
42
54
  desc "Builds Teaspoon #{framework_name} into the distribution ready bundle"
43
55
  task build: "#{framework}:build:javascripts"
44
56
 
@@ -61,7 +73,7 @@ module Teaspoon
61
73
  Rake::Task["default"].prerequisites.clear
62
74
  Rake::Task["default"].clear
63
75
 
64
- task default: "teaspoon:#{framework}:spec"
76
+ task default: ["teaspoon:#{framework}:spec", "teaspoon:#{framework}:jsspec"]
65
77
  end
66
78
  end
67
79
  end
@@ -62,7 +62,7 @@ module Teaspoon
62
62
  class Suite
63
63
  attr_accessor :matcher, :helper, :javascripts, :stylesheets,
64
64
  :boot_partial, :body_partial,
65
- :hooks, :expand_assets
65
+ :hooks, :expand_assets, :js_extensions
66
66
 
67
67
  def initialize(name = nil)
68
68
  @matcher = "{spec/javascripts,app/assets}/**/*_spec.{js,js.coffee,coffee}"
@@ -75,6 +75,7 @@ module Teaspoon
75
75
 
76
76
  @hooks = Hash.new { |h, k| h[k] = [] }
77
77
  @expand_assets = true
78
+ @js_extensions = [/(\.js)?\.coffee/, /(\.js)?\.es6/, ".es6.js"]
78
79
 
79
80
  default = Teaspoon.configuration.suite_configs["default"]
80
81
  instance_eval(&default[:block]) if default
@@ -93,7 +94,6 @@ module Teaspoon
93
94
 
94
95
  raise Teaspoon::UnknownFrameworkVersion.new(name: name, version: version)
95
96
  end
96
- alias_method :use_framework=, :use_framework
97
97
 
98
98
  def hook(group = :default, &block)
99
99
  @hooks[group.to_s] << block
@@ -56,7 +56,7 @@ module Teaspoon
56
56
  output_path = File.join(@config.output_path, @suite_name)
57
57
  result = %x{#{@executable} report --include=#{input.shellescape} --dir #{output_path} #{format} 2>&1}
58
58
  return result.gsub("Done", "").gsub("Using reporter [#{format}]", "").strip if $?.exitstatus == 0
59
- raise Teaspoon::DependencyError.new("Unable to generate #{format} coverage report.")
59
+ raise Teaspoon::DependencyError.new("Unable to generate #{format} coverage report:\n#{result}")
60
60
  end
61
61
 
62
62
  def threshold_args
@@ -83,6 +83,11 @@ teaspoon coverage directive has changed and is now more flexible, define coverag
83
83
  []
84
84
  end
85
85
  alias_method :no_coverage=, :no_coverage
86
+
87
+ def use_framework=(name, _version = nil)
88
+ Teaspoon.dep("suite.use_framework= is deprecated, use suite.use_framework instead.")
89
+ use_framework(*name)
90
+ end
86
91
  end
87
92
  end
88
93
  end
@@ -11,18 +11,22 @@ require "teaspoon/driver/base"
11
11
  module Teaspoon
12
12
  module Driver
13
13
  class CapybaraWebkit < Base
14
+ class TeaspoonNotFinishedError < StandardError; end
14
15
  def initialize(_options = nil)
15
16
  end
16
17
 
17
18
  def run_specs(runner, url)
18
19
  session.visit(url)
19
20
 
20
- session.document.synchronize(Teaspoon.configuration.driver_timeout.to_i) do
21
+ timeout = Teaspoon.configuration.driver_timeout.to_i
22
+ session.document.synchronize(timeout, errors: [TeaspoonNotFinishedError]) do
21
23
  done = session.evaluate_script("window.Teaspoon && window.Teaspoon.finished")
22
24
  (session.evaluate_script("window.Teaspoon && window.Teaspoon.getMessages()") || []).each do |line|
23
25
  runner.process("#{line}\n")
24
26
  end
25
- done
27
+ unless done
28
+ raise TeaspoonNotFinishedError
29
+ end
26
30
  end
27
31
  end
28
32
 
@@ -33,6 +33,10 @@ module Teaspoon
33
33
 
34
34
  def run(*args, &block)
35
35
  IO.popen([executable, *args].join(" ")) { |io| io.each(&block) }
36
+
37
+ unless $?.success?
38
+ raise Teaspoon::DependencyError.new("Failed to use phantomjs, which exited with status code: #{$?.exitstatus}")
39
+ end
36
40
  end
37
41
 
38
42
  def driver_options(url)
@@ -28,7 +28,7 @@ module Teaspoon
28
28
 
29
29
  def self.find_env(override = nil)
30
30
  override ||= ENV["TEASPOON_ENV"]
31
- env_files = override ? [override] : standard_environments
31
+ env_files = override && !override.empty? ? [override] : standard_environments
32
32
 
33
33
  env_files.each do |filename|
34
34
  file = File.expand_path(filename, Dir.pwd)
@@ -53,7 +53,14 @@ module Teaspoon
53
53
 
54
54
  def self.load_rails
55
55
  rails_env = ENV["TEASPOON_RAILS_ENV"] || File.expand_path("config/environment", Dir.pwd)
56
- require rails_env
56
+
57
+ # Try to load rails, assume teaspoon_env will do it if the expected
58
+ # environment isn't found.
59
+ if File.exists?(rails_env)
60
+ require rails_env
61
+ else
62
+ require_environment
63
+ end
57
64
  end
58
65
  end
59
66
  end
@@ -1,6 +1,8 @@
1
1
  module Teaspoon
2
2
  module Formatter
3
3
  class Base
4
+ RESERVED_PARAMS = ["body", "instrument"]
5
+
4
6
  attr_accessor :total_count, :run_count, :passes, :pendings, :failures, :errors
5
7
 
6
8
  def initialize(suite_name = :default, output_file = nil)
@@ -142,7 +144,14 @@ module Teaspoon
142
144
  end
143
145
 
144
146
  def filename(file)
145
- file.gsub(%r(^http://127.0.0.1:\d+/assets/), "").gsub(/[\?|&]?body=1/, "")
147
+ uri = URI(file)
148
+ params = uri.query.split("&").reject do |param|
149
+ RESERVED_PARAMS.include?(param.split("=").first)
150
+ end
151
+
152
+ filename = uri.path.sub(%r(^/assets/), "")
153
+ filename += "?#{params.join("&")}" if params.any?
154
+ filename
146
155
  end
147
156
  end
148
157
  end
@@ -94,8 +94,10 @@ module Teaspoon
94
94
  normalize_js_extension(filename)
95
95
  end
96
96
 
97
- def normalize_js_extension(filename)
98
- filename.gsub(".erb", "").gsub(/(\.js\.coffee|\.coffee|\.es6|\.js\.es6)$/, ".js")
97
+ def normalize_js_extension(original_filename)
98
+ config.js_extensions.inject(original_filename.gsub(".erb", "")) do |filename, extension|
99
+ filename.gsub(Regexp.new(extension.to_s + "$"), ".js")
100
+ end
99
101
  end
100
102
 
101
103
  def glob
@@ -1,3 +1,3 @@
1
1
  module Teaspoon
2
- VERSION = "1.0.2"
2
+ VERSION = "1.1.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: teaspoon
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - jejacks0n
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2015-05-06 00:00:00.000000000 Z
14
+ date: 2015-10-09 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: railties
@@ -52,6 +52,8 @@ files:
52
52
  - app/assets/javascripts/teaspoon/error.coffee
53
53
  - app/assets/javascripts/teaspoon/fixture.coffee
54
54
  - app/assets/javascripts/teaspoon/hook.coffee
55
+ - app/assets/javascripts/teaspoon/mixins/_namespace.coffee
56
+ - app/assets/javascripts/teaspoon/mixins/filter_url.coffee
55
57
  - app/assets/javascripts/teaspoon/reporters/console.coffee
56
58
  - app/assets/javascripts/teaspoon/reporters/html.coffee
57
59
  - app/assets/javascripts/teaspoon/reporters/html/base_view.coffee
@@ -63,7 +65,10 @@ files:
63
65
  - app/assets/javascripts/teaspoon/reporters/html/suite_view.coffee
64
66
  - app/assets/javascripts/teaspoon/reporters/html/template.coffee
65
67
  - app/assets/javascripts/teaspoon/runner.coffee
68
+ - app/assets/javascripts/teaspoon/spec.coffee
69
+ - app/assets/javascripts/teaspoon/suite.coffee
66
70
  - app/assets/javascripts/teaspoon/teaspoon.coffee
71
+ - app/assets/javascripts/teaspoon/utility.coffee
67
72
  - app/assets/stylesheets/teaspoon.css
68
73
  - app/controllers/teaspoon/suite_controller.rb
69
74
  - app/views/teaspoon/suite/_body.html.erb
@@ -144,7 +149,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
144
149
  version: '0'
145
150
  requirements: []
146
151
  rubyforge_project:
147
- rubygems_version: 2.4.5
152
+ rubygems_version: 2.4.6
148
153
  signing_key:
149
154
  specification_version: 4
150
155
  summary: 'Teaspoon: A Javascript test runner built on top of Rails'