Skip to content

Commit 5c84039

Browse files
committed
Serialize and deserialize gradients to primitives
1 parent baab4d3 commit 5c84039

File tree

4 files changed

+108
-5
lines changed

4 files changed

+108
-5
lines changed

lib/gradient/map.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ class Map
33

44
attr_reader :points, :locations
55

6+
class << self
7+
def deserialize(points=[])
8+
new(points.map { |point| Gradient::Point.deserialize(*point) })
9+
end
10+
end
11+
612
def initialize(*points)
713
@points = points.flatten.sort
814
@locations = @points.map { |point| point.location }
@@ -17,5 +23,13 @@ def to_css(**args)
1723
@css_printer.css(**args)
1824
end
1925

26+
def serialize
27+
@points.map(&:serialize)
28+
end
29+
30+
def as_json(json={})
31+
serialize
32+
end
33+
2034
end
2135
end

lib/gradient/point.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,20 @@ class Point
33

44
attr_reader :location, :color, :opacity
55

6+
class << self
7+
def deserialize(location, color_type, color_values, opacity)
8+
self.new(location, color_from(color_type, color_values), opacity)
9+
end
10+
11+
private def color_from(color_type, color_values)
12+
case color_type
13+
when "rgb" then Color::RGB.new(*color_values)
14+
else
15+
raise NotImplementedError.new("#{string} is not a valid color type")
16+
end
17+
end
18+
end
19+
620
def initialize(location, color, opacity)
721
@location, @color, @opacity = location, color, opacity
822
end
@@ -15,5 +29,20 @@ def <=>(other)
1529
self.location <=> other.location
1630
end
1731

32+
def serialize
33+
[location, "rgb", [color.red.round, color.green.round, color.blue.round], opacity]
34+
end
35+
36+
def as_json(json={})
37+
serialize
38+
end
39+
40+
def ==(other)
41+
unless other.kind_of?(Gradient::Point)
42+
raise ArgumentError.new("cannot compare Point with #{ other.class } using `=='")
43+
end
44+
location == other.location && color == other.color && opacity == other.opacity
45+
end
46+
1847
end
1948
end

spec/gradient/map_spec.rb

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
RSpec.describe Gradient::Map do
22

3-
describe "#initialize" do
3+
let(:left_blue) { Gradient::Point.new(0, Color::RGB.new(0, 0, 255), 1) }
4+
let(:middle_green) { Gradient::Point.new(0.5, Color::RGB.new(0, 255, 0), 1) }
5+
let(:right_red) { Gradient::Point.new(1, Color::RGB.new(255, 0, 0), 1) }
46

5-
let(:left_blue) { Gradient::Point.new(0, Color::RGB.new(0, 0, 255), 1) }
6-
let(:middle_green) { Gradient::Point.new(0.5, Color::RGB.new(0, 255, 0), 1) }
7-
let(:right_red) { Gradient::Point.new(1, Color::RGB.new(255, 0, 0), 1) }
7+
subject(:map) { Gradient::Map.new(middle_green, left_blue, right_red) }
88

9-
let(:map) { Gradient::Map.new(middle_green, left_blue, right_red) }
9+
describe "#initialize" do
1010

1111
it "sorts the points" do
1212
expect(map.points[0]).to eq left_blue
@@ -20,4 +20,40 @@
2020

2121
end
2222

23+
describe ".deserialize" do
24+
it "returns a point with the right attributes" do
25+
deserialized_map = described_class.deserialize([
26+
[0, "rgb", [0, 0, 255], 1],
27+
[0.5, "rgb", [0, 255, 0], 1],
28+
[1, "rgb", [255, 0, 0], 1]
29+
])
30+
expect(deserialized_map.points[0].opacity).to eq 1
31+
expect(deserialized_map.points[0].location).to eq 0
32+
expect(deserialized_map.points[1].opacity).to eq 1
33+
expect(deserialized_map.points[1].location).to eq 0.5
34+
expect(deserialized_map.points[2].opacity).to eq 1
35+
expect(deserialized_map.points[2].location).to eq 1
36+
end
37+
end
38+
39+
describe "#serialize" do
40+
it "returns an array with the points as nested hashes" do
41+
expect(map.serialize).to eq([
42+
[0, "rgb", [0, 0, 255], 1],
43+
[0.5, "rgb", [0, 255, 0], 1],
44+
[1, "rgb", [255, 0, 0], 1]
45+
])
46+
end
47+
end
48+
49+
describe "#as_json" do
50+
it "returns an array with the points as nested hashes" do
51+
expect(map.as_json({})).to eq([
52+
[0, "rgb", [0, 0, 255], 1],
53+
[0.5, "rgb", [0, 255, 0], 1],
54+
[1, "rgb", [255, 0, 0], 1]
55+
])
56+
end
57+
end
58+
2359
end

spec/gradient/point_spec.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
RSpec.describe Gradient::Point do
2+
3+
describe ".deserialize" do
4+
it "returns a point based on the provided array of values" do
5+
point = Gradient::Point.deserialize(0.5, "rgb", [0, 255, 0], 1)
6+
expect(point).to eq Gradient::Point.new(0.5, Color::RGB.new(0, 255, 0), 1)
7+
end
8+
end
9+
10+
describe "#serialize" do
11+
it "returns an array with the color values" do
12+
point = Gradient::Point.new(0.5, Color::RGB.new(0, 255, 0), 1)
13+
expect(point.serialize).to eq([0.5, "rgb", [0, 255, 0], 1])
14+
end
15+
end
16+
17+
describe "#as_json" do
18+
it "returns an array with the color values" do
19+
point = Gradient::Point.new(0.5, Color::RGB.new(0, 255, 0), 1)
20+
expect(point.as_json({})).to eq([0.5, "rgb", [0, 255, 0], 1])
21+
end
22+
end
23+
24+
end

0 commit comments

Comments
 (0)