opal-rspec-formatter 1.0.0 → 1.0.1

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: c18b7c448071807ba181cfe4aa8ac6b515265af1
4
- data.tar.gz: 717b8483156f782172de643fb72dcab27b198144
3
+ metadata.gz: 7d4a38e1bec4f304a7304a6b7238654ca9b41651
4
+ data.tar.gz: 7579c4647dc630f846e0feed10808d0c3f0942c5
5
5
  SHA512:
6
- metadata.gz: 61a36ba9e3817522f08bb980864d47147f1b158ee3af1ad2b335e970ab603fe8f73444e1f70e52ce88db5690ec17bd13071f2f5ef671759ab4fe235ae4735ad3
7
- data.tar.gz: 62b14e729fc312ecc4084dfd895d433b620e62d7d400f135e93673e050211e9e625fe429b7c0a972d282abe5859438bfcf9106eea0069c5a1b7db6eaaadfc9c3
6
+ metadata.gz: bc545ae22aabe7becb1a17d303e65dd22dfd861afa3a3c412428974229e5ec4fd6ef2e2026f76ace0459268eb3e695f2f5b87d60c1269e10cdb7b46fadf795fa
7
+ data.tar.gz: ca724bd6cba020aa0eb4a159010df3319524f4e60091980541dec53faf9251d2b8b6fb7551d566f3e109b56ce48f4764cf7d5cbe3db5d193f9f800564a7ffee5
@@ -0,0 +1,7 @@
1
+ # 1.0.1
2
+ * Don't complain if this formatter's require is used, but no SPEC_OPTS are supplied
3
+ * Fix TeamCity issues and take advantage/work with of default formatter information set by TeamCity in SPEC_OPTS
4
+
5
+ # 1.0.0
6
+
7
+ Initial release
data/README.md CHANGED
@@ -14,6 +14,8 @@ gem 'opal-rspec-formatter'
14
14
 
15
15
  ### Use in your application
16
16
 
17
+ #### General
18
+
17
19
  In your Rakefile, make the following change
18
20
 
19
21
  ```ruby
@@ -23,6 +25,22 @@ require 'opal/rspec-formatter/rake_task'
23
25
  Opal::RSpec::RakeTask.new(:default)
24
26
  ```
25
27
 
28
+ #### Opal-Rails
29
+
30
+ If you are using opal-rails, you will not have require 'opal/rspec/rake_task' in your Rakefile because the opal:spec task is created from the opal-rails gem. You need to add the require to the top level Rakefile **before** opal-rails loads its task so that the formatter changes will take effect. It should look something like this:
31
+
32
+ ```ruby
33
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
34
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
35
+
36
+ require File.expand_path('../config/application', __FILE__)
37
+
38
+ # needs to go in before opal-rails (which is triggered by Rails.application.load_tasks)
39
+ require 'opal/rspec-formatter/rake_task'
40
+
41
+ Rails.application.load_tasks
42
+ ```
43
+
26
44
  #### JUnit
27
45
 
28
46
  Now on the command line, supply the SPEC_OPTS environment variable. Example:
@@ -37,10 +55,13 @@ If you omit either of these settings, the default opal-rspec formatter will be u
37
55
 
38
56
  Example:
39
57
  ```bash
40
- SPEC_OPTS="--append_exp_from_load_path patch/bdd --append_exp_from_load_path patch/common --require opal/rspec/formatters/teamcity --format Opal::RSpec::Formatters::TeamCity" rake
58
+ # TeamCity/RubyMine will normally add all this for you and all you need to do is run your Rake task within its environment
59
+ RUBYLIB="/Applications/RubyMine.app/Contents/rb/testing/patch/bdd:/Applications/RubyMine.app/Contents/rb/testing/patch/common" SPEC_OPTS="--require teamcity/spec/runner/formatter/teamcity/formatter --format Spec::Runner::Formatter::TeamcityFormatter" rake
41
60
  ```
42
61
 
43
- 'append_exp_from_load_path' is there to avoid distributing a copy of the TeamCity formatter, we only include the patches here. TeamCity and Rubymine usually include the load path to their formatters when they launch Ruby. The append_exp_from_load_path parameter will cause this GEM to selectively add items in the Ruby load path that match the given expression to the Opal load path.
62
+ This GEM will look for anything on the load path that matches patch/common or patch/bdd and add it to the Opal path for you. It will also change the formatter class from the stock one (Spec::Runner::Formatter::TeamcityFormatter) to Opal::RSpec::Formatters::TeamCity automatically. If these items change, you can supply 'append_exp_from_load_path' in SPEC_OPTS to specify different expressions for locating the TeamCity/RubyMine files in the load path.
63
+
64
+ In order to avoid distributing a copy of the TeamCity formatter, we only include the patches here.
44
65
 
