rustle 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/lib/rustle/debug_port.rb +18 -0
- data/lib/rustle/exceptions.rb +9 -0
- data/lib/rustle/frame.rb +8 -0
- data/lib/rustle/receiver.rb +25 -26
- data/lib/rustle/strip.rb +7 -2
- data/lib/rustle/version.rb +1 -1
- data/lib/rustle.rb +3 -0
- data/spec/color_spec.rb +28 -39
- data/spec/frame_spec.rb +16 -0
- data/spec/receiver_spec.rb +28 -1
- data/spec/strip_spec.rb +33 -0
- metadata +6 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5471958598d61f4dc25f459bdad141ada82b1bd0
|
4
|
+
data.tar.gz: 9f0f17ec4a82206000b729e697bffd7778848d68
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6744cbf1557218443148fc94c02f3728af062d97320202323d234e2251415a8696fb2369b2ec9d9401519e4cb5250b621a8a982ff153337f8f317847b6e240b7
|
7
|
+
data.tar.gz: 41a86f55fa7681a319da9853a3dcd3c06aa392daeac3cc91dadbb5cada709ae7a298e6c4d90e6dd3e4e5850b6907a45c45229b13aceb2314fc4f33bab1648368
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# Rustle Changelog
|
2
2
|
|
3
|
+
## 0.1.2
|
4
|
+
|
5
|
+
#### New
|
6
|
+
|
7
|
+
* Much more spec coverage.
|
8
|
+
* Invalid data handling
|
9
|
+
* **Debug mode**: to make specs easier, Receiver objects can be set to debug mode, in which no actual data will be sent to the Arduino, and instead will be returned as arrays.
|
10
|
+
|
11
|
+
#### Deprecated
|
12
|
+
|
13
|
+
* The old DSL-style Receiver instantiation syntax. See the documentation for Receiver#initialize because the syntax is now quite different.
|
14
|
+
|
3
15
|
## 0.1.1
|
4
16
|
|
5
17
|
#### New
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Rustle
|
2
|
+
# = DebugPort
|
3
|
+
#
|
4
|
+
# This class's purpose is simply to provide a mock serial port for debugging
|
5
|
+
# purposes. Instead of writing to an actual TTY connection, it simply
|
6
|
+
# deserializes and returns the values passed into it. It's convenient because
|
7
|
+
# it allows one to test without requiring a physical Arduino.
|
8
|
+
class DebugPort
|
9
|
+
# @param [String] string the string of chars to be written to the mock
|
10
|
+
# serial port
|
11
|
+
#
|
12
|
+
# @return [Array<Fixnum>] an array containing the deserialized values found
|
13
|
+
# in +string+
|
14
|
+
def write(string)
|
15
|
+
string.chars.map(&:ord)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/rustle/exceptions.rb
CHANGED
@@ -7,4 +7,13 @@ module Rustle
|
|
7
7
|
|
8
8
|
# Raised when a user provides an invalid hexadecimal color
|
9
9
|
class InvalidHexColorCode < Error; end
|
10
|
+
|
11
|
+
# Raised when a user does not provide a receiver when instantiating a strip
|
12
|
+
class ReceiverNotFound < Error; end
|
13
|
+
|
14
|
+
# Raised when a user does not specify the number of LEDs for a strip
|
15
|
+
class NumLEDsInvalid < Error; end
|
16
|
+
|
17
|
+
# Raised when a user tries to provide data that is not an array of {Color} objects
|
18
|
+
class InvalidLEDArray < Error; end
|
10
19
|
end
|
data/lib/rustle/frame.rb
CHANGED
@@ -28,6 +28,8 @@ module Rustle
|
|
28
28
|
# @param [Array] leds n array of {Color} objects, whose length is the same
|
29
29
|
# as the number of LEDs connected to the strip.
|
30
30
|
def initialize(leds)
|
31
|
+
validate_leds(leds)
|
32
|
+
|
31
33
|
@leds = leds
|
32
34
|
end
|
33
35
|
|
@@ -38,5 +40,11 @@ module Rustle
|
|
38
40
|
def serialize
|
39
41
|
@leds.map(&:serialize).join + 255.chr
|
40
42
|
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def validate_leds(arr)
|
47
|
+
raise InvalidLEDArray unless arr.all? { |l| l.is_a? Color }
|
48
|
+
end
|
41
49
|
end
|
42
50
|
end
|
data/lib/rustle/receiver.rb
CHANGED
@@ -11,10 +11,7 @@ module Rustle
|
|
11
11
|
#
|
12
12
|
# The Receiver class is initialized using a block.
|
13
13
|
#
|
14
|
-
# bedroom_arduino = Rustle::Receiver.new
|
15
|
-
# port_file "/dev/[PORT_FILE]"
|
16
|
-
# num_leds 30
|
17
|
-
# end
|
14
|
+
# bedroom_arduino = Rustle::Receiver.new("/dev/[PORT_FILE]")
|
18
15
|
#
|
19
16
|
# Your port file can be found using the Arduino IDE.
|
20
17
|
class Receiver
|
@@ -23,29 +20,33 @@ module Rustle
|
|
23
20
|
# @return [Strip] the strip associated with the Receiver
|
24
21
|
attr_reader :strip
|
25
22
|
|
26
|
-
# Initializes a new receiver.
|
23
|
+
# Initializes a new receiver.
|
27
24
|
#
|
28
25
|
# @example
|
29
|
-
# kitchen_arduino = Rustle::Receiver.new
|
30
|
-
#
|
31
|
-
# num_leds 60
|
32
|
-
# end
|
26
|
+
# kitchen_arduino = Rustle::Receiver.new("/deb/tty.usbmodem411",
|
27
|
+
# num_leds: 30, baud: 921_600, debug: false)
|
33
28
|
#
|
34
|
-
# @
|
29
|
+
# @param [String] port_file the location of serial port file. It can be
|
35
30
|
# found in the Arduino IDE (or via Ino).
|
36
|
-
# @
|
31
|
+
# @param [Fixnum] baud the serial baud rate (make sure it matches the one in
|
37
32
|
# your sketch)
|
38
|
-
# @
|
33
|
+
# @param [Fixnum] num_leds the total number of LEDs connected to your
|
39
34
|
# receiver. Note that this attribute only affects how the {Strip} object
|
40
35
|
# is instantiated; the number of LEDs is not actually stored in the
|
41
36
|
# Receiver object.
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
37
|
+
# @param [Boolean] debug whether or not to enable debug mode. See
|
38
|
+
# {DebugPort}.
|
39
|
+
def initialize(port_file = nil, baud: 921_600, num_leds: 30, debug: false)
|
40
|
+
@port_file = port_file
|
41
|
+
@baud = baud
|
42
|
+
@debug = debug
|
43
|
+
@strip = Strip.new(self, num_leds)
|
47
44
|
|
48
45
|
init_serialport
|
46
|
+
|
47
|
+
# Sending a blank frame upon initialization seems to fix all timing
|
48
|
+
# constraint problems.
|
49
|
+
@strip.off!
|
49
50
|
end
|
50
51
|
|
51
52
|
# Serializes +frame+ and sends it off to the the serial port. +push_frame+
|
@@ -58,16 +59,14 @@ module Rustle
|
|
58
59
|
|
59
60
|
private
|
60
61
|
|
61
|
-
#
|
62
|
-
def port_file(file); @port_file = file; end
|
63
|
-
def baud(int); @baud = int; end
|
64
|
-
def num_leds(count)
|
65
|
-
@strip = Strip.new(self, count)
|
66
|
-
end
|
67
|
-
|
68
|
-
# Instantiates a new serial port
|
62
|
+
# Instantiates a new port
|
69
63
|
def init_serialport
|
70
|
-
|
64
|
+
if @debug
|
65
|
+
@port = DebugPort.new
|
66
|
+
else
|
67
|
+
raise PortFileNotSpecified if @debug == false
|
68
|
+
@port = SerialPort.new @port_file, @baud, 8, 1, SerialPort::NONE
|
69
|
+
end
|
71
70
|
end
|
72
71
|
end
|
73
72
|
end
|
data/lib/rustle/strip.rb
CHANGED
@@ -3,7 +3,7 @@ require 'active_support/inflector'
|
|
3
3
|
module Rustle
|
4
4
|
# = Strips
|
5
5
|
#
|
6
|
-
# The Strip class' purpose is to respond to requests to change the color of
|
6
|
+
# The Strip class's purpose is to respond to requests to change the color of
|
7
7
|
# the physical strip, and send changes to the {Receiver} when appropriate.
|
8
8
|
# All Strip objects also have a buffer, which is simply an array of {Frame}
|
9
9
|
# objects. Calling any method which advances to the next frame causes the
|
@@ -27,6 +27,9 @@ module Rustle
|
|
27
27
|
@receiver = receiver
|
28
28
|
@num_leds = num_leds
|
29
29
|
@queue = []
|
30
|
+
|
31
|
+
raise ReceiverNotFound unless receiver.is_a? Receiver
|
32
|
+
raise NumLEDsInvalid unless @num_leds && @num_leds > 0
|
30
33
|
end
|
31
34
|
|
32
35
|
# @return [Frame] the next frame in the buffer. If the buffer only has one
|
@@ -56,6 +59,7 @@ module Rustle
|
|
56
59
|
|
57
60
|
# Turns off all LEDs on the strip
|
58
61
|
def off!
|
62
|
+
sleep 0.0025
|
59
63
|
@queue << Frame.new([Color.new(0,0,0)] * @num_leds)
|
60
64
|
next_frame!
|
61
65
|
end
|
@@ -64,6 +68,7 @@ module Rustle
|
|
64
68
|
#
|
65
69
|
# @param [Color] color
|
66
70
|
def to(color)
|
71
|
+
sleep 0.0025
|
67
72
|
@queue << Frame.new([color] * @num_leds)
|
68
73
|
next_frame!
|
69
74
|
end
|
@@ -89,7 +94,7 @@ module Rustle
|
|
89
94
|
# :fade_to => FadeToTransition
|
90
95
|
klass = "#{klass.to_s.camelize}Transition".constantize
|
91
96
|
|
92
|
-
klass.new(self, duration, opts)
|
97
|
+
klass.new(self, duration, opts)
|
93
98
|
end
|
94
99
|
end
|
95
100
|
end
|
data/lib/rustle/version.rb
CHANGED
data/lib/rustle.rb
CHANGED
@@ -4,10 +4,13 @@ require "rustle/receiver"
|
|
4
4
|
require "rustle/strip"
|
5
5
|
require "rustle/color"
|
6
6
|
require "rustle/frame"
|
7
|
+
|
7
8
|
require "rustle/transition"
|
8
9
|
require "rustle/transitions/wipe_to_transition"
|
9
10
|
require "rustle/transitions/fade_to_transition"
|
11
|
+
|
10
12
|
require "rustle/exceptions"
|
13
|
+
require "rustle/debug_port"
|
11
14
|
|
12
15
|
module Rustle
|
13
16
|
FRAME_RATE = 60
|
data/spec/color_spec.rb
CHANGED
@@ -8,49 +8,38 @@ describe Rustle::Color do
|
|
8
8
|
let(:color_with_invalid_params) { Rustle::Color.new(-100,1000,0) }
|
9
9
|
|
10
10
|
it "corrects negative rgb values to zero" do
|
11
|
-
(color_with_invalid_params.r).
|
11
|
+
expect(color_with_invalid_params.r).to eq(0)
|
12
12
|
end
|
13
13
|
|
14
14
|
it "corrects very large rgb values to 255" do
|
15
|
-
(color_with_invalid_params.g).
|
15
|
+
expect(color_with_invalid_params.g).to eq(255)
|
16
16
|
end
|
17
17
|
|
18
18
|
it "makes no changes to rgb values between 0 and 255" do
|
19
19
|
color1 = Rustle::Color.new(0,0,0)
|
20
|
-
(color1.r).
|
21
|
-
(color1.g).
|
22
|
-
(color1.b).
|
20
|
+
expect(color1.r).to eq(0)
|
21
|
+
expect(color1.g).to eq(0)
|
22
|
+
expect(color1.b).to eq(0)
|
23
23
|
|
24
24
|
color2 = Rustle::Color.new(255,255,255)
|
25
|
-
(color2.r).
|
26
|
-
(color2.g).
|
27
|
-
(color2.b).
|
25
|
+
expect(color2.r).to eq(255)
|
26
|
+
expect(color2.g).to eq(255)
|
27
|
+
expect(color2.b).to eq(255)
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
31
|
describe "#to_a" do
|
32
32
|
it "returns an array" do
|
33
|
-
(color.to_a).
|
33
|
+
expect(color.to_a).to be_a(Array)
|
34
34
|
end
|
35
35
|
|
36
36
|
it "the array has the correct [r,g,b] values" do
|
37
|
-
(color.to_a).
|
37
|
+
expect(color.to_a).to eq([128,128,128])
|
38
38
|
end
|
39
39
|
|
40
40
|
it "rounds decimal values down to the nearest whole number" do
|
41
41
|
fractional_rgbs = Rustle::Color.rgb(0.5,10.7,99.9)
|
42
|
-
(fractional_rgbs.to_a).
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
describe "#to_s" do
|
47
|
-
it "returns a string with information about the color" do
|
48
|
-
(color.to_s).should eq("rgb(128, 128, 128)")
|
49
|
-
end
|
50
|
-
|
51
|
-
it "pads strings so that even small rgb values align properly" do
|
52
|
-
other_color = Rustle::Color.rgb(0,1,2)
|
53
|
-
(other_color.to_s).should eq("rgb( 0, 1, 2)")
|
42
|
+
expect(fractional_rgbs.to_a).to eq([0, 10, 99])
|
54
43
|
end
|
55
44
|
end
|
56
45
|
|
@@ -60,11 +49,11 @@ describe Rustle::Color do
|
|
60
49
|
let(:colorB) { Rustle::Color.rgb(0, 0, 0) }
|
61
50
|
|
62
51
|
it "returns true if the reciever and parameter objects hold equivalent rgb values" do
|
63
|
-
(colorA.eql?(another_colorA)).
|
52
|
+
expect(colorA.eql?(another_colorA)).to be_true
|
64
53
|
end
|
65
54
|
|
66
55
|
it "returns false if the reciever and parameter objects differ in rgb values" do
|
67
|
-
(colorA.eql?(colorB)).
|
56
|
+
expect(colorA.eql?(colorB)).to be_false
|
68
57
|
end
|
69
58
|
end
|
70
59
|
|
@@ -75,11 +64,11 @@ describe Rustle::Color do
|
|
75
64
|
let (:badass) { Rustle::Color.hex "BADA55" }
|
76
65
|
|
77
66
|
it "creates a color object" do
|
78
|
-
(badass).
|
67
|
+
expect(badass).to be_a(Rustle::Color)
|
79
68
|
end
|
80
69
|
|
81
70
|
it "has the proper rgb values" do
|
82
|
-
(badass).
|
71
|
+
expect(badass).to eql(badass_rgb)
|
83
72
|
end
|
84
73
|
end
|
85
74
|
|
@@ -87,11 +76,11 @@ describe Rustle::Color do
|
|
87
76
|
let(:badass) { Rustle::Color.hex "#BADA55" }
|
88
77
|
|
89
78
|
it "creates a color object" do
|
90
|
-
(badass).
|
79
|
+
expect(badass).to be_a(Rustle::Color)
|
91
80
|
end
|
92
81
|
|
93
82
|
it "has the right rgb values" do
|
94
|
-
(badass).
|
83
|
+
expect(badass).to eql(badass_rgb)
|
95
84
|
end
|
96
85
|
end
|
97
86
|
|
@@ -100,18 +89,18 @@ describe Rustle::Color do
|
|
100
89
|
let(:bad_rgb) { Rustle::Color.rgb 187, 170, 221 }
|
101
90
|
|
102
91
|
it "creates a color object" do
|
103
|
-
(bad_hex).
|
92
|
+
expect(bad_hex).to be_a(Rustle::Color)
|
104
93
|
end
|
105
94
|
|
106
95
|
it "should have the correct rgb values" do
|
107
|
-
(bad_hex).
|
96
|
+
expect(bad_hex).to eql(bad_rgb)
|
108
97
|
end
|
109
98
|
end
|
110
99
|
|
111
100
|
it "is case insensitive" do
|
112
101
|
first_badass = Rustle::Color.hex "#BADa55"
|
113
102
|
second_badass = Rustle::Color.hex "#badA55"
|
114
|
-
(first_badass).
|
103
|
+
expect(first_badass).to eql(second_badass)
|
115
104
|
end
|
116
105
|
|
117
106
|
it "raises an error when given an invalid color code string" do
|
@@ -127,14 +116,14 @@ describe Rustle::Color do
|
|
127
116
|
# HSV: 260 (260), saturation: 23 (23.0769), value: 87 (86.6667)
|
128
117
|
|
129
118
|
it "produces a color object" do
|
130
|
-
hsb.
|
119
|
+
expect(hsb).to be_a(Rustle::Color)
|
131
120
|
end
|
132
121
|
|
133
122
|
it "has the correct rgb properties" do
|
134
123
|
# Use be_within to give some allowance for rounting errors
|
135
|
-
(hsb.r).
|
136
|
-
(hsb.g).
|
137
|
-
(hsb.b).
|
124
|
+
expect(hsb.r).to be_within(3).of(rgb.r)
|
125
|
+
expect(hsb.g).to be_within(3).of(rgb.g)
|
126
|
+
expect(hsb.b).to be_within(3).of(rgb.b)
|
138
127
|
end
|
139
128
|
end
|
140
129
|
|
@@ -142,14 +131,14 @@ describe Rustle::Color do
|
|
142
131
|
let(:hsb) { Rustle::Color.hsb 180, 0.5, 0.8 }
|
143
132
|
|
144
133
|
it "returns an array of [h,s,v] coordinates" do
|
145
|
-
color.to_hsb.
|
134
|
+
expect(color.to_hsb).to be_a(Array)
|
146
135
|
end
|
147
136
|
|
148
137
|
it "should have the (approximate) [h,s,v] coordinates" do
|
149
138
|
hsb_arr = hsb.to_hsb
|
150
|
-
hsb_arr[0].
|
151
|
-
hsb_arr[1].
|
152
|
-
hsb_arr[2].
|
139
|
+
expect(hsb_arr[0]).to be_within(1).of(180)
|
140
|
+
expect(hsb_arr[1]).to be_within(0.1).of(0.5)
|
141
|
+
expect(hsb_arr[2]).to be_within(0.1).of(0.8)
|
153
142
|
end
|
154
143
|
|
155
144
|
end
|
data/spec/frame_spec.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Rustle::Frame do
|
4
|
+
describe "initialization" do
|
5
|
+
it "should require a valid array of LEDs" do
|
6
|
+
valid = [Rustle::Color.rgb(255, 0, 0)] * 5
|
7
|
+
invalid = ["poop"] * 5
|
8
|
+
|
9
|
+
expect { Rustle::Frame.new(invalid) }
|
10
|
+
.to raise_error(Rustle::InvalidLEDArray)
|
11
|
+
|
12
|
+
expect { Rustle::Frame.new(valid) }
|
13
|
+
.not_to raise_error
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/spec/receiver_spec.rb
CHANGED
@@ -1,5 +1,32 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Rustle::Receiver do
|
4
|
-
|
4
|
+
describe "#initialize" do
|
5
|
+
let(:receiver) do
|
6
|
+
Rustle::Receiver.new(nil, num_leds: 30, debug: true)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should intantiate a Strip with the appropriate number of LEDs" do
|
10
|
+
expect(receiver.strip).to be_a(Rustle::Strip)
|
11
|
+
expect(receiver.strip.num_leds).to eq(30)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should only require a portfile when not in debug mode" do
|
15
|
+
expect { Rustle::Receiver.new(nil, debug: false) }
|
16
|
+
.to raise_error(Rustle::PortFileNotSpecified)
|
17
|
+
expect { Rustle::Receiver.new(nil, debug: true) }
|
18
|
+
.not_to raise_error
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#push_frame" do
|
23
|
+
let(:receiver) do
|
24
|
+
Rustle::Receiver.new(nil, num_leds: 30, debug: true)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should send a frame to the port" do
|
28
|
+
frame = Rustle::Frame.new([Rustle::Color.new(0,0,0)] * 30)
|
29
|
+
expect(receiver.push_frame(frame)).to have(91).items
|
30
|
+
end
|
31
|
+
end
|
5
32
|
end
|
data/spec/strip_spec.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Rustle::Strip do
|
4
|
+
context "when initializing" do
|
5
|
+
it "should require a receiver" do
|
6
|
+
expect { Rustle::Strip.new(nil, 30) }.to raise_error(Rustle::ReceiverNotFound)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should require an LED count" do
|
10
|
+
receiver = Rustle::Receiver.new(nil, debug: true)
|
11
|
+
expect { Rustle::Strip.new(receiver, nil) }.to raise_error(Rustle::NumLEDsInvalid)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "queue" do
|
16
|
+
let(:strip) { Rustle::Receiver.new(nil, num_leds: 5, debug: true).strip }
|
17
|
+
|
18
|
+
it "should be initialized with a black frame" do
|
19
|
+
expect(strip.current_frame).to_not be_nil
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should be initialized with a black frame" do
|
23
|
+
frame = Rustle::Frame.new [Rustle::Color.new(255, 0, 0)] * 5
|
24
|
+
|
25
|
+
strip.queue_frames [frame]
|
26
|
+
expect(strip.next_frame).to_not be_nil
|
27
|
+
|
28
|
+
# After advancing to the next frame, there shouldn't be a next_frame
|
29
|
+
strip.next_frame!
|
30
|
+
expect(strip.next_frame).to eq(strip.current_frame)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rustle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Hamon
|
@@ -117,6 +117,7 @@ files:
|
|
117
117
|
- Rakefile
|
118
118
|
- lib/rustle.rb
|
119
119
|
- lib/rustle/color.rb
|
120
|
+
- lib/rustle/debug_port.rb
|
120
121
|
- lib/rustle/exceptions.rb
|
121
122
|
- lib/rustle/frame.rb
|
122
123
|
- lib/rustle/receiver.rb
|
@@ -129,8 +130,10 @@ files:
|
|
129
130
|
- rustle_logo.png
|
130
131
|
- sketches/basic.ino
|
131
132
|
- spec/color_spec.rb
|
133
|
+
- spec/frame_spec.rb
|
132
134
|
- spec/receiver_spec.rb
|
133
135
|
- spec/spec_helper.rb
|
136
|
+
- spec/strip_spec.rb
|
134
137
|
homepage: ''
|
135
138
|
licenses:
|
136
139
|
- MIT
|
@@ -158,6 +161,8 @@ specification_version: 4
|
|
158
161
|
summary: Control an individually-addressable RGB LED strip in Ruby.
|
159
162
|
test_files:
|
160
163
|
- spec/color_spec.rb
|
164
|
+
- spec/frame_spec.rb
|
161
165
|
- spec/receiver_spec.rb
|
162
166
|
- spec/spec_helper.rb
|
167
|
+
- spec/strip_spec.rb
|
163
168
|
has_rdoc:
|