From 01c9782fa2392729bea08409e348fe049857d9d6 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Fri, 6 Dec 2013 19:13:51 +0100 Subject: better error message for constants autoloaded from anonymous modules [fixes #13204] load_missing_constant is a private method that basically plays the role of const_missing. This method has an error condition that is surprising: it raises if the class or module already has the missing constant. How is it possible that if the class of module has the constant Ruby has called const_missing in the first place? The answer is that the from_mod argument is self except for anonymous modules, because const_missing passes down Object in such case (see the comment in the source code of the patch for the rationale). But then, it is better to pass down Object *if Object is also missing the constant* and otherwise err with an informative message right away. --- activesupport/test/dependencies_test.rb | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) (limited to 'activesupport/test') diff --git a/activesupport/test/dependencies_test.rb b/activesupport/test/dependencies_test.rb index 2392b71960..e56bab6d4c 100644 --- a/activesupport/test/dependencies_test.rb +++ b/activesupport/test/dependencies_test.rb @@ -530,29 +530,21 @@ class DependenciesTest < ActiveSupport::TestCase end end - def test_const_missing_should_not_double_load - $counting_loaded_times = 0 + def test_const_missing_in_anonymous_modules_loads_top_level_constants with_autoloading_fixtures do - require_dependency '././counting_loader' - assert_equal 1, $counting_loaded_times - assert_raise(NameError) { ActiveSupport::Dependencies.load_missing_constant Object, :CountingLoader } - assert_equal 1, $counting_loaded_times + # class_eval STRING pushes the class to the nesting of the eval'ed code. + klass = Class.new.class_eval "E" + assert_equal E, klass end end - def test_const_missing_within_anonymous_module - $counting_loaded_times = 0 - m = Module.new - m.module_eval "def a() CountingLoader; end" - extend m + def test_const_missing_in_anonymous_modules_raises_if_the_constant_belongs_to_Object with_autoloading_fixtures do - kls = nil - assert_nothing_raised { kls = a } - assert_equal "CountingLoader", kls.name - assert_equal 1, $counting_loaded_times + require_dependency 'e' - assert_nothing_raised { kls = a } - assert_equal 1, $counting_loaded_times + mod = Module.new + msg = 'E cannot be autoloaded from an anonymous class or module' + assert_raise(NameError, msg) { mod::E } end end -- cgit v1.2.3