45
66
  #### Custom
46
67
  This GEM currently includes a JUnit XML formatter and patches to make the TeamCity/Rubymine runner work, but you can use any formatter you can get working with Opal.
@@ -4,6 +4,50 @@ class Opal::RSpec::RakeTask
4
4
  # Monkey patching the constructor without duplicating it here
5
5
  alias_method :orig_init, :initialize
6
6
 
7
+ def self.get_requires
8
+ spec_opts = ENV['SPEC_OPTS']
9
+ return [] unless spec_opts
10
+ spec_opts.scan(/--require (\S+)/).flatten
11
+ end
12
+
13
+ def get_custom_load_path_expressions
14
+ spec_opts = ENV['SPEC_OPTS']
15
+ return [] unless spec_opts
16
+ matches = spec_opts.scan /--append_exp_from_load_path (\S+)/
17
+ matches.flatten.map {|m| Regexp.new(Regexp.escape(m))}
18
+ end
19
+
20
+ def add_to_load_path(expressions, server)
21
+ expressions.each do |r|
22
+ matches = $:.select {|path| r.match(path)}
23
+ matches.each do |load_path|
24
+ puts "Adding #{load_path} to Opal path"
25
+ server.append_path load_path
26
+ end
27
+ end
28
+ end
29
+
30
+ def get_default_teamcity_load_path_expressions
31
+ [/patch\/bdd/, /patch\/common/]
32
+ end
33
+
34
+ def teamcity_require_indicator
35
+ 'teamcity/spec/runner/formatter/teamcity/formatter'
36
+ end
37
+
38
+ def is_teamcity
39
+ Opal::RSpec::RakeTask.get_requires.include? teamcity_require_indicator
40
+ end
41
+
42
+ def validate_teamcity_is_there(server)
43
+ filename = teamcity_require_indicator+'.rb'
44
+ paths = server.sprockets.paths
45
+ found = paths.find {|p| File.exist?(File.join(p, filename))}
46
+ unless found
47
+ raise "TeamCity formatter require (#{filename}) supplied, but was not able to find Teamcity classes in Opal paths #{Opal.paths}. By default, anything in the Ruby load path that matches #{get_default_teamcity_load_path_expressions} will be used. If this needs to be changed, supply -- append_exp_from_load_path in the SPEC_OPTS env variable with another regex."
48
+ end
49
+ end
50
+
7
51
  def initialize(name = 'opal:rspec', &block)
8
52
  # We'll add our formatter set code before any main code that uses this task runs. This also should work
9
53
  # out of the box with opal-rails, which uses a different server.main util than others
@@ -13,15 +57,14 @@ class Opal::RSpec::RakeTask
13
57
  # TODO: Surely a better way than environment variables to pass this on?
14
58
  ENV['opal_rspec_after_formatter_set'] = run_before_this
15
59
  server.main = 'opal/rspec/sprockets_runner_customformat'
16
- regexes = ENV['SPEC_OPTS'].scan /--append_exp_from_load_path (\S+)/
17
- regexes.each do |r|
18
- exp = Regexp.new(Regexp.escape(r[0]))
19
- matches = $:.select {|path| exp.match(path)}
20
- matches.each do |load_path|
21
- server.append_path load_path
22
- end
60
+
61
+ add_to_load_path get_custom_load_path_expressions, server
62
+ if is_teamcity
63
+ add_to_load_path get_default_teamcity_load_path_expressions, server
64
+ validate_teamcity_is_there server
23
65
  end
24
66
  end
67
+
25
68
  orig_init name, &runner_block
26
69
  end
27
70
  end
@@ -1,7 +1,7 @@
1
1
  module Opal
2
2
  module RSpec
3
3
  module Formatter
4
- VERSION = '1.0.0'
4
+ VERSION = '1.0.1'
5
5
  end
6
6
  end
7
7
  end
@@ -2,21 +2,26 @@ require 'opal'
2
2
  require 'opal-rspec'
3
3
  <%
4
4
  spec_opts = ENV['SPEC_OPTS']
