nyan 0.0.1
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.
- data/.gitignore +5 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/Guardfile +6 -0
- data/README.md +80 -0
- data/Rakefile +7 -0
- data/bin/nyan.rb +11 -0
- data/lib/nyan.rb +20 -0
- data/lib/nyan/colour.rb +27 -0
- data/lib/nyan/flight.rb +51 -0
- data/lib/nyan/formatter.rb +44 -0
- data/lib/nyan/shape.rb +16 -0
- data/lib/nyan/sprite.rb +60 -0
- data/lib/nyan/sprites/cat_head.rb +26 -0
- data/lib/nyan/sprites/pop_tart.rb +28 -0
- data/lib/nyan/sprites/rainbow.rb +45 -0
- data/lib/nyan/sprites/star.rb +81 -0
- data/lib/nyan/sprites/tail.rb +27 -0
- data/lib/nyan/stage.rb +109 -0
- data/lib/nyan/version.rb +3 -0
- data/nyan.gemspec +28 -0
- data/spec/lib/colour_spec.rb +15 -0
- data/spec/lib/shape_spec.rb +41 -0
- data/spec/lib/sprite_spec.rb +124 -0
- data/spec/lib/stage_spec.rb +175 -0
- data/spec/spec_helper.rb +1 -0
- metadata +141 -0
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour
|
data/Gemfile
ADDED
data/Guardfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
Nyan 
|
2
|
+
==================
|
3
|
+
|
4
|
+
Your favourite aging meme is reheated as an RSpec custom formatter.
|
5
|
+
|
6
|
+
For entertainment purposes only.
|
7
|
+
|
8
|
+
FAQ
|
9
|
+
---
|
10
|
+
|
11
|
+
* Didn't this meme jump the shark, like, ages ago?
|
12
|
+
|
13
|
+
Yes.
|
14
|
+
|
15
|
+
* It's got no tail
|
16
|
+
|
17
|
+
Look closer.
|
18
|
+
|
19
|
+
* It's got no feet!
|
20
|
+
|
21
|
+
LOOK CLOSER.
|
22
|
+
|
23
|
+
* It's really slow
|
24
|
+
|
25
|
+
Write faster specs.
|
26
|
+
|
27
|
+
* It's still really slow
|
28
|
+
|
29
|
+
Send me a pull request where the animation runs in a separate thread.
|
30
|
+
|
31
|
+
* The colours are all wrong
|
32
|
+
|
33
|
+
Probably need a new graphics card or something.
|
34
|
+
|
35
|
+
Requirements
|
36
|
+
------------
|
37
|
+
|
38
|
+
* RSpec 2 (tested against RSpec 2.6)
|
39
|
+
|
40
|
+
Install
|
41
|
+
-------
|
42
|
+
|
43
|
+
Add to your `Gemfile` (usually inside your `:test` group):
|
44
|
+
|
45
|
+
gem "nyan"
|
46
|
+
|
47
|
+
Alternatively install directly:
|
48
|
+
|
49
|
+
$ gem install nyan
|
50
|
+
|
51
|
+
Usage
|
52
|
+
-----
|
53
|
+
|
54
|
+
$ rspec spec -f Nyan::Formatter
|
55
|
+
|
56
|
+
Or if you want the joy of Nyan without running specs, use the binary:
|
57
|
+
|
58
|
+
$ nyan
|
59
|
+
|
60
|
+
Your terminal should be at least 180 columns x 50 rows.
|
61
|
+
|
62
|
+
Development
|
63
|
+
-----------
|
64
|
+
|
65
|
+
* Source hosted at [GitHub](https://github.com/kapoq/nyan)
|
66
|
+
* Report issues/Questions/Feature requests on [GitHub Issues](https://github.com/kapoq/nyan)
|
67
|
+
* CI at [Travis](http://travis-ci.org/#!/textgoeshere/nyan)
|
68
|
+
|
69
|
+
Pull requests are very welcome! Make sure your patches are well tested. Please create a topic branch for every separate change
|
70
|
+
you make.
|
71
|
+
|
72
|
+
Testing
|
73
|
+
-------
|
74
|
+
|
75
|
+
$ rake
|
76
|
+
|
77
|
+
Author
|
78
|
+
------
|
79
|
+
|
80
|
+
[Dave Nolan](https://github.com/textgoeshere)
|
data/Rakefile
ADDED
data/bin/nyan.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
nyan_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
$LOAD_PATH.unshift(nyan_dir) unless $LOAD_PATH.include?(nyan_dir)
|
4
|
+
require "nyan"
|
5
|
+
|
6
|
+
print cls
|
7
|
+
flight = Nyan::Flight.new
|
8
|
+
loop do
|
9
|
+
flight.next!
|
10
|
+
end
|
11
|
+
|
data/lib/nyan.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require "nyan/version"
|
2
|
+
|
3
|
+
require "nyan/colour"
|
4
|
+
require "nyan/shape"
|
5
|
+
require "nyan/sprite"
|
6
|
+
require "nyan/stage"
|
7
|
+
|
8
|
+
require "nyan/flight"
|
9
|
+
|
10
|
+
module Nyan
|
11
|
+
BLOCK = "\u2588"
|
12
|
+
SPACE = "\x20"
|
13
|
+
NEWLINE = "\n"
|
14
|
+
|
15
|
+
require "nyan/sprites/rainbow"
|
16
|
+
require "nyan/sprites/cat_head"
|
17
|
+
require "nyan/sprites/pop_tart"
|
18
|
+
require "nyan/sprites/tail"
|
19
|
+
require "nyan/sprites/star"
|
20
|
+
end
|
data/lib/nyan/colour.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require "ansi"
|
2
|
+
include ANSI::Code
|
3
|
+
|
4
|
+
module Nyan
|
5
|
+
module Colour
|
6
|
+
MAP = {
|
7
|
+
"#" => "#{bright}#{black}",
|
8
|
+
"b" => "#{dark}#{black}",
|
9
|
+
"R" => "#{bright}#{magenta}",
|
10
|
+
"p" => "#{dark}#{magenta}",
|
11
|
+
"2" => "#{bright}#{yellow}",
|
12
|
+
"`" => "#{dark}#{yellow}",
|
13
|
+
"o" => "#{bright}#{white}",
|
14
|
+
"_" => "#{bright}#{white}",
|
15
|
+
"." => "#{dark}#{white}",
|
16
|
+
"1" => "#{bright}#{red}",
|
17
|
+
"3" => "#{bright}#{green}",
|
18
|
+
"4" => "#{bright}#{blue}",
|
19
|
+
"5" => "#{bright}#{magenta}"
|
20
|
+
}
|
21
|
+
|
22
|
+
def self.colourize(char)
|
23
|
+
escape_codes = MAP.fetch(char, reset)
|
24
|
+
"#{escape_codes}#{Nyan::BLOCK}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/nyan/flight.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
module Nyan
|
2
|
+
class Flight
|
3
|
+
def initialize
|
4
|
+
@stage = Stage.new
|
5
|
+
|
6
|
+
@rainbow = Sprite.new(:x => 0, :y => 17, :z => 1, :frames => Nyan::Rainbow.to_frames)
|
7
|
+
|
8
|
+
@cat_head = Sprite.new(:x => Nyan::Rainbow::TOTAL_LENGTH - 2,
|
9
|
+
:y => 17,
|
10
|
+
:z => 100,
|
11
|
+
:frames => Nyan::CatHead.to_frames,
|
12
|
+
:animation => Proc.new do
|
13
|
+
@initial_x ||= @x
|
14
|
+
@initial_y ||= @y
|
15
|
+
case offset = [@x == @initial_x && :initial || :offset, @y == @initial_y && :initial || :offset]
|
16
|
+
when [:initial, :initial] then @y -= 2
|
17
|
+
when [:initial, :offset] then @x += 2
|
18
|
+
when [:offset, :offset] then @y += 2
|
19
|
+
when [:offset, :initial] then @x -= 2
|
20
|
+
end
|
21
|
+
end)
|
22
|
+
|
23
|
+
@pop_tart = Sprite.new(:x => @cat_head.x - 20,
|
24
|
+
:y => @cat_head.y - 2,
|
25
|
+
:z => @cat_head.z - 1,
|
26
|
+
:frames => Nyan::PopTart.to_frames)
|
27
|
+
|
28
|
+
@stage.add_sprite(@rainbow)
|
29
|
+
@stage.add_sprite(@cat_head)
|
30
|
+
@stage.add_sprite(@pop_tart)
|
31
|
+
@tick_time = Time.now
|
32
|
+
end
|
33
|
+
|
34
|
+
def next!
|
35
|
+
if rand > 0.85
|
36
|
+
speed = rand > 0.5 ? 2 : 5
|
37
|
+
star = Sprite.new(:x => @stage.width,
|
38
|
+
:y => rand(@stage.height - 11),
|
39
|
+
:z => 0,
|
40
|
+
:speed => speed,
|
41
|
+
:frames => Nyan::Star.to_frames,
|
42
|
+
:frame_index => rand(Nyan::Star.to_frames.length - 1),
|
43
|
+
:animation => Proc.new { self.x -= @options[:speed] })
|
44
|
+
@stage.add_sprite(star)
|
45
|
+
end
|
46
|
+
@stage.play!
|
47
|
+
loop until Time.now - @tick_time >= 0.09
|
48
|
+
@tick_time = Time.now
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'rspec/core/formatters/base_text_formatter'
|
2
|
+
require 'nyan'
|
3
|
+
|
4
|
+
module Nyan
|
5
|
+
class Formatter < RSpec::Core::Formatters::BaseTextFormatter
|
6
|
+
def initialize(*args)
|
7
|
+
super
|
8
|
+
@nyan_flight = Nyan::Flight.new
|
9
|
+
@still_passing = true
|
10
|
+
print cls
|
11
|
+
puts "Awaiting Nyan..."
|
12
|
+
end
|
13
|
+
|
14
|
+
def example_passed(_)
|
15
|
+
@nyan_flight.next! if @still_passing
|
16
|
+
end
|
17
|
+
|
18
|
+
def example_failed(example)
|
19
|
+
super
|
20
|
+
@output.print cls
|
21
|
+
@output.print move(0,0)
|
22
|
+
@output.puts red("NO NYAN FOR YOU")
|
23
|
+
@still_passing = false
|
24
|
+
end
|
25
|
+
|
26
|
+
def dump_failures
|
27
|
+
return if failed_examples.empty?
|
28
|
+
output.puts
|
29
|
+
output.puts "Failures:"
|
30
|
+
failed_examples.each_with_index do |example, index|
|
31
|
+
output.puts
|
32
|
+
dump_pending_example_fixed(example, index) || dump_failure(example, index)
|
33
|
+
dump_backtrace(example)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def dump_backtrace(example)
|
38
|
+
format_backtrace(example.execution_result[:exception].backtrace, example).each do |backtrace_info|
|
39
|
+
output.puts cyan(" # #{backtrace_info}")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
data/lib/nyan/shape.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
module Nyan
|
2
|
+
module Shape
|
3
|
+
attr_accessor :top, :bottom, :left, :right
|
4
|
+
|
5
|
+
def outside?(other_shape)
|
6
|
+
(right < other_shape.left) or
|
7
|
+
(top > other_shape.bottom) or
|
8
|
+
(left > other_shape.right) or
|
9
|
+
(bottom < other_shape.top)
|
10
|
+
end
|
11
|
+
|
12
|
+
def inside?(other_shape)
|
13
|
+
!outside(other_shape)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/nyan/sprite.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module Nyan
|
3
|
+
class Sprite
|
4
|
+
include Shape
|
5
|
+
|
6
|
+
attr_accessor :x, :y, :z, :frames, :frame_index
|
7
|
+
attr_reader :blk
|
8
|
+
|
9
|
+
def initialize(options = {}, &blk)
|
10
|
+
@options = options
|
11
|
+
self.x = @options.fetch(:x, 0)
|
12
|
+
self.y = @options.fetch(:y, 0)
|
13
|
+
self.z = @options.fetch(:z, 0)
|
14
|
+
self.frames = @options.fetch(:frames, [])
|
15
|
+
self.frame_index = @options.fetch(:frame_index, 0)
|
16
|
+
@blk = blk || @options[:animation]
|
17
|
+
end
|
18
|
+
|
19
|
+
def frame
|
20
|
+
frames[frame_index]
|
21
|
+
end
|
22
|
+
|
23
|
+
def lines
|
24
|
+
frame.lines
|
25
|
+
end
|
26
|
+
|
27
|
+
def animate!
|
28
|
+
self.frame_index = (self.frame_index + 1) % frames.length
|
29
|
+
self.instance_eval(&blk) if blk
|
30
|
+
end
|
31
|
+
|
32
|
+
def height
|
33
|
+
@height ||= frame.lines.count
|
34
|
+
end
|
35
|
+
|
36
|
+
def width
|
37
|
+
@width ||= frame.lines.map { |l| l.chomp.unansi.length }.max
|
38
|
+
end
|
39
|
+
|
40
|
+
def top
|
41
|
+
y
|
42
|
+
end
|
43
|
+
|
44
|
+
def bottom
|
45
|
+
y + height
|
46
|
+
end
|
47
|
+
|
48
|
+
def left
|
49
|
+
x
|
50
|
+
end
|
51
|
+
|
52
|
+
def right
|
53
|
+
x + width
|
54
|
+
end
|
55
|
+
|
56
|
+
def <=>(other)
|
57
|
+
z <=> other.z
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Nyan
|
2
|
+
module CatHead
|
3
|
+
SHAPE =<<EOF
|
4
|
+
# #
|
5
|
+
#.### ###.#
|
6
|
+
#....## ##...#
|
7
|
+
#__....############...__#
|
8
|
+
___...#..........#..___
|
9
|
+
#__.................__#
|
10
|
+
#.....................#
|
11
|
+
#....o#.......o#....#
|
12
|
+
#....##.......##....#
|
13
|
+
#........b.b........#
|
14
|
+
#.p.......b.......p.#
|
15
|
+
#.p.b....b....b.p.#
|
16
|
+
#...b....b....b...#
|
17
|
+
#....bbbb.bbbb....#
|
18
|
+
###...........###
|
19
|
+
###########
|
20
|
+
EOF
|
21
|
+
|
22
|
+
def self.to_frames
|
23
|
+
@frames ||= Array(SHAPE)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Nyan
|
2
|
+
module PopTart
|
3
|
+
SHAPE =<<-EOF
|
4
|
+
ooooooooooooooooooooooooooooo
|
5
|
+
o22222222222222222222222222222o
|
6
|
+
o222222ppppppppppppppppp22222222o
|
7
|
+
o22222ppppppRRRpppppppppppppppp222o
|
8
|
+
o22pppppppppRRRppppppppppppppppp22o
|
9
|
+
o22pppppRRRppRRRpppppppRRpppppppp222o
|
10
|
+
o222ppppRRRppppppppppppRppppppppp222o
|
11
|
+
o222pppppppppppppppppppRpppppppppp22o
|
12
|
+
o222ppppRRRppppppRRRppppppppppp222o
|
13
|
+
o222ppppRRRppppppRRRppppppppppp2222o
|
14
|
+
o22pppppppppppppppppppppppppppp22222o
|
15
|
+
o22ppppppppRRRpppppppppppppppppp2222o
|
16
|
+
o22ppppppppRRRppppppRRRppppppppp2222o
|
17
|
+
o22ppppppppRRRppppppRRRppppppppp2222o
|
18
|
+
o22pppppppppppppppppRRRpppppppppp222o
|
19
|
+
o222pppppppppppppppppppppppppppp2222o
|
20
|
+
o222222ppppppppppppppppp222222222222o
|
21
|
+
ooooooooooooooooooooooooooooooooooo
|
22
|
+
EOF
|
23
|
+
|
24
|
+
def self.to_frames
|
25
|
+
@fames ||= Array(SHAPE)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Nyan
|
2
|
+
module Rainbow
|
3
|
+
BAND_HEIGHT = 3
|
4
|
+
BEND_LENGTH = 18
|
5
|
+
SECTIONS = 5
|
6
|
+
|
7
|
+
COLOURS = %w(1 2 3 4 5)
|
8
|
+
BLANK = ([Nyan::SPACE] * BEND_LENGTH).join
|
9
|
+
|
10
|
+
FRAME_HEIGHT = COLOURS.length * BAND_HEIGHT + 1
|
11
|
+
FRAME_WIDTH = SECTIONS * BEND_LENGTH
|
12
|
+
|
13
|
+
TOTAL_LENGTH = SECTIONS * BEND_LENGTH
|
14
|
+
TOTAL_HEIGHT = BAND_HEIGHT * COLOURS.length
|
15
|
+
|
16
|
+
SLICE = COLOURS.each_with_object([]) do |colour, slice|
|
17
|
+
BAND_HEIGHT.times do
|
18
|
+
slice << "#{colour}" * BEND_LENGTH
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.frame(is_peak = true)
|
23
|
+
frame_rows = Array.new(FRAME_HEIGHT + 1) { String.new }
|
24
|
+
|
25
|
+
SECTIONS.times do
|
26
|
+
this_slice = SLICE.dup
|
27
|
+
FRAME_HEIGHT.times do |i|
|
28
|
+
this_row = if (is_peak && i == FRAME_HEIGHT - 1) or (!is_peak && i == 0)
|
29
|
+
BLANK
|
30
|
+
else
|
31
|
+
this_slice.shift
|
32
|
+
end
|
33
|
+
frame_rows[i] << this_row
|
34
|
+
end
|
35
|
+
is_peak = !is_peak
|
36
|
+
end
|
37
|
+
|
38
|
+
frame_rows.join(NEWLINE)
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.to_frames
|
42
|
+
@frames ||= [frame(true), frame(false)]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Nyan
|
2
|
+
module Star
|
3
|
+
SHAPE_LIST =<<EOF
|
4
|
+
...........
|
5
|
+
...........
|
6
|
+
...........
|
7
|
+
...........
|
8
|
+
...........
|
9
|
+
.....X.....
|
10
|
+
...........
|
11
|
+
...........
|
12
|
+
...........
|
13
|
+
...........
|
14
|
+
...........
|
15
|
+
--
|
16
|
+
...........
|
17
|
+
...........
|
18
|
+
...........
|
19
|
+
...........
|
20
|
+
.....X.....
|
21
|
+
....X.X....
|
22
|
+
.....X.....
|
23
|
+
...........
|
24
|
+
...........
|
25
|
+
...........
|
26
|
+
...........
|
27
|
+
--
|
28
|
+
...........
|
29
|
+
...........
|
30
|
+
...........
|
31
|
+
.....X.....
|
32
|
+
.....X.....
|
33
|
+
...XX.XX...
|
34
|
+
.....X.....
|
35
|
+
.....X.....
|
36
|
+
...........
|
37
|
+
...........
|
38
|
+
...........
|
39
|
+
--
|
40
|
+
...........
|
41
|
+
.....X.....
|
42
|
+
.....X.....
|
43
|
+
.....X.....
|
44
|
+
...........
|
45
|
+
.XXX.X.XXX.
|
46
|
+
...........
|
47
|
+
.....X.....
|
48
|
+
.....X.....
|
49
|
+
.....X.....
|
50
|
+
...........
|
51
|
+
--
|
52
|
+
...........
|
53
|
+
....XXX....
|
54
|
+
...X...X...
|
55
|
+
.X.......X.
|
56
|
+
X.........X
|
57
|
+
X.........X
|
58
|
+
X.........X
|
59
|
+
.X.......X.
|
60
|
+
..X.....X..
|
61
|
+
....XXX....
|
62
|
+
...........
|
63
|
+
--
|
64
|
+
.....X.....
|
65
|
+
...........
|
66
|
+
...........
|
67
|
+
...........
|
68
|
+
...........
|
69
|
+
X.........X
|
70
|
+
...........
|
71
|
+
...........
|
72
|
+
...........
|
73
|
+
...........
|
74
|
+
.....X.....
|
75
|
+
EOF
|
76
|
+
|
77
|
+
def self.to_frames
|
78
|
+
@frames ||= SHAPE_LIST.gsub(/\./, SPACE).gsub(/X/, BLOCK).split(/--./m)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Nyan
|
2
|
+
module Tail
|
3
|
+
SHAPE_LIST =<<-EOF
|
4
|
+
..................
|
5
|
+
..................
|
6
|
+
..................
|
7
|
+
..................
|
8
|
+
..................
|
9
|
+
--
|
10
|
+
..................
|
11
|
+
..................
|
12
|
+
..................
|
13
|
+
..................
|
14
|
+
..................
|
15
|
+
--
|
16
|
+
..................
|
17
|
+
..................
|
18
|
+
..................
|
19
|
+
..................
|
20
|
+
..................
|
21
|
+
EOF
|
22
|
+
|
23
|
+
def self.to_frames
|
24
|
+
@frames ||= SHAPE_LIST.gsub(/\./, SPACE).gsub(/X/, BLOCK).split(/--./m)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/nyan/stage.rb
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
module Nyan
|
2
|
+
class Stage
|
3
|
+
include Shape
|
4
|
+
|
5
|
+
SPACE = "\x20"
|
6
|
+
NOTHING = ""
|
7
|
+
|
8
|
+
attr_reader :output, :height, :width
|
9
|
+
|
10
|
+
def initialize(options = {})
|
11
|
+
@output = options.fetch(:output, $stdout)
|
12
|
+
@height = options.fetch(:height, ANSI::Terminal.terminal_height)
|
13
|
+
@width = options.fetch(:width, ANSI::Terminal.terminal_width)
|
14
|
+
@coloured = options.fetch(:coloured, true)
|
15
|
+
clear_buffer
|
16
|
+
end
|
17
|
+
|
18
|
+
def sprites
|
19
|
+
@sprites ||= []
|
20
|
+
end
|
21
|
+
|
22
|
+
def add_sprite(sprite)
|
23
|
+
self.sprites.push(sprite)
|
24
|
+
end
|
25
|
+
|
26
|
+
def remove_sprite(sprite)
|
27
|
+
self.sprites.delete(sprite)
|
28
|
+
end
|
29
|
+
|
30
|
+
def play!
|
31
|
+
render
|
32
|
+
animate!
|
33
|
+
clean!
|
34
|
+
end
|
35
|
+
|
36
|
+
def render
|
37
|
+
clear_buffer
|
38
|
+
sprites.sort.each { |s| write_to_buffer(s) }
|
39
|
+
print_buffer
|
40
|
+
end
|
41
|
+
|
42
|
+
def animate!
|
43
|
+
sprites.each { |s| s.animate! }
|
44
|
+
end
|
45
|
+
|
46
|
+
def clean!
|
47
|
+
sprites.delete_if { |s| s.outside?(self) }
|
48
|
+
end
|
49
|
+
|
50
|
+
def top
|
51
|
+
0
|
52
|
+
end
|
53
|
+
|
54
|
+
def bottom
|
55
|
+
height - 1
|
56
|
+
end
|
57
|
+
|
58
|
+
def left
|
59
|
+
0
|
60
|
+
end
|
61
|
+
|
62
|
+
def right
|
63
|
+
width - 1
|
64
|
+
end
|
65
|
+
|
66
|
+
def coloured?
|
67
|
+
@coloured
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def clear_buffer
|
73
|
+
@buffer = Array.new(height) do
|
74
|
+
Array.new(width) do
|
75
|
+
{ :char => SPACE, :colourized_char => SPACE }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def write_to_buffer(sprite)
|
81
|
+
sprite.lines.each_with_index do |line, i|
|
82
|
+
line_y = sprite.y + i
|
83
|
+
previous_colourized_char = nil
|
84
|
+
if line_y.between?(top, bottom)
|
85
|
+
line.chomp.chars.each_with_index do |char, j|
|
86
|
+
char_x = sprite.x + j
|
87
|
+
if char_x.between?(left, right) && char != Nyan::SPACE
|
88
|
+
colourized_char = Colour.colourize(char)
|
89
|
+
colourized_char = Nyan::BLOCK if colourized_char == previous_colourized_char
|
90
|
+
@buffer[line_y][char_x] = { :char => char, :colourized_char => colourized_char }
|
91
|
+
previous_colourized_char = colourized_char
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def print_buffer
|
99
|
+
key = coloured? ? :colourized_char : :char
|
100
|
+
@buffer.each_with_index do |row, i|
|
101
|
+
output.print move(i, 0)
|
102
|
+
output.print clear_line
|
103
|
+
output.print reset
|
104
|
+
output.print row.map { |h| h[key] }.join
|
105
|
+
output.print "\n" unless i == bottom
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
data/lib/nyan/version.rb
ADDED
data/nyan.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "nyan/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "nyan"
|
7
|
+
s.version = Nyan::VERSION
|
8
|
+
s.authors = ["dave@kapoq.com"]
|
9
|
+
s.email = ["dave@kapoq.com"]
|
10
|
+
s.homepage = "https://github.com/kapoq/nyan_formatter"
|
11
|
+
s.summary = "Nyan Cat flies across your terminal while your RSpec specs run!"
|
12
|
+
s.description = "Your favourite aging meme is reheated as an RSpec custom formatter. For entertainment purposes only. WARNING: enterprise-ready"
|
13
|
+
|
14
|
+
s.add_dependency "ansi"
|
15
|
+
s.add_dependency "rspec"
|
16
|
+
|
17
|
+
s.add_development_dependency "guard-rspec"
|
18
|
+
s.add_development_dependency "rake"
|
19
|
+
if RUBY_PLATFORM =~ /linux/
|
20
|
+
s.add_development_dependency "rb-inotify"
|
21
|
+
s.add_development_dependency "libnotify"
|
22
|
+
end
|
23
|
+
|
24
|
+
s.files = `git ls-files`.split("\n")
|
25
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
26
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
27
|
+
s.require_paths = ["lib"]
|
28
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Nyan::Colour do
|
4
|
+
describe ".colourize" do
|
5
|
+
it "looks up the char in the map" do
|
6
|
+
Nyan::Colour::MAP.should_receive(:fetch).with("X", anything)
|
7
|
+
Nyan::Colour.colourize("X")
|
8
|
+
end
|
9
|
+
|
10
|
+
it "returns the escape code for the colour followed by a block char" do
|
11
|
+
Nyan::Colour::MAP.stub(:fetch => "__ESC__")
|
12
|
+
Nyan::Colour.colourize("X").should eql "__ESC__#{Nyan::BLOCK}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class SimpleShape
|
4
|
+
include ::Nyan::Shape
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@top, @bottom, @left, @right = [0, 0, 0, 0]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe Nyan::Shape do
|
12
|
+
let(:shape) { SimpleShape.new }
|
13
|
+
|
14
|
+
describe "#outside?" do
|
15
|
+
let(:other_shape) { SimpleShape.new }
|
16
|
+
|
17
|
+
it "is outside when its right edge is beyond the left edge of the other shape" do
|
18
|
+
shape.right = other_shape.left - 1
|
19
|
+
shape.should be_outside(other_shape)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "is outside when its left edge is beyond the right edge of the other shape" do
|
23
|
+
shape.left = other_shape.right + 1
|
24
|
+
shape.should be_outside(other_shape)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "is outside when its top edge is below the bottom edge of the other shape" do
|
28
|
+
shape.top = other_shape.bottom + 1
|
29
|
+
shape.should be_outside(other_shape)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "is outside when its bottom edge is above the top edge of the other shape" do
|
33
|
+
shape.bottom = other_shape.top - 1
|
34
|
+
shape.should be_outside(other_shape)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "is not outside when its edges are all within the edges of the other shape" do
|
38
|
+
shape.should_not be_outside(other_shape)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Nyan::Sprite do
|
4
|
+
let(:output) { StringIO.new }
|
5
|
+
let(:sprite) { Nyan::Sprite.new }
|
6
|
+
let(:frame1) { double(:frame1) }
|
7
|
+
let(:frame2) { double(:frame2) }
|
8
|
+
let(:frames) { [frame1, frame2] }
|
9
|
+
|
10
|
+
describe "#initialize" do
|
11
|
+
it "accepts optional x, y, and frames parameters and sets its instance variables to their values" do
|
12
|
+
sprite = Nyan::Sprite.new(:x => 1, :y => 2, :z => 3, :frames => frames, :frame_index => 4)
|
13
|
+
sprite.x.should == 1
|
14
|
+
sprite.y.should == 2
|
15
|
+
sprite.z.should == 3
|
16
|
+
sprite.frame_index.should == 4
|
17
|
+
sprite.frames.should == frames
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "defaults" do
|
21
|
+
it "x = 0" do
|
22
|
+
sprite.x.should == 0
|
23
|
+
end
|
24
|
+
|
25
|
+
it "y = 0" do
|
26
|
+
sprite.y.should == 0
|
27
|
+
end
|
28
|
+
|
29
|
+
it "z = 0" do
|
30
|
+
sprite.z.should == 0
|
31
|
+
end
|
32
|
+
|
33
|
+
it "frames is an empty array" do
|
34
|
+
sprite.frames.should == []
|
35
|
+
end
|
36
|
+
|
37
|
+
it "frame_index = 0" do
|
38
|
+
sprite.frame_index.should == 0
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
it "accepts an block which is executed each animation step" do
|
43
|
+
sprite = Nyan::Sprite.new(:frames => frames) do
|
44
|
+
self.x = 99
|
45
|
+
end
|
46
|
+
sprite.should_receive(:x=).with(99)
|
47
|
+
sprite.animate!
|
48
|
+
end
|
49
|
+
|
50
|
+
it "accepts a Proc as an optional animation parameter which is executed each animation step" do
|
51
|
+
sprite = Nyan::Sprite.new(:frames => frames, :animation => Proc.new { self.x = 99 })
|
52
|
+
sprite.should_receive(:x=).with(99)
|
53
|
+
sprite.animate!
|
54
|
+
end
|
55
|
+
|
56
|
+
it "has left at x" do
|
57
|
+
sprite.x = 99
|
58
|
+
sprite.left.should == 99
|
59
|
+
end
|
60
|
+
|
61
|
+
it "has right at x + width" do
|
62
|
+
sprite.x = 99
|
63
|
+
sprite.stub(:width => 99)
|
64
|
+
sprite.right.should == 198
|
65
|
+
end
|
66
|
+
|
67
|
+
it "has top at y" do
|
68
|
+
sprite.y = 77
|
69
|
+
sprite.top.should == 77
|
70
|
+
end
|
71
|
+
|
72
|
+
it "has bottom at y + height" do
|
73
|
+
sprite.y = 77
|
74
|
+
sprite.stub(:height => 99)
|
75
|
+
sprite.bottom.should == 176
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "frames" do
|
80
|
+
before do
|
81
|
+
sprite.frames = frames
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "#frames" do
|
85
|
+
it "returns array of frames" do
|
86
|
+
sprite.frames.should eql frames
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "#frame" do
|
91
|
+
it "returns the current frame" do
|
92
|
+
sprite.frame.should eql frame1
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "#animate!" do
|
97
|
+
it "sets current frame to the next frame, looping to the start when necessary" do
|
98
|
+
sprite.frame_index = 1
|
99
|
+
sprite.animate!
|
100
|
+
sprite.frame.should eql frame1
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
it "has a height equal to the number of lines in the frame" do
|
106
|
+
sprite.frames = ["1\n2\n3\n4"]
|
107
|
+
sprite.height.should == 4
|
108
|
+
end
|
109
|
+
|
110
|
+
it "has a width equal to the number of characters in widest line of the frame excluding line breaks" do
|
111
|
+
sprite.frames = ["1\n22\n333\n22\n22"]
|
112
|
+
sprite.width.should == 3
|
113
|
+
end
|
114
|
+
|
115
|
+
describe "#<=>" do
|
116
|
+
let(:a) { double("Sprite a") }
|
117
|
+
let(:b) { double("Sprite b") }
|
118
|
+
|
119
|
+
it "sorts by z" do
|
120
|
+
a.should_receive(:<=>).with(b)
|
121
|
+
a <=> b
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,175 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Nyan::Stage do
|
4
|
+
let(:output) { StringIO.new }
|
5
|
+
let(:stage) { Nyan::Stage.new(:output => output, :height => 5, :width => 5, :coloured => false) }
|
6
|
+
let(:sprite) { mock(:sprite) }
|
7
|
+
|
8
|
+
before do
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#initialize" do
|
13
|
+
context "when output parameter is present" do
|
14
|
+
it "sets output to the value of the output parameter" do
|
15
|
+
stage = Nyan::Stage.new(:output => output)
|
16
|
+
stage.output.should eql output
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context "defaults" do
|
21
|
+
let(:default_stage) { Nyan::Stage.new }
|
22
|
+
|
23
|
+
it "sets output to $stdout" do
|
24
|
+
default_stage.output.should eql $stdout
|
25
|
+
end
|
26
|
+
|
27
|
+
it "is coloured" do
|
28
|
+
default_stage.should be_coloured
|
29
|
+
end
|
30
|
+
|
31
|
+
it "has a height equal to the terminal height" do
|
32
|
+
::ANSI::Terminal.stub(:terminal_height => 99)
|
33
|
+
default_stage.height.should == 99
|
34
|
+
end
|
35
|
+
|
36
|
+
it "has a width equal to the terminal width" do
|
37
|
+
::ANSI::Terminal.stub(:terminal_width => 99)
|
38
|
+
default_stage.width.should == 99
|
39
|
+
end
|
40
|
+
|
41
|
+
it "has top at 0" do
|
42
|
+
default_stage.top.should == 0
|
43
|
+
end
|
44
|
+
|
45
|
+
it "has left at 0" do
|
46
|
+
default_stage.left.should == 0
|
47
|
+
end
|
48
|
+
|
49
|
+
it "has right at width - 1" do
|
50
|
+
width = 99
|
51
|
+
default_stage.stub :width => width
|
52
|
+
default_stage.right.should == width - 1
|
53
|
+
end
|
54
|
+
|
55
|
+
it "has bottom at height - 1" do
|
56
|
+
height = 99
|
57
|
+
default_stage.stub :height => height
|
58
|
+
default_stage.bottom.should == height - 1
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "#add_sprite" do
|
64
|
+
it "adds a sprite" do
|
65
|
+
stage.add_sprite(sprite)
|
66
|
+
stage.sprites.should include(sprite)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "#remove_sprite" do
|
71
|
+
it "removes a sprite" do
|
72
|
+
sprite1 = double(:sprite1)
|
73
|
+
sprite2 = double(:sprite2)
|
74
|
+
stage.add_sprite(sprite1)
|
75
|
+
stage.add_sprite(sprite2)
|
76
|
+
stage.remove_sprite(sprite1)
|
77
|
+
stage.sprites.should == [sprite2]
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "#play!" do
|
82
|
+
it "renders, animates, and cleans" do
|
83
|
+
stage.should_receive(:render)
|
84
|
+
stage.should_receive(:animate!)
|
85
|
+
stage.should_receive(:clean!)
|
86
|
+
stage.play!
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "#render" do
|
91
|
+
let(:sprites) { double("Sprites") }
|
92
|
+
let(:sprite) { Nyan::Sprite.new }
|
93
|
+
|
94
|
+
before do
|
95
|
+
stage.stub(:sprites => sprites)
|
96
|
+
sprites.stub(:sort => [sprite])
|
97
|
+
end
|
98
|
+
|
99
|
+
it "renders its sprites to its output in order of z-index" do
|
100
|
+
sprites.should_receive(:sort).and_return([])
|
101
|
+
stage.render
|
102
|
+
end
|
103
|
+
|
104
|
+
it "prints each sprite to the output" do
|
105
|
+
sprite.frames = %w(XXXX)
|
106
|
+
stage.render
|
107
|
+
output.string.should =~ /XXXX/
|
108
|
+
end
|
109
|
+
|
110
|
+
it "only prints characters within the viewport" do
|
111
|
+
stage.stub(:height => 1, :width => 1)
|
112
|
+
sprite.x = -1
|
113
|
+
sprite.y = -1
|
114
|
+
sprite.frames = ["OOO\nOXO\nOOO"]
|
115
|
+
stage.render
|
116
|
+
output.string.should =~ /X/
|
117
|
+
output.string.should_not =~ /O/
|
118
|
+
end
|
119
|
+
|
120
|
+
it "renders each sprite at its correct position" do
|
121
|
+
sprite.x = stage.right
|
122
|
+
sprite.y = stage.bottom
|
123
|
+
sprite.frames = %w(X)
|
124
|
+
stage.render
|
125
|
+
output.string.unansi.should =~ /X$/
|
126
|
+
end
|
127
|
+
|
128
|
+
context "when coloured" do
|
129
|
+
before do
|
130
|
+
stage.stub(:coloured? => true)
|
131
|
+
end
|
132
|
+
|
133
|
+
it "prints coloured chars" do
|
134
|
+
Nyan::Colour.stub(:colourize => "__COLOURED__")
|
135
|
+
sprite.frames = %w(x)
|
136
|
+
stage.render
|
137
|
+
output.string.should =~ /__COLOURED__/
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
describe "#clean!" do
|
143
|
+
before do
|
144
|
+
stage.stub(:sprites => [sprite])
|
145
|
+
end
|
146
|
+
|
147
|
+
it "checks whether the sprite is outside the stage" do
|
148
|
+
sprite.should_receive(:outside?).with(stage)
|
149
|
+
stage.clean!
|
150
|
+
end
|
151
|
+
|
152
|
+
it "removes sprites outside the stage" do
|
153
|
+
sprite.stub(:outside? => true)
|
154
|
+
stage.clean!
|
155
|
+
stage.sprites.should_not include(sprite)
|
156
|
+
end
|
157
|
+
|
158
|
+
it "does not remove sprites inside the stage" do
|
159
|
+
sprite.stub(:outside? => false)
|
160
|
+
stage.clean!
|
161
|
+
stage.sprites.should include(sprite)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
describe "#animate!" do
|
166
|
+
before do
|
167
|
+
stage.add_sprite(sprite)
|
168
|
+
end
|
169
|
+
|
170
|
+
it "updates its sprites to their next frame" do
|
171
|
+
sprite.should_receive(:animate!)
|
172
|
+
stage.animate!
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'nyan'
|
metadata
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nyan
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- dave@kapoq.com
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-10-07 00:00:00.000000000 +02:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: ansi
|
17
|
+
requirement: &10658100 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *10658100
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: rspec
|
28
|
+
requirement: &10657680 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: *10657680
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: guard-rspec
|
39
|
+
requirement: &10657260 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
type: :development
|
46
|
+
prerelease: false
|
47
|
+
version_requirements: *10657260
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: rake
|
50
|
+
requirement: &10705640 !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ! '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
type: :development
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: *10705640
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: rb-inotify
|
61
|
+
requirement: &10705180 !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ! '>='
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
type: :development
|
68
|
+
prerelease: false
|
69
|
+
version_requirements: *10705180
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: libnotify
|
72
|
+
requirement: &10704760 !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
type: :development
|
79
|
+
prerelease: false
|
80
|
+
version_requirements: *10704760
|
81
|
+
description: ! 'Your favourite aging meme is reheated as an RSpec custom formatter.
|
82
|
+
For entertainment purposes only. WARNING: enterprise-ready'
|
83
|
+
email:
|
84
|
+
- dave@kapoq.com
|
85
|
+
executables:
|
86
|
+
- nyan.rb
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- .gitignore
|
91
|
+
- .rspec
|
92
|
+
- Gemfile
|
93
|
+
- Guardfile
|
94
|
+
- README.md
|
95
|
+
- Rakefile
|
96
|
+
- bin/nyan.rb
|
97
|
+
- lib/nyan.rb
|
98
|
+
- lib/nyan/colour.rb
|
99
|
+
- lib/nyan/flight.rb
|
100
|
+
- lib/nyan/formatter.rb
|
101
|
+
- lib/nyan/shape.rb
|
102
|
+
- lib/nyan/sprite.rb
|
103
|
+
- lib/nyan/sprites/cat_head.rb
|
104
|
+
- lib/nyan/sprites/pop_tart.rb
|
105
|
+
- lib/nyan/sprites/rainbow.rb
|
106
|
+
- lib/nyan/sprites/star.rb
|
107
|
+
- lib/nyan/sprites/tail.rb
|
108
|
+
- lib/nyan/stage.rb
|
109
|
+
- lib/nyan/version.rb
|
110
|
+
- nyan.gemspec
|
111
|
+
- spec/lib/colour_spec.rb
|
112
|
+
- spec/lib/shape_spec.rb
|
113
|
+
- spec/lib/sprite_spec.rb
|
114
|
+
- spec/lib/stage_spec.rb
|
115
|
+
- spec/spec_helper.rb
|
116
|
+
has_rdoc: true
|
117
|
+
homepage: https://github.com/kapoq/nyan_formatter
|
118
|
+
licenses: []
|
119
|
+
post_install_message:
|
120
|
+
rdoc_options: []
|
121
|
+
require_paths:
|
122
|
+
- lib
|
123
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
124
|
+
none: false
|
125
|
+
requirements:
|
126
|
+
- - ! '>='
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0'
|
129
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
130
|
+
none: false
|
131
|
+
requirements:
|
132
|
+
- - ! '>='
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: '0'
|
135
|
+
requirements: []
|
136
|
+
rubyforge_project:
|
137
|
+
rubygems_version: 1.6.2
|
138
|
+
signing_key:
|
139
|
+
specification_version: 3
|
140
|
+
summary: Nyan Cat flies across your terminal while your RSpec specs run!
|
141
|
+
test_files: []
|