summaryrefslogtreecommitdiff
path: root/test/ruby/test_comparable.rb
blob: b849217b7d4216b3b9eb68000a61afa4b929f47a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# frozen_string_literal: false
require 'test/unit'

class TestComparable < Test::Unit::TestCase
  def setup
    @o = Object.new
    @o.extend(Comparable)
  end
  def cmp(b)
    class << @o; self; end.class_eval {
      undef :<=>
      define_method(:<=>, b)
    }
  end

  def test_equal
    cmp->(x) do 0; end
    assert_equal(true, @o == nil)
    cmp->(x) do 1; end
    assert_equal(false, @o == nil)
    cmp->(x) do nil; end
    assert_equal(false, @o == nil)

    cmp->(x) do raise NotImplementedError, "Not a RuntimeError" end
    assert_raise(NotImplementedError) { @o == nil }

    bug7688 = 'Comparable#== should not silently rescue' \
              'any Exception [ruby-core:51389] [Bug #7688]'
    cmp->(x) do raise StandardError end
    assert_raise(StandardError, bug7688) { @o == nil }
    cmp->(x) do "bad value"; end
    assert_raise(ArgumentError, bug7688) { @o == nil }
  end

  def test_gt
    cmp->(x) do 1; end
    assert_equal(true, @o > nil)
    cmp->(x) do 0; end
    assert_equal(false, @o > nil)
    cmp->(x) do -1; end
    assert_equal(false, @o > nil)
  end

  def test_ge
    cmp->(x) do 1; end
    assert_equal(true, @o >= nil)
    cmp->(x) do 0; end
    assert_equal(true, @o >= nil)
    cmp->(x) do -1; end
    assert_equal(false, @o >= nil)
  end

  def test_lt
    cmp->(x) do 1; end
    assert_equal(false, @o < nil)
    cmp->(x) do 0; end
    assert_equal(false, @o < nil)
    cmp->(x) do -1; end
    assert_equal(true, @o < nil)
  end

  def test_le
    cmp->(x) do 1; end
    assert_equal(false, @o <= nil)
    cmp->(x) do 0; end
    assert_equal(true, @o <= nil)
    cmp->(x) do -1; end
    assert_equal(true, @o <= nil)
  end

  def test_between
    cmp->(x) do 0 <=> x end
    assert_equal(false, @o.between?(1, 2))
    assert_equal(false, @o.between?(-2, -1))
    assert_equal(true, @o.between?(-1, 1))
    assert_equal(true, @o.between?(0, 0))
  end

  def test_clamp
    cmp->(x) do 0 <=> x end
    assert_equal(1, @o.clamp(1, 2))
    assert_equal(-1, @o.clamp(-2, -1))
    assert_equal(@o, @o.clamp(-1, 3))

    assert_equal(1, @o.clamp(1, 1))
    assert_equal(@o, @o.clamp(0, 0))

    assert_raise_with_message(ArgumentError, 'min argument must be smaller than max argument') {
      @o.clamp(2, 1)
    }
  end

  def test_clamp_with_range
    cmp->(x) do 0 <=> x end
    assert_equal(1, @o.clamp(1..2))
    assert_equal(-1, @o.clamp(-2..-1))
    assert_equal(@o, @o.clamp(-1..3))

    assert_equal(1, @o.clamp(1..1))
    assert_equal(@o, @o.clamp(0..0))

    assert_equal(1, @o.clamp(1..))
    assert_equal(1, @o.clamp(1...))
    assert_equal(@o, @o.clamp(0..))
    assert_equal(@o, @o.clamp(0...))
    assert_equal(@o, @o.clamp(..2))
    assert_equal(-1, @o.clamp(-2..-1))
    assert_equal(@o, @o.clamp(-2..0))
    assert_equal(@o, @o.clamp(-2..))
    assert_equal(@o, @o.clamp(-2...))

    exc = [ArgumentError, 'cannot clamp with an exclusive range']
    assert_raise_with_message(*exc) {@o.clamp(1...2)}
    assert_raise_with_message(*exc) {@o.clamp(0...2)}
    assert_raise_with_message(*exc) {@o.clamp(-1...0)}
    assert_raise_with_message(*exc) {@o.clamp(...2)}

    assert_raise_with_message(ArgumentError, 'min argument must be smaller than max argument') {
      @o.clamp(2..1)
    }
  end

  def test_err
    assert_raise(ArgumentError) { 1.0 < nil }
    assert_raise(ArgumentError) { 1.0 < Object.new }
    e = EnvUtil.labeled_class("E\u{30a8 30e9 30fc}")
    assert_raise_with_message(ArgumentError, /E\u{30a8 30e9 30fc}/) {
      1.0 < e.new
    }
  end

  def test_inversed_compare
    bug7870 = '[ruby-core:52305] [Bug #7870]'
    assert_nothing_raised(SystemStackError, bug7870) {
      assert_nil(Time.new <=> "")
    }
  end

  def test_no_cmp
    bug9003 = '[ruby-core:57736] [Bug #9003]'
    assert_nothing_raised(SystemStackError, bug9003) {
      @o <=> @o.dup
    }
  end
end