5
- formatter_require_matches = spec_opts.scan /--require (\S+)/
6
- formatter_class_match = /--format (\S+)/.match(spec_opts)
7
- if formatter_require_matches.any? and formatter_class_match
8
- formatter_class = formatter_class_match.captures[0]
9
-
10
- formatter_require_matches.flatten.each do |format_req|
5
+ if spec_opts
6
+ requires = ::Opal::RSpec::RakeTask.get_requires
7
+ formatter_class_matches = spec_opts.scan /--format (\S+)/
8
+ if requires.any? and formatter_class_matches.any?
9
+ # TeamCity will add its own contents to SPEC_OPTS but we need to supercede those
10
+ requires = requires.map {|r| r == 'teamcity/spec/runner/formatter/teamcity/formatter' ? 'opal/rspec/formatters/teamcity' : r}
11
+ formats = formatter_class_matches.flatten.map {|f| f == 'Spec::Runner::Formatter::TeamcityFormatter' ? 'Opal::RSpec::Formatters::TeamCity' : f}
12
+
13
+ formatter_class = formats.last
14
+ requires.each do |format_req|
11
15
  %>
12
- require '<%= format_req %>'
16
+ require '<%= format_req %>'
13
17
  <% end %>
14
18
 
15
- RSpec.configure do |config|
16
- config.default_formatter = <%= formatter_class %>
19
+ RSpec.configure do |config|
20
+ config.default_formatter = <%= formatter_class %>
21
+ end
22
+ <%
17
23
  end
18
-
19
- <% end %>
24
+ end %>
20
25
 
21
26
  # We've interrupted the usual opal-rspec flow to set the formatter, now run the rest of the 's.main' code
22
27
  # This environment variable was set in the Rake task monkey patch in this GEM
@@ -1,42 +1,52 @@
1
1
  require 'nokogiri'
2
2
 
3
3
  describe 'JUnit' do
4
- RSpec::Matchers.define :have_xpath do |xpath|
5
- get_item = lambda do |document|
6
- results = document.xpath(xpath)
7
- results = results.map {|r| r.text }
8
- results.length == 1 ? results[0] : results
4
+ context 'no env variable set' do
5
+ subject do
6
+ `rake raw_specs`
9
7
  end
10
8
 
11
- match do |document|
12
- actual = get_item[document]
13
- @value.is_a?(Regexp) ? @value.match(actual) : (actual == @value)
14
- end
9
+ it { is_expected.to match /2 examples, 1 failures, 0 pending/ }
10
+ end
11
+
12
+ context 'env variable supplied' do
13
+ RSpec::Matchers.define :have_xpath do |xpath|
14
+ get_item = lambda do |document|
15
+ results = document.xpath(xpath)
16
+ results = results.map {|r| r.text }
17
+ results.length == 1 ? results[0] : results
18
+ end
15
19
 
16
- failure_message do |document|
17
- "Expected #{@value} but got #{get_item[document]}"
18
- end
20
+ match do |document|
21
+ actual = get_item[document]
22
+ @value.is_a?(Regexp) ? @value.match(actual) : (actual == @value)
23
+ end
19
24
 
20
- chain :with_value do |value|
21
- @value = value
25
+ failure_message do |document|
26
+ "Expected #{@value} but got #{get_item[document]}"
27
+ end
28
+
29
+ chain :with_value do |value|
30
+ @value = value
31
+ end
22
32
  end
23
- end
24
33
 
25
- before :all do
26
- # this is expensive to run!
27
- output = `SPEC_OPTS="--require opal/rspec/formatters/junit --format Opal::RSpec::Formatters::Junit" rake raw_specs`
28
- xml = /<\?xml.*\<\/testsuite\>/m.match(output)[0]
29
- @@parsed = Nokogiri::XML xml do |config|
30
- config.strict
34
+ before :context do
35
+ # this is expensive to run!
36
+ output = `SPEC_OPTS="--require opal/rspec/formatters/junit --format Opal::RSpec::Formatters::Junit" rake raw_specs`
37
+ xml = /<\?xml.*\<\/testsuite\>/m.match(output)[0]
38
+ @@parsed = Nokogiri::XML xml do |config|
39
+ config.strict
40
+ end
31
41
  end
32
- end
33
42
 
34
- subject { @@parsed }
43
+ subject { @@parsed }
35
44
 
