geometry 6.2 → 6.3

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.
@@ -0,0 +1,199 @@
1
+ require 'minitest/autorun'
2
+ require 'geometry/point_one'
3
+
4
+ describe Geometry::PointOne do
5
+ subject { Geometry::PointOne.new }
6
+ let(:one) { Geometry::PointOne.new }
7
+
8
+ describe 'arithmetic' do
9
+ let(:left) { Point[1,2] }
10
+ let(:right) { Point[3,4] }
11
+
12
+ it 'must pretend to be a Point' do
13
+ subject.is_a?(Point).must_equal true
14
+ subject.kind_of?(Point).must_equal true
15
+
16
+ subject.is_a?(Geometry::PointOne).must_equal true
17
+ subject.kind_of?(Geometry::PointOne).must_equal true
18
+
19
+ subject.instance_of?(Point).must_equal false
20
+ subject.instance_of?(Geometry::PointOne).must_equal true
21
+ end
22
+
23
+ it 'must have +@' do
24
+ (+one).must_be :eql?, 1
25
+ (+one).must_be_instance_of(Geometry::PointOne)
26
+ end
27
+
28
+ it 'must have unary negation' do
29
+ (-one).must_be :eql?, -1
30
+ # (-one).must_be_instance_of(Geometry::PointOne)
31
+ end
32
+
33
+ describe 'Accessors' do
34
+ it 'must return 1 for array access' do
35
+ one[3].must_equal 1
36
+ end
37
+
38
+ it 'must return 1 for named element access' do
39
+ one.x.must_equal 1
40
+ one.y.must_equal 1
41
+ one.z.must_equal 1
42
+ end
43
+ end
44
+
45
+ it 'must add a number' do
46
+ (one + 3).must_equal 4
47
+ (3 + one).must_equal 4
48
+ end
49
+
50
+ it 'return a Point when adding two Points' do
51
+ (one + right).must_be_kind_of Point
52
+ (left + one).must_be_kind_of Point
53
+ end
54
+
55
+ it 'must return an Array when adding an array' do
56
+ (one + [5,6]).must_equal [6, 7]
57
+ ([5,6] + one).must_equal [5,6]
58
+ end
59
+
60
+ it 'must return a Point when adding a Size' do
61
+ (one + Size[5,6]).must_be_instance_of(Point)
62
+ (one + Size[5,6]).must_equal Point[6,7]
63
+ end
64
+
65
+ describe 'when subtracting' do
66
+ it 'must subtract a number' do
67
+ (one - 3).must_equal -2
68
+ (3 - one).must_equal 2
69
+ end
70
+
71
+ it 'return a Point when subtracting two Points' do
72
+ (one - right).must_equal Point[-2, -3]
73
+ (left - one).must_equal Point[0, 1]
74
+ end
75
+
76
+ it 'must return a Point when subtracting an array' do
77
+ (one - [5,6]).must_equal [-4, -5]
78
+ # ([5,6] - one).must_equal [4,5]
79
+ end
80
+
81
+ it 'must return a Point when subtracting a Size' do
82
+ (one - Size[5,6]).must_be_instance_of(Point)
83
+ (one - Size[5,6]).must_equal Point[-4,-5]
84
+ end
85
+ end
86
+
87
+ it 'must multiply by a scalar' do
88
+ (one * 3).must_equal 3
89
+ (one * 3.0).must_equal 3.0
90
+ end
91
+
92
+ it 'must refuse to multiply by a Point' do
93
+ -> { one * Point[1, 2] }.must_raise Geometry::OperationNotDefined
94
+ end
95
+
96
+ it 'must refuse to multiply by a Vector' do
97
+ -> { one * Vector[2, 3] }.must_raise Geometry::OperationNotDefined
98
+ end
99
+
100
+ it 'must divide by a scalar' do
101
+ (one / 3).must_equal 1/3
102
+ (one / 4.0).must_equal 1/4.0
103
+ end
104
+
105
+ it 'must raise an exception when divided by 0' do
106
+ -> { one / 0 }.must_raise ZeroDivisionError
107
+ end
108
+
109
+ describe 'division' do
110
+ it 'must raise an exception for Points' do
111
+ lambda { one / Point[1,2] }.must_raise Geometry::OperationNotDefined
112
+ end
113
+
114
+ it 'must raise an exception for Vectors' do
115
+ lambda { one / Vector[1,2] }.must_raise Geometry::OperationNotDefined
116
+ end
117
+ end
118
+ end
119
+
120
+ describe 'coercion' do
121
+ it 'must coerce Arrays into Points' do
122
+ one.coerce([3,4]).must_equal [Point[3,4], Point[1, 1]]
123
+ end
124
+
125
+ it 'must coerce Vectors into Vectors' do
126
+ one.coerce(Vector[3,4]).must_equal [Vector[3,4], Vector[1, 1]]
127
+ end
128
+
129
+ it 'must coerce Points into Points' do
130
+ one.coerce(Point[5,6]).must_equal [Point[5,6], Point[1, 1]]
131
+ end
132
+ end
133
+
134
+ describe 'comparison' do
135
+ subject { Geometry::PointOne.new }
136
+
137
+ it 'must be equal to 1 and 1.0' do
138
+ one.must_be :eql?, 1
139
+ one.must_be :eql?, 1.0
140
+ end
141
+
142
+ it 'must not be equal to a non-one number' do
143
+ 0.wont_equal one
144
+ 3.14.wont_equal one
145
+ end
146
+
147
+ it 'must be equal to an Array of ones' do
148
+ one.must_be :==, [1,1]
149
+ one.must_be :eql?, [1,1]
150
+ one.must_be :===, [1,1]
151
+ [1, 1].must_equal one
152
+ one.must_equal [1, 1]
153
+ end
154
+
155
+ it 'must not be equal to a non-one Array' do
156
+ one.wont_equal [3, 2, 1]
157
+ [3, 2, 1].wont_equal one
158
+ end
159
+
160
+ it 'must not be equal to a Point at the origin' do
161
+ one.wont_be :==, Point[0,0]
162
+ one.wont_be :eql?, Point[0,0]
163
+ one.wont_be :===, Point[0,0]
164
+ Point[0,0].wont_equal one
165
+ subject.wont_equal Point[0,0]
166
+ end
167
+
168
+ it 'must not be equal to a Point not at the origin' do
169
+ one.wont_equal Point[3,2]
170
+ Point[3,2].wont_equal one
171
+ end
172
+
173
+ it 'must be equal to a Point of ones' do
174
+ one.must_be :==, Point[1,1]
175
+ one.must_be :eql?, Point[1,1]
176
+ one.must_be :===, Point[1,1]
177
+ Point[1,1].must_equal one
178
+ one.must_equal Point[1,1]
179
+ end
180
+
181
+ it 'must be equal to an Vector of ones' do
182
+ one.must_be :eql?, Vector[1, 1]
183
+ Vector[1, 1].must_equal one
184
+ end
185
+
186
+ it 'must not be equal to a non-one Vector' do
187
+ one.wont_equal Vector[3,2]
188
+ Vector[3,2].wont_equal one
189
+ end
190
+ end
191
+
192
+ describe 'when enumerating' do
193
+ it 'must have a first method' do
194
+ one.first.must_equal 1
195
+ one.first(1).must_equal [1]
196
+ one.first(5).must_equal [1,1,1,1,1]
197
+ end
198
+ end
199
+ end
@@ -2,12 +2,24 @@ require 'minitest/autorun'
2
2
  require 'geometry/point_zero'
