rspec-tap-formatters 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/.document +5 -0
- data/.yardopts +6 -0
- data/CHANGELOG.md +7 -0
- data/LICENSE.md +23 -0
- data/README.md +127 -0
- data/lib/rspec/tap/formatters.rb +14 -0
- data/lib/rspec/tap/formatters/compact.rb +168 -0
- data/lib/rspec/tap/formatters/core_ext/hash.rb +52 -0
- data/lib/rspec/tap/formatters/core_ext/string.rb +48 -0
- data/lib/rspec/tap/formatters/default.rb +169 -0
- data/lib/rspec/tap/formatters/flat.rb +139 -0
- data/lib/rspec/tap/formatters/flat_compact.rb +138 -0
- data/lib/rspec/tap/formatters/printer.rb +445 -0
- data/lib/rspec/tap/formatters/test_stats.rb +50 -0
- data/lib/rspec/tap/formatters/version.rb +16 -0
- data/spec/rspec/tap/formatters/compact_spec.rb +399 -0
- data/spec/rspec/tap/formatters/default_spec.rb +407 -0
- data/spec/rspec/tap/formatters/flat_compact_spec.rb +257 -0
- data/spec/rspec/tap/formatters/flat_spec.rb +266 -0
- data/spec/rspec/tap/formatters/printer_spec.rb +1075 -0
- data/spec/rspec/tap/formatters/test_stats_spec.rb +92 -0
- metadata +138 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: fd8a0abda3b907ea87d405f47d2fffe1cb223780512851ac382728f3eac84397
|
4
|
+
data.tar.gz: dd32b01b12fd9856218e4048cdaca91363ff9660542bbf4f82322982bd748707
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6129728991705d169d3b348f37b63a2d85c86f8855e38bd6bcddacfa3c38e6ea70ddc41dfc0a13f9febe465a4cf8b9c907fa346028bd39a729ef4a30849c8461
|
7
|
+
data.tar.gz: fbc6a0360a91354968a6fd1b768e2bad394e0a8d31e945212227be060f1b31c9608aa49bcd6674f2825ae1232a187931ff48814aaf2309a03efa81f5e8550a21
|
data/.document
ADDED
data/.yardopts
ADDED
data/CHANGELOG.md
ADDED
data/LICENSE.md
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
=====================
|
3
|
+
|
4
|
+
- **Copyright © 2019 Abhimanyu Singh**
|
5
|
+
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
7
|
+
a copy of this software and associated documentation files (the
|
8
|
+
"Software"), to deal in the Software without restriction, including
|
9
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
10
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
11
|
+
permit persons to whom the Software is furnished to do so, subject to
|
12
|
+
the following conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be
|
15
|
+
included in all copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
18
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
19
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
20
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
21
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
22
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
23
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
[![Build Status](https://travis-ci.com/avmnu-sng/rspec-tap-formatters.svg?branch=master)](https://travis-ci.com/avmnu-sng/rspec-tap-formatters)
|
2
|
+
[![Documentation Status](https://readthedocs.org/projects/rspec-tap-formatters/badge/?version=latest)](https://rspec-tap-formatters.readthedocs.io/en/latest/?badge=latest)
|
3
|
+
[![Inline docs](http://inch-ci.org/github/avmnu-sng/rspec-tap-formatters.svg?branch=master)](http://inch-ci.org/github/avmnu-sng/rspec-tap-formatters)
|
4
|
+
[![Maintainability](https://api.codeclimate.com/v1/badges/7dd41099b7e8569fc7ec/maintainability)](https://codeclimate.com/github/avmnu-sng/rspec-tap-formatters/maintainability)
|
5
|
+
[![Test Coverage](https://api.codeclimate.com/v1/badges/7dd41099b7e8569fc7ec/test_coverage)](https://codeclimate.com/github/avmnu-sng/rspec-tap-formatters/test_coverage)
|
6
|
+
|
7
|
+
**RSpec TAP Formatters** provides four different [TAP 13](https://testanything.org/tap-version-13-specification.html) format style with
|
8
|
+
a proper nested display of example groups and includes stats for the total
|
9
|
+
number of passed, failed, and pending tests per example group. The supported
|
10
|
+
formats are:
|
11
|
+
|
12
|
+
1. `RSpec::TAP::Formatters::Default`
|
13
|
+
2. `RSpec::TAP::Formatters::Compact`
|
14
|
+
3. `RSpec::TAP::Formatters::Flat`
|
15
|
+
4. `RSpec::TAP::Formatters::FlatCompact`
|
16
|
+
|
17
|
+
Each formatter respects the color configuration for the execution and only
|
18
|
+
prints colored output when enabled. However, writing to a file will never use
|
19
|
+
colors.
|
20
|
+
|
21
|
+
When writing the report to a file, each formatter will print progress status
|
22
|
+
on the standard output:
|
23
|
+
- `.` denotes a passing example.
|
24
|
+
- `F` denotes a failing example.
|
25
|
+
- `*` denotes a pending example.
|
26
|
+
|
27
|
+
Sample report for [string_spec.rb](resources/string_spec.rb) using
|
28
|
+
`RSpec::TAP::Formatters::Default` format:
|
29
|
+
```text
|
30
|
+
TAP version 13
|
31
|
+
# test: String {
|
32
|
+
# group: #present? {
|
33
|
+
# group: when whitespaces and other characters {
|
34
|
+
ok 1 - returns true
|
35
|
+
1..1
|
36
|
+
# tests: 1, passed: 1
|
37
|
+
}
|
38
|
+
# group: when nil {
|
39
|
+
not ok 1 - returns false
|
40
|
+
---
|
41
|
+
location: "./resources/string_spec.rb:8"
|
42
|
+
error: |-
|
43
|
+
Failure/Error: expect(string.present?).to eq(false)
|
44
|
+
NoMethodError:
|
45
|
+
undefined method `present?' for nil:NilClass
|
46
|
+
backtrace: "./resources/string_spec.rb:9:in `block (4 levels) in <top (required)>'"
|
47
|
+
...
|
48
|
+
1..1
|
49
|
+
# tests: 1, failed: 1
|
50
|
+
}
|
51
|
+
# group: when whitespaces only {
|
52
|
+
ok 1 - returns false
|
53
|
+
1..1
|
54
|
+
# tests: 1, passed: 1
|
55
|
+
}
|
56
|
+
1..3
|
57
|
+
# tests: 3, passed: 2, failed: 1
|
58
|
+
}
|
59
|
+
1..3
|
60
|
+
# tests: 3, passed: 2, failed: 1
|
61
|
+
}
|
62
|
+
1..3
|
63
|
+
# tests: 3, passed: 2, failed: 1
|
64
|
+
# duration: 0.026471 seconds
|
65
|
+
# seed: 27428
|
66
|
+
```
|
67
|
+
|
68
|
+
You can check the reports for other formats [here](resources/reports).
|
69
|
+
|
70
|
+
## Installation
|
71
|
+
|
72
|
+
Installation is pretty standard:
|
73
|
+
```sh
|
74
|
+
gem install rspec-tap-formatters
|
75
|
+
```
|
76
|
+
|
77
|
+
You can install using `bundler` also but do not require it in `Gemfile`.
|
78
|
+
Make sure to use it as a test dependency:
|
79
|
+
```ruby
|
80
|
+
group :test do
|
81
|
+
# other gems
|
82
|
+
gem 'rspec-tap-formatter', '~> 0.1.0', require: false
|
83
|
+
end
|
84
|
+
```
|
85
|
+
|
86
|
+
You can also install using the GitHub package registry:
|
87
|
+
```ruby
|
88
|
+
source 'https://rubygems.pkg.github.com/avmnu-sng' do
|
89
|
+
gem 'rspec-tap-formatter', '~> 0.1.0', require: false
|
90
|
+
end
|
91
|
+
```
|
92
|
+
|
93
|
+
## Usage
|
94
|
+
|
95
|
+
You can specify the format as the command argument:
|
96
|
+
```sh
|
97
|
+
rspec --format RSpec::TAP::Formatters::Default
|
98
|
+
```
|
99
|
+
|
100
|
+
To write to file, provide the `--out` argument:
|
101
|
+
```sh
|
102
|
+
rspec --format RSpec::TAP::Formatters::Default --out report.tap
|
103
|
+
```
|
104
|
+
|
105
|
+
You can also configure the `.rspec` file:
|
106
|
+
```sh
|
107
|
+
# other configurations
|
108
|
+
--format RSpec::TAP::Formatters::Default
|
109
|
+
--out report.tap
|
110
|
+
```
|
111
|
+
|
112
|
+
## Documentation
|
113
|
+
Read more about TAP specifications and supported formats in the [official docs](https://rspec-tap-formatters.readthedocs.io/en/latest/).
|
114
|
+
|
115
|
+
## Source Code Documentation
|
116
|
+
Read the source code documentation [here](https://rubydoc.info/github/avmnu-sng/rspec-tap-formatters/master).
|
117
|
+
|
118
|
+
## Compatibility
|
119
|
+
RSpec TAP Formatters supports `MRI 2.3+` and `RSpec 3`.
|
120
|
+
|
121
|
+
## Changelog
|
122
|
+
|
123
|
+
The changelog is available [here](CHANGELOG.md).
|
124
|
+
|
125
|
+
## Copyright
|
126
|
+
Copyright (c) 2019 Abhimanyu Singh. See [LICENSE.md](LICENSE.md) for
|
127
|
+
further details.
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'English'
|
4
|
+
require 'psych'
|
5
|
+
|
6
|
+
require_relative 'formatters/core_ext/hash'
|
7
|
+
require_relative 'formatters/core_ext/string'
|
8
|
+
require_relative 'formatters/version'
|
9
|
+
require_relative 'formatters/compact'
|
10
|
+
require_relative 'formatters/default'
|
11
|
+
require_relative 'formatters/flat'
|
12
|
+
require_relative 'formatters/flat_compact'
|
13
|
+
require_relative 'formatters/printer'
|
14
|
+
require_relative 'formatters/test_stats'
|
@@ -0,0 +1,168 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rspec/core/formatters/base_formatter'
|
4
|
+
require_relative 'printer'
|
5
|
+
require_relative 'test_stats'
|
6
|
+
|
7
|
+
module RSpec
|
8
|
+
module TAP
|
9
|
+
module Formatters
|
10
|
+
# Compact TAP formatter
|
11
|
+
class Compact < RSpec::Core::Formatters::BaseFormatter
|
12
|
+
# List of subscribed notifications
|
13
|
+
NOTIFICATIONS = %i[
|
14
|
+
seed
|
15
|
+
start
|
16
|
+
start_dump
|
17
|
+
example_group_started
|
18
|
+
example_group_finished
|
19
|
+
example_started
|
20
|
+
example_passed
|
21
|
+
example_failed
|
22
|
+
example_pending
|
23
|
+
message
|
24
|
+
dump_failures
|
25
|
+
dump_pending
|
26
|
+
dump_summary
|
27
|
+
].freeze
|
28
|
+
|
29
|
+
RSpec::Core::Formatters.register(self, *NOTIFICATIONS)
|
30
|
+
|
31
|
+
# Constructor
|
32
|
+
#
|
33
|
+
# @param output [StringIO, File] output stream
|
34
|
+
def initialize(output)
|
35
|
+
super
|
36
|
+
|
37
|
+
@printer = Printer.new(output)
|
38
|
+
@test_stats = TestStats.new
|
39
|
+
@seed = nil
|
40
|
+
@level = 0
|
41
|
+
@example_number = 0
|
42
|
+
end
|
43
|
+
|
44
|
+
# Seed notification
|
45
|
+
#
|
46
|
+
# @param notification [SeedNotification]
|
47
|
+
def seed(notification)
|
48
|
+
@seed = notification.seed if notification.seed_used?
|
49
|
+
end
|
50
|
+
|
51
|
+
# Start notification
|
52
|
+
#
|
53
|
+
# @param notification [StartNotification]
|
54
|
+
def start(notification)
|
55
|
+
super
|
56
|
+
|
57
|
+
@printer.start_output
|
58
|
+
end
|
59
|
+
|
60
|
+
# Execution finished notification
|
61
|
+
#
|
62
|
+
# @param _notification [NullNotification]
|
63
|
+
def start_dump(_notification)
|
64
|
+
@printer.example_progress_dump
|
65
|
+
end
|
66
|
+
|
67
|
+
# Example group start notification
|
68
|
+
#
|
69
|
+
# @param notification [GroupNotification]
|
70
|
+
def example_group_started(notification)
|
71
|
+
@printer.group_start_output(notification, @level)
|
72
|
+
|
73
|
+
@level += 1
|
74
|
+
@example_number = 0
|
75
|
+
end
|
76
|
+
|
77
|
+
# Example group finish notification
|
78
|
+
#
|
79
|
+
# @param notification [GroupNotification]
|
80
|
+
def example_group_finished(notification)
|
81
|
+
@printer.group_finished_output(
|
82
|
+
@test_stats.data[notification.group.metadata[:line_number]],
|
83
|
+
@level
|
84
|
+
)
|
85
|
+
|
86
|
+
@level -= 1 if @level.positive?
|
87
|
+
@test_stats = TestStats.new if @level.zero?
|
88
|
+
end
|
89
|
+
|
90
|
+
# Example start notification
|
91
|
+
#
|
92
|
+
# @param _notification [ExampleNotification]
|
93
|
+
def example_started(_notification)
|
94
|
+
@example_number += 1
|
95
|
+
end
|
96
|
+
|
97
|
+
# Passing example notification
|
98
|
+
#
|
99
|
+
# @param notification [ExampleNotification]
|
100
|
+
def example_passed(notification)
|
101
|
+
@test_stats.populate(notification, 1)
|
102
|
+
@printer.example_progress_output(:success)
|
103
|
+
@printer.success_output(
|
104
|
+
notification.example.description.strip,
|
105
|
+
@example_number,
|
106
|
+
@level
|
107
|
+
)
|
108
|
+
end
|
109
|
+
|
110
|
+
# Failing example notification
|
111
|
+
#
|
112
|
+
# @param notification [FailedExampleNotification]
|
113
|
+
def example_failed(notification)
|
114
|
+
@test_stats.populate(notification, 2)
|
115
|
+
@printer.example_progress_output(:failure)
|
116
|
+
@printer.failure_output(
|
117
|
+
notification.example.description.strip,
|
118
|
+
@example_number,
|
119
|
+
@level
|
120
|
+
)
|
121
|
+
end
|
122
|
+
|
123
|
+
# Pending example notification
|
124
|
+
#
|
125
|
+
# @param notification [PendingExampleFailedAsExpectedNotification
|
126
|
+
# , SkippedExampleException]
|
127
|
+
def example_pending(notification)
|
128
|
+
@test_stats.populate(notification, 3)
|
129
|
+
@printer.example_progress_output(:pending)
|
130
|
+
@printer.pending_output(
|
131
|
+
notification,
|
132
|
+
notification.example.description.strip,
|
133
|
+
@example_number,
|
134
|
+
@level
|
135
|
+
)
|
136
|
+
end
|
137
|
+
|
138
|
+
# Failure outside of example notification
|
139
|
+
#
|
140
|
+
# @param notification [MessageNotification]
|
141
|
+
def message(notification)
|
142
|
+
@printer.message_output(notification)
|
143
|
+
end
|
144
|
+
|
145
|
+
# Failure examples notification
|
146
|
+
#
|
147
|
+
# @param notification [ExamplesNotification]
|
148
|
+
def dump_failures(notification)
|
149
|
+
@printer.store_failed_examples_summary(notification)
|
150
|
+
end
|
151
|
+
|
152
|
+
# Pending examples notification
|
153
|
+
#
|
154
|
+
# @param notification [ExamplesNotification]
|
155
|
+
def dump_pending(notification)
|
156
|
+
@printer.store_pending_examples_summary(notification)
|
157
|
+
end
|
158
|
+
|
159
|
+
# Examples summary notification
|
160
|
+
#
|
161
|
+
# @param notification [SummaryNotification]
|
162
|
+
def dump_summary(notification)
|
163
|
+
@printer.summary_output(notification, @seed)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Extensions to the core String class
|
4
|
+
class Hash
|
5
|
+
unless method_defined?(:compact)
|
6
|
+
# Removes nil and blank values.
|
7
|
+
# The value is either +NilClass+ or +String+.
|
8
|
+
#
|
9
|
+
# @return [Hash] compact hash
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# { you: 0, me: nil, we: ' ' }.compact
|
13
|
+
# #=> { you: 0 }
|
14
|
+
def compact
|
15
|
+
reject { |_, value| value.nil? || value.blank? }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
unless method_defined?(:transform_keys)
|
20
|
+
# Transforms hash keys.
|
21
|
+
# The value is either +NilClass+ or +String+.
|
22
|
+
#
|
23
|
+
# @return [Hash] with transformed keys
|
24
|
+
#
|
25
|
+
# @example
|
26
|
+
# { you: 0, me: nil, we: ' '}.transform_keys(&:upcase)
|
27
|
+
# #=> { YOU: 0, ME: nil, WE: ' '}
|
28
|
+
def transform_keys
|
29
|
+
return enum_for(:transform_keys) { size } unless block_given?
|
30
|
+
|
31
|
+
new_hash = {}
|
32
|
+
|
33
|
+
each_key { |key| new_hash[yield(key)] = self[key] }
|
34
|
+
|
35
|
+
new_hash
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
unless method_defined?(:stringify_keys)
|
40
|
+
# Transforms hash keys by using +to_s+.
|
41
|
+
# The value is either +NilClass+ or +String+.
|
42
|
+
#
|
43
|
+
# @return [Hash] with transformed keys
|
44
|
+
#
|
45
|
+
# @example
|
46
|
+
# { you: 0, me: nil, we: ' '}.stringify_keys
|
47
|
+
# #=> { "you" => 0, "me" => nil, "we" => ' '}
|
48
|
+
def stringify_keys
|
49
|
+
transform_keys(&:to_s)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Extensions to the core String class
|
4
|
+
class String
|
5
|
+
unless method_defined?(:blank?)
|
6
|
+
# Checks whether a string is blank. A string is considered blank if it
|
7
|
+
# is either empty or contains only whitespaces.
|
8
|
+
#
|
9
|
+
# @return [Boolean] true is the string is blank, false otherwise
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# ''.blank?
|
13
|
+
# #=> true
|
14
|
+
#
|
15
|
+
# @example
|
16
|
+
# ' '.blank?
|
17
|
+
# #=> true
|
18
|
+
#
|
19
|
+
# @example
|
20
|
+
# ' abc '.blank?
|
21
|
+
# #=> false
|
22
|
+
def blank?
|
23
|
+
empty? || strip.empty?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
unless method_defined?(:present?)
|
28
|
+
# Checks whether a string is present. A string is considered present if it
|
29
|
+
# is not blank.
|
30
|
+
#
|
31
|
+
# @return [Boolean] true is the string is present, false otherwise
|
32
|
+
#
|
33
|
+
# @example
|
34
|
+
# ''.present?
|
35
|
+
# #=> false
|
36
|
+
#
|
37
|
+
# @example
|
38
|
+
# ' '.present?
|
39
|
+
# #=> false
|
40
|
+
#
|
41
|
+
# @example
|
42
|
+
# ' abc '.present?
|
43
|
+
# #=> true
|
44
|
+
def present?
|
45
|
+
!blank?
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|