diff options
| -rw-r--r-- | lib/ruby2d/circle.rb | 2 | ||||
| -rw-r--r-- | lib/ruby2d/line.rb | 6 | ||||
| -rw-r--r-- | lib/ruby2d/music.rb | 4 | ||||
| -rw-r--r-- | lib/ruby2d/quad.rb | 2 | ||||
| -rw-r--r-- | lib/ruby2d/renderable.rb | 2 | ||||
| -rw-r--r-- | lib/ruby2d/sprite.rb | 1 | ||||
| -rw-r--r-- | lib/ruby2d/text.rb | 4 | ||||
| -rw-r--r-- | lib/ruby2d/triangle.rb | 7 | ||||
| -rw-r--r-- | test/circle_spec.rb | 37 | ||||
| -rw-r--r-- | test/image_spec.rb | 53 | ||||
| -rw-r--r-- | test/line_spec.rb | 92 | ||||
| -rw-r--r-- | test/music_spec.rb | 19 | ||||
| -rw-r--r-- | test/quad_spec.rb | 112 | ||||
| -rw-r--r-- | test/rectangle_spec.rb | 92 | ||||
| -rw-r--r-- | test/renderable_spec.rb | 177 | ||||
| -rw-r--r-- | test/sound_spec.rb | 5 | ||||
| -rw-r--r-- | test/sprite_spec.rb | 51 | ||||
| -rw-r--r-- | test/square_spec.rb | 91 | ||||
| -rw-r--r-- | test/text_spec.rb | 104 | ||||
| -rw-r--r-- | test/triangle_spec.rb | 47 |
20 files changed, 761 insertions, 147 deletions
diff --git a/lib/ruby2d/circle.rb b/lib/ruby2d/circle.rb index d232d68..7951db7 100644 --- a/lib/ruby2d/circle.rb +++ b/lib/ruby2d/circle.rb @@ -4,7 +4,7 @@ module Ruby2D class Circle include Renderable - attr_accessor :radius, :sectors + attr_accessor :x, :y, :radius, :sectors def initialize(opts = {}) @x = opts[:x] || 25 diff --git a/lib/ruby2d/line.rb b/lib/ruby2d/line.rb index fa3535d..ebbb0d9 100644 --- a/lib/ruby2d/line.rb +++ b/lib/ruby2d/line.rb @@ -4,15 +4,15 @@ module Ruby2D class Line include Renderable - attr_accessor :x1, :x2, :y1, :y2 + attr_accessor :x1, :x2, :y1, :y2, :width def initialize(opts = {}) @x1 = opts[:x1] || 0 @y1 = opts[:y1] || 0 @x2 = opts[:x2] || 100 @y2 = opts[:y2] || 100 - @width = opts[:width] || 2 @z = opts[:z] || 0 + @width = opts[:width] || 2 self.color = opts[:color] || 'white' self.opacity = opts[:opacity] if opts[:opacity] add @@ -53,7 +53,7 @@ module Ruby2D @c3 = c[2] @c4 = c[3] else - raise ArgumentError, "Lines require 4 colors, one for each vertex. #{c.length} were given." + raise ArgumentError, "`#{self.class}` requires 4 colors, one for each vertex. #{c.length} were given." end else @c1 = c diff --git a/lib/ruby2d/music.rb b/lib/ruby2d/music.rb index 46aab0a..3c9406f 100644 --- a/lib/ruby2d/music.rb +++ b/lib/ruby2d/music.rb @@ -6,12 +6,12 @@ module Ruby2D attr_reader :path attr_accessor :loop, :data - def initialize(path) + def initialize(path, opts = {}) unless File.exist? path raise Error, "Cannot find audio file `#{path}`" end @path = path - @loop = false + @loop = opts[:loop] || false unless ext_init(@path) raise Error, "Music `#{@path}` cannot be created" end diff --git a/lib/ruby2d/quad.rb b/lib/ruby2d/quad.rb index 6315ae7..08cee84 100644 --- a/lib/ruby2d/quad.rb +++ b/lib/ruby2d/quad.rb @@ -62,7 +62,7 @@ module Ruby2D @c3 = c[2] @c4 = c[3] else - raise ArgumentError, "Quads require 4 colors, one for each vertex. #{c.length} were given." + raise ArgumentError, "`#{self.class}` requires 4 colors, one for each vertex. #{c.length} were given." end else @c1 = c diff --git a/lib/ruby2d/renderable.rb b/lib/ruby2d/renderable.rb index 2861c70..d6e7ae8 100644 --- a/lib/ruby2d/renderable.rb +++ b/lib/ruby2d/renderable.rb @@ -49,7 +49,7 @@ module Ruby2D # Add a contains method stub def contains?(x, y) - x > @x && x < (@x + @width) && y > @y && y < (@y + @height) + x >= @x && x <= (@x + @width) && y >= @y && y <= (@y + @height) end end diff --git a/lib/ruby2d/sprite.rb b/lib/ruby2d/sprite.rb index 8405e5f..ca64e0b 100644 --- a/lib/ruby2d/sprite.rb +++ b/lib/ruby2d/sprite.rb @@ -4,6 +4,7 @@ module Ruby2D class Sprite include Renderable + attr_reader :path attr_accessor :rotate, :loop, :clip_x, :clip_y, :clip_width, :clip_height, :data def initialize(path, opts = {}) diff --git a/lib/ruby2d/text.rb b/lib/ruby2d/text.rb index d62bc0b..10fdabe 100644 --- a/lib/ruby2d/text.rb +++ b/lib/ruby2d/text.rb @@ -4,8 +4,8 @@ module Ruby2D class Text include Renderable - attr_reader :text, :size, :font - attr_accessor :x, :y, :rotate, :data + attr_reader :text, :font + attr_accessor :x, :y, :size, :rotate, :data def initialize(text, opts = {}) @x = opts[:x] || 0 diff --git a/lib/ruby2d/triangle.rb b/lib/ruby2d/triangle.rb index a4d6d27..63c570b 100644 --- a/lib/ruby2d/triangle.rb +++ b/lib/ruby2d/triangle.rb @@ -26,9 +26,8 @@ module Ruby2D update_color(@color) end - # Point is inside a triangle if - # the area of 3 triangles, constructed from triangle sides and that point - # is equal to the area of triangle. + # A point is inside a triangle if the area of 3 triangles, constructed from + # triangle sides and the given point, is equal to the area of triangle. def contains?(x, y) self_area = triangle_area(@x1, @y1, @x2, @y2, @x3, @y3) questioned_area = @@ -52,7 +51,7 @@ module Ruby2D @c2 = c[1] @c3 = c[2] else - raise ArgumentError, "Triangles require 3 colors, one for each vertex. #{c.length} were given." + raise ArgumentError, "`#{self.class}` requires 3 colors, one for each vertex. #{c.length} were given." end else @c1 = c diff --git a/test/circle_spec.rb b/test/circle_spec.rb index 0c88b7f..5b06d9f 100644 --- a/test/circle_spec.rb +++ b/test/circle_spec.rb @@ -11,6 +11,43 @@ RSpec.describe Ruby2D::Circle do expect(circle.color.b).to eq(1) expect(circle.color.a).to eq(1) end + + it "creates a circle with options" do + circle = Circle.new( + x: 10, y: 20, z: 30, + radius: 40, sectors: 50, + color: 'gray', opacity: 0.5 + ) + + expect(circle.x).to eq(10) + expect(circle.y).to eq(20) + expect(circle.z).to eq(30) + expect(circle.radius).to eq(40) + expect(circle.sectors).to eq(50) + expect(circle.color.r).to eq(2/3.0) + expect(circle.opacity).to eq(0.5) + end + end + + describe "attributes" do + it "can be set and read" do + circle = Circle.new + circle.x = 10 + circle.y = 20 + circle.z = 30 + circle.radius = 40 + circle.sectors = 50 + circle.color = 'gray' + circle.opacity = 0.5 + + expect(circle.x).to eq(10) + expect(circle.y).to eq(20) + expect(circle.z).to eq(30) + expect(circle.radius).to eq(40) + expect(circle.sectors).to eq(50) + expect(circle.color.r).to eq(2/3.0) + expect(circle.opacity).to eq(0.5) + end end end diff --git a/test/image_spec.rb b/test/image_spec.rb index 7d4f96d..3abfd04 100644 --- a/test/image_spec.rb +++ b/test/image_spec.rb @@ -4,7 +4,58 @@ RSpec.describe Ruby2D::Image do describe "#new" do it "raises exception if image file doesn't exist" do - expect { Image.new("bad_image.png") }.to raise_error(Ruby2D::Error) + expect { Image.new('bad_image.png') }.to raise_error(Ruby2D::Error) + end + + it "creates an image with a white filter by default" do + img = Image.new('test/media/colors.png') + expect(img.color).to be_a(Ruby2D::Color) + expect(img.color.r).to eq(1) + expect(img.color.g).to eq(1) + expect(img.color.b).to eq(1) + expect(img.color.a).to eq(1) + end + + it "creates an image with options" do + img = Image.new( + 'test/media/colors.png', + x: 10, y: 20, z: 30, + width: 40, height: 50, rotate: 60, + color: 'gray', opacity: 0.5 + ) + + expect(img.path).to eq('test/media/colors.png') + expect(img.x).to eq(10) + expect(img.y).to eq(20) + expect(img.z).to eq(30) + expect(img.width).to eq(40) + expect(img.height).to eq(50) + expect(img.rotate).to eq(60) + expect(img.color.r).to eq(2/3.0) + expect(img.opacity).to eq(0.5) + end + end + + describe "attributes" do + it "can be set and read" do + img = Image.new('test/media/colors.png') + img.x = 10 + img.y = 20 + img.z = 30 + img.width = 40 + img.height = 50 + img.rotate = 60 + img.color = 'gray' + img.opacity = 0.5 + + expect(img.x).to eq(10) + expect(img.y).to eq(20) + expect(img.z).to eq(30) + expect(img.width).to eq(40) + expect(img.height).to eq(50) + expect(img.rotate).to eq(60) + expect(img.color.r).to eq(2/3.0) + expect(img.opacity).to eq(0.5) end end diff --git a/test/line_spec.rb b/test/line_spec.rb index 2129073..5fd6ae8 100644 --- a/test/line_spec.rb +++ b/test/line_spec.rb @@ -2,6 +2,98 @@ require 'ruby2d' RSpec.describe Ruby2D::Line do + describe "#new" do + it "creates a white line by default" do + line = Line.new + expect(line.color).to be_a(Ruby2D::Color) + expect(line.color.r).to eq(1) + expect(line.color.g).to eq(1) + expect(line.color.b).to eq(1) + expect(line.color.a).to eq(1) + end + + it "creates a line with options" do + line = Line.new( + x1: 10, y1: 20, x2: 30, y2: 40, z: 50, width: 60, + color: 'gray', opacity: 0.5 + ) + + expect(line.x1).to eq(10) + expect(line.y1).to eq(20) + expect(line.x2).to eq(30) + expect(line.y2).to eq(40) + expect(line.z).to eq(50) + expect(line.width).to eq(60) + expect(line.length).to be_within(0.0001).of(28.2843) + expect(line.color.r).to eq(2/3.0) + expect(line.opacity).to eq(0.5) + end + + it "creates a new line with one color via string" do + line = Line.new(color: 'red') + expect(line.color).to be_a(Ruby2D::Color) + end + + it "creates a new line with one color via array of numbers" do + line = Quad.new(color: [0.1, 0.3, 0.5, 0.7]) + expect(line.color).to be_a(Ruby2D::Color) + end + + it "creates a new line with 4 colors via array of 4 strings" do + line = Line.new(color: ['red', 'green', 'blue', 'black']) + expect(line.color).to be_a(Ruby2D::Color::Set) + end + + it "creates a new line with 4 colors via array of 4 arrays of arrays of numbers" do + line = Line.new( + color: [ + [0.1, 0.3, 0.5, 0.7], + [0.2, 0.4, 0.6, 0.8], + [0.3, 0.5, 0.7, 0.9], + [0.4, 0.6, 0.8, 1.0] + ] + ) + expect(line.color).to be_a(Ruby2D::Color::Set) + end + + it "throws an error when array of 3 strings is passed" do + expect do + Line.new(color: ['red', 'green', 'blue']) + end.to raise_error("`Ruby2D::Line` requires 4 colors, one for each vertex. 3 were given.") + end + + it "throws an error when array of 5 strings is passed" do + expect do + Line.new(color: ['red', 'green', 'blue', 'black', 'fuchsia']) + end.to raise_error("`Ruby2D::Line` requires 4 colors, one for each vertex. 5 were given.") + end + end + + describe "attributes" do + it "can be set and read" do + line = Line.new + line.x1 = 10 + line.y1 = 20 + line.x2 = 30 + line.y2 = 40 + line.z = 50 + line.width = 60 + line.color = 'gray' + line.opacity = 0.5 + + expect(line.x1).to eq(10) + expect(line.y1).to eq(20) + expect(line.x2).to eq(30) + expect(line.y2).to eq(40) + expect(line.z).to eq(50) + expect(line.width).to eq(60) + expect(line.length).to be_within(0.0001).of(28.2843) + expect(line.color.r).to eq(2/3.0) + expect(line.opacity).to eq(0.5) + end + end + + # TODO: This test should be more precise, like `Renderable#contains?` describe "#contains?" do line = Line.new(x1: 0, y1: 0, x2: 100, y2: 100) diff --git a/test/music_spec.rb b/test/music_spec.rb index 09b6f1c..0e89b8b 100644 --- a/test/music_spec.rb +++ b/test/music_spec.rb @@ -4,17 +4,28 @@ RSpec.describe Ruby2D::Music do describe "#new" do it "raises exception if audio file doesn't exist" do - expect { Music.new("bad_music.mp3") }.to raise_error(Ruby2D::Error) + expect { Music.new('bad_music.mp3') }.to raise_error(Ruby2D::Error) end - it "creates new music" do - Music.new("test/media/music.mp3") + it "creates music with options" do + mus = Music.new('test/media/music.mp3', loop: true) + expect(mus.path).to eq('test/media/music.mp3') + expect(mus.loop).to be true + end + end + + describe "attributes" do + it "can be set and read" do + mus = Music.new('test/media/music.mp3') + expect(mus.loop).to be false + mus.loop = true + expect(mus.loop).to be true end end describe "#volume" do it "sets the volume on music instances" do - mus = Music.new("test/media/music.mp3") + mus = Music.new('test/media/music.mp3') expect(mus.volume).to eq(100) mus.volume = 68 expect(mus.volume).to eq(68) diff --git a/test/quad_spec.rb b/test/quad_spec.rb index 8cace25..b3b862a 100644 --- a/test/quad_spec.rb +++ b/test/quad_spec.rb @@ -3,7 +3,7 @@ require 'ruby2d' RSpec.describe Ruby2D::Quad do describe "#new" do - it "creates a quad with white color by default" do + it "creates a white quad by default" do quad = Quad.new expect(quad.color).to be_a(Ruby2D::Color) expect(quad.color.r).to eq(1) @@ -12,12 +12,35 @@ RSpec.describe Ruby2D::Quad do expect(quad.color.a).to eq(1) end + it "creates a quad with options" do + quad = Quad.new( + x1: 10, y1: 20, + x2: 30, y2: 40, + x3: 50, y3: 60, + x4: 70, y4: 80, + z: 90, + color: 'gray', opacity: 0.5 + ) + + expect(quad.x1).to eq(10) + expect(quad.y1).to eq(20) + expect(quad.x2).to eq(30) + expect(quad.y2).to eq(40) + expect(quad.x3).to eq(50) + expect(quad.y3).to eq(60) + expect(quad.x4).to eq(70) + expect(quad.y4).to eq(80) + expect(quad.z).to eq(90) + expect(quad.color.r).to eq(2/3.0) + expect(quad.opacity).to eq(0.5) + end + it "creates a new quad with one color via string" do quad = Quad.new(color: 'red') expect(quad.color).to be_a(Ruby2D::Color) end - it "creates a new triangle with one color via array of numbers" do + it "creates a new quad with one color via array of numbers" do quad = Quad.new(color: [0.1, 0.3, 0.5, 0.7]) expect(quad.color).to be_a(Ruby2D::Color) end @@ -42,32 +65,97 @@ RSpec.describe Ruby2D::Quad do it "throws an error when array of 3 strings is passed" do expect do Quad.new(color: ['red', 'green', 'blue']) - end.to raise_error("Quads require 4 colors, one for each vertex. 3 were given.") + end.to raise_error("`Ruby2D::Quad` requires 4 colors, one for each vertex. 3 were given.") end it "throws an error when array of 5 strings is passed" do expect do Quad.new(color: ['red', 'green', 'blue', 'black', 'fuchsia']) - end.to raise_error("Quads require 4 colors, one for each vertex. 5 were given.") + end.to raise_error("`Ruby2D::Quad` requires 4 colors, one for each vertex. 5 were given.") end end + describe "attributes" do + it "can be set and read" do + quad = Quad.new + quad.x1 = 10 + quad.y1 = 20 + quad.x2 = 30 + quad.y2 = 40 + quad.x3 = 50 + quad.y3 = 60 + quad.x4 = 70 + quad.y4 = 80 + quad.z = 90 + quad.color = 'gray' + quad.opacity = 0.5 + + expect(quad.x1).to eq(10) + expect(quad.y1).to eq(20) + expect(quad.x2).to eq(30) + expect(quad.y2).to eq(40) + expect(quad.x3).to eq(50) + expect(quad.y3).to eq(60) + expect(quad.x4).to eq(70) + expect(quad.y4).to eq(80) + expect(quad.z).to eq(90) + expect(quad.color.r).to eq(2/3.0) + expect(quad.opacity).to eq(0.5) + end + end + + # Quads define their own `contains?` method describe "#contains?" do quad = Quad.new( - x1: -25, y1: 0, - x2: 0, y2: -25, - x3: 25, y3: 0, - x4: 0, y4: 25 + x1: 1, y1: 1, + x2: 3, y2: 1, + x3: 3, y3: 3, + x4: 1, y4: 3 ) + # Grid looks like this, 2x2 quad at point (1, 1): + # + # 0 1 2 3 4 + # 0 +--+--+--+--+ + # | | | | | + # 1 +--+--+--+--+ + # | |XX|XX| | + # 2 +--+--+--+--+ + # | |XX|XX| | + # 3 +--+--+--+--+ + # | | | | | + # 4 +--+--+--+--+ + it "returns true if point is inside the quad" do - expect(quad.contains?(0 , 0)).to be true - expect(quad.contains?(25, 0)).to be true + expect(quad.contains?(1, 1)).to be true + expect(quad.contains?(2, 1)).to be true + expect(quad.contains?(3, 1)).to be true + expect(quad.contains?(1, 2)).to be true + expect(quad.contains?(2, 2)).to be true + expect(quad.contains?(3, 2)).to be true + expect(quad.contains?(1, 3)).to be true + expect(quad.contains?(2, 3)).to be true + expect(quad.contains?(3, 3)).to be true end it "returns false if point is outside the quad" do - expect(quad.contains?(-26, 0)).to be false - expect(quad.contains?( 0, 26)).to be false + # Clockwise around the quad + expect(quad.contains?(0, 0)).to be false + expect(quad.contains?(1, 0)).to be false + expect(quad.contains?(2, 0)).to be false + expect(quad.contains?(3, 0)).to be false + expect(quad.contains?(4, 0)).to be false + expect(quad.contains?(4, 1)).to be false + expect(quad.contains?(4, 2)).to be false + expect(quad.contains?(4, 3)).to be false + expect(quad.contains?(4, 4)).to be false + expect(quad.contains?(3, 4)).to be false + expect(quad.contains?(2, 4)).to be false + expect(quad.contains?(1, 4)).to be false + expect(quad.contains?(0, 4)).to be false + expect(quad.contains?(0, 3)).to be false + expect(quad.contains?(0, 2)).to be false + expect(quad.contains?(0, 1)).to be false end end diff --git a/test/rectangle_spec.rb b/test/rectangle_spec.rb new file mode 100644 index 0000000..6628c5a --- /dev/null +++ b/test/rectangle_spec.rb @@ -0,0 +1,92 @@ +require 'ruby2d' + +RSpec.describe Ruby2D::Rectangle do + + describe "#new" do + it "creates a white rectangle by default" do + rectangle = Rectangle.new + expect(rectangle.color).to be_a(Ruby2D::Color) + expect(rectangle.color.r).to eq(1) + expect(rectangle.color.g).to eq(1) + expect(rectangle.color.b).to eq(1) + expect(rectangle.color.a).to eq(1) + end + + it "creates a rectangle with options" do + rectangle = Rectangle.new( + x: 10, y: 20, z: 30, + width: 40, height: 50, + color: 'gray', opacity: 0.5 + ) + + expect(rectangle.x).to eq(10) + expect(rectangle.y).to eq(20) + expect(rectangle.z).to eq(30) + expect(rectangle.width).to eq(40) + expect(rectangle.height).to eq(50) + expect(rectangle.color.r).to eq(2/3.0) + expect(rectangle.opacity).to eq(0.5) + end + + it "creates a new rectangle with one color via string" do + rectangle = Rectangle.new(color: 'red') + expect(rectangle.color).to be_a(Ruby2D::Color) + end + + it "creates a new rectangle with one color via array of numbers" do + rectangle = Rectangle.new(color: [0.1, 0.3, 0.5, 0.7]) + expect(rectangle.color).to be_a(Ruby2D::Color) + end + + it "creates a new rectangle with 4 colors via array of 4 strings" do + rectangle = Rectangle.new(color: ['red', 'green', 'blue', 'black']) + expect(rectangle.color).to be_a(Ruby2D::Color::Set) + end + + it "creates a new rectangle with 4 colors via array of 4 arrays of arrays of numbers" do + rectangle = Rectangle.new( + color: [ + [0.1, 0.3, 0.5, 0.7], + [0.2, 0.4, 0.6, 0.8], + [0.3, 0.5, 0.7, 0.9], + [0.4, 0.6, 0.8, 1.0] + ] + ) + expect(rectangle.color).to be_a(Ruby2D::Color::Set) + end + + it "throws an error when array of 3 strings is passed" do + expect do + Rectangle.new(color: ['red', 'green', 'blue']) + end.to raise_error("`Ruby2D::Rectangle` requires 4 colors, one for each vertex. 3 were given.") + end + + it "throws an error when array of 5 strings is passed" do + expect do + Rectangle.new(color: ['red', 'green', 'blue', 'black', 'fuchsia']) + end.to raise_error("`Ruby2D::Rectangle` requires 4 colors, one for each vertex. 5 were given.") + end + end + + describe "attributes" do + it "can be set and read" do + rectangle = Rectangle.new + rectangle.x = 10 + rectangle.y = 20 + rectangle.z = 30 + rectangle.width = 40 + rectangle.height = 50 + rectangle.color = 'gray' + rectangle.opacity = 0.5 + + expect(rectangle.x).to eq(10) + expect(rectangle.y).to eq(20) + expect(rectangle.z).to eq(30) + expect(rectangle.width).to eq(40) + expect(rectangle.height).to eq(50) + expect(rectangle.color.r).to eq(2/3.0) + expect(rectangle.opacity).to eq(0.5) + end + end + +end diff --git a/test/renderable_spec.rb b/test/renderable_spec.rb index 1352d5b..2f855b1 100644 --- a/test/renderable_spec.rb +++ b/test/renderable_spec.rb @@ -2,69 +2,78 @@ require 'ruby2d' RSpec.describe Ruby2D::Renderable do + # Create and use a fresh class to ensure nothing is overridden + class SomeShape + include Renderable + def initialize(x: 0, y: 0, width: 100, height: 100) + @x, @y, @width, @height = x, y, width, height + end + end + it "allows colors to be set on objects" do - quad = Quad.new - - quad.color = 'red' - expect(quad.color.r).to eq(1) - - quad.color = [0.9, 0.8, 0.7, 0.6] - expect(quad.color.r).to eq(0.9) - expect(quad.color.g).to eq(0.8) - expect(quad.color.b).to eq(0.7) - expect(quad.color.a).to eq(0.6) - - quad.color.r = 0.1 - quad.color.g = 0.2 - quad.color.b = 0.3 - quad.color.a = 0.4 - expect(quad.color.r).to eq(0.1) - expect(quad.color.g).to eq(0.2) - expect(quad.color.b).to eq(0.3) - expect(quad.color.a).to eq(0.4) - - quad.r = 0.5 - quad.g = 0.6 - quad.b = 0.7 - quad.a = 0.8 - expect(quad.r).to eq(0.5) - expect(quad.g).to eq(0.6) - expect(quad.b).to eq(0.7) - expect(quad.a).to eq(0.8) + shape = SomeShape.new + + shape.color = 'red' + expect(shape.color.r).to eq(1) + + shape.color = [0.9, 0.8, 0.7, 0.6] + expect(shape.color.r).to eq(0.9) + expect(shape.color.g).to eq(0.8) + expect(shape.color.b).to eq(0.7) + expect(shape.color.a).to eq(0.6) + + shape.color.r = 0.1 + shape.color.g = 0.2 + shape.color.b = 0.3 + shape.color.a = 0.4 + expect(shape.color.r).to eq(0.1) + expect(shape.color.g).to eq(0.2) + expect(shape.color.b).to eq(0.3) + expect(shape.color.a).to eq(0.4) + + shape.r = 0.5 + shape.g = 0.6 + shape.b = 0.7 + shape.a = 0.8 + expect(shape.r).to eq(0.5) + expect(shape.g).to eq(0.6) + expect(shape.b).to eq(0.7) + expect(shape.a).to eq(0.8) end it "allows British English spelling of color (colour)" do - quad = Quad.new - - quad.colour = 'blue' - expect(quad.color.r).to eq(0) - - quad.colour = [0.1, 0.2, 0.3, 0.4] - expect(quad.color.r).to eq(0.1) - expect(quad.color.g).to eq(0.2) - expect(quad.color.b).to eq(0.3) - expect(quad.color.a).to eq(0.4) - - quad.colour.r = 0.9 - quad.colour.g = 0.8 - quad.colour.b = 0.7 - quad.colour.a = 0.6 - expect(quad.colour.r).to eq(0.9) - expect(quad.colour.g).to eq(0.8) - expect(quad.colour.b).to eq(0.7) - expect(quad.colour.a).to eq(0.6) - expect(quad.color.r).to eq(0.9) - expect(quad.color.g).to eq(0.8) - expect(quad.color.b).to eq(0.7) - expect(quad.color.a).to eq(0.6) - expect(quad.r).to eq(0.9) - expect(quad.g).to eq(0.8) - expect(quad.b).to eq(0.7) - expect(quad.a).to eq(0.6) + shape = SomeShape.new + + shape.colour = 'blue' + expect(shape.color.r).to eq(0) + + shape.colour = [0.1, 0.2, 0.3, 0.4] + expect(shape.color.r).to eq(0.1) + expect(shape.color.g).to eq(0.2) + expect(shape.color.b).to eq(0.3) + expect(shape.color.a).to eq(0.4) + + shape.colour.r = 0.9 + shape.colour.g = 0.8 + shape.colour.b = 0.7 + shape.colour.a = 0.6 + expect(shape.colour.r).to eq(0.9) + expect(shape.colour.g).to eq(0.8) + expect(shape.colour.b).to eq(0.7) + expect(shape.colour.a).to eq(0.6) + expect(shape.color.r).to eq(0.9) + expect(shape.color.g).to eq(0.8) + expect(shape.color.b).to eq(0.7) + expect(shape.color.a).to eq(0.6) + expect(shape.r).to eq(0.9) + expect(shape.g).to eq(0.8) + expect(shape.b).to eq(0.7) + expect(shape.a).to eq(0.6) end describe "#contains?" do - square = Square.new(x: 1, y: 1, size: 2) + + shape = SomeShape.new(x: 1, y: 1, width: 2, height: 2) # Grid looks like this, 2x2 square at point (1, 1): # @@ -79,36 +88,36 @@ RSpec.describe Ruby2D::Renderable do # | | | | | # 4 +--+--+--+--+ - it "returns true if point is inside the rectangle" do - expect(square.contains?(1, 1)).to be true - expect(square.contains?(2, 1)).to be true - expect(square.contains?(3, 1)).to be true - expect(square.contains?(1, 2)).to be true - expect(square.contains?(2, 2)).to be true - expect(square.contains?(3, 2)).to be true - expect(square.contains?(1, 3)).to be true - expect(square.contains?(2, 3)).to be true - expect(square.contains?(3, 3)).to be true + it "returns true if point is inside the shape" do + expect(shape.contains?(1, 1)).to be true + expect(shape.contains?(2, 1)).to be true + expect(shape.contains?(3, 1)).to be true + expect(shape.contains?(1, 2)).to be true + expect(shape.contains?(2, 2)).to be true + expect(shape.contains?(3, 2)).to be true + expect(shape.contains?(1, 3)).to be true + expect(shape.contains?(2, 3)).to be true + expect(shape.contains?(3, 3)).to be true end - it "returns false if point is outside the rectangle" do - # Clockwise around the square - expect(square.contains?(0, 0)).to be false - expect(square.contains?(1, 0)).to be false - expect(square.contains?(2, 0)).to be false - expect(square.contains?(3, 0)).to be false - expect(square.contains?(4, 0)).to be false - expect(square.contains?(4, 1)).to be false - expect(square.contains?(4, 2)).to be false - expect(square.contains?(4, 3)).to be false - expect(square.contains?(4, 4)).to be false - expect(square.contains?(3, 4)).to be false - expect(square.contains?(2, 4)).to be false - expect(square.contains?(1, 4)).to be false - expect(square.contains?(0, 4)).to be false - expect(square.contains?(0, 3)).to be false - expect(square.contains?(0, 2)).to be false - expect(square.contains?(0, 1)).to be false + it "returns false if point is outside the shape" do + # Clockwise around the shape + expect(shape.contains?(0, 0)).to be false + expect(shape.contains?(1, 0)).to be false + expect(shape.contains?(2, 0)).to be false + expect(shape.contains?(3, 0)).to be false + expect(shape.contains?(4, 0)).to be false + expect(shape.contains?(4, 1)).to be false + expect(shape.contains?(4, 2)).to be false + expect(shape.contains?(4, 3)).to be false + expect(shape.contains?(4, 4)).to be false + expect(shape.contains?(3, 4)).to be false + expect(shape.contains?(2, 4)).to be false + expect(shape.contains?(1, 4)).to be false + expect(shape.contains?(0, 4)).to be false + expect(shape.contains?(0, 3)).to be false + expect(shape.contains?(0, 2)).to be false + expect(shape.contains?(0, 1)).to be false end end diff --git a/test/sound_spec.rb b/test/sound_spec.rb index 5458abe..f181b61 100644 --- a/test/sound_spec.rb +++ b/test/sound_spec.rb @@ -6,6 +6,11 @@ RSpec.describe Ruby2D::Sound do it "raises exception if audio file doesn't exist" do expect { Sound.new("bad_sound.wav") }.to raise_error(Ruby2D::Error) end + + it "creates sound" do + snd = Sound.new('test/media/music.mp3') + expect(snd.path).to eq('test/media/music.mp3') + end end end diff --git a/test/sprite_spec.rb b/test/sprite_spec.rb index c4ad61e..2b8adc2 100644 --- a/test/sprite_spec.rb +++ b/test/sprite_spec.rb @@ -7,8 +7,55 @@ RSpec.describe Ruby2D::Sprite do expect { Sprite.new("bad_sprite_sheet.png") }.to raise_error(Ruby2D::Error) end - it "creates a new sprite" do - Sprite.new("test/media/coin.png") + it "creates a sprite with a white filter by default" do + spr = Sprite.new('test/media/coin.png') + expect(spr.color).to be_a(Ruby2D::Color) + expect(spr.color.r).to eq(1) + expect(spr.color.g).to eq(1) + expect(spr.color.b).to eq(1) + expect(spr.color.a).to eq(1) + end + + it "creates an image with options" do + spr = Sprite.new( + 'test/media/coin.png', + x: 10, y: 20, z: 30, + width: 40, height: 50, rotate: 60, + color: 'gray', opacity: 0.5 + ) + + expect(spr.path).to eq('test/media/coin.png') + expect(spr.x).to eq(10) + expect(spr.y).to eq(20) + expect(spr.z).to eq(30) + expect(spr.width).to eq(40) + expect(spr.height).to eq(50) + expect(spr.rotate).to eq(60) + expect(spr.color.r).to eq(2/3.0) + expect(spr.opacity).to eq(0.5) + end + end + + describe "attributes" do + it "can be set and read" do + spr = Sprite.new('test/media/coin.png') + spr.x = 10 + spr.y = 20 + spr.z = 30 + spr.width = 40 + spr.height = 50 + spr.rotate = 60 + spr.color = 'gray' + spr.opacity = 0.5 + + expect(spr.x).to eq(10) + expect(spr.y).to eq(20) + expect(spr.z).to eq(30) + expect(spr.width).to eq(40) + expect(spr.height).to eq(50) + expect(spr.rotate).to eq(60) + expect(spr.color.r).to eq(2/3.0) + expect(spr.opacity).to eq(0.5) end end diff --git a/test/square_spec.rb b/test/square_spec.rb new file mode 100644 index 0000000..127a13c --- /dev/null +++ b/test/square_spec.rb @@ -0,0 +1,91 @@ +require 'ruby2d' + +RSpec.describe Ruby2D::Square do + + describe "#new" do + it "creates a white square by default" do + square = Square.new + expect(square.color).to be_a(Ruby2D::Color) + expect(square.color.r).to eq(1) + expect(square.color.g).to eq(1) + expect(square.color.b).to eq(1) + expect(square.color.a).to eq(1) + end + + it "creates a square with options" do + square = Square.new( + x: 10, y: 20, z: 30, + size: 40, + color: 'gray', opacity: 0.5 + ) + + expect(square.x).to eq(10) + expect(square.y).to eq(20) + expect(square.z).to eq(30) + expect(square.size).to eq(40) + expect(square.width).to eq(40) + expect(square.height).to eq(40) + expect(square.color.r).to eq(2/3.0) + expect(square.opacity).to eq(0.5) + end + + it "creates a new square with one color via string" do + square = Square.new(color: 'red') + expect(square.color).to be_a(Ruby2D::Color) + end + + it "creates a new square with one color via array of numbers" do + square = Square.new(color: [0.1, 0.3, 0.5, 0.7]) + expect(square.color).to be_a(Ruby2D::Color) + end + + it "creates a new square with 4 colors via array of 4 strings" do + square = Square.new(color: ['red', 'green', 'blue', 'black']) + expect(square.color).to be_a(Ruby2D::Color::Set) + end + + it "creates a new square with 4 colors via array of 4 arrays of arrays of numbers" do + square = Square.new( + color: [ + [0.1, 0.3, 0.5, 0.7], + [0.2, 0.4, 0.6, 0.8], + [0.3, 0.5, 0.7, 0.9], + [0.4, 0.6, 0.8, 1.0] + ] + ) + expect(square.color).to be_a(Ruby2D::Color::Set) + end + + it "throws an error when array of 3 strings is passed" do + expect do + Square.new(color: ['red', 'green', 'blue']) + end.to raise_error("`Ruby2D::Square` requires 4 colors, one for each vertex. 3 were given.") + end + + it "throws an error when array of 5 strings is passed" do + expect do + Square.new(color: ['red', 'green', 'blue', 'black', 'fuchsia']) + end.to raise_error("`Ruby2D::Square` requires 4 colors, one for each vertex. 5 were given.") + end + end + + describe "attributes" do + it "can be set and read" do + square = Square.new + square.x = 10 + square.y = 20 + square.z = 30 + square.size = 40 + square.color = 'gray' + square.opacity = 0.5 + + expect(square.x).to eq(10) + expect(square.y).to eq(20) + expect(square.z).to eq(30) + expect(square.size).to eq(40) + expect(square.color.r).to eq(2/3.0) + expect(square.opacity).to eq(0.5) + end + end + +end diff --git a/test/text_spec.rb b/test/text_spec.rb index 63acec7..5454510 100644 --- a/test/text_spec.rb +++ b/test/text_spec.rb @@ -4,69 +4,117 @@ RSpec.describe Ruby2D::Text do describe "#new" do it "raises exception if font file doesn't exist" do - expect { Text.new("hello", font: "bad_font.ttf") }.to raise_error(Ruby2D::Error) + expect { Text.new('hello', font: 'bad_font.ttf') }.to raise_error(Ruby2D::Error) end it "uses the system default font if one is not provided" do - t = Text.new("hello") - expect(t.font).to eq(Font.default) + txt = Text.new('hello') + expect(txt.font).to eq(Font.default) + end + + it "creates text with a white filter by default" do + txt = Text.new('hello') + expect(txt.color).to be_a(Ruby2D::Color) + expect(txt.color.r).to eq(1) + expect(txt.color.g).to eq(1) + expect(txt.color.b).to eq(1) + expect(txt.color.a).to eq(1) + end + + it "creates an image with options" do + txt = Text.new( + 'hello', font: 'test/media/bitstream_vera/vera.ttf', + x: 10, y: 20, z: 30, + size: 40, rotate: 50, + color: 'gray', opacity: 0.5 + ) + + expect(txt.text).to eq('hello') + expect(txt.x).to eq(10) + expect(txt.y).to eq(20) + expect(txt.z).to eq(30) + expect(txt.size).to eq(40) + expect(txt.rotate).to eq(50) + expect(txt.color.r).to eq(2/3.0) + expect(txt.opacity).to eq(0.5) + end + end + + describe "attributes" do + it "can be set and read" do + txt = Text.new('hello') + txt.x = 10 + txt.y = 20 + txt.z = 30 + txt.size = 40 + txt.rotate = 50 + txt.color = 'gray' + txt.opacity = 0.5 + + expect(txt.x).to eq(10) + expect(txt.y).to eq(20) + expect(txt.z).to eq(30) + expect(txt.size).to eq(40) + expect(txt.rotate).to eq(50) + expect(txt.color.r).to eq(2/3.0) + expect(txt.opacity).to eq(0.5) end end describe "#text=" do it "maps Time to string" do - t = Text.new("hello", font: "test/media/bitstream_vera/vera.ttf") - t.text = Time.new(1, 1, 1, 1, 1, 1, 1) - expect(t.text).to eq("0001-01-01 01:01:01 +0000") + txt = Text.new('hello', font: 'test/media/bitstream_vera/vera.ttf') + txt.text = Time.new(1, 1, 1, 1, 1, 1, 1) + expect(txt.text).to eq('0001-01-01 01:01:01 +0000') end it "maps Number to string" do - t = Text.new("hello", font: "test/media/bitstream_vera/vera.ttf") - t.text = 0 - expect(t.text).to eq("0") + txt = Text.new('hello', font: 'test/media/bitstream_vera/vera.ttf') + txt.text = 0 + expect(txt.text).to eq('0') end end describe "#width" do it "is known after creation" do - t = Text.new("Hello Ruby!", font: "test/media/bitstream_vera/vera.ttf") - expect(t.width).to be_between(110, 120) + txt = Text.new('Hello Ruby!', font: 'test/media/bitstream_vera/vera.ttf') + expect(txt.width).to be_between(110, 120) end it "is known after updating" do - t = Text.new("hello", font: "test/media/bitstream_vera/vera.ttf") - t.text = "Hello!" - expect(t.width).to eq(59) + txt = Text.new('hello', font: 'test/media/bitstream_vera/vera.ttf') + txt.text = 'Hello!' + expect(txt.width).to eq(59) end end describe "#height" do it "is known after creation" do - t = Text.new("hello", font: "test/media/bitstream_vera/vera.ttf") - expect(t.height).to eq(24) + txt = Text.new('hello', font: 'test/media/bitstream_vera/vera.ttf') + expect(txt.height).to eq(24) end it "is known after updating" do - t = Text.new("hello", font: "test/media/bitstream_vera/vera.ttf") - t.text = "Good morning world!" - expect(t.height).to eq(24) + txt = Text.new('hello', font: 'test/media/bitstream_vera/vera.ttf') + txt.text = 'Good morning world!' + expect(txt.height).to eq(24) end end describe "#contains?" do it "returns true if point is inside the text" do - t = Text.new("hello", font: "test/media/bitstream_vera/vera.ttf") - t.text = "Hello world!" - expect(t.contains?(t.width / 2, t.height / 2)).to be true + txt = Text.new('hello', font: 'test/media/bitstream_vera/vera.ttf') + txt.text = 'Hello world!' + expect(txt.contains?(txt.width / 2, txt.height / 2)).to be true end it "returns false if point is outside the text" do - t = Text.new("hello", font: "test/media/bitstream_vera/vera.ttf") - t.text = "Hello world!" - expect(t.contains?( - t.width / 2, t.height / 2)).to be false - expect(t.contains?( t.width / 2, - t.height / 2)).to be false - expect(t.contains?(3 * t.width / 2, t.height / 2)).to be false - expect(t.contains?( t.width / 2, 3 * t.height / 2)).to be false + txt = Text.new('hello', font: 'test/media/bitstream_vera/vera.ttf') + txt.text = 'Hello world!' + expect(txt.contains?( - txt.width / 2, txt.height / 2)).to be false + expect(txt.contains?( txt.width / 2, - txt.height / 2)).to be false + expect(txt.contains?(3 * txt.width / 2, txt.height / 2)).to be false + expect(txt.contains?( txt.width / 2, 3 * txt.height / 2)).to be false end end diff --git a/test/triangle_spec.rb b/test/triangle_spec.rb index 2600d6f..8dd2605 100644 --- a/test/triangle_spec.rb +++ b/test/triangle_spec.rb @@ -12,6 +12,23 @@ RSpec.describe Ruby2D::Triangle do expect(triangle.color.a).to eq(1) end + it "creates a triangle with options" do + triangle = Triangle.new( + x1: 10, y1: 20, x2: 30, y2: 40, x3: 50, y3: 60, z: 70, + color: 'gray', opacity: 0.5 + ) + + expect(triangle.x1).to eq(10) + expect(triangle.y1).to eq(20) + expect(triangle.x2).to eq(30) + expect(triangle.y2).to eq(40) + expect(triangle.x3).to eq(50) + expect(triangle.y3).to eq(60) + expect(triangle.z).to eq(70) + expect(triangle.color.r).to eq(2/3.0) + expect(triangle.opacity).to eq(0.5) + end + it "creates a new triangle with one color via string" do triangle = Triangle.new(color: 'black') expect(triangle.color).to be_a(Ruby2D::Color) @@ -41,16 +58,42 @@ RSpec.describe Ruby2D::Triangle do it "throws an error when array of 2 strings is passed" do expect do Triangle.new(color: ['red', 'green']) - end.to raise_error("Triangles require 3 colors, one for each vertex. 2 were given.") + end.to raise_error("`Ruby2D::Triangle` requires 3 colors, one for each vertex. 2 were given.") end it "throws an error when array of 4 strings is passed" do expect do Triangle.new(color: ['red', 'green', 'blue', 'fuchsia']) - end.to raise_error("Triangles require 3 colors, one for each vertex. 4 were given.") + end.to raise_error("`Ruby2D::Triangle` requires 3 colors, one for each vertex. 4 were given.") + end + end + + describe "attributes" do + it "can be set and read" do + triangle = Triangle.new + triangle.x1 = 10 + triangle.y1 = 20 + triangle.x2 = 30 + triangle.y2 = 40 + triangle.x3 = 50 + triangle.y3 = 60 + triangle.z = 70 + triangle.color = 'gray' + triangle.opacity = 0.5 + + expect(triangle.x1).to eq(10) + expect(triangle.y1).to eq(20) + expect(triangle.x2).to eq(30) + expect(triangle.y2).to eq(40) + expect(triangle.x3).to eq(50) + expect(triangle.y3).to eq(60) + expect(triangle.z).to eq(70) + expect(triangle.color.r).to eq(2/3.0) + expect(triangle.opacity).to eq(0.5) end end + # TODO: This test should be more precise, like `Renderable#contains?` describe "#contains?" do triangle = Triangle.new( x1: 0, y1: 0, |