3
3
 
4
4
  describe Geometry::PointZero do
5
+ subject { Geometry::PointZero.new }
5
6
  let(:zero) { Geometry::PointZero.new }
6
7
 
7
8
  describe "arithmetic" do
8
9
  let(:left) { Point[1,2] }
9
10
  let(:right) { Point[3,4] }
10
-
11
+
12
+ it 'must pretend to be a Point' do
13
+ subject.is_a?(Point).must_equal true
14
+ subject.kind_of?(Point).must_equal true
15
+
16
+ subject.is_a?(PointZero).must_equal true
17
+ subject.kind_of?(PointZero).must_equal true
18
+
19
+ subject.instance_of?(Point).must_equal false
20
+ subject.instance_of?(PointZero).must_equal true
21
+ end
22
+
11
23
  it "must have +@" do
12
24
  (+zero).must_be :eql?, 0
13
25
  (+zero).must_be_instance_of(Geometry::PointZero)
@@ -31,8 +43,9 @@ describe Geometry::PointZero do
31
43
  end
32
44
 
33
45
  describe "when adding" do
34
- it "must return a number" do
46
+ it "must return a PointIso when adding a number" do
35
47
  (zero + 3).must_equal 3
48
+ (zero + 3).must_be_instance_of Geometry::PointIso
36
49
  (3 + zero).must_equal 3
37
50
  end
38
51
 
@@ -174,4 +187,12 @@ describe Geometry::PointZero do
174
187
  Vector[3,2].wont_equal zero
175
188
  end
176
189
  end
190
+
191
+ describe 'when enumerating' do
192
+ it 'must have a first method' do
193
+ subject.first.must_equal 0
194
+ subject.first(1).must_equal [0]
195
+ subject.first(5).must_equal [0,0,0,0,0]
196
+ end
197
+ end
177
198
  end
