rainbow_formatter 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
![](data/tina_bike.gif)
|
3
|
+
![](data/tina_dream.gif)
|
4
|
+
![](data/car.gif)
|
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
|