specify_html_reporter 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +49 -0
- data/.hound.yml +73 -0
- data/.rspec +4 -0
- data/.rubocop.yml +6 -0
- data/.travis.yml +13 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +7 -0
- data/LICENSE.md +21 -0
- data/README.md +87 -0
- data/Rakefile +36 -0
- data/bin/console +7 -0
- data/bin/setup +8 -0
- data/lib/specify_html_reporter/example.rb +120 -0
- data/lib/specify_html_reporter/problem.rb +93 -0
- data/lib/specify_html_reporter/version.rb +3 -0
- data/lib/specify_html_reporter.rb +212 -0
- data/resources/Chart.min.js +10 -0
- data/resources/bootstrap-4.0.0-dist/css/bootstrap.min.css +7 -0
- data/resources/bootstrap-4.0.0-dist/fonts/glyphicons-halflings-regular.eot +0 -0
- data/resources/bootstrap-4.0.0-dist/fonts/glyphicons-halflings-regular.svg +229 -0
- data/resources/bootstrap-4.0.0-dist/fonts/glyphicons-halflings-regular.ttf +0 -0
- data/resources/bootstrap-4.0.0-dist/fonts/glyphicons-halflings-regular.woff +0 -0
- data/resources/bootstrap-4.0.0-dist/js/bootstrap.min.js +7 -0
- data/resources/bootstrap-4.0.0-dist/themes/bootstrap-theme-yeti.min.css +11 -0
- data/resources/jquery-3.3.1.min.js +2 -0
- data/specify_html_reporter.gemspec +37 -0
- data/templates/overview.erb +121 -0
- data/templates/report.erb +209 -0
- metadata +198 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 686bb5892af39dd3816a22c1187e20336a66e93ec399519ebf45735f7f06959f
|
4
|
+
data.tar.gz: f131e7e4cf200f2c94b08c7ca86b131c6c6a1d322eaf9413c812fba2bc220360
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2398bee6ecec1c4e673599ae99dd8d8fe2e56d1eb907e7da956f71fa5591300b7f9ec506550d1a2ab8721ffebb8aa47105ddf8fd2bee4f47fcf9ffa22d81bf66
|
7
|
+
data.tar.gz: c1e348cdf3ec823f20993ab1502dffb038c33ac1c7222437b097e64f3b445385430dc21c7227c9c9b32dd561b86085db4c0af269bbdd3693e1edb552e04d9dab
|
data/.gitignore
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# Ruby Generated
|
2
|
+
|
3
|
+
/Gemfile.lock
|
4
|
+
/.bundle/
|
5
|
+
/.yardoc
|
6
|
+
/_yardoc/
|
7
|
+
/coverage/
|
8
|
+
/doc/
|
9
|
+
/pkg/
|
10
|
+
/spec/reports/
|
11
|
+
/spec/coverage/
|
12
|
+
/tmp/
|
13
|
+
|
14
|
+
# Generated Reports
|
15
|
+
reports/
|
16
|
+
|
17
|
+
# Rspec Failure Tracking
|
18
|
+
|
19
|
+
.rspec_status
|
20
|
+
|
21
|
+
# IDE Files
|
22
|
+
|
23
|
+
.idea/
|
24
|
+
*.iml
|
25
|
+
*.iws
|
26
|
+
*.ipr
|
27
|
+
.vscode/
|
28
|
+
.settings/
|
29
|
+
.metadata
|
30
|
+
.classpath
|
31
|
+
.loadpath
|
32
|
+
.buildpath
|
33
|
+
.project
|
34
|
+
|
35
|
+
# OS Files
|
36
|
+
|
37
|
+
.DS_Store
|
38
|
+
.DS_Store?
|
39
|
+
._*
|
40
|
+
.Spotlight-V100
|
41
|
+
.Trashes
|
42
|
+
ehthumbs.db
|
43
|
+
Thumbs.db
|
44
|
+
$RECYCLE.BIN/
|
45
|
+
Desktop.ini
|
46
|
+
*.tmp
|
47
|
+
*.bak
|
48
|
+
*.swp
|
49
|
+
*~.nib
|
data/.hound.yml
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
AllCops:
|
2
|
+
Exclude:
|
3
|
+
- specify_html_reporter.gemspec
|
4
|
+
- spec/**/*
|
5
|
+
|
6
|
+
# Removing need for frozen string literal comment.
|
7
|
+
Style/FrozenStringLiteralComment:
|
8
|
+
Enabled: false
|
9
|
+
|
10
|
+
# Removing the preference for string single quotes.
|
11
|
+
Style/StringLiterals:
|
12
|
+
Enabled: false
|
13
|
+
|
14
|
+
# Missing top-level module documentation comment.
|
15
|
+
Style/Documentation:
|
16
|
+
Enabled: false
|
17
|
+
|
18
|
+
# Prefer reduce over inject.
|
19
|
+
Style/CollectionMethods:
|
20
|
+
PreferredMethods:
|
21
|
+
reduce: 'inject'
|
22
|
+
|
23
|
+
# Use each_with_object instead of inject.
|
24
|
+
Style/EachWithObject:
|
25
|
+
Enabled: false
|
26
|
+
|
27
|
+
# Prefer fail over raise.
|
28
|
+
Style/SignalException:
|
29
|
+
Enabled: false
|
30
|
+
|
31
|
+
# This never works for validations.
|
32
|
+
Layout/AlignHash:
|
33
|
+
EnforcedLastArgumentHashStyle: ignore_implicit
|
34
|
+
|
35
|
+
# Align multi-line params with previous line.
|
36
|
+
Layout/AlignParameters:
|
37
|
+
EnforcedStyle: with_fixed_indentation
|
38
|
+
|
39
|
+
# Indent `when` clause one step from `case`.
|
40
|
+
Layout/CaseIndentation:
|
41
|
+
IndentOneStep: true
|
42
|
+
|
43
|
+
# Don't force bad var names for reduce/inject loops.
|
44
|
+
Style/SingleLineBlockParams:
|
45
|
+
Enabled: false
|
46
|
+
|
47
|
+
# For method chains, keep the dot with the method name.
|
48
|
+
Layout/DotPosition:
|
49
|
+
EnforcedStyle: leading
|
50
|
+
|
51
|
+
# Stop nesting so hard.
|
52
|
+
Metrics/BlockNesting:
|
53
|
+
Max: 2
|
54
|
+
|
55
|
+
# Encourage short methods.
|
56
|
+
Metrics/MethodLength:
|
57
|
+
Max: 15
|
58
|
+
|
59
|
+
# Encourage short (as possible) modules.
|
60
|
+
Metrics/ModuleLength:
|
61
|
+
Max: 100
|
62
|
+
|
63
|
+
# Encourage fewer parameters.
|
64
|
+
Metrics/ParameterLists:
|
65
|
+
Max: 4
|
66
|
+
|
67
|
+
# Remove execute permissions check.
|
68
|
+
Lint/ScriptPermission:
|
69
|
+
Enabled: false
|
70
|
+
|
71
|
+
# Specify HTML Reporter Additions
|
72
|
+
Metrics/AbcSize:
|
73
|
+
Max: 18
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
data/.travis.yml
ADDED
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
2
|
+
|
3
|
+
## Our Pledge
|
4
|
+
|
5
|
+
In the interest of fostering an open and welcoming environment, we as
|
6
|
+
contributors and maintainers pledge to making participation in our project and
|
7
|
+
our community a harassment-free experience for everyone, regardless of age, body
|
8
|
+
size, disability, ethnicity, gender identity and expression, level of experience,
|
9
|
+
nationality, personal appearance, race, religion, or sexual identity and
|
10
|
+
orientation.
|
11
|
+
|
12
|
+
## Our Standards
|
13
|
+
|
14
|
+
Examples of behavior that contributes to creating a positive environment
|
15
|
+
include:
|
16
|
+
|
17
|
+
* Using welcoming and inclusive language
|
18
|
+
* Being respectful of differing viewpoints and experiences
|
19
|
+
* Gracefully accepting constructive criticism
|
20
|
+
* Focusing on what is best for the community
|
21
|
+
* Showing empathy towards other community members
|
22
|
+
|
23
|
+
Examples of unacceptable behavior by participants include:
|
24
|
+
|
25
|
+
* The use of sexualized language or imagery and unwelcome sexual attention or
|
26
|
+
advances
|
27
|
+
* Trolling, insulting/derogatory comments, and personal or political attacks
|
28
|
+
* Public or private harassment
|
29
|
+
* Publishing others' private information, such as a physical or electronic
|
30
|
+
address, without explicit permission
|
31
|
+
* Other conduct which could reasonably be considered inappropriate in a
|
32
|
+
professional setting
|
33
|
+
|
34
|
+
## Our Responsibilities
|
35
|
+
|
36
|
+
Project maintainers are responsible for clarifying the standards of acceptable
|
37
|
+
behavior and are expected to take appropriate and fair corrective action in
|
38
|
+
response to any instances of unacceptable behavior.
|
39
|
+
|
40
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
41
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
42
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
43
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
44
|
+
threatening, offensive, or harmful.
|
45
|
+
|
46
|
+
## Scope
|
47
|
+
|
48
|
+
This Code of Conduct applies both within project spaces and in public spaces
|
49
|
+
when an individual is representing the project or its community. Examples of
|
50
|
+
representing a project or community include using an official project e-mail
|
51
|
+
address, posting via an official social media account, or acting as an appointed
|
52
|
+
representative at an online or offline event. Representation of a project may be
|
53
|
+
further defined and clarified by project maintainers.
|
54
|
+
|
55
|
+
## Enforcement
|
56
|
+
|
57
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
58
|
+
reported by contacting the project team at jeff.nyman@yello.co. All
|
59
|
+
complaints will be reviewed and investigated and will result in a response that
|
60
|
+
is deemed necessary and appropriate to the circumstances. The project team is
|
61
|
+
obligated to maintain confidentiality with regard to the reporter of an incident.
|
62
|
+
Further details of specific enforcement policies may be posted separately.
|
63
|
+
|
64
|
+
Project maintainers who do not follow or enforce the Code of Conduct in good
|
65
|
+
faith may face temporary or permanent repercussions as determined by other
|
66
|
+
members of the project's leadership.
|
67
|
+
|
68
|
+
## Attribution
|
69
|
+
|
70
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
71
|
+
available at [http://contributor-covenant.org/version/1/4][version]
|
72
|
+
|
73
|
+
[homepage]: http://contributor-covenant.org
|
74
|
+
[version]: http://contributor-covenant.org/version/1/4/
|
data/Gemfile
ADDED
data/LICENSE.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2018 Jeff Nyman
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
# Specify HTML Reporter
|
2
|
+
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/specify_html_reporter.svg)](http://badge.fury.io/rb/specify_html_reporter)
|
4
|
+
[![Build Status](https://travis-ci.org/jeffnyman/specify_html_reporter.svg)](https://travis-ci.org/jeffnyman/specify_html_reporter)
|
5
|
+
[![License](http://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/jeffnyman/specify_html_reporter/blob/master/LICENSE.md)
|
6
|
+
[![Maintainability](https://api.codeclimate.com/v1/badges/3a112fb395c56c961d87/maintainability)](https://codeclimate.com/github/jeffnyman/specify_html_reporter/maintainability)
|
7
|
+
|
8
|
+
This gem provides a custom formatter for RSpec execution that generates an HTML-based repository of results files.
|
9
|
+
|
10
|
+
While this projet was designed to augment my [Specify](https://github.com/jeffnyman/specify) tool, it will generate reports for any RSpec execution.
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
Add this line to your application's Gemfile:
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
gem 'specify_html_reporter'
|
18
|
+
```
|
19
|
+
|
20
|
+
To get the latest code:
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
gem 'specify_html_reporter', git: 'https://github.com/jeffnyman/specify_html_reporter'
|
24
|
+
```
|
25
|
+
|
26
|
+
After doing one of the above, execute the following command:
|
27
|
+
|
28
|
+
```
|
29
|
+
$ bundle
|
30
|
+
```
|
31
|
+
|
32
|
+
You can also install Specify HTML Reporter just as you would any other gem:
|
33
|
+
|
34
|
+
```
|
35
|
+
$ gem install specify_html_reporter
|
36
|
+
```
|
37
|
+
|
38
|
+
## Usage
|
39
|
+
|
40
|
+
The usage is fairly simple and follows the standard pattern you would use for any RSpec formatter. Make sure to require the gem in your `spec_helper.rb` file:
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
require "specify_html_reporter"
|
44
|
+
```
|
45
|
+
|
46
|
+
Then, in your `.rspec` file, make sure the following line is in place:
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
--format SpecifyHtmlReport
|
50
|
+
```
|
51
|
+
|
52
|
+
If you aren't using an `.rspec` file, just provide `--format SpecifyHtmlReport` as part of your `rspec` execution command.
|
53
|
+
|
54
|
+
With the above being done, upon execution of your RSpec suite, you should get a directory called `reports` and within that you'll find an `overview.html` file that serves as the entry point for all reporting. Each spec file is given its own report format and is linked to from the overview file.
|
55
|
+
|
56
|
+
## Development
|
57
|
+
|
58
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rake spec:all` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
59
|
+
|
60
|
+
To experiment with the code, run `bin/console` for an interactive prompt. If you want to make changes and see how they work as a gem installed on your local machine, run `bundle exec rake install`.
|
61
|
+
|
62
|
+
The default `rake` command will run all tests as well as a Rubocop analysis.
|
63
|
+
|
64
|
+
If you have rights to deploy a new version, make sure to update the version number in `version.rb`, and then run `bundle exec rake release`. This will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
65
|
+
|
66
|
+
## Contributing
|
67
|
+
|
68
|
+
Bug reports and pull requests are welcome on GitHub at [https://github.com/jeffnyman/specify_html_reporter](https://github.com/jeffnyman/specify_html_reporter). The testing ecosystem of Ruby is very large and this project is intended to be a welcoming arena for collaboration on yet another test-supporting tool. As such, contributors are very much welcome but are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) which is provided as a [code of conduct](https://github.com/jeffnyman/specify_html_reporter/blob/master/CODE_OF_CONDUCT.md).
|
69
|
+
|
70
|
+
The Specify HTML Reporter gem follows [semantic versioning](http://semver.org).
|
71
|
+
|
72
|
+
To contribute to Specify HTML Reporter:
|
73
|
+
|
74
|
+
1. [Fork the project](http://gun.io/blog/how-to-github-fork-branch-and-pull-request/).
|
75
|
+
2. Create your feature branch. (`git checkout -b my-new-feature`)
|
76
|
+
3. Commit your changes. (`git commit -am 'new feature'`)
|
77
|
+
4. Push the branch. (`git push origin my-new-feature`)
|
78
|
+
5. Create a new [pull request](https://help.github.com/articles/using-pull-requests).
|
79
|
+
|
80
|
+
## Author
|
81
|
+
|
82
|
+
* [Jeff Nyman](http://testerstories.com)
|
83
|
+
|
84
|
+
## License
|
85
|
+
|
86
|
+
Specify HTML Reporter is distributed under the [MIT](http://www.opensource.org/licenses/MIT) license.
|
87
|
+
See the [LICENSE](https://github.com/jeffnyman/specify_html_reporter/blob/master/LICENSE.md) file for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
require "bundler/gem_tasks"
|
3
|
+
|
4
|
+
require "rdoc/task"
|
5
|
+
require "rubocop/rake_task"
|
6
|
+
require "rspec/core/rake_task"
|
7
|
+
|
8
|
+
RuboCop::RakeTask.new
|
9
|
+
|
10
|
+
RSpec::Core::RakeTask.new(:spec)
|
11
|
+
|
12
|
+
namespace :spec do
|
13
|
+
desc 'Clean all generated reports'
|
14
|
+
task :clean do
|
15
|
+
system('rm -rf spec/reports')
|
16
|
+
system('rm -rf spec/coverage')
|
17
|
+
end
|
18
|
+
|
19
|
+
RSpec::Core::RakeTask.new(all: :clean) do |config|
|
20
|
+
options = %w[--color]
|
21
|
+
options += %w[--format documentation]
|
22
|
+
options += %w[--format SpecifyHtmlReport]
|
23
|
+
options += %w[--format html --out spec/reports/test-report.html]
|
24
|
+
|
25
|
+
config.rspec_opts = options
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
Rake::RDocTask.new do |rdoc|
|
30
|
+
rdoc.rdoc_dir = 'doc'
|
31
|
+
rdoc.main = 'README.md'
|
32
|
+
rdoc.title = "Specify HTML Reporter #{SpecifyHtmlReporter::VERSION}"
|
33
|
+
rdoc.rdoc_files.include('README*', 'lib/**/*.rb')
|
34
|
+
end
|
35
|
+
|
36
|
+
task default: ['spec:all', :rubocop]
|
data/bin/console
ADDED
data/bin/setup
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
require "rouge"
|
2
|
+
require "active_support"
|
3
|
+
require "active_support/core_ext/numeric"
|
4
|
+
|
5
|
+
require "specify_html_reporter/problem"
|
6
|
+
|
7
|
+
class Example
|
8
|
+
attr_reader :duration, :status, :run_time, :exception, :file_path,
|
9
|
+
:metadata, :spec, :screen_grab, :video_record
|
10
|
+
|
11
|
+
def initialize(example)
|
12
|
+
@spec = nil
|
13
|
+
@example = example
|
14
|
+
setup_execution_result
|
15
|
+
setup_example_data
|
16
|
+
setup_metadata
|
17
|
+
setup_exception
|
18
|
+
end
|
19
|
+
|
20
|
+
def result_type(prefix = 'label-')
|
21
|
+
class_map = {
|
22
|
+
passed: "#{prefix}success",
|
23
|
+
failed: "#{prefix}danger",
|
24
|
+
pending: "#{prefix}warning"
|
25
|
+
}
|
26
|
+
|
27
|
+
class_map[@status.to_sym]
|
28
|
+
end
|
29
|
+
|
30
|
+
def example_title
|
31
|
+
full_title = @example_group.to_s.split('::') - %w[RSpec ExampleGroups]
|
32
|
+
full_title.push @description
|
33
|
+
full_title.join(' → ')
|
34
|
+
end
|
35
|
+
|
36
|
+
def exception?
|
37
|
+
!@exception.problem.nil?
|
38
|
+
end
|
39
|
+
|
40
|
+
def spec?
|
41
|
+
!@spec.nil?
|
42
|
+
end
|
43
|
+
|
44
|
+
def screen_grab?
|
45
|
+
!@screen_grab.nil? && !@screen_grab.empty?
|
46
|
+
end
|
47
|
+
|
48
|
+
def video_record?
|
49
|
+
!@video_record.nil?
|
50
|
+
end
|
51
|
+
|
52
|
+
def comment
|
53
|
+
ERB::Util.html_escape(@comment)
|
54
|
+
end
|
55
|
+
|
56
|
+
def comment?
|
57
|
+
!@comment.nil?
|
58
|
+
end
|
59
|
+
|
60
|
+
def create_spec_line(spec_text)
|
61
|
+
formatter = Rouge::Formatters::HTML.new(css_class: 'highlight')
|
62
|
+
lexer = Rouge::Lexers::Gherkin.new
|
63
|
+
@spec = formatter.format(lexer.lex(spec_text.gsub('#->', '')))
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.load_spec_comments!(examples)
|
67
|
+
examples.group_by(&:file_path).each do |file_path, file_examples|
|
68
|
+
lines = File.readlines(file_path)
|
69
|
+
|
70
|
+
file_examples.zip(file_examples.rotate).each do |example, next_ex|
|
71
|
+
determine_lexical_next(example, next_ex)
|
72
|
+
process_spec_lines(example, next_ex, lines)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
class << self
|
80
|
+
private
|
81
|
+
|
82
|
+
def determine_lexical_next(example, next_ex)
|
83
|
+
@lexical = next_ex &&
|
84
|
+
next_ex.file_path == example.file_path &&
|
85
|
+
next_ex.metadata[:line_number] > example.metadata[:line_number]
|
86
|
+
end
|
87
|
+
|
88
|
+
def process_spec_lines(example, next_ex, lines)
|
89
|
+
start_line = example.metadata[:line_number] - 1
|
90
|
+
next_start = (@lexical ? next_ex.metadata[:line_number] : lines.size) - 1
|
91
|
+
spec_lines = lines[start_line...next_start].select { |l| l.match(/#->/) }
|
92
|
+
example.create_spec_line(spec_lines.join) unless spec_lines.empty?
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def setup_execution_result
|
97
|
+
@execution_result = @example.execution_result
|
98
|
+
@run_time = @execution_result.run_time.round(5)
|
99
|
+
@status = @execution_result.status.to_s
|
100
|
+
@duration = @execution_result.run_time.to_s(:rounded, precision: 5)
|
101
|
+
end
|
102
|
+
|
103
|
+
def setup_example_data
|
104
|
+
@example_group = @example.example_group.to_s
|
105
|
+
@description = @example.description
|
106
|
+
@full_description = @example.full_description
|
107
|
+
@metadata = @example.metadata
|
108
|
+
end
|
109
|
+
|
110
|
+
def setup_metadata
|
111
|
+
@file_path = @metadata[:file_path]
|
112
|
+
@comment = @metadata[:comment]
|
113
|
+
@screen_grab = @metadata[:screen_grab]
|
114
|
+
@video_record = @metadata[:video_record]
|
115
|
+
end
|
116
|
+
|
117
|
+
def setup_exception
|
118
|
+
@exception = Problem.new(@example, @file_path)
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require "rouge"
|
2
|
+
require "rbconfig"
|
3
|
+
|
4
|
+
class Problem
|
5
|
+
attr_reader :problem, :explanation, :backtrace_message, :highlighted_source
|
6
|
+
|
7
|
+
def initialize(example, file_path)
|
8
|
+
@example = example
|
9
|
+
@file_path = file_path
|
10
|
+
@exception = @example.exception
|
11
|
+
|
12
|
+
return if @exception.nil?
|
13
|
+
|
14
|
+
@problem = @exception.class
|
15
|
+
@message = @exception.message.encode("utf-8")
|
16
|
+
@backtrace_message = format_backtrace
|
17
|
+
@highlighted_source = format_source
|
18
|
+
@explanation = format_message
|
19
|
+
end
|
20
|
+
|
21
|
+
def format_message
|
22
|
+
formatter = Rouge::Formatters::HTML.new(css_class: 'highlight')
|
23
|
+
lexer = Rouge::Lexers::Ruby.new
|
24
|
+
formatter.format(lexer.lex(@message))
|
25
|
+
end
|
26
|
+
|
27
|
+
def format_backtrace
|
28
|
+
formatted_backtrace(@example, @exception).map do |entry|
|
29
|
+
ERB::Util.html_escape(entry)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def formatted_backtrace(example, exception)
|
34
|
+
# This logic is in place to avoid an error in the format_backtrace method
|
35
|
+
# for the RSpec formatter. RSpec versions below 3.5 will throw an exception.
|
36
|
+
return [] unless example
|
37
|
+
|
38
|
+
formatter = RSpec.configuration.backtrace_formatter
|
39
|
+
formatter.format_backtrace(exception.backtrace, example.metadata)
|
40
|
+
end
|
41
|
+
|
42
|
+
def format_source
|
43
|
+
return '' if @backtrace_message.empty?
|
44
|
+
|
45
|
+
data = @backtrace_message.first.split(':')
|
46
|
+
|
47
|
+
return if data.empty?
|
48
|
+
|
49
|
+
if os == :windows
|
50
|
+
file_path = data[0] + ':' + data[1]
|
51
|
+
line_number = data[2].to_i
|
52
|
+
else
|
53
|
+
file_path = data.first
|
54
|
+
line_number = data[1].to_i
|
55
|
+
end
|
56
|
+
|
57
|
+
format_source_context(file_path, line_number)
|
58
|
+
end
|
59
|
+
|
60
|
+
def format_source_context(file_path, line_number)
|
61
|
+
lines = File.readlines(file_path)
|
62
|
+
start_line = line_number - 2
|
63
|
+
end_line = line_number + 3
|
64
|
+
|
65
|
+
source = lines[start_line..end_line].join("")
|
66
|
+
|
67
|
+
formatter = Rouge::Formatters::HTML.new(
|
68
|
+
css_class: 'highlight', line_numbers: true, start_line: start_line + 1
|
69
|
+
)
|
70
|
+
|
71
|
+
lexer = Rouge::Lexers::Ruby.new
|
72
|
+
formatter.format(lexer.lex(source.encode('utf-8')))
|
73
|
+
end
|
74
|
+
|
75
|
+
def os
|
76
|
+
@os ||= begin
|
77
|
+
host_os = RbConfig::CONFIG['host_os']
|
78
|
+
|
79
|
+
case host_os
|
80
|
+
when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
|
81
|
+
:windows
|
82
|
+
when /darwin|mac os/
|
83
|
+
:macosx
|
84
|
+
when /linux/
|
85
|
+
:linux
|
86
|
+
when /solaris|bsd/
|
87
|
+
:unix
|
88
|
+
else
|
89
|
+
raise Exception, "Unknown operating system: #{host_os.inspect}"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|