rainbow_formatter 0.1.5
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.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/.rspec +2 -0
- data/.rubocop.yml +11 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +0 -0
- data/Gemfile +6 -0
- data/LICENSE.md +22 -0
- data/README.md +117 -0
- data/Rakefile +10 -0
- data/data/car.gif +0 -0
- data/data/dog.gif +0 -0
- data/data/monkey.gif +0 -0
- data/data/tina_bike.gif +0 -0
- data/data/tina_bike.mp3 +0 -0
- data/data/tina_dream.gif +0 -0
- data/data/tina_dream.mp3 +0 -0
- data/demo.rb +24 -0
- data/lib/formatter/common.rb +249 -0
- data/lib/formatter/configuration.rb +17 -0
- data/lib/formatter/custom/car.rb +18 -0
- data/lib/formatter/custom/dog.rb +20 -0
- data/lib/formatter/custom/monkey.rb +18 -0
- data/lib/formatter/custom/tina_bike.rb +18 -0
- data/lib/formatter/custom/tina_dream.rb +26 -0
- data/lib/formatter/insta_fail.rb +12 -0
- data/lib/formatter/music.rb +79 -0
- data/lib/formatter/verbose.rb +15 -0
- data/lib/formatter/version.rb +5 -0
- data/lib/rainbow_formatter.rb +88 -0
- data/lib/rainbow_insta_fail_formatter.rb +10 -0
- data/lib/rainbow_music_formatter.rb +10 -0
- data/lib/rainbow_verbose_formatter.rb +10 -0
- data/rainbow_formatter.gemspec +26 -0
- data/spec/rainbow_formatter_spec.rb +156 -0
- data/spec/rainbow_insta_fail_formatter_spec.rb +23 -0
- data/spec/rainbow_music_formatter_spec.rb +122 -0
- data/spec/rainbow_verbose_formatter_spec.rb +20 -0
- data/spec/spec_helper.rb +5 -0
- metadata +129 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 1f1db74fd8a49272248b3dd804d84e7a0ae70afc7ddf8c7853a5522c226d8a77
|
4
|
+
data.tar.gz: ee87a058bd4d4e1911152e688b9c1081789946d680c607a3121ab62e166494d0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d37022065d796e659ba7caa66fe932e607eef908acc31c9f53a4075a7802fef6133044bf97279c55bca151758d88b32e898115b3cdf62a6b832bfb7447cff42d
|
7
|
+
data.tar.gz: 7343072a5e504bc565e00ac00cf268e158492d9b48918a24291e1bab1f00013d959cbfffd7cb868eb95ba207ae4a81e0354298a2489736cffc006951ae11e2c2
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.4.5
|
data/CHANGELOG.md
ADDED
File without changes
|
data/Gemfile
ADDED
data/LICENSE.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2019 Farina Federico
|
4
|
+
Copyright (c) 2011 Matt Sears
|
5
|
+
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
8
|
+
in the Software without restriction, including without limitation the rights
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
11
|
+
furnished to do so, subject to the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be included in
|
14
|
+
all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
Fully customizable Rainbow trail RSpec formatter.
|
2
|
+

|
3
|
+

|
4
|
+