@@ -22,6 +22,10 @@ describe Geometry::Polyline do
22
22
  polyline.vertices.count.must_equal 4
23
23
  end
24
24
 
25
+ it 'must have a points attribute' do
26
+ unit_square.points.must_equal [Point[0,0], Point[1,0], Point[1,1], Point[0,1]]
27
+ end
28
+
25
29
  it 'must know the max' do
26
30
  unit_square.max.must_equal Point[1,1]
27
31
  end
@@ -111,6 +111,10 @@ describe Geometry::Rectangle do
111
111
  rectangle.center.must_equal Point[2,3]
112
112
  end
113
113
 
114
+ it 'must always be closed' do
115
+ subject.closed?.must_equal true
116
+ end
117
+
114
118
  it "have a width property" do
115
119
  assert_equal(2, rectangle.width)
116
120
  end
@@ -4,7 +4,13 @@ require 'geometry/regular_polygon'
4
4
  describe Geometry::RegularPolygon do
5
5
  RegularPolygon = Geometry::RegularPolygon
6
6
 
7
- describe "when constructed with named center and radius arguments" do
7
+ subject { RegularPolygon.new sides:4, center:[1,2], radius:3 }
8
+
9
+ it 'must always be closed' do
10
+ subject.closed?.must_equal true
11
+ end
12
+
13
+ describe 'when constructed with a center and circumradius' do
8
14
  let(:polygon) { RegularPolygon.new sides:4, center:[1,2], radius:3 }
9
15
  subject { RegularPolygon.new sides:4, center:[1,2], radius:3 }
10
16
 
@@ -33,16 +39,19 @@ describe Geometry::RegularPolygon do
33
39
  subject.vertices.must_equal [Point[4.0, 2.0], Point[1.0000000000000002, 5.0], Point[-2.0, 2.0000000000000004], Point[0.9999999999999994, -1.0]]
34
40
  end
35
41
  end
42
+
43
+ it 'must have an indiameter' do
44
+ subject.indiameter.must_be_close_to 4.242
45
+ end
46
+
47
+ it 'must have an inradius' do
48
+ subject.inradius.must_be_close_to 2.121
49
+ end
36
50
  end
37
51
 
38
52
  describe "when constructed with a center and diameter" do
39
53
  let(:polygon) { RegularPolygon.new sides:4, center:[1,2], diameter:4 }
40
54
 
41
- it "must be a DiameterRegularPolygon" do
42
- polygon.must_be_instance_of(Geometry::DiameterRegularPolygon)
43
- polygon.must_be_kind_of(RegularPolygon)
44
- end
45
-
46
55
  it "must have the correct number of sides" do
47
56
  polygon.edge_count.must_equal 4
48
57
  end
@@ -67,11 +76,6 @@ describe Geometry::RegularPolygon do
67
76
  describe "when constructed with a diameter and no center" do
68
77
  let(:polygon) { RegularPolygon.new sides:4, diameter:4 }
69
78
 
70
- it "must be a DiameterRegularPolygon" do
71
- polygon.must_be_instance_of(Geometry::DiameterRegularPolygon)
72
- polygon.must_be_kind_of(RegularPolygon)
73
- end
74
-
75
79
  it "must have the correct number of sides" do
76
80
  polygon.edge_count.must_equal 4
77
81
  end
@@ -89,6 +93,41 @@ describe Geometry::RegularPolygon do
89
93
  end
90
94
  end
91
95
 
96
+ describe 'when constructed with an indiameter and center' do
97
+ subject { RegularPolygon.new sides:6, indiameter:4 }
98
+
99
+ it 'must have a circumdiameter' do
100
+ subject.diameter.must_be_close_to 4.618
101
+ end
102
+
103
+ it 'must have a circumradius' do
104
+ subject.circumradius.must_be_close_to 2.309
105
+ end
106
+
107
+ it 'must have an indiameter' do
108
+ subject.indiameter.must_be_close_to 4
109
+ end
110
+
111
+ it 'must have an inradius' do
112
+ subject.inradius.must_be_close_to 2
113
+ end
114
+ end
115
+
116
+ describe 'when constructed with an inradius and center' do
117
+ subject { RegularPolygon.new sides:6, inradius:4 }
118
+
119
+ it 'must have a circumradius' do
120
+ subject.circumradius.must_be_close_to 4.618
121
+ end
122
+
123
+ it 'must have points' do
124
+ expected_points = [Point[4.618, 0], Point[2.309, 4], Point[-2.309, 4], Point[-4.618, 0], Point[-2.309, -4], Point[2.309, -4]]
125
+ subject.points.zip(expected_points) do |point0, point1|
126
+ point0.to_a.zip(point1.to_a) {|a, b| a.must_be_close_to b }
127
+ end
128
+ end
129
+ end
130
+
92
131
  describe "properties" do
