rspec_org_formatter 0.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.
- data/Gemfile +1 -0
- data/README.md +33 -0
- data/lib/rspec/core/formatters/org_formatter.rb +184 -0
- data/lib/rspec_org_formatter.rb +8 -0
- metadata +59 -0
data/Gemfile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
gem 'rspec', ">= 2.0"
|
data/README.md
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# RSpec Org Formatter
|
2
|
+
|
3
|
+
An [RSpec][rspec] formatter that outputs results meant to be viewed with [emacs][emacs] in an [Org mode][orgmode] buffer.
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
Install the gem:
|
8
|
+
|
9
|
+
gem install rspec_org_formatter
|
10
|
+
|
11
|
+
Use it:
|
12
|
+
|
13
|
+
rspec --fRspecOrgFormatter --out rspec.org
|
14
|
+
|
15
|
+
You'll get an org file with your results in it.
|
16
|
+
|
17
|
+
## More Permanent Usage
|
18
|
+
|
19
|
+
Add it to your Gemfile if you're using [Bundler][bundler].
|
20
|
+
|
21
|
+
In your .rspec, usually alongside another formatter, add:
|
22
|
+
|
23
|
+
--format RspecOrgFormatter
|
24
|
+
--out rspec.org
|
25
|
+
|
26
|
+
## License
|
27
|
+
|
28
|
+
The MIT License, see [LICENSE][license].
|
29
|
+
|
30
|
+
[rspec]: http://rspec.info/
|
31
|
+
[bundler]: http://gembundler.com/
|
32
|
+
[license]: https://github.com/sj26/rspec-junit-formatter/blob/master/LICENSE
|
33
|
+
|
@@ -0,0 +1,184 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'rspec/core/formatters/base_text_formatter'
|
3
|
+
|
4
|
+
module RSpec
|
5
|
+
module Core
|
6
|
+
module Formatters
|
7
|
+
class OrgFormatter < BaseTextFormatter
|
8
|
+
|
9
|
+
def initialize(output)
|
10
|
+
super(output)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
def method_missing(m, *a, &b)
|
15
|
+
# no-op
|
16
|
+
end
|
17
|
+
protected
|
18
|
+
def section_level(example_or_group)
|
19
|
+
if example_or_group.respond_to? :ancestors
|
20
|
+
example_or_group.ancestors.size
|
21
|
+
else
|
22
|
+
example_or_group.example_group.ancestors.size + 1
|
23
|
+
end
|
24
|
+
end
|
25
|
+
# returs a string containing the right amount of * for an org section title
|
26
|
+
# relative to an example or example_group
|
27
|
+
def section_markup(example_or_group)
|
28
|
+
'*' * (section_level example_or_group)
|
29
|
+
end
|
30
|
+
# returns a string containing the correct amount of spaces
|
31
|
+
# to correctly indent the text inside the section relative
|
32
|
+
# to an example or an example_group
|
33
|
+
def section_indent(example_or_group)
|
34
|
+
' ' * (section_level example_or_group)
|
35
|
+
end
|
36
|
+
|
37
|
+
# returns the first line of the exception message text
|
38
|
+
def exception_message_head (exception)
|
39
|
+
nl = exception.message.index(?\n)
|
40
|
+
if nl
|
41
|
+
exception.message.slice(0, nl)
|
42
|
+
else
|
43
|
+
exception.message
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# returns the exception message from the second line onwards
|
48
|
+
def exception_message_body(exception)
|
49
|
+
nl = exception.message.index(?\n)
|
50
|
+
if nl
|
51
|
+
exception.message[nl..-1]
|
52
|
+
else
|
53
|
+
nil
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# outputs an exception
|
58
|
+
def output_exception(exception, example)
|
59
|
+
@output.puts "#{section_indent example} #{exception_message_head exception}" unless exception.nil?
|
60
|
+
exception_msg_body = exception_message_body exception
|
61
|
+
if !(exception_msg_body.blank?)
|
62
|
+
exception_msg_body = (exception_msg_body.strip.split("\n").map! { |line| "#{section_indent example} #{line}" }).join("\n").chomp
|
63
|
+
@output.puts "#{section_indent example} :DETAILS:"
|
64
|
+
@output.puts exception_msg_body
|
65
|
+
@output.puts "#{section_indent example} :END:"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def org_link(file, line)
|
70
|
+
current_dir = Dir.pwd
|
71
|
+
"[[#{current_dir}#{file}::#{line}][#{file[1..-1]}:#{line}]]"
|
72
|
+
end
|
73
|
+
# outputs the backtrace of an exception
|
74
|
+
def output_backtrace(exception, example)
|
75
|
+
if (exception)
|
76
|
+
@output.puts "#{section_indent example} *Backtrace*"
|
77
|
+
fmtbktr = format_backtrace exception.backtrace, example
|
78
|
+
fmtbktr.each { |bktr|
|
79
|
+
file, line, rest = bktr.match(/(.*):(.*):(in.*)/).to_a.drop(1)
|
80
|
+
if file.index('./') == 0
|
81
|
+
file = file[1..-1]
|
82
|
+
end
|
83
|
+
@output.puts "#{section_indent example} #{org_link file, line} #{rest}"
|
84
|
+
}
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# outputs the visibility properties for failed examples
|
89
|
+
def output_failure_properties(example)
|
90
|
+
@output.puts "#{section_indent example} :PROPERTIES:"
|
91
|
+
@output.puts "#{section_indent example} :VISIBILITY: children"
|
92
|
+
@output.puts "#{section_indent example} :END:"
|
93
|
+
end
|
94
|
+
|
95
|
+
def exception_pending_fixed?(exception)
|
96
|
+
if exception.respond_to? :pending_fixed?
|
97
|
+
exception.pending_fixed?
|
98
|
+
else
|
99
|
+
RSpec::Core::PendingExampleFixedError === exception
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
|
104
|
+
public
|
105
|
+
def message(message)
|
106
|
+
end
|
107
|
+
|
108
|
+
# The number of the currently running example (a global counter)
|
109
|
+
|
110
|
+
def start(example_count)
|
111
|
+
super(example_count)
|
112
|
+
end
|
113
|
+
|
114
|
+
# returns the org section level for an example or an example_group
|
115
|
+
|
116
|
+
def example_group_started(example_group)
|
117
|
+
super(example_group)
|
118
|
+
@output.puts "#{section_markup example_group} #{example_group.description}"
|
119
|
+
@output.flush
|
120
|
+
end
|
121
|
+
|
122
|
+
def start_dump
|
123
|
+
end
|
124
|
+
|
125
|
+
def example_passed(example)
|
126
|
+
@output.puts "#{section_markup example} SUCCESS #{example.description}"
|
127
|
+
@output.flush
|
128
|
+
end
|
129
|
+
|
130
|
+
|
131
|
+
|
132
|
+
|
133
|
+
def example_failed(example)
|
134
|
+
super(example)
|
135
|
+
exception = example.metadata[:execution_result][:exception]
|
136
|
+
failure_style = exception_pending_fixed?(exception) ? 'pending_fixed' : 'failed'
|
137
|
+
# @header_red = true
|
138
|
+
# @example_group_red = true
|
139
|
+
@output.puts "#{section_markup example} #{failure_style.upcase} #{example.description}"
|
140
|
+
output_exception(exception, example)
|
141
|
+
output_backtrace(exception, example)
|
142
|
+
output_failure_properties example
|
143
|
+
@output.flush
|
144
|
+
end
|
145
|
+
|
146
|
+
def example_pending(example)
|
147
|
+
message = example.metadata[:execution_result][:pending_message]
|
148
|
+
@output.puts "#{section_markup example} PENDING #{example.description}"
|
149
|
+
@output.puts "#{section_indent example} #{message}"
|
150
|
+
@output.flush
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
|
155
|
+
def dump_failures
|
156
|
+
end
|
157
|
+
|
158
|
+
def dump_pending
|
159
|
+
end
|
160
|
+
|
161
|
+
def dump_summary(duration, example_count, failure_count, pending_count)
|
162
|
+
# TODO - kill dry_run?
|
163
|
+
@output.puts "* Summary"
|
164
|
+
if dry_run?
|
165
|
+
totals = "This was a dry-run"
|
166
|
+
else
|
167
|
+
totals = "#{example_count} example#{'s' unless example_count == 1}, "
|
168
|
+
totals << "#{failure_count} failure#{'s' unless failure_count == 1}"
|
169
|
+
totals << ", #{pending_count} pending" if pending_count > 0
|
170
|
+
end
|
171
|
+
@output.puts "Finished in *#{duration} seconds*"
|
172
|
+
@output.puts totals
|
173
|
+
@output.puts " :PROPERTIES:"
|
174
|
+
@output.puts " :VISIBILITY: children"
|
175
|
+
@output.puts " :END:"
|
176
|
+
@output.puts "#+DRAWERS: DETAILS PROPERTIES"
|
177
|
+
@output.puts "#+TODO: FAILED PENDING_FIXED PENDING | SUCCESS"
|
178
|
+
@output.flush
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
metadata
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rspec_org_formatter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Alessandro Piras
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-01-07 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: &85664870 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 2.6.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *85664870
|
25
|
+
description: RSpec results meant to be viewed in an emacs org buffer
|
26
|
+
email: laynor@gmail.com
|
27
|
+
executables: []
|
28
|
+
extensions: []
|
29
|
+
extra_rdoc_files: []
|
30
|
+
files:
|
31
|
+
- lib/rspec_org_formatter.rb
|
32
|
+
- lib/rspec/core/formatters/org_formatter.rb
|
33
|
+
- README.md
|
34
|
+
- Gemfile
|
35
|
+
homepage: https://github.com/laynor/rspec_org_formatter
|
36
|
+
licenses: []
|
37
|
+
post_install_message:
|
38
|
+
rdoc_options: []
|
39
|
+
require_paths:
|
40
|
+
- lib
|
41
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
48
|
+
none: false
|
49
|
+
requirements:
|
50
|
+
- - ! '>='
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
requirements: []
|
54
|
+
rubyforge_project:
|
55
|
+
rubygems_version: 1.8.5
|
56
|
+
signing_key:
|
57
|
+
specification_version: 3
|
58
|
+
summary: RSpec Org Formatter
|
59
|
+
test_files: []
|