geometry-in-ruby 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 +6 -0
- data/Gemfile +7 -0
- data/LICENSE +21 -0
- data/README.markdown +105 -0
- data/Rakefile +24 -0
- data/geometry-in-ruby.gemspec +23 -0
- data/lib/geometry/arc.rb +94 -0
- data/lib/geometry/circle.rb +122 -0
- data/lib/geometry/cluster_factory.rb +15 -0
- data/lib/geometry/edge.rb +140 -0
- data/lib/geometry/line.rb +154 -0
- data/lib/geometry/obround.rb +238 -0
- data/lib/geometry/path.rb +67 -0
- data/lib/geometry/point.rb +163 -0
- data/lib/geometry/point_zero.rb +107 -0
- data/lib/geometry/polygon.rb +368 -0
- data/lib/geometry/polyline.rb +318 -0
- data/lib/geometry/rectangle.rb +378 -0
- data/lib/geometry/regular_polygon.rb +136 -0
- data/lib/geometry/rotation.rb +190 -0
- data/lib/geometry/size.rb +75 -0
- data/lib/geometry/size_zero.rb +70 -0
- data/lib/geometry/square.rb +113 -0
- data/lib/geometry/text.rb +24 -0
- data/lib/geometry/transformation/composition.rb +39 -0
- data/lib/geometry/transformation.rb +171 -0
- data/lib/geometry/triangle.rb +78 -0
- data/lib/geometry/vector.rb +34 -0
- data/lib/geometry.rb +22 -0
- data/test/geometry/arc.rb +25 -0
- data/test/geometry/circle.rb +112 -0
- data/test/geometry/edge.rb +132 -0
- data/test/geometry/line.rb +132 -0
- data/test/geometry/obround.rb +25 -0
- data/test/geometry/path.rb +66 -0
- data/test/geometry/point.rb +258 -0
- data/test/geometry/point_zero.rb +177 -0
- data/test/geometry/polygon.rb +214 -0
- data/test/geometry/polyline.rb +266 -0
- data/test/geometry/rectangle.rb +154 -0
- data/test/geometry/regular_polygon.rb +120 -0
- data/test/geometry/rotation.rb +108 -0
- data/test/geometry/size.rb +97 -0
- data/test/geometry/size_zero.rb +153 -0
- data/test/geometry/square.rb +66 -0
- data/test/geometry/transformation/composition.rb +49 -0
- data/test/geometry/transformation.rb +169 -0
- data/test/geometry/triangle.rb +32 -0
- data/test/geometry/vector.rb +41 -0
- data/test/geometry.rb +5 -0
- metadata +117 -0
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'geometry/line'
|
3
|
+
|
4
|
+
describe Geometry::Line do
|
5
|
+
Line = Geometry::Line
|
6
|
+
Point = Geometry::Point
|
7
|
+
|
8
|
+
describe "when initializing" do
|
9
|
+
it "must accept two named points" do
|
10
|
+
line = Line.new(from:Point[0,0], to:Point[10,10])
|
11
|
+
line.must_be_kind_of(Line)
|
12
|
+
line.must_be_instance_of(Geometry::TwoPointLine)
|
13
|
+
line.first.must_equal Point[0,0]
|
14
|
+
line.last.must_equal Point[10,10]
|
15
|
+
end
|
16
|
+
|
17
|
+
it "must accept named start and end points" do
|
18
|
+
line = Line.new(start:Point[0,0], end:Point[10,10])
|
19
|
+
line.must_be_kind_of(Line)
|
20
|
+
line.must_be_instance_of(Geometry::TwoPointLine)
|
21
|
+
line.first.must_equal Point[0,0]
|
22
|
+
line.last.must_equal Point[10,10]
|
23
|
+
end
|
24
|
+
|
25
|
+
it "must raise an exception when no arguments are given" do
|
26
|
+
-> { Line.new }.must_raise ArgumentError
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
it "create a Line object from 2 Points" do
|
31
|
+
line = Geometry::Line[Geometry::Point[0,0], Geometry::Point[10,10]]
|
32
|
+
assert_kind_of(Geometry::Line, line)
|
33
|
+
assert_kind_of(Geometry::TwoPointLine, line)
|
34
|
+
end
|
35
|
+
it "create a Line object from two arrays" do
|
36
|
+
line = Geometry::Line[[0,0], [10,10]]
|
37
|
+
assert(line.is_a?(Geometry::Line))
|
38
|
+
assert_kind_of(Geometry::TwoPointLine, line)
|
39
|
+
assert_kind_of(Geometry::Point, line.first)
|
40
|
+
assert_kind_of(Geometry::Point, line.last)
|
41
|
+
end
|
42
|
+
it "create a Line object from two Vectors" do
|
43
|
+
line = Geometry::Line[Vector[0,0], Vector[10,10]]
|
44
|
+
assert(line.is_a?(Geometry::Line))
|
45
|
+
assert_kind_of(Geometry::TwoPointLine, line)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "create a Line from a slope and y-intercept" do
|
49
|
+
line = Geometry::Line[0.75, 5]
|
50
|
+
assert(line.is_a?(Geometry::Line))
|
51
|
+
assert_kind_of(Geometry::SlopeInterceptLine, line)
|
52
|
+
assert_equal(5, line.intercept)
|
53
|
+
assert_equal(0.75, line.slope)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "create a Line from a Rational slope and y-intercept" do
|
57
|
+
line = Geometry::Line[Rational(3,4), 5]
|
58
|
+
assert_kind_of(Geometry::SlopeInterceptLine, line)
|
59
|
+
assert(line.is_a?(Geometry::Line))
|
60
|
+
assert_equal(Rational(3,4), line.slope)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "have a special constructor for horizontal lines" do
|
64
|
+
line = Geometry::Line.horizontal
|
65
|
+
assert(line.horizontal?)
|
66
|
+
end
|
67
|
+
it "have a special constructor for vertical lines" do
|
68
|
+
line = Geometry::Line.vertical
|
69
|
+
assert(line.vertical?)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "have accessor for y-intercept" do
|
73
|
+
line = Geometry::Line[0.75, 5]
|
74
|
+
assert_equal(5, line.intercept)
|
75
|
+
assert_equal(5, line.intercept(:y))
|
76
|
+
end
|
77
|
+
it "have accessor for x-intercept" do
|
78
|
+
line = Geometry::Line.vertical(7)
|
79
|
+
assert_equal(7, line.intercept(:x))
|
80
|
+
end
|
81
|
+
|
82
|
+
it "return the correct x-intercept for vertical lines" do
|
83
|
+
line = Geometry::Line.vertical(7)
|
84
|
+
assert_equal(7, line.intercept(:x))
|
85
|
+
end
|
86
|
+
it "return the correct y-intercept for horizontal lines" do
|
87
|
+
line = Geometry::Line.horizontal(4)
|
88
|
+
assert_equal(4, line.intercept(:y))
|
89
|
+
end
|
90
|
+
|
91
|
+
it "return nil x-intercept for horizontal lines" do
|
92
|
+
line = Geometry::Line.horizontal
|
93
|
+
assert_nil(line.intercept(:x))
|
94
|
+
end
|
95
|
+
it "return nil y-intercept for vertical lines" do
|
96
|
+
line = Geometry::Line.vertical
|
97
|
+
assert_nil(line.intercept(:y))
|
98
|
+
end
|
99
|
+
|
100
|
+
it "implement inspect" do
|
101
|
+
line = Geometry::Line[[0,0], [10,10]]
|
102
|
+
assert_equal('Line(Point[0, 0], Point[10, 10])', line.inspect)
|
103
|
+
end
|
104
|
+
it "implement to_s" do
|
105
|
+
line = Geometry::Line[[0,0], [10,10]]
|
106
|
+
assert_equal('Line(Point[0, 0], Point[10, 10])', line.to_s)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe Geometry::PointSlopeLine do
|
111
|
+
subject { Geometry::PointSlopeLine.new [1,2], 3 }
|
112
|
+
|
113
|
+
it "must have a slope attribute" do
|
114
|
+
subject.slope.must_equal 3
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe Geometry::SlopeInterceptLine do
|
119
|
+
subject { Geometry::SlopeInterceptLine.new 3, 2 }
|
120
|
+
|
121
|
+
it "must have a slope attribute" do
|
122
|
+
subject.slope.must_equal 3
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe Geometry::TwoPointLine do
|
127
|
+
subject { Geometry::TwoPointLine.new [1,2], [3,4] }
|
128
|
+
|
129
|
+
it "must have a slope attribute" do
|
130
|
+
subject.slope.must_equal 1
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'geometry/obround'
|
3
|
+
|
4
|
+
describe Geometry::Obround do
|
5
|
+
Obround = Geometry::Obround
|
6
|
+
|
7
|
+
describe "when constructed" do
|
8
|
+
it "must accept two Points" do
|
9
|
+
obround = Geometry::Obround.new [1,2], [3,4]
|
10
|
+
obround.must_be_kind_of Geometry::Obround
|
11
|
+
end
|
12
|
+
|
13
|
+
it "must accept a width and height" do
|
14
|
+
obround = Geometry::Obround.new 2, 3
|
15
|
+
obround.must_be_kind_of Geometry::Obround
|
16
|
+
obround.height.must_equal 3
|
17
|
+
obround.width.must_equal 2
|
18
|
+
end
|
19
|
+
|
20
|
+
it "must compare equal" do
|
21
|
+
obround = Geometry::Obround.new [1,2], [3,4]
|
22
|
+
obround.must_equal Obround.new([1,2], [3,4])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'geometry/path'
|
3
|
+
|
4
|
+
describe Geometry::Path do
|
5
|
+
describe "construction" do
|
6
|
+
it "must create a Path with no arguments" do
|
7
|
+
path = Geometry::Path.new
|
8
|
+
path.must_be_kind_of Geometry::Path
|
9
|
+
path.elements.wont_be_nil
|
10
|
+
path.elements.size.must_equal 0
|
11
|
+
end
|
12
|
+
|
13
|
+
it "must create a Path from Points" do
|
14
|
+
path = Geometry::Path.new Point[1,1], Point[2,2], Point[3,3]
|
15
|
+
path.elements.size.must_equal 2
|
16
|
+
path.elements.each {|a| a.must_be_kind_of Geometry::Edge }
|
17
|
+
end
|
18
|
+
|
19
|
+
it "with connected Edges" do
|
20
|
+
path = Geometry::Path.new Edge.new([1,1], [2,2]), Edge.new([2,2], [3,3])
|
21
|
+
path.elements.size.must_equal 2
|
22
|
+
path.elements.each {|a| a.must_be_kind_of Geometry::Edge }
|
23
|
+
end
|
24
|
+
|
25
|
+
it "with disjoint Edges" do
|
26
|
+
path = Geometry::Path.new Edge.new([1,1], [2,2]), Edge.new([3,3], [4,4])
|
27
|
+
path.elements.size.must_equal 3
|
28
|
+
path.elements.each {|a| a.must_be_kind_of Geometry::Edge }
|
29
|
+
end
|
30
|
+
|
31
|
+
it "with Points and Arcs" do
|
32
|
+
path = Geometry::Path.new [0,0], [1.0,0.0], Arc.new(center:[1,1], radius:1, start:-90*Math::PI/180, end:0), [2.0,1.0], [1,2]
|
33
|
+
path.elements.size.must_equal 3
|
34
|
+
path.elements[0].must_be_kind_of Geometry::Edge
|
35
|
+
path.elements[1].must_be_kind_of Geometry::Arc
|
36
|
+
path.elements[2].must_be_kind_of Geometry::Edge
|
37
|
+
end
|
38
|
+
|
39
|
+
it "with Edges and Arcs" do
|
40
|
+
path = Geometry::Path.new Edge.new([0,0], [1.0,0.0]), Arc.new(center:[1,1], radius:1, start:-90*Math::PI/180, end:0), Edge.new([2.0,1.0], [1,2])
|
41
|
+
path.elements.size.must_equal 3
|
42
|
+
path.elements[0].must_be_kind_of Geometry::Edge
|
43
|
+
path.elements[1].must_be_kind_of Geometry::Arc
|
44
|
+
path.elements[2].must_be_kind_of Geometry::Edge
|
45
|
+
end
|
46
|
+
|
47
|
+
it "with disjoint Edges and Arcs" do
|
48
|
+
path = Geometry::Path.new Edge.new([0,0], [1,0]), Arc.new(center:[2,1], radius:1, start:-90*Math::PI/180, end:0), Edge.new([3,1], [1,2])
|
49
|
+
path.elements.size.must_equal 4
|
50
|
+
path.elements[0].must_be_kind_of Geometry::Edge
|
51
|
+
path.elements[1].must_be_kind_of Geometry::Edge
|
52
|
+
path.elements[2].must_be_kind_of Geometry::Arc
|
53
|
+
path.elements[3].must_be_kind_of Geometry::Edge
|
54
|
+
end
|
55
|
+
|
56
|
+
it "with disjoint Arcs" do
|
57
|
+
path = Geometry::Path.new Arc.new(center:[2,1], radius:1, start:-90*Math::PI/180, end:0), Arc.new(center:[3,1], radius:1, start:-90*Math::PI/180, end:0)
|
58
|
+
path.elements.size.must_equal 3
|
59
|
+
path.elements[0].must_be_kind_of Geometry::Arc
|
60
|
+
path.elements[1].must_be_kind_of Geometry::Edge
|
61
|
+
path.elements[2].must_be_kind_of Geometry::Arc
|
62
|
+
|
63
|
+
path.elements[0].last.must_equal path.elements[1].first
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,258 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'geometry/point'
|
3
|
+
|
4
|
+
describe Geometry::Point do
|
5
|
+
PointZero = Geometry::PointZero
|
6
|
+
|
7
|
+
describe "class methods" do
|
8
|
+
it "must generate a PointZero" do
|
9
|
+
Point.zero.must_be_instance_of(PointZero)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "must generate a Point full of zeros" do
|
13
|
+
Point.zero(3).must_equal Point[0,0,0]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "constructor" do
|
18
|
+
it "must return the Point when constructed from a Point" do
|
19
|
+
original_point = Point[3,4]
|
20
|
+
point = Geometry::Point[original_point]
|
21
|
+
point.must_be_same_as original_point
|
22
|
+
point.size.must_equal 2
|
23
|
+
point.x.must_equal 3
|
24
|
+
point.y.must_equal 4
|
25
|
+
end
|
26
|
+
|
27
|
+
it "must return the PointZero when constructed from a PointZero" do
|
28
|
+
original_point = Geometry::PointZero.new
|
29
|
+
point = Geometry::Point[original_point]
|
30
|
+
point.must_be_same_as original_point
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it "create a Point object from an array" do
|
35
|
+
point = Geometry::Point[[3,4]]
|
36
|
+
assert_equal(2, point.size)
|
37
|
+
assert_equal(3, point.x)
|
38
|
+
assert_equal(4, point.y)
|
39
|
+
end
|
40
|
+
it "create a Point object from individual parameters" do
|
41
|
+
point = Geometry::Point[3,4]
|
42
|
+
assert_equal(2, point.size)
|
43
|
+
assert_equal(3, point.x)
|
44
|
+
assert_equal(4, point.y)
|
45
|
+
end
|
46
|
+
it "create a Point object from a Vector" do
|
47
|
+
point = Geometry::Point[Vector[3,4]]
|
48
|
+
assert_equal(2, point.size)
|
49
|
+
assert_equal(3, point.x)
|
50
|
+
assert_equal(4, point.y)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "create a Point object from a Point using list syntax" do
|
54
|
+
point = Geometry::Point[Geometry::Point[13,14]]
|
55
|
+
assert_equal(2, point.size)
|
56
|
+
assert_equal(13, point.x)
|
57
|
+
assert_equal(14, point.y)
|
58
|
+
end
|
59
|
+
it "allow indexed element access" do
|
60
|
+
point = Geometry::Point[5,6]
|
61
|
+
assert_equal(2, point.size)
|
62
|
+
assert_equal(5, point[0])
|
63
|
+
assert_equal(6, point[1])
|
64
|
+
end
|
65
|
+
it "allow named element access" do
|
66
|
+
point = Geometry::Point[5,6,7]
|
67
|
+
assert_equal(3, point.size)
|
68
|
+
assert_equal(5, point.x)
|
69
|
+
assert_equal(6, point.y)
|
70
|
+
assert_equal(7, point.z)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "implement inspect" do
|
74
|
+
point = Geometry::Point[8,9]
|
75
|
+
assert_equal('Point[8, 9]', point.inspect)
|
76
|
+
end
|
77
|
+
it "implement to_s" do
|
78
|
+
point = Geometry::Point[10,11]
|
79
|
+
assert_equal('Point[10, 11]', point.to_s)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "must support array access" do
|
83
|
+
Point[1,2][0].must_equal 1
|
84
|
+
Point[1,2][1].must_equal 2
|
85
|
+
Point[1,2][2].must_equal nil
|
86
|
+
end
|
87
|
+
|
88
|
+
it "must clone" do
|
89
|
+
Point[1,2].clone.must_be_instance_of(Point)
|
90
|
+
Point[1,2].clone.must_equal Point[1,2]
|
91
|
+
end
|
92
|
+
|
93
|
+
it "must duplicate" do
|
94
|
+
Point[1,2].dup.must_be_instance_of(Point)
|
95
|
+
Point[1,2].dup.must_equal Point[1,2]
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "arithmetic" do
|
99
|
+
let(:left) { Point[1,2] }
|
100
|
+
let(:right) { Point[3,4] }
|
101
|
+
|
102
|
+
it "must have +@" do
|
103
|
+
(+left).must_equal Point[1,2]
|
104
|
+
(+left).must_be_instance_of(Point)
|
105
|
+
end
|
106
|
+
|
107
|
+
it "must have unary negation" do
|
108
|
+
(-left).must_equal Point[-1,-2]
|
109
|
+
(-left).must_be_instance_of(Point)
|
110
|
+
end
|
111
|
+
|
112
|
+
describe "when adding" do
|
113
|
+
it "return a Point when adding two Points" do
|
114
|
+
assert_kind_of(Point, left+right)
|
115
|
+
end
|
116
|
+
|
117
|
+
it "must return a Point when adding an array to a Point" do
|
118
|
+
(left + [5,6]).must_equal Point[6,8]
|
119
|
+
end
|
120
|
+
|
121
|
+
it "must add a Numeric to all elements" do
|
122
|
+
(left + 2).must_equal Point[3,4]
|
123
|
+
(2 + left).must_equal Point[3,4]
|
124
|
+
end
|
125
|
+
|
126
|
+
it "must raise an exception when adding mismatched sizes" do
|
127
|
+
lambda { left + [1,2,3,4] }.must_raise Geometry::DimensionMismatch
|
128
|
+
end
|
129
|
+
|
130
|
+
it "must return a Point when adding a Vector" do
|
131
|
+
(left + Vector[5,6]).must_equal Point[6,8]
|
132
|
+
(Vector[5,6] + right).must_equal Vector[8,10]
|
133
|
+
end
|
134
|
+
|
135
|
+
it "must return self when adding a PointZero" do
|
136
|
+
(left + Point.zero).must_equal left
|
137
|
+
end
|
138
|
+
|
139
|
+
it "must return self when adding a NilClass" do
|
140
|
+
(left + nil).must_equal left
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
describe "when subtracting" do
|
145
|
+
it "return a Point when subtracting two Points" do
|
146
|
+
assert_kind_of(Point, left-right)
|
147
|
+
end
|
148
|
+
|
149
|
+
it "must return a Point when subtracting an array from a Point" do
|
150
|
+
(left - [5,6]).must_equal Point[-4, -4]
|
151
|
+
end
|
152
|
+
|
153
|
+
it "must subtract a Numeric from all elements" do
|
154
|
+
(left - 2).must_equal Point[-1, 0]
|
155
|
+
(2 - left).must_equal Point[1,0]
|
156
|
+
end
|
157
|
+
|
158
|
+
it "must raise an exception when subtracting mismatched sizes" do
|
159
|
+
lambda { left - [1,2,3,4] }.must_raise Geometry::DimensionMismatch
|
160
|
+
end
|
161
|
+
|
162
|
+
it "must return self when subtracting a PointZero" do
|
163
|
+
(left - Point.zero).must_equal left
|
164
|
+
end
|
165
|
+
|
166
|
+
it "must return self when subtracting a NilClass" do
|
167
|
+
(left - nil).must_equal left
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
describe "when multiplying" do
|
172
|
+
it "must return a Point when multiplied by a Matrix" do
|
173
|
+
(Matrix[[1,2],[3,4]]*Point[5,6]).must_equal Point[17, 39]
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
describe "coercion" do
|
179
|
+
subject { Point[1,2] }
|
180
|
+
|
181
|
+
it "must coerce Arrays into Points" do
|
182
|
+
subject.coerce([3,4]).must_equal [Point[3,4], subject]
|
183
|
+
end
|
184
|
+
|
185
|
+
it "must coerce Vectors into Points" do
|
186
|
+
subject.coerce(Vector[3,4]).must_equal [Point[3,4], subject]
|
187
|
+
end
|
188
|
+
|
189
|
+
it "must coerce a Numeric into a Point" do
|
190
|
+
subject.coerce(42).must_equal [Point[42,42], subject]
|
191
|
+
end
|
192
|
+
|
193
|
+
it "must reject anything that can't be coerced" do
|
194
|
+
-> { subject.coerce(NilClass) }.must_raise TypeError
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
describe "comparison" do
|
199
|
+
let(:point) { Point[1,2] }
|
200
|
+
|
201
|
+
it "must compare equal to an equal Array" do
|
202
|
+
point.must_be :==, [1,2]
|
203
|
+
point.must_be :eql?, [1,2]
|
204
|
+
[1,2].must_equal point
|
205
|
+
end
|
206
|
+
|
207
|
+
it "must not compare equal to an unequal Array" do
|
208
|
+
point.wont_equal [3,2]
|
209
|
+
[3,2].wont_equal point
|
210
|
+
end
|
211
|
+
|
212
|
+
it "must compare equal to an equal Point" do
|
213
|
+
point.must_be :==, Point[1,2]
|
214
|
+
point.must_be :eql?, Point[1,2]
|
215
|
+
Point[1,2].must_equal point
|
216
|
+
end
|
217
|
+
|
218
|
+
it "must not compare equal to an unequal Point" do
|
219
|
+
point.wont_equal Point[3,2]
|
220
|
+
Point[3,2].wont_equal point
|
221
|
+
end
|
222
|
+
|
223
|
+
it "must compare equal to an equal Vector" do
|
224
|
+
point.must_equal Vector[1,2]
|
225
|
+
Vector[1,2].must_equal point
|
226
|
+
end
|
227
|
+
|
228
|
+
it "must not compare equal to an unequal Vector" do
|
229
|
+
point.wont_equal Vector[3,2]
|
230
|
+
Vector[3,2].wont_equal point
|
231
|
+
end
|
232
|
+
|
233
|
+
it "must think that floats == ints" do
|
234
|
+
Point[1,2].must_be :==, Point[1.0,2.0]
|
235
|
+
Point[1.0,2.0].must_be :==, Point[1,2]
|
236
|
+
end
|
237
|
+
|
238
|
+
it "must not think that floats eql? ints" do
|
239
|
+
Point[1,2].wont_be :eql?, Point[1.0,2.0]
|
240
|
+
Point[1.0,2.0].wont_be :eql?, Point[1,2]
|
241
|
+
end
|
242
|
+
|
243
|
+
describe "spaceship" do
|
244
|
+
it "must spaceship with another Point of the same length" do
|
245
|
+
(Point[1,2] <=> Point[0,3]).must_equal Point[1,-1]
|
246
|
+
end
|
247
|
+
|
248
|
+
it "must spaceship with another Point of different length" do
|
249
|
+
(Point[1,2] <=> Point[0,3,4]).must_equal Point[1,-1]
|
250
|
+
(Point[1,2,4] <=> Point[0,3]).must_equal Point[1,-1]
|
251
|
+
end
|
252
|
+
|
253
|
+
it "must spaceship with an Array" do
|
254
|
+
(Point[1,2] <=> [0,3]).must_equal Point[1,-1]
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
@@ -0,0 +1,177 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'geometry/point_zero'
|
3
|
+
|
4
|
+
describe Geometry::PointZero do
|
5
|
+
let(:zero) { Geometry::PointZero.new }
|
6
|
+
|
7
|
+
describe "arithmetic" do
|
8
|
+
let(:left) { Point[1,2] }
|
9
|
+
let(:right) { Point[3,4] }
|
10
|
+
|
11
|
+
it "must have +@" do
|
12
|
+
(+zero).must_be :eql?, 0
|
13
|
+
(+zero).must_be_instance_of(Geometry::PointZero)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "must have unary negation" do
|
17
|
+
(-zero).must_be :eql?, 0
|
18
|
+
(-zero).must_be_instance_of(Geometry::PointZero)
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "Accessors" do
|
22
|
+
it "must return 0 for array access" do
|
23
|
+
zero[3].must_equal 0
|
24
|
+
end
|
25
|
+
|
26
|
+
it "must return 0 for named element access" do
|
27
|
+
zero.x.must_equal 0
|
28
|
+
zero.y.must_equal 0
|
29
|
+
zero.z.must_equal 0
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "when adding" do
|
34
|
+
it "must return a number" do
|
35
|
+
(zero + 3).must_equal 3
|
36
|
+
(3 + zero).must_equal 3
|
37
|
+
end
|
38
|
+
|
39
|
+
it "return a Point when adding two Points" do
|
40
|
+
(zero + right).must_be_kind_of Point
|
41
|
+
(left + zero).must_be_kind_of Point
|
42
|
+
end
|
43
|
+
|
44
|
+
it "must return an Array when adding an array" do
|
45
|
+
(zero + [5,6]).must_equal [5,6]
|
46
|
+
# ([5,6] + zero).must_equal [5,6]
|
47
|
+
end
|
48
|
+
|
49
|
+
it "must return a Point when adding a Size" do
|
50
|
+
(zero + Size[5,6]).must_be_instance_of(Point)
|
51
|
+
(zero + Size[5,6]).must_equal Point[5,6]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "when subtracting" do
|
56
|
+
it "must return a number" do
|
57
|
+
(zero - 3).must_equal -3
|
58
|
+
(3 - zero).must_equal 3
|
59
|
+
end
|
60
|
+
|
61
|
+
it "return a Point when subtracting two Points" do
|
62
|
+
(zero - right).must_equal Point[-3,-4]
|
63
|
+
(left - zero).must_equal Point[1,2]
|
64
|
+
end
|
65
|
+
|
66
|
+
it "must return a Point when subtracting an array" do
|
67
|
+
(zero - [5,6]).must_equal [-5, -6]
|
68
|
+
# ([5,6] - zero).must_equal [5,6]
|
69
|
+
end
|
70
|
+
|
71
|
+
it "must return a Point when subtracting a Size" do
|
72
|
+
(zero - Size[5,6]).must_be_instance_of(Point)
|
73
|
+
(zero - Size[5,6]).must_equal Point[-5,-6]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "multiplication" do
|
78
|
+
it "must return 0 for scalars" do
|
79
|
+
(zero * 3).must_equal 0
|
80
|
+
(zero * 3.0).must_equal 0.0
|
81
|
+
end
|
82
|
+
|
83
|
+
it "must return 0 for Points" do
|
84
|
+
(zero * Point[1,2]).must_equal 0
|
85
|
+
end
|
86
|
+
|
87
|
+
it "must return 0 for Vectors" do
|
88
|
+
(zero * Vector[2,3]).must_equal 0
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "division" do
|
93
|
+
it "must return 0 for non-zero scalars" do
|
94
|
+
(zero / 3).must_equal 0
|
95
|
+
(zero / 4.0).must_equal 0
|
96
|
+
end
|
97
|
+
|
98
|
+
it "must raise an exception when divided by 0" do
|
99
|
+
lambda { zero / 0 }.must_raise ZeroDivisionError
|
100
|
+
end
|
101
|
+
|
102
|
+
it "must raise an exception for Points" do
|
103
|
+
lambda { zero / Point[1,2] }.must_raise Geometry::OperationNotDefined
|
104
|
+
end
|
105
|
+
|
106
|
+
it "must raise an exception for Vectors" do
|
107
|
+
lambda { zero / Vector[1,2] }.must_raise Geometry::OperationNotDefined
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
describe "coercion" do
|
115
|
+
it "must coerce Arrays into Points" do
|
116
|
+
zero.coerce([3,4]).must_equal [Point[3,4], Point[0,0]]
|
117
|
+
end
|
118
|
+
|
119
|
+
it "must coerce Vectors into Vectors" do
|
120
|
+
zero.coerce(Vector[3,4]).must_equal [Vector[3,4], Vector[0,0]]
|
121
|
+
end
|
122
|
+
|
123
|
+
it "must coerce Points into Points" do
|
124
|
+
zero.coerce(Point[5,6]).must_equal [Point[5,6], Point[0,0]]
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe "comparison" do
|
129
|
+
subject { Geometry::PointZero.new }
|
130
|
+
|
131
|
+
it "must be equal to 0 and 0.0" do
|
132
|
+
zero.must_be :eql?, 0
|
133
|
+
zero.must_be :eql?, 0.0
|
134
|
+
end
|
135
|
+
|
136
|
+
it "must not be equal to a non-zero number" do
|
137
|
+
1.wont_equal zero
|
138
|
+
3.14.wont_equal zero
|
139
|
+
end
|
140
|
+
|
141
|
+
it "must be equal to an Array of zeros" do
|
142
|
+
zero.must_be :==, [0,0]
|
143
|
+
zero.must_be :eql?, [0,0]
|
144
|
+
zero.must_be :===, [0,0]
|
145
|
+
[0,0].must_equal zero
|
146
|
+
subject.must_equal [0,0]
|
147
|
+
end
|
148
|
+
|
149
|
+
it "must not be equal to a non-zero Array" do
|
150
|
+
zero.wont_equal [3,2]
|
151
|
+
[3,2].wont_equal zero
|
152
|
+
end
|
153
|
+
|
154
|
+
it "must be equal to a Point at the origin" do
|
155
|
+
zero.must_be :==, Point[0,0]
|
156
|
+
zero.must_be :eql?, Point[0,0]
|
157
|
+
zero.must_be :===, Point[0,0]
|
158
|
+
Point[0,0].must_equal zero
|
159
|
+
subject.must_equal Point[0,0]
|
160
|
+
end
|
161
|
+
|
162
|
+
it "must not be equal to a Point not at the origin" do
|
163
|
+
zero.wont_equal Point[3,2]
|
164
|
+
Point[3,2].wont_equal zero
|
165
|
+
end
|
166
|
+
|
167
|
+
it "must be equal to an Vector of zeroes" do
|
168
|
+
zero.must_be :eql?, Vector[0,0]
|
169
|
+
Vector[0,0].must_equal zero
|
170
|
+
end
|
171
|
+
|
172
|
+
it "must not be equal to a non-zero Vector" do
|
173
|
+
zero.wont_equal Vector[3,2]
|
174
|
+
Vector[3,2].wont_equal zero
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|