Skip to content

Commit 47dcb0b

Browse files
committed
finalized tests
1 parent 6beac29 commit 47dcb0b

3 files changed

Lines changed: 89 additions & 15 deletions

File tree

core/integer.rbs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -520,9 +520,9 @@ class Integer < Numeric
520520
#
521521
# Raises an exception if the slice cannot be constructed.
522522
#
523-
def []: (int) -> Integer
524-
| (int i, int len) -> Integer
525-
| (Range[int]) -> Integer
523+
def []: (int offset) -> (0 | 1)
524+
| (int offset, int size) -> Integer
525+
| (range[int?] range) -> Integer # Technically needs to have things beyond `int` (eg `<=>` and `coerce`), but too cumbersome to annotate
526526

527527
# <!--
528528
# rdoc-file=numeric.c
@@ -819,7 +819,6 @@ class Integer < Numeric
819819
def divmod: (O other) -> R
820820
end
821821

822-
823822
# <!--
824823
# rdoc-file=numeric.c
825824
# - downto(limit) {|i| ... } -> self
@@ -838,8 +837,10 @@ class Integer < Numeric
838837
#
839838
# With no block given, returns an Enumerator.
840839
#
841-
def downto: (Numeric limit) { (Integer) -> void } -> Integer
842-
| (Numeric limit) -> ::Enumerator[Integer, self]
840+
def downto: (Integer limit) { (Integer i) -> void } -> self
841+
| (Integer limit) -> Enumerator[Integer, self]
842+
| [S] (Numeric::_Coerce[self, RBS::Ops::_LessThan[S, boolish], S] other) { (Integer i) -> void } -> self
843+
| [S] (Numeric::_Coerce[self, RBS::Ops::_LessThan[S, boolish], S] other) -> Enumerator[Integer, self] # Technically, need more bounds for `size`?
843844

844845
# <!--
845846
# rdoc-file=numeric.rb
@@ -1341,8 +1342,10 @@ class Integer < Numeric
13411342
#
13421343
# With no block given, returns an Enumerator.
13431344
#
1344-
def upto: (Numeric limit) { (Integer) -> void } -> Integer
1345-
| (Numeric limit) -> ::Enumerator[Integer, self]
1345+
def upto: (Integer limit) { (Integer i) -> void } -> self
1346+
| (Integer limit) -> Enumerator[Integer, self]
1347+
| [S] (Numeric::_Coerce[self, RBS::Ops::_GreaterThan[S, boolish], S] other) { (Integer i) -> void } -> self
1348+
| [S] (Numeric::_Coerce[self, RBS::Ops::_GreaterThan[S, boolish], S] other) -> Enumerator[Integer, self] # Technically, need more bounds for `size`?
13461349

13471350
# <!--
13481351
# rdoc-file=numeric.rb

test/stdlib/Integer_test.rb

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,30 @@ def test_op_rsh
217217
end
218218

219219
def test_op_aref
220-
# omit 'todo'
220+
with_int 3 do |offset|
221+
assert_send_type '(int) -> (0 | 1)',
222+
38, :[], offset
223+
224+
with_int 5 do |size|
225+
assert_send_type '(int, int) -> Integer',
226+
38, :[], offset, size
227+
end
228+
end
229+
230+
assert_send_type '(range[int?]) -> Integer',
231+
38, :[], 3..nil
232+
assert_send_type '(range[int?]) -> Integer',
233+
38, :[], nil..0
234+
assert_send_type '(range[int?]) -> Integer',
235+
38, :[], 1r..3r
236+
assert_send_type '(range[int?]) -> Integer',
237+
38, :[], 1.0..3.0
238+
239+
start = ToInt.new(1)
240+
def start.<=>(other) = to_int <=> other.to_int
241+
def start.coerce(other) = [other.to_int, to_int]
242+
assert_send_type '(range[int?]) -> Integer',
243+
38, :[], CustomRange.new(start, ToInt.new(3))
221244
end
222245

223246
def test_op_xor
@@ -346,7 +369,26 @@ def test_divmod
346369
end
347370