93
132
  subject { RegularPolygon.new sides:6, diameter:4 }
94
133
 
@@ -101,6 +140,13 @@ describe Geometry::RegularPolygon do
101
140
  end
102
141
  end
103
142
 
143
+ it 'must have points' do
144
+ expected_points = [Point[2, 0], Point[1, 1.732], Point[-1, 1.732], Point[-2, 0], Point[-1, -1.732], Point[1, -1.732]]
145
+ subject.points.zip(expected_points) do |point0, point1|
146
+ point0.to_a.zip(point1.to_a) {|a, b| a.must_be_close_to b }
147
+ end
148
+ end
149
+
104
150
  it "must have a bounds property that returns a Rectangle" do
105
151
  subject.bounds.must_equal Rectangle.new([-2,-2], [2,2])
106
152
  end
@@ -93,6 +93,8 @@ describe Geometry::Rotation do
93
93
  end
94
94
 
95
95
  describe "when transforming a Point" do
96
+ subject { Rotation.new(angle:Math::PI/2) }
97
+
96
98
  describe "when no rotation is set" do
97
99
  it "must return the Point" do
98
100
  Rotation.new.transform(Point[1,0]).must_equal Point[1,0]
@@ -104,5 +106,9 @@ describe Geometry::Rotation do
104
106
  rotated_point.x.must_be_close_to 0
105
107
  rotated_point.y.must_be_close_to 1
106
108
  end
109
+
110
+ it 'must transform a PointZero' do
111
+ subject.transform(Point.zero).must_equal Point.zero
112
+ end
107
113
  end
108
114
  end
@@ -41,12 +41,21 @@ describe Geometry::Size do
41
41
  end
42
42
  end
43
43
 
44
- it "allow indexed element access" do
45
- size = Geometry::Size[5,6]
46
- assert_equal(2, size.size)
47
- assert_equal(5, size[0])
48
- assert_equal(6, size[1])
44
+ describe 'when array access' do
45
+ it 'must allow indexed access' do
46
+ size = Geometry::Size[5,6]
47
+ size.size.must_equal 2
48
+ size[0].must_equal 5
49
+ size[1].must_equal 6
50
+ end
51
+
52
+ it 'must slize with a start index and a length' do
53
+ size = Geometry::Size[5, 6, 7]
54
+ slice = size[1,2]
55
+ slice.length.must_equal 2
56
+ end
49
57
  end
58
+
50
59
  it "allow named element access" do
51
60
  size = Geometry::Size[5,6,7]
52
61
  assert_equal(3, size.size)
@@ -99,9 +108,15 @@ describe Geometry::Size do
99
108
 
100
109
  it 'must inset with horizontal and vertical insets' do
101
110
  subject.inset(4).must_equal Geometry::Size[6, 6]
102
- subject.inset(2,3).must_equal Geometry::Size[8, 7]
103
- subject.inset(x:2, y:3).must_equal Geometry::Size[8, 7]
111
+ subject.inset(2,3).must_equal Geometry::Size[6, 4]
112
+ subject.inset(x:2, y:3).must_equal Geometry::Size[6, 4]
113
+ end
114
+
115
+ it 'must inset with left and top' do
104
116
  subject.inset(left:2, top:3).must_equal Geometry::Size[8, 7]
117
+ end
118
+
119
+ it 'must inset with right and bottom' do
105
120
  subject.inset(right:2, bottom:3).must_equal Geometry::Size[8, 7]
106
121
  end
107
122
 
@@ -111,13 +126,19 @@ describe Geometry::Size do
111
126
 
112
127
  it 'must outset' do
113
128
  subject.outset(4).must_equal Geometry::Size[14, 14]
114
- subject.outset(2,3).must_equal Geometry::Size[12, 13]
115
- subject.outset(x:2, y:3).must_equal Geometry::Size[12, 13]
129
+ subject.outset(2,3).must_equal Geometry::Size[14, 16]
130
+ subject.outset(x:2, y:3).must_equal Geometry::Size[14, 16]
131
+ end
132
+
133
+ it 'must outset with left and top' do
116
134
  subject.outset(left:2, top:3).must_equal Geometry::Size[12, 13]
135
+ end
136
+
137
+ it 'must outset with right and bottom' do
117
138
  subject.outset(right:2, bottom:3).must_equal Geometry::Size[12, 13]
118
139
  end
119
140
 
120
- it 'must inset with insets for top, left, bottom, right' do
141
+ it 'must outset with insets for top, left, bottom, right' do
121
142
  subject.outset(top:1, left:2, bottom:3, right:4).must_equal Geometry::Size[16, 14]
122
143
  end
123
144
  end