diff options
author | Jean Boussier <jean.boussier@gmail.com> | 2021-05-22 12:04:01 +0200 |
---|---|---|
committer | Jean Boussier <jean.boussier@gmail.com> | 2022-01-14 11:30:07 +0100 |
commit | 8d05047d72d0a4b97f57b23bddbca639375bbd03 (patch) | |
tree | d3caaf18c73b9f3423402162626c5dc5abc4965e /spec/ruby/core | |
parent | 53a4e101465a4d2ae38ea3bfd3cb7dd3c9f12f61 (diff) | |
download | ruby-8d05047d72d0a4b97f57b23bddbca639375bbd03.tar.gz |
Add a Module#const_added callback
[Feature #17881]
Works similarly to `method_added` but for constants.
```ruby
Foo::BAR = 42 # call Foo.const_added(:FOO)
class Foo::Baz; end # call Foo.const_added(:Baz)
Foo.autoload(:Something, "path") # call Foo.const_added(:Something)
```
Diffstat (limited to 'spec/ruby/core')
-rw-r--r-- | spec/ruby/core/module/const_added_spec.rb | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/spec/ruby/core/module/const_added_spec.rb b/spec/ruby/core/module/const_added_spec.rb new file mode 100644 index 0000000000..ff2ee0987f --- /dev/null +++ b/spec/ruby/core/module/const_added_spec.rb @@ -0,0 +1,125 @@ +require_relative '../../spec_helper' +require_relative 'fixtures/classes' + +describe "Module#const_added" do + ruby_version_is "3.1" do + it "is a private instance method" do + Module.should have_private_instance_method(:const_added) + end + + it "returns nil in the default implementation" do + Module.new do + const_added(:TEST).should == nil + end + end + + it "is called when a new constant is assigned on self" do + ScratchPad.record [] + + mod = Module.new do + def self.const_added(name) + ScratchPad << name + end + end + + mod.module_eval(<<-RUBY, __FILE__, __LINE__ + 1) + TEST = 1 + RUBY + + ScratchPad.recorded.should == [:TEST] + end + + it "is called when a new constant is assigned on self throught const_set" do + ScratchPad.record [] + + mod = Module.new do + def self.const_added(name) + ScratchPad << name + end + end + + mod.const_set(:TEST, 1) + + ScratchPad.recorded.should == [:TEST] + end + + it "is called when a new module is defined under self" do + ScratchPad.record [] + + mod = Module.new do + def self.const_added(name) + ScratchPad << name + end + end + + mod.module_eval(<<-RUBY, __FILE__, __LINE__ + 1) + module SubModule + end + + module SubModule + end + RUBY + + ScratchPad.recorded.should == [:SubModule] + end + + it "is called when a new class is defined under self" do + ScratchPad.record [] + + mod = Module.new do + def self.const_added(name) + ScratchPad << name + end + end + + mod.module_eval(<<-RUBY, __FILE__, __LINE__ + 1) + class SubClass + end + + class SubClass + end + RUBY + + ScratchPad.recorded.should == [:SubClass] + end + + it "is called when an autoload is defined" do + ScratchPad.record [] + + mod = Module.new do + def self.const_added(name) + ScratchPad << name + end + end + + mod.autoload :Autoload, "foo" + ScratchPad.recorded.should == [:Autoload] + end + + it "is called with a precise caller location with the line of definition" do + ScratchPad.record [] + + mod = Module.new do + def self.const_added(name) + location = caller_locations(1, 1)[0] + ScratchPad << location.lineno + end + end + + line = __LINE__ + mod.module_eval(<<-RUBY, __FILE__, __LINE__ + 1) + TEST = 1 + + module SubModule + end + + class SubClass + end + RUBY + + mod.const_set(:CONST_SET, 1) + + ScratchPad.recorded.should == [line + 2, line + 4, line + 7, line + 11] + end + end +end |