rspec-tap-formatters 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.
@@ -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
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ -
3
+ README.md
4
+ LICENSE.md
5
+ CHANGELOG.md
@@ -0,0 +1,6 @@
1
+ --markup markdown
2
+ --default-return ''
3
+ --private
4
+ -
5
+ LICENSE.md
6
+ CHANGELOG.md
@@ -0,0 +1,7 @@
1
+ ## v0.1.0 (November 1, 2019)
2
+ **First Release**
3
+ - Added support for four TAP formats:
4
+ - RSpec::TAP::Formatters::Default
5
+ - RSpec::TAP::Formatters::Compact
6
+ - RSpec::TAP::Formatters::Flat
7
+ - RSpec::TAP::Formatters::FlatCompact
@@ -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.
@@ -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