1 | class UserDefinedNumeric < Numeric
|
---|
2 | def initialize(n)
|
---|
3 | @n = n
|
---|
4 | end
|
---|
5 |
|
---|
6 | def <=>(rhs)
|
---|
7 | return nil unless rhs.respond_to?(:to_i)
|
---|
8 | rhs = rhs.to_i
|
---|
9 | rhs < 0 ? nil : @n <=> rhs
|
---|
10 | end
|
---|
11 |
|
---|
12 | def inspect
|
---|
13 | "#{self.class}(#{@n})"
|
---|
14 | end
|
---|
15 | end
|
---|
16 |
|
---|
17 | class ComplexLikeNumeric < UserDefinedNumeric
|
---|
18 | def ==(rhs)
|
---|
19 | @n == 0 && rhs == 0
|
---|
20 | end
|
---|
21 |
|
---|
22 | undef <=>
|
---|
23 | end
|
---|
24 |
|
---|
25 | def assert_rational(exp, real)
|
---|
26 | assert "assert_rational" do
|
---|
27 | assert_float exp.numerator, real.numerator
|
---|
28 | assert_float exp.denominator, real.denominator
|
---|
29 | end
|
---|
30 | end
|
---|
31 |
|
---|
32 | def assert_equal_rational(exp, o1, o2)
|
---|
33 | assert "assert_equal_rational" do
|
---|
34 | if exp
|
---|
35 | assert_operator(o1, :==, o2)
|
---|
36 | assert_not_operator(o1, :!=, o2)
|
---|
37 | else
|
---|
38 | assert_not_operator(o1, :==, o2)
|
---|
39 | assert_operator(o1, :!=, o2)
|
---|
40 | end
|
---|
41 | end
|
---|
42 | end
|
---|
43 |
|
---|
44 | def assert_cmp(exp, o1, o2)
|
---|
45 | if exp == (o1 <=> o2)
|
---|
46 | pass
|
---|
47 | else
|
---|
48 | flunk "", " Expected #{o1.inspect} <=> #{o2.inspect} to be #{exp}."
|
---|
49 | end
|
---|
50 | end
|
---|
51 |
|
---|
52 | assert 'Rational' do
|
---|
53 | r = 5r
|
---|
54 | assert_equal(Rational, r.class)
|
---|
55 | assert_equal([5, 1], [r.numerator, r.denominator])
|
---|
56 | end
|
---|
57 |
|
---|
58 | assert 'Kernel#Rational' do
|
---|
59 | r = Rational(4,10)
|
---|
60 | assert_equal(2, r.numerator)
|
---|
61 | assert_equal(5, r.denominator)
|
---|
62 |
|
---|
63 | r = Rational(3)
|
---|
64 | assert_equal(3, r.numerator)
|
---|
65 | assert_equal(1, r.denominator)
|
---|
66 |
|
---|
67 | assert_raise(ArgumentError) { Rational() }
|
---|
68 | assert_raise(ArgumentError) { Rational(1,2,3) }
|
---|
69 | end
|
---|
70 |
|
---|
71 | assert 'Rational#to_f' do
|
---|
72 | assert_float(2.0, Rational(2).to_f)
|
---|
73 | assert_float(2.25, Rational(9, 4).to_f)
|
---|
74 | assert_float(-0.75, Rational(-3, 4).to_f)
|
---|
75 | assert_float(6.666666666666667, Rational(20, 3).to_f)
|
---|
76 | end
|
---|
77 |
|
---|
78 | assert 'Rational#to_i' do
|
---|
79 | assert_equal(0, Rational(2, 3).to_i)
|
---|
80 | assert_equal(3, Rational(3).to_i)
|
---|
81 | assert_equal(300, Rational(300.6).to_i)
|
---|
82 | assert_equal(1, Rational(98, 71).to_i)
|
---|
83 | assert_equal(-15, Rational(-30, 2).to_i)
|
---|
84 | end
|
---|
85 |
|
---|
86 | assert 'Rational#*' do
|
---|
87 | assert_rational(Rational(4, 9), Rational(2, 3) * Rational(2, 3))
|
---|
88 | assert_rational(Rational(900, 1), Rational(900) * Rational(1))
|
---|
89 | assert_rational(Rational(1, 1), Rational(-2, 9) * Rational(-9, 2))
|
---|
90 | assert_rational(Rational(9, 2), Rational(9, 8) * 4)
|
---|
91 | assert_float( 21.77777777777778, Rational(20, 9) * 9.8)
|
---|
92 | end
|
---|
93 |
|
---|
94 | assert 'Rational#+' do
|
---|
95 | assert_rational(Rational(4, 3), Rational(2, 3) + Rational(2, 3))
|
---|
96 | assert_rational(Rational(901, 1), Rational(900) + Rational(1))
|
---|
97 | assert_rational(Rational(-85, 18), Rational(-2, 9) + Rational(-9, 2))
|
---|
98 | assert_rational(Rational(41, 8), Rational(9, 8) + 4)
|
---|
99 | assert_float( 12.022222222222222, Rational(20, 9) + 9.8)
|
---|
100 | end
|
---|
101 |
|
---|
102 | assert 'Rational#-' do
|
---|
103 | assert_rational(Rational(0, 1), Rational(2, 3) - Rational(2, 3))
|
---|
104 | assert_rational(Rational(899, 1), Rational(900) - Rational(1))
|
---|
105 | assert_rational(Rational(77, 18), Rational(-2, 9) - Rational(-9, 2))
|
---|
106 | assert_rational(Rational(-23, 8), Rational(9, 8) - 4)
|
---|
107 | assert_float( -7.577777777777778, Rational(20, 9) - 9.8)
|
---|
108 | end
|
---|
109 |
|
---|
110 | assert 'Rational#/' do
|
---|
111 | assert_rational(Rational(1, 1), Rational(2, 3) / Rational(2, 3))
|
---|
112 | assert_rational(Rational(900, 1), Rational(900) / Rational(1))
|
---|
113 | assert_rational(Rational(4, 81), Rational(-2, 9) / Rational(-9, 2))
|
---|
114 | assert_rational(Rational(9, 32), Rational(9, 8) / 4)
|
---|
115 | assert_float( 0.22675736961451246, Rational(20, 9) / 9.8)
|
---|
116 | end
|
---|
117 |
|
---|
118 | assert 'Rational#==, Rational#!=' do
|
---|
119 | assert_equal_rational(true, Rational(1,1), Rational(1))
|
---|
120 | assert_equal_rational(true, Rational(-1,1), -1r)
|
---|
121 | assert_equal_rational(true, Rational(13,4), 3.25)
|
---|
122 | assert_equal_rational(true, Rational(13,3.25), Rational(4,1))
|
---|
123 | assert_equal_rational(true, Rational(-3,-4), Rational(3,4))
|
---|
124 | assert_equal_rational(true, Rational(-4,5), Rational(4,-5))
|
---|
125 | assert_equal_rational(true, Rational(4,2), 2)
|
---|
126 | assert_equal_rational(true, Rational(-4,2), -2)
|
---|
127 | assert_equal_rational(true, Rational(4,-2), -2)
|
---|
128 | assert_equal_rational(true, Rational(4,2), 2.0)
|
---|
129 | assert_equal_rational(true, Rational(-4,2), -2.0)
|
---|
130 | assert_equal_rational(true, Rational(4,-2), -2.0)
|
---|
131 | assert_equal_rational(true, Rational(8,6), Rational(4,3))
|
---|
132 | assert_equal_rational(false, Rational(13,4), 3)
|
---|
133 | assert_equal_rational(false, Rational(13,4), 3.3)
|
---|
134 | assert_equal_rational(false, Rational(2,1), 1r)
|
---|
135 | assert_equal_rational(false, Rational(1), nil)
|
---|
136 | assert_equal_rational(false, Rational(1), '')
|
---|
137 | assert_equal_rational(true, 0r, UserDefinedNumeric.new(0))
|
---|
138 | assert_equal_rational(true, 1r, UserDefinedNumeric.new(1))
|
---|
139 | assert_equal_rational(false, 1r, UserDefinedNumeric.new(2))
|
---|
140 | assert_equal_rational(false, -1r, UserDefinedNumeric.new(-1))
|
---|
141 | assert_equal_rational(true, 0r, ComplexLikeNumeric.new(0))
|
---|
142 | assert_equal_rational(false, 1r, ComplexLikeNumeric.new(1))
|
---|
143 | assert_equal_rational(false, 1r, ComplexLikeNumeric.new(2))
|
---|
144 | end
|
---|
145 |
|
---|
146 | assert 'Fixnum#==(Rational), Fixnum#!=(Rational)' do
|
---|
147 | assert_equal_rational(true, 2, Rational(4,2))
|
---|
148 | assert_equal_rational(true, -2, Rational(-4,2))
|
---|
149 | assert_equal_rational(true, -2, Rational(4,-2))
|
---|
150 | assert_equal_rational(false, 3, Rational(13,4))
|
---|
151 | end
|
---|
152 |
|
---|
153 | assert 'Float#==(Rational), Float#!=(Rational)' do
|
---|
154 | assert_equal_rational(true, 2.0, Rational(4,2))
|
---|
155 | assert_equal_rational(true, -2.0, Rational(-4,2))
|
---|
156 | assert_equal_rational(true, -2.0, Rational(4,-2))
|
---|
157 | assert_equal_rational(false, 3.3, Rational(13,4))
|
---|
158 | end
|
---|
159 |
|
---|
160 | assert 'Rational#<=>' do
|
---|
161 | assert_cmp(-1, Rational(-1), Rational(0))
|
---|
162 | assert_cmp(0, Rational(0), Rational(0))
|
---|
163 | assert_cmp(1, Rational(1), Rational(0))
|
---|
164 | assert_cmp(-1, Rational(-1), 0)
|
---|
165 | assert_cmp(0, Rational(0), 0)
|
---|
166 | assert_cmp(1, Rational(1), 0)
|
---|
167 | assert_cmp(-1, Rational(-1), 0.0)
|
---|
168 | assert_cmp(0, Rational(0), 0.0)
|
---|
169 | assert_cmp(1, Rational(1), 0.0)
|
---|
170 | assert_cmp(-1, Rational(1,2), Rational(2,3))
|
---|
171 | assert_cmp(0, Rational(2,3), Rational(2,3))
|
---|
172 | assert_cmp(1, Rational(2,3), Rational(1,2))
|
---|
173 | assert_cmp(1, Rational(2,3), Rational(1,2))
|
---|
174 | assert_cmp(1, Rational(0), Rational(-1))
|
---|
175 | assert_cmp(-1, Rational(0), Rational(1))
|
---|
176 | assert_cmp(1, Rational(2,3), Rational(1,2))
|
---|
177 | assert_cmp(0, Rational(2,3), Rational(2,3))
|
---|
178 | assert_cmp(-1, Rational(1,2), Rational(2,3))
|
---|
179 | assert_cmp(-1, Rational(1,2), Rational(2,3))
|
---|
180 | assert_cmp(nil, 3r, "3")
|
---|
181 | assert_cmp(1, 3r, UserDefinedNumeric.new(2))
|
---|
182 | assert_cmp(0, 3r, UserDefinedNumeric.new(3))
|
---|
183 | assert_cmp(-1, 3r, UserDefinedNumeric.new(4))
|
---|
184 | assert_cmp(nil, Rational(-3), UserDefinedNumeric.new(5))
|
---|
185 | assert_raise(NoMethodError) { 0r <=> ComplexLikeNumeric.new(0) }
|
---|
186 | assert_raise(NoMethodError) { 1r <=> ComplexLikeNumeric.new(2) }
|
---|
187 | end
|
---|
188 |
|
---|
189 | assert 'Fixnum#<=>(Rational)' do
|
---|
190 | assert_cmp(-1, -2, Rational(-9,5))
|
---|
191 | assert_cmp(0, 5, 5r)
|
---|
192 | assert_cmp(1, 3, Rational(8,3))
|
---|
193 | end
|
---|
194 |
|
---|
195 | assert 'Float#<=>(Rational)' do
|
---|
196 | assert_cmp(-1, -2.1, Rational(-9,5))
|
---|
197 | assert_cmp(0, 5.0, 5r)
|
---|
198 | assert_cmp(1, 2.7, Rational(8,3))
|
---|
199 | end
|
---|
200 |
|
---|
201 | assert 'Rational#<' do
|
---|
202 | assert_operator(Rational(1,2), :<, Rational(2,3))
|
---|
203 | assert_not_operator(Rational(2,3), :<, Rational(2,3))
|
---|
204 | assert_operator(Rational(2,3), :<, 1)
|
---|
205 | assert_not_operator(2r, :<, 2)
|
---|
206 | assert_not_operator(Rational(2,3), :<, -3)
|
---|
207 | assert_operator(Rational(-4,3), :<, -0.3)
|
---|
208 | assert_not_operator(Rational(13,4), :<, 3.25)
|
---|
209 | assert_not_operator(Rational(2,3), :<, 0.6)
|
---|
210 | assert_raise(ArgumentError) { 1r < "2" }
|
---|
211 | end
|
---|
212 |
|
---|
213 | assert 'Fixnum#<(Rational)' do
|
---|
214 | assert_not_operator(1, :<, Rational(2,3))
|
---|
215 | assert_not_operator(2, :<, 2r)
|
---|
216 | assert_operator(-3, :<, Rational(2,3))
|
---|
217 | end
|
---|
218 |
|
---|
219 | assert 'Float#<(Rational)' do
|
---|
220 | assert_not_operator(-0.3, :<, Rational(-4,3))
|
---|
221 | assert_not_operator(3.25, :<, Rational(13,4))
|
---|
222 | assert_operator(0.6, :<, Rational(2,3))
|
---|
223 | end
|
---|
224 |
|
---|
225 | assert 'Rational#<=' do
|
---|
226 | assert_operator(Rational(1,2), :<=, Rational(2,3))
|
---|
227 | assert_operator(Rational(2,3), :<=, Rational(2,3))
|
---|
228 | assert_operator(Rational(2,3), :<=, 1)
|
---|
229 | assert_operator(2r, :<=, 2)
|
---|
230 | assert_not_operator(Rational(2,3), :<=, -3)
|
---|
231 | assert_operator(Rational(-4,3), :<=, -0.3)
|
---|
232 | assert_operator(Rational(13,4), :<=, 3.25)
|
---|
233 | assert_not_operator(Rational(2,3), :<=, 0.6)
|
---|
234 | assert_raise(ArgumentError) { 1r <= "2" }
|
---|
235 | end
|
---|
236 |
|
---|
237 | assert 'Fixnum#<=(Rational)' do
|
---|
238 | assert_not_operator(1, :<=, Rational(2,3))
|
---|
239 | assert_operator(2, :<=, 2r)
|
---|
240 | assert_operator(-3, :<=, Rational(2,3))
|
---|
241 | end
|
---|
242 |
|
---|
243 | assert 'Float#<=(Rational)' do
|
---|
244 | assert_not_operator(-0.3, :<=, Rational(-4,3))
|
---|
245 | assert_operator(3.25, :<=, Rational(13,4))
|
---|
246 | assert_operator(0.6, :<=, Rational(2,3))
|
---|
247 | end
|
---|
248 |
|
---|
249 | assert 'Rational#>' do
|
---|
250 | assert_not_operator(Rational(1,2), :>, Rational(2,3))
|
---|
251 | assert_not_operator(Rational(2,3), :>, Rational(2,3))
|
---|
252 | assert_not_operator(Rational(2,3), :>, 1)
|
---|
253 | assert_not_operator(2r, :>, 2)
|
---|
254 | assert_operator(Rational(2,3), :>, -3)
|
---|
255 | assert_not_operator(Rational(-4,3), :>, -0.3)
|
---|
256 | assert_not_operator(Rational(13,4), :>, 3.25)
|
---|
257 | assert_operator(Rational(2,3), :>, 0.6)
|
---|
258 | assert_raise(ArgumentError) { 1r > "2" }
|
---|
259 | end
|
---|
260 |
|
---|
261 | assert 'Fixnum#>(Rational)' do
|
---|
262 | assert_operator(1, :>, Rational(2,3))
|
---|
263 | assert_not_operator(2, :>, 2r)
|
---|
264 | assert_not_operator(-3, :>, Rational(2,3))
|
---|
265 | end
|
---|
266 |
|
---|
267 | assert 'Float#>(Rational)' do
|
---|
268 | assert_operator(-0.3, :>, Rational(-4,3))
|
---|
269 | assert_not_operator(3.25, :>, Rational(13,4))
|
---|
270 | assert_not_operator(0.6, :>, Rational(2,3))
|
---|
271 | end
|
---|
272 |
|
---|
273 | assert 'Rational#>=' do
|
---|
274 | assert_not_operator(Rational(1,2), :>=, Rational(2,3))
|
---|
275 | assert_operator(Rational(2,3), :>=, Rational(2,3))
|
---|
276 | assert_not_operator(Rational(2,3), :>=, 1)
|
---|
277 | assert_operator(2r, :>=, 2)
|
---|
278 | assert_operator(Rational(2,3), :>=, -3)
|
---|
279 | assert_not_operator(Rational(-4,3), :>=, -0.3)
|
---|
280 | assert_operator(Rational(13,4), :>=, 3.25)
|
---|
281 | assert_operator(Rational(2,3), :>=, 0.6)
|
---|
282 | assert_raise(ArgumentError) { 1r >= "2" }
|
---|
283 | end
|
---|
284 |
|
---|
285 | assert 'Fixnum#>=(Rational)' do
|
---|
286 | assert_operator(1, :>=, Rational(2,3))
|
---|
287 | assert_operator(2, :>=, 2r)
|
---|
288 | assert_not_operator(-3, :>=, Rational(2,3))
|
---|
289 | end
|
---|
290 |
|
---|
291 | assert 'Float#>=(Rational)' do
|
---|
292 | assert_operator(-0.3, :>=, Rational(-4,3))
|
---|
293 | assert_operator(3.25, :>=, Rational(13,4))
|
---|
294 | assert_not_operator(0.6, :>=, Rational(2,3))
|
---|
295 | end
|
---|
296 |
|
---|
297 | assert 'Rational#negative?' do
|
---|
298 | assert_predicate(Rational(-2,3), :negative?)
|
---|
299 | assert_predicate(Rational(2,-3), :negative?)
|
---|
300 | assert_not_predicate(Rational(2,3), :negative?)
|
---|
301 | assert_not_predicate(Rational(0), :negative?)
|
---|
302 | end
|
---|
303 |
|
---|
304 | assert 'Rational#frozen?' do
|
---|
305 | assert_predicate(1r, :frozen?)
|
---|
306 | assert_predicate(Rational(2,3), :frozen?)
|
---|
307 | assert_predicate(4/5r, :frozen?)
|
---|
308 | end
|
---|