teaspoon 1.0.2 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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'