opal-rspec-formatter 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +23 -2
- data/lib/opal/rspec-formatter/rake_task.rb +50 -7
- data/lib/opal/rspec-formatter/version.rb +1 -1
- data/opal/opal/rspec/sprockets_runner_customformat.rb.erb +16 -11
- data/spec_mri/junit_spec.rb +39 -29
- data/spec_mri/teamcity_spec.rb +67 -0
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7d4a38e1bec4f304a7304a6b7238654ca9b41651
|
4
|
+
data.tar.gz: 7579c4647dc630f846e0feed10808d0c3f0942c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bc545ae22aabe7becb1a17d303e65dd22dfd861afa3a3c412428974229e5ec4fd6ef2e2026f76ace0459268eb3e695f2f5b87d60c1269e10cdb7b46fadf795fa
|
7
|
+
data.tar.gz: ca724bd6cba020aa0eb4a159010df3319524f4e60091980541dec53faf9251d2b8b6fb7551d566f3e109b56ce48f4764cf7d5cbe3db5d193f9f800564a7ffee5
|
data/CHANGELOG.md
ADDED
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
|
-
|
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
|
-
|
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
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|
@@ -2,21 +2,26 @@ require 'opal'
|
|
2
2
|
require 'opal-rspec'
|
3
3
|
<%
|
4
4
|
spec_opts = ENV['SPEC_OPTS']
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
16
|
+
require '<%= format_req %>'
|
13
17
|
<% end %>
|
14
18
|
|
15
|
-
|
16
|
-
|
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
|
data/spec_mri/junit_spec.rb
CHANGED
@@ -1,42 +1,52 @@
|
|
1
1
|
require 'nokogiri'
|
2
2
|
|
3
3
|
describe 'JUnit' do
|
4
|
-
|
5
|
-
|
6
|
-
|
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
|
12
|
-
|
13
|
-
|
14
|
-
|
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
|
-
|
17
|
-
|
18
|
-
|
20
|
+
match do |document|
|
21
|
+
actual = get_item[document]
|
22
|
+
@value.is_a?(Regexp) ? @value.match(actual) : (actual == @value)
|
23
|
+
end
|
19
24
|
|
20
|
-
|
21
|
-
|
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
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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
|
-
|
43
|
+
subject { @@parsed }
|
35
44
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
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.
|
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: {}
|