summaryrefslogtreecommitdiff
path: root/test/ruby/test_name_error.rb
blob: f0402de4b93c4b4b3c280686933ffed597898db9 (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
146
147
148
149
150
151
152
153
154
155
156
require 'test/unit'

class TestNameError < Test::Unit::TestCase
  def test_new_default
    error = NameError.new
    assert_equal("NameError", error.message)
  end

  def test_new_message
    error = NameError.new("Message")
    assert_equal("Message", error.message)
  end

  def test_new_name
    error = NameError.new("Message")
    assert_nil(error.name)

    error = NameError.new("Message", :foo)
    assert_equal(:foo, error.name)
  end

  def test_new_receiver
    receiver = Object.new

    error = NameError.new
    assert_raise(ArgumentError) {error.receiver}
    assert_equal("NameError", error.message)

    error = NameError.new(receiver: receiver)
    assert_equal(["NameError", receiver],
                 [error.message, error.receiver])

    error = NameError.new("Message", :foo, receiver: receiver)
    assert_equal(["Message", receiver, :foo],
                 [error.message, error.receiver, error.name])
  end

  PrettyObject =
    Class.new(BasicObject) do
      alias object_id __id__
      def pretty_inspect; "`obj'"; end
      alias inspect pretty_inspect
    end

  def test_info_const
    obj = PrettyObject.new

    e = assert_raise(NameError) {
      obj.instance_eval("Object")
    }
    assert_equal(:Object, e.name)

    e = assert_raise(NameError) {
      BasicObject::X
    }
    assert_same(BasicObject, e.receiver)
    assert_equal(:X, e.name)
  end

  def test_info_const_name
    mod = Module.new do
      def self.name
        "ModuleName"
      end

      def self.inspect
        raise "<unusable info>"
      end
    end
    assert_raise_with_message(NameError, /ModuleName/) {mod::DOES_NOT_EXIST}
  end

  def test_info_method
    obj = PrettyObject.new

    e = assert_raise(NameError) {
      obj.instance_eval {foo}
    }
    assert_equal(:foo, e.name)
    assert_same(obj, e.receiver)

    e = assert_raise(NoMethodError) {
      obj.foo(1, 2)
    }
    assert_equal(:foo, e.name)
    assert_equal([1, 2], e.args)
    assert_same(obj, e.receiver)
    assert_not_predicate(e, :private_call?)

    e = assert_raise(NoMethodError) {
      obj.instance_eval {foo(1, 2)}
    }
    assert_equal(:foo, e.name)
    assert_equal([1, 2], e.args)
    assert_same(obj, e.receiver)
    assert_predicate(e, :private_call?)
  end

  def test_info_local_variables
    obj = PrettyObject.new
    def obj.test(a, b=nil, *c, &d)
      e = a
      1.times {|f| g = foo; g}
      e
    end

    e = assert_raise(NameError) {
      obj.test(3)
    }
    assert_equal(:foo, e.name)
    assert_same(obj, e.receiver)
    assert_equal(%i[a b c d e f g], e.local_variables.sort)
  end

  def test_info_method_missing
    obj = PrettyObject.new
    def obj.method_missing(*)
      super
    end

    e = assert_raise(NoMethodError) {
      obj.foo(1, 2)
    }
    assert_equal(:foo, e.name)
    assert_equal([1, 2], e.args)
    assert_same(obj, e.receiver)
    assert_not_predicate(e, :private_call?)

    e = assert_raise(NoMethodError) {
      obj.instance_eval {foo(1, 2)}
    }
    assert_equal(:foo, e.name)
    assert_equal([1, 2], e.args)
    assert_same(obj, e.receiver)
    assert_predicate(e, :private_call?)
  end

  def test_info_parent_iseq_mark
    assert_separately(['-', File.join(__dir__, 'bug-11928.rb')], <<-'end;')
      -> {require ARGV[0]}.call
    end;
  end

  def test_large_receiver_inspect
    receiver = Class.new do
      def self.inspect
        'A' * 120
      end
    end

    error = assert_raise(NameError) do
      receiver::FOO
    end
    assert_match(/\Auninitialized constant #{'A' * 120}::FOO$/, error.message)
  end
end