36
- it { is_expected.to have_xpath('/testsuite/@tests').with_value('2') }
37
- it { is_expected.to have_xpath('/testsuite/@failures').with_value('1') }
38
- it { is_expected.to have_xpath('/testsuite/@errors').with_value('0') }
39
- it { is_expected.to have_xpath('/testsuite/testcase/@classname').with_value(%w{foobar::succeeds foobar::fails}) }
40
- it { is_expected.to have_xpath('/testsuite/testcase/@name').with_value(['should eq true', 'should eq false']) }
41
- it { is_expected.to have_xpath('/testsuite/testcase[@classname="foobar::fails"]/failure/@message').with_value(/expected: false.*got: true/m) }
45
+ it { is_expected.to have_xpath('/testsuite/@tests').with_value('2') }
46
+ it { is_expected.to have_xpath('/testsuite/@failures').with_value('1') }
47
+ it { is_expected.to have_xpath('/testsuite/@errors').with_value('0') }
48
+ it { is_expected.to have_xpath('/testsuite/testcase/@classname').with_value(%w{foobar::succeeds foobar::fails}) }
49
+ it { is_expected.to have_xpath('/testsuite/testcase/@name').with_value(['should eq true', 'should eq false']) }
50
+ it { is_expected.to have_xpath('/testsuite/testcase[@classname="foobar::fails"]/failure/@message').with_value(/expected: false.*got: true/m) }
51
+ end
42
52
  end
@@ -0,0 +1,67 @@
1
+ describe 'TeamCity', skip: 'No TeamCity on Travis' do
2
+ before do
3
+ raise "Ensure you've copied the /Applications/RubyMine.app/Contents/rb/testing directory to ../teamcity before running" unless Dir.exist?('../teamcity')
4
+ end
5
+
6
+ let(:command) {
7
+ "RUBYLIB='#{load_path}' SPEC_OPTS='#{spec_opts}' rake raw_specs 2>&1"
8
+ }
9
+
10
+ subject { `#{command}` }
11
+
12
+ RSpec.shared_context :success_example do
13
+ it { is_expected.to match /##teamcity\[testSuiteFinished/ }
14
+ end
15
+
16
+ RSpec.shared_context :fail_example do
17
+ it { is_expected.to match /TeamCity formatter require \(\S+\) supplied, but was not able to find Teamcity classes in Opal paths.*/ }
18
+ end
19
+
20
+ context 'default' do
21
+ let(:spec_opts) {
22
+ '--require teamcity/spec/runner/formatter/teamcity/formatter --format Spec::Runner::Formatter::TeamcityFormatter'
23
+ }
24
+
25
+ context 'found' do
26
+ let(:load_path) { '../teamcity/patch/common:../teamcity/patch/bdd' }
27
+
28
+ include_context :success_example
29
+ end
30
+
31
+ context 'not found' do
32
+ let(:load_path) { '../teamcity/patch_foo/common:../teamcity/patch/bdd_foo' }
33
+
34
+ include_context :fail_example
35
+ end
36
+ end
37
+
38
+ context 'custom append exp settings' do
39
+ before do
40
+ FileUtils.mv '../teamcity/patch/bdd', '../teamcity/patch/foo_bdd'
41
+ FileUtils.mv '../teamcity/patch/common', '../teamcity/patch/foo_common'
42
+ end
43
+
44
+ after do
45
+ FileUtils.mv '../teamcity/patch/foo_bdd', '../teamcity/patch/bdd'
46
+ FileUtils.mv '../teamcity/patch/foo_common', '../teamcity/patch/common'
47
+ end
48
+
49
+ let(:load_path) { '../teamcity/patch/foo_common:../teamcity/patch/foo_bdd' }
50
+
51
+ context 'found' do
52
+ let(:spec_opts) {
53
+ '--append_exp_from_load_path patch/foo_bdd --append_exp_from_load_path patch/foo_common --require teamcity/spec/runner/formatter/teamcity/formatter --format Spec::Runner::Formatter::TeamcityFormatter'
54
+ }
55
+
56
+ include_context :success_example
57
+ end
58
+
59
+ context 'not found' do
60
+ let(:spec_opts) {
61
+ '--append_exp_from_load_path patch/bdd_2 --append_exp_from_load_path patch/common_2 --require teamcity/spec/runner/formatter/teamcity/formatter --format Spec::Runner::Formatter::TeamcityFormatter'
62
+ }
63
+
64
+ include_context :fail_example
65
+ end
66
+ end
67
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opal-rspec-formatter
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brady Wied
@@ -96,6 +96,7 @@ files:
96
96
  - ".gitignore"
97
97
  - ".gitmodules"
98
98
  - ".travis.yml"
99
+ - CHANGELOG.md
99
100
  - Gemfile
100
101
  - README.md
101
102
  - Rakefile
@@ -117,6 +118,7 @@ files:
117
118
  - opal/opal/rspec/sprockets_runner_customformat.rb.erb
118
119
  - spec/test_spec.rb
119
120
  - spec_mri/junit_spec.rb
121
+ - spec_mri/teamcity_spec.rb
120
122
  homepage: https://github.com/wied03/opal-rspec-formatter
121
123
  licenses: []
122
124
  metadata: {}