summaryrefslogtreecommitdiff
path: root/spec/ruby/core/module/set_temporary_name_spec.rb
blob: 46605ed6758877013c935d7823c0a1426f8448ac (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
require_relative '../../spec_helper'
require_relative 'fixtures/set_temporary_name'

ruby_version_is "3.3" do
  describe "Module#set_temporary_name" do
    it "can assign a temporary name" do
      m = Module.new
      m.name.should be_nil

      m.set_temporary_name("fake_name")
      m.name.should == "fake_name"

      m.set_temporary_name(nil)
      m.name.should be_nil
    end

    it "returns self" do
      m = Module.new
      m.set_temporary_name("fake_name").should.equal? m
    end

    it "can assign a temporary name which is not a valid constant path" do
      m = Module.new

      m.set_temporary_name("name")
      m.name.should == "name"

      m.set_temporary_name("Template['foo.rb']")
      m.name.should == "Template['foo.rb']"

      m.set_temporary_name("a::B")
      m.name.should == "a::B"

      m.set_temporary_name("A::b")
      m.name.should == "A::b"

      m.set_temporary_name("A::B::")
      m.name.should == "A::B::"

      m.set_temporary_name("A::::B")
      m.name.should == "A::::B"

      m.set_temporary_name("A=")
      m.name.should == "A="
    end

    it "can't assign empty string as name" do
      m = Module.new
      -> { m.set_temporary_name("") }.should raise_error(ArgumentError, "empty class/module name")
    end

    it "can't assign a constant name as a temporary name" do
      m = Module.new
      -> { m.set_temporary_name("Object") }.should raise_error(ArgumentError, "the temporary name must not be a constant path to avoid confusion")
    end

    it "can't assign a constant path as a temporary name" do
      m = Module.new
      -> { m.set_temporary_name("A::B") }.should raise_error(ArgumentError, "the temporary name must not be a constant path to avoid confusion")
      -> { m.set_temporary_name("::A") }.should raise_error(ArgumentError, "the temporary name must not be a constant path to avoid confusion")
      -> { m.set_temporary_name("::A::B") }.should raise_error(ArgumentError, "the temporary name must not be a constant path to avoid confusion")
    end

    it "can't assign name to permanent module" do
      -> { Object.set_temporary_name("fake_name") }.should raise_error(RuntimeError, "can't change permanent name")
    end

    it "can assign a temporary name to a module nested into an anonymous module" do
      m = Module.new
      module m::N; end
      m::N.name.should =~ /\A#<Module:0x\h+>::N\z/

      m::N.set_temporary_name("fake_name")
      m::N.name.should == "fake_name"

      m::N.set_temporary_name(nil)
      m::N.name.should be_nil
    end

    it "discards a temporary name when an outer anonymous module gets a permanent name" do
      m = Module.new
      module m::N; end

      m::N.set_temporary_name("fake_name")
      m::N.name.should == "fake_name"

      ModuleSpecs::SetTemporaryNameSpec::M = m
      m::N.name.should == "ModuleSpecs::SetTemporaryNameSpec::M::N"
      ModuleSpecs::SetTemporaryNameSpec.send :remove_const, :M
    end

    it "can update the name when assigned to a constant" do
      m = Module.new
      m::N = Module.new
      m::N.name.should =~ /\A#<Module:0x\h+>::N\z/
      m::N.set_temporary_name(nil)

      m::M = m::N
      m::M.name.should =~ /\A#<Module:0x\h+>::M\z/m
    end

    it "can reassign a temporary name repeatedly" do
      m = Module.new

      m.set_temporary_name("fake_name")
      m.name.should == "fake_name"

      m.set_temporary_name("fake_name_2")
      m.name.should == "fake_name_2"
    end

    ruby_bug "#21094", ""..."4.0" do
      it "also updates a name of a nested module" do
        m = Module.new
        m::N = Module.new
        m::N.name.should =~ /\A#<Module:0x\h+>::N\z/

        m.set_temporary_name "m"
        m::N.name.should == "m::N"

        m.set_temporary_name nil
        m::N.name.should == nil
      end
    end

    it "keeps temporary name when assigned in an anonymous module" do
      outer = Module.new
      m = Module.new
      m.set_temporary_name "m"
      m.name.should == "m"
      outer::M = m
      m.name.should == "m"
      m.inspect.should == "m"
    end

    it "keeps temporary name when assigned in an anonymous module and nested before" do
      outer = Module.new
      m = Module.new
      outer::A = m
      m.set_temporary_name "m"
      m.name.should == "m"
      outer::M = m
      m.name.should == "m"
      m.inspect.should == "m"
    end
  end
end