348371
def test_downto
349-
# omit 'todo'
372+
assert_send_type '(Integer) { (Integer) -> void } -> 38',
373+
38, :downto, 35 do end
374+
assert_send_type '(Integer) -> Enumerator[Integer, 38]',
375+
38, :downto, 35
376+
assert_send_type '(Rational) { (Integer) -> void } -> 38',
377+
38, :downto, 35r do end
378+
assert_send_type '(Rational) -> Enumerator[Integer, 38]',
379+
38, :downto, 35r
380+
assert_send_type '(Float) { (Integer) -> void } -> 38',
381+
38, :downto, 35.0 do end
382+
assert_send_type '(Float) -> Enumerator[Integer, 38]',
383+
38, :downto, 35.0
384+
385+
assert_send_type '(Coercable) { (Integer) -> void } -> 38',
386+
38, :downto, Coercable.for_op(:<) { it.__value__ < 35 } do end
387+
388+
coercable = Coercable.for_op(:<) { it.__value__ < 35 }
389+
def coercable.-(rhs) = 35 - rhs # Required by `Enumerator#size`, which the unit test harness uses
390+
assert_send_type '(Coercable) -> Enumerator[Integer, 38]',
391+
38, :downto, coercable
350392
end
351393

352394
def test_even?
@@ -568,7 +610,26 @@ def test_truncate
568610
end
569611

570612
def test_upto
571-
# omit 'todo'
613+
assert_send_type '(Integer) { (Integer) -> void } -> 38',
614+
38, :upto, 40 do end
615+
assert_send_type '(Integer) -> Enumerator[Integer, 38]',
616+
38, :upto, 40
617+
assert_send_type '(Rational) { (Integer) -> void } -> 38',
618+
38, :upto, 40r do end
619+
assert_send_type '(Rational) -> Enumerator[Integer, 38]',
620+
38, :upto, 40r
621+
assert_send_type '(Float) { (Integer) -> void } -> 38',
622+
38, :upto, 40.0 do end
623+
assert_send_type '(Float) -> Enumerator[Integer, 38]',
624+
38, :upto, 40.0
625+
626+
assert_send_type '(Coercable) { (Integer) -> void } -> 38',
627+
38, :upto, Coercable.for_op(:>) { it.__value__ > 40 } do end
628+
629+
coercable = Coercable.for_op(:>) { it.__value__ > 40 }
630+
def coercable.-(rhs) = 40 - rhs # Required by `Enumerator#size`, which the unit test harness uses
631+
assert_send_type '(Coercable) -> Enumerator[Integer, 38]',
632+
38, :upto, coercable
572633
end
573634

574635
def test_zero?

test/stdlib/test_helper.rb

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,16 +85,26 @@ class OpReturn < ::RBS::UnitTest::Convertibles::BlankSlate
8585
end
8686

8787
class CoerceOther < ::RBS::UnitTest::Convertibles::BlankSlate
88+
attr_reader :__value__
89+
def initialize(value) = @__value__ = value
8890
end
8991

9092
class CoerceSelf < ::RBS::UnitTest::Convertibles::BlankSlate
91-
def initialize(method, result:)
92-
::Kernel.instance_method(:define_singleton_method).bind_call(self, method) { |other| result }
93+
def initialize(method, &block)
94+
::Kernel.instance_method(:define_singleton_method).bind_call(self, method, &block)
9395
end
9496
end
9597

96-
def self.for_op(method, result: OpReturn.new)
97-
new(CoerceSelf.new(method, result:)){ |x| CoerceOther.new }
98+
def self.for_op(method, result: noresult = true, &block)
99+
if block_given?
100+
unless noresult
101+
raise ArgumentError, "cannot provide both a block and a result"
102+
end
103+
else
104+
block = proc { |other| noresult ? OpReturn.new : result }
105+
end
106+
107+
new(CoerceSelf.new(method, &block)) { |x| CoerceOther.new(x) }
98108
end
99109

100110
def initialize(self_ret, &converter)

0 commit comments

Comments
 (0)