|
5
|
+
|
6
|
+
It simply creates a rainbow trail of test results. It also counts the number of examples as they execute and highlights failed and pending specs.
|
7
|
+
|
8
|
+
The rainbow changes colors as it runs!.
|
9
|
+
|
10
|
+
Works with RSpec 3.x
|
11
|
+
|
12
|
+
Based on [Matt Sears](https://github.com/mattsears/nyan-cat-formatter) Nyan Cat RSpec Formatter
|
13
|
+
|
14
|
+
Using Rainbow
|
15
|
+
---------------
|
16
|
+
|
17
|
+
You can either specify the formatting when using the `rspec` command:
|
18
|
+
|
19
|
+
rspec --format RainbowFormatter
|
20
|
+
|
21
|
+
Or add `--format RainbowFormatter` to a `.rspec` file placed in your project's root directory,
|
22
|
+
so that you won't have to specify the `--format` option everytime you run the command.
|
23
|
+
|
24
|
+
#### Only animation formatter .rspec file
|
25
|
+
```
|
26
|
+
--color
|
27
|
+
--format RainbowFormatter
|
28
|
+
```
|
29
|
+
|
30
|
+
#### Music formatter .rspec file
|
31
|
+
```
|
32
|
+
--color
|
33
|
+
--format RainbowMusicFormatter
|
34
|
+
```
|
35
|
+
|
36
|
+
Then run `rspec spec` and enjoy Rainbow formatted text output accompanied by Rainbow song by default!.
|
37
|
+
|
38
|
+
All music was composed by [Maria Delfina Ciarrochi](https://soundcloud.com/mariadelfinaciarrochi)
|
39
|
+
|
40
|
+
**This currently only works on Mac OS X or on Linux (if you have mpg321 or mpg123 installed).**
|
41
|
+
|
42
|
+
#### With running test output
|
43
|
+
```
|
44
|
+
--color
|
45
|
+
--format RainbowVerboseFormatter
|
46
|
+
```
|
47
|
+
|
48
|
+
Displays "running" line with name of test on the first line.
|
49
|
+
|
50
|
+
|
51
|
+
#### Display failed tests immediately
|
52
|
+
```
|
53
|
+
--color
|
54
|
+
--format RainbowInstaFailFormatter
|
55
|
+
```
|
56
|
+
|
57
|
+
Displays failed tests immediately!
|
58
|
+
|
59
|
+
|
60
|
+
### Using with Bundler
|
61
|
+
|
62
|
+
To use Rainbow formatter with a project that uses Bundler (Rails or Sinatra f.e.) you need to add Rainbow Cat dependecy to your Gemfile:
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
group :test do
|
66
|
+
gem "rainbow_formatter"
|
67
|
+
end
|
68
|
+
```
|
69
|
+
|
70
|
+
And then run `bundle install`.
|
71
|
+
|
72
|
+
Customizing Rainbow
|
73
|
+
---------------------------------
|
74
|
+
You can create your own version, with your own song and draw, this way:
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
module YourCustomMode
|
78
|
+
def ascii_array
|
79
|
+
'your_ascii_animation_array'
|
80
|
+
end
|
81
|
+
def rainbow_mp3
|
82
|
+
'your_song_path'
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
RainbowFormatter.configure do |config|
|
87
|
+
config.formatter = YourCustomMode
|
88
|
+
# OR config.formatter = :tina_dream OR onw of already bundle modes below
|
89
|
+
end
|
90
|
+
```
|
91
|
+
|
92
|
+
It's easy to build your array using a string [escape tool](https://www.freeformatter.com/java-dotnet-escape.html#ad-output). Each position of array should be an escaped version of chosen ascii and could be used one after the other as an animation. You can view some examples at /lib/formatter/custom folder. [This](https://www.asciiart.eu) is a good start point to choose some asciis.
|
93
|
+
|
94
|
+
#### Already bundled modes:
|
95
|
+
|
96
|
+
1. :car
|
97
|
+
2. :dog
|
98
|
+
3. :monkey
|
99
|
+
4. :tina_bike
|
100
|
+
5. :tina_dream
|
101
|
+
|
102
|
+
Contributing
|
103
|
+
----------
|
104
|
+
|
105
|
+
Once you've made your great commits:
|
106
|
+
|
107
|
+
1. Fork Rainbow
|
108
|
+
2. Create a topic branch - git checkout -b my_branch
|
109
|
+
3. Push to your branch - git push origin my_branch
|
110
|
+
4. Create a Pull Request from your branch
|
111
|
+
5. That's it!
|
112
|
+
|
113
|
+
Author
|
114
|
+
----------
|
115
|
+
[Federico Farina](https://github.com/fedefa)
|
116
|
+
|
117
|
+
[Maria Delfina Ciarrochi](https://soundcloud.com/mariadelfinaciarrochi)
|
data/Rakefile
ADDED
data/data/car.gif
ADDED
Binary file
|
data/data/dog.gif
ADDED
Binary file
|
data/data/monkey.gif
ADDED
Binary file
|
data/data/tina_bike.gif
ADDED
Binary file
|
data/data/tina_bike.mp3
ADDED
Binary file
|
data/data/tina_dream.gif
ADDED
Binary file
|
data/data/tina_dream.mp3
ADDED
Binary file
|
data/demo.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'spec/spec_helper'
|
4
|
+
|
5
|
+
describe RainbowFormatter do
|
6
|
+
before do
|
7
|
+
sleep(0.5) # Just to slow it down a little :-)
|
8
|
+
end
|
9
|
+
|
10
|
+
15.times do
|
11
|
+
it 'Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit..' do
|
12
|
+
expect(0).to eql(0)
|
13
|
+
end
|
14
|
+
it 'Another passed' do
|
15
|
+
expect(0).to eql(0)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'One failed' do
|
19
|
+
expect(0).to eql(1)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'pending specs' if [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1].sample == 1
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,249 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Formatter
|
4
|
+
module Common
|
5
|
+
ESC = "\e["
|
6
|
+
NND = "#{ESC}0m"
|
7
|
+
PASS = '='
|
8
|
+
PASS_ARY = ['-', '_'].freeze
|
9
|
+
FAIL = '*'
|
10
|
+
ERROR = '!'
|
11
|
+
PENDING = '+'
|
12
|
+
|
13
|
+
VT100_CODES =
|
14
|
+
{
|
15
|
+
black: 30,
|
16
|
+
red: 31,
|
17
|
+
green: 32,
|
18
|
+
yellow: 33,
|
19
|
+
blue: 34,
|
20
|
+
magenta: 35,
|
21
|
+
cyan: 36,
|
22
|
+
white: 37,
|
23
|
+
bold: 1
|
24
|
+
}.freeze
|
25
|
+
|
26
|
+
VT100_CODE_VALUES = VT100_CODES.invert
|
27
|
+
|
28
|
+
def self.included(base)
|
29
|
+
base.class_eval do
|
30
|
+
attr_reader :current, :example_results, :color_index, :pending_count, :failure_count, :example_count
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Increments the example count and displays the current progress
|
35
|
+
#
|
36
|
+
# @returns nothing
|
37
|
+
def tick(mark: PASS)
|
38
|
+
@example_results << mark
|
39
|
+
@current = @current > @example_count ? @example_count : @current + 1
|
40
|
+
@animation_index = (@animation_index + 1) % ascii_array.size
|
41
|
+
dump_progress
|
42
|
+
end
|
43
|
+
|
44
|
+
# Determine which Ascii to format(display.
|
45
|
+
#
|
46
|
+
# @return [String] Ascii to display
|
47
|
+
def ascii_to_display
|
48
|
+
ascii_array[@animation_index % ascii_array.size]
|
49
|
+
end
|
50
|
+
|
51
|
+
# Displays the current progress in all Rainbow glory
|
52
|
+
#
|
53
|
+
# @return nothing
|
54
|
+
def dump_progress
|
55
|
+
output.print(progress_lines.join("\n") + eol)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Determines line by line tail plus score output
|
59
|
+
#
|
60
|
+
# @return [Array]
|
61
|
+
def progress_lines
|
62
|
+
rainbow_trails = rainbow_trail.split("\n")
|
63
|
+
[
|
64
|
+
rainbow_trails.each_with_index.inject([]) do |result, (trail, index)|
|
65
|
+
value = trail_progress_line_score(index)
|
66
|
+
result << "#{value} #{trail}"
|
67
|
+
end
|
68
|
+
].flatten
|
69
|
+
end
|
70
|
+
|
71
|
+
def trail_progress_line_score(trail_index)
|
72
|
+
if scoreboard[trail_index]
|
73
|
+
"#{scoreboard[trail_index]}/#{@example_count}:"
|
74
|
+
else
|
75
|
+
' ' * "#{scoreboard[0]}/#{@example_count}:".size
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# Determines how we end the trail line. If complete, return a newline etc.
|
80
|
+
#
|
81
|
+
# @return [String]
|
82
|
+
def eol
|
83
|
+
return "\n" if @current == @example_count
|
84
|
+
|
85
|
+
length = progress_lines.length - 1
|
86
|
+
length.positive? ? format("\e[1A" * length + "\r") : "\r"
|
87
|
+
end
|
88
|
+
|
89
|
+
# Calculates the current flight length
|
90
|
+
#
|
91
|
+
# @return [Fixnum]
|
92
|
+
def current_width
|
93
|
+
# padding_width + example_width + ascii_length
|
94
|
+
padding_width + (@current * example_width) + ascii_length
|
95
|
+
end
|
96
|
+
|
97
|
+
# Gets the padding for the current example count
|
98
|
+
#
|
99
|
+
# @return [Fixnum]
|
100
|
+
def padding_width
|
101
|
+
@example_count.to_s.length * 2 + 6
|
102
|
+
end
|
103
|
+
|
104
|
+
# A Unix trick using stty to get the console columns
|
105
|
+
#
|
106
|
+
# @return [Fixnum]
|
107
|
+
def terminal_width
|
108
|
+
stty_size = `stty size 2>/dev/null`
|
109
|
+
default_width = if !stty_size || defined? JRUBY_VERSION
|
110
|
+
80
|
111
|
+
else
|
112
|
+
stty_size.split.map(&:to_i).reverse.first - 1
|
113
|
+
end
|
114
|
+
@terminal_width ||= default_width
|
115
|
+
end
|
116
|
+
|
117
|
+
# Creates a data store of pass, failed, and pending example results
|
118
|
+
# We have to pad the results here because sprintf can't properly pad color
|
119
|
+
#
|
120
|
+
# @return [Array]
|
121
|
+
def scoreboard
|
122
|
+
@pending_examples ||= []
|
123
|
+
@failed_examples ||= []
|
124
|
+
padding = @example_count.to_s.length
|
125
|
+
[@current.to_s.rjust(padding),
|
126
|
+
success_color((@current - @pending_examples.size - @failed_examples.size).to_s.rjust(padding)),
|
127
|
+
pending_color(@pending_examples.size.to_s.rjust(padding)),
|
128
|
+
failure_color(@failed_examples.size.to_s.rjust(padding))]
|
129
|
+
end
|
130
|
+
|
131
|
+
# Creates a rainbow trail
|
132
|
+
#
|
133
|
+
# @return [String] the sprintf format of the Nyan cat
|
134
|
+
def rainbow_trail
|
135
|
+
marks = @example_results.each_with_index.map { |mark, i| highlight(mark) * example_width(i) }
|
136
|
+
marks.shift(current_width - terminal_width) if current_width >= terminal_width
|
137
|
+
ascii_to_display.split("\n").each_with_index.map do |line, _index|
|
138
|
+
"#{marks.join}#{line}"
|
139
|
+
end.join("\n")
|
140
|
+
end
|
141
|
+
|
142
|
+
# Times a mark has to be repeated
|
143
|
+
def example_width(_item = 1)
|
144
|
+
1
|
145
|
+
end
|
146
|
+
|
147
|
+
# Colorizes the string with raindow colors of the rainbow
|
148
|
+
#
|
149
|
+
# @params string [String]
|
150
|
+
# @return [String]
|
151
|
+
def rainbowify(string)
|
152
|
+
c = colors[@color_index % colors.size]
|
153
|
+
@color_index += 1
|
154
|
+
"#{ESC}38;5;#{c}m#{string}#{NND}"
|
155
|
+
end
|
156
|
+
|
157
|
+
# Calculates the colors of the rainbow
|
158
|
+
#
|
159
|
+
# @return [Array]
|
160
|
+
def colors
|
161
|
+
@colors ||= (0...(6 * 7)).map do |n|
|
162
|
+
pi3 = Math::PI / 3
|
163
|
+
n *= 1.0 / 6
|
164
|
+
r = (3 * Math.sin(n) + 3).to_i
|
165
|
+
g = (3 * Math.sin(n + 2 * pi3) + 3).to_i
|
166
|
+
b = (3 * Math.sin(n + 4 * pi3) + 3).to_i
|
167
|
+
36 * r + 6 * g + b + 16
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
# Determines how to color the example. If pass, it is rainbowified, otherwise
|
172
|
+
# we assign red if failed or yellow if an error occurred.
|
173
|
+
#
|
174
|
+
# @return [String]
|
175
|
+
def highlight(mark = PASS)
|
176
|
+
case mark
|
177
|
+
when PASS then rainbowify PASS_ARY[@color_index % 2]
|
178
|
+
when FAIL then "\e[31m#{mark}\e[0m"
|
179
|
+
when ERROR then "\e[33m#{mark}\e[0m"
|
180
|
+
when PENDING then "\e[33m#{mark}\e[0m"
|
181
|
+
else mark
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
# Converts a float of seconds into a minutes/seconds string
|
186
|
+
#
|
187
|
+
# @return [String]
|
188
|
+
def format_duration(duration)
|
189
|
+
seconds = ((duration % 60) * 100.0).round / 100.0 # 1.8.7 safe .round(2)
|
190
|
+
seconds = seconds.to_i if seconds.to_i == seconds # drop that zero if it's not needed
|
191
|
+
|
192
|
+
message = "#{seconds} second#{seconds == 1 ? '' : 's'}"
|
193
|
+
message = "#{(duration / 60).to_i} minute#{(duration / 60).to_i == 1 ? '' : 's'} and " + message if duration >= 60
|
194
|
+
|
195
|
+
message
|
196
|
+
end
|
197
|
+
|
198
|
+
# Determines if the specs have completed
|
199
|
+
#
|
200
|
+
# @returns [Boolean] true if finished; false otherwise
|
201
|
+
def finished?
|
202
|
+
(@current == @example_count)
|
203
|
+
end
|
204
|
+
|
205
|
+
# Determines if the any specs failed or are in pending state
|
206
|
+
#
|
207
|
+
# @returns [Boolean] true if failed or pending; false otherwise
|
208
|
+
def failed_or_pending?
|
209
|
+
(@failure_count.to_i.positive? || @pending_count.to_i.positive?)
|
210
|
+
end
|
211
|
+
|
212
|
+
# Returns the ascii length
|
213
|
+
#
|
214
|
+
# @returns [Fixnum]
|
215
|
+
def ascii_length
|
216
|
+
ascii_to_display.split("\n").group_by(&:size).max.first
|
217
|
+
end
|
218
|
+
|
219
|
+
def success_color(text)
|
220
|
+
wrap(text, :green)
|
221
|
+
end
|
222
|
+
|
223
|
+
def pending_color(text)
|
224
|
+
wrap(text, :yellow)
|
225
|
+
end
|
226
|
+
|
227
|
+
def failure_color(text)
|
228
|
+
wrap(text, :red)
|
229
|
+
end
|
230
|
+
|
231
|
+
def console_code_for(code_or_symbol)
|
232
|
+
if VT100_CODE_VALUES.key?(code_or_symbol)
|
233
|
+
code_or_symbol
|
234
|
+
else
|
235
|
+
VT100_CODES.fetch(code_or_symbol) do
|
236
|
+
console_code_for(:white)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
def wrap(text, code_or_symbol)
|
242
|
+
if RSpec.configuration.color_enabled?
|
243
|
+
"\e[#{console_code_for(code_or_symbol)}m#{text}\e[0m"
|
244
|
+
else
|
245
|
+
text
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|