PageRenderTime 51ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/Languages/Ruby/Tests/Libraries/Rails-3.0.0/activesupport/test/dependencies_test.rb

http://github.com/IronLanguages/main
Ruby | 851 lines | 764 code | 84 blank | 3 comment | 5 complexity | 04e8bcdf3858a6ecb7ccfd0130ddc111 MD5 | raw file
Possible License(s): CPL-1.0, BSD-3-Clause, ISC, GPL-2.0, MPL-2.0-no-copyleft-exception
  1. require 'abstract_unit'
  2. require 'pp'
  3. require 'active_support/dependencies'
  4. require 'active_support/core_ext/kernel/reporting'
  5. module ModuleWithMissing
  6. mattr_accessor :missing_count
  7. def self.const_missing(name)
  8. self.missing_count += 1
  9. name
  10. end
  11. end
  12. module ModuleWithConstant
  13. InheritedConstant = "Hello"
  14. end
  15. class DependenciesTest < Test::Unit::TestCase
  16. def teardown
  17. ActiveSupport::Dependencies.clear
  18. end
  19. def with_loading(*from)
  20. old_mechanism, ActiveSupport::Dependencies.mechanism = ActiveSupport::Dependencies.mechanism, :load
  21. this_dir = File.dirname(__FILE__)
  22. parent_dir = File.dirname(this_dir)
  23. $LOAD_PATH.unshift(parent_dir) unless $LOAD_PATH.include?(parent_dir)
  24. prior_autoload_paths = ActiveSupport::Dependencies.autoload_paths
  25. ActiveSupport::Dependencies.autoload_paths = from.collect { |f| "#{this_dir}/#{f}" }
  26. yield
  27. ensure
  28. ActiveSupport::Dependencies.autoload_paths = prior_autoload_paths
  29. ActiveSupport::Dependencies.mechanism = old_mechanism
  30. ActiveSupport::Dependencies.explicitly_unloadable_constants = []
  31. end
  32. def with_autoloading_fixtures(&block)
  33. with_loading 'autoloading_fixtures', &block
  34. end
  35. def test_tracking_loaded_files
  36. require_dependency 'dependencies/service_one'
  37. require_dependency 'dependencies/service_two'
  38. assert_equal 2, ActiveSupport::Dependencies.loaded.size
  39. ensure
  40. Object.send(:remove_const, :ServiceOne) if Object.const_defined?(:ServiceOne)
  41. Object.send(:remove_const, :ServiceTwo) if Object.const_defined?(:ServiceTwo)
  42. end
  43. def test_tracking_identical_loaded_files
  44. require_dependency 'dependencies/service_one'
  45. require_dependency 'dependencies/service_one'
  46. assert_equal 1, ActiveSupport::Dependencies.loaded.size
  47. ensure
  48. Object.send(:remove_const, :ServiceOne) if Object.const_defined?(:ServiceOne)
  49. end
  50. def test_missing_dependency_raises_missing_source_file
  51. assert_raise(MissingSourceFile) { require_dependency("missing_service") }
  52. end
  53. def test_missing_association_raises_nothing
  54. assert_nothing_raised { require_association("missing_model") }
  55. end
  56. def test_dependency_which_raises_exception_isnt_added_to_loaded_set
  57. with_loading do
  58. filename = 'dependencies/raises_exception'
  59. $raises_exception_load_count = 0
  60. 5.times do |count|
  61. begin
  62. require_dependency filename
  63. flunk 'should have loaded dependencies/raises_exception which raises an exception'
  64. rescue Exception => e
  65. assert_equal 'Loading me failed, so do not add to loaded or history.', e.message
  66. end
  67. assert_equal count + 1, $raises_exception_load_count
  68. assert !ActiveSupport::Dependencies.loaded.include?(filename)
  69. assert !ActiveSupport::Dependencies.history.include?(filename)
  70. end
  71. end
  72. end
  73. def test_warnings_should_be_enabled_on_first_load
  74. with_loading 'dependencies' do
  75. old_warnings, ActiveSupport::Dependencies.warnings_on_first_load = ActiveSupport::Dependencies.warnings_on_first_load, true
  76. filename = "check_warnings"
  77. expanded = File.expand_path("#{File.dirname(__FILE__)}/dependencies/#{filename}")
  78. $check_warnings_load_count = 0
  79. assert !ActiveSupport::Dependencies.loaded.include?(expanded)
  80. assert !ActiveSupport::Dependencies.history.include?(expanded)
  81. silence_warnings { require_dependency filename }
  82. assert_equal 1, $check_warnings_load_count
  83. assert_equal true, $checked_verbose, 'On first load warnings should be enabled.'
  84. assert ActiveSupport::Dependencies.loaded.include?(expanded)
  85. ActiveSupport::Dependencies.clear
  86. assert !ActiveSupport::Dependencies.loaded.include?(expanded)
  87. assert ActiveSupport::Dependencies.history.include?(expanded)
  88. silence_warnings { require_dependency filename }
  89. assert_equal 2, $check_warnings_load_count
  90. assert_equal nil, $checked_verbose, 'After first load warnings should be left alone.'
  91. assert ActiveSupport::Dependencies.loaded.include?(expanded)
  92. ActiveSupport::Dependencies.clear
  93. assert !ActiveSupport::Dependencies.loaded.include?(expanded)
  94. assert ActiveSupport::Dependencies.history.include?(expanded)
  95. enable_warnings { require_dependency filename }
  96. assert_equal 3, $check_warnings_load_count
  97. assert_equal true, $checked_verbose, 'After first load warnings should be left alone.'
  98. assert ActiveSupport::Dependencies.loaded.include?(expanded)
  99. ActiveSupport::Dependencies.warnings_on_first_load = old_warnings
  100. end
  101. end
  102. def test_mutual_dependencies_dont_infinite_loop
  103. with_loading 'dependencies' do
  104. $mutual_dependencies_count = 0
  105. assert_nothing_raised { require_dependency 'mutual_one' }
  106. assert_equal 2, $mutual_dependencies_count
  107. ActiveSupport::Dependencies.clear
  108. $mutual_dependencies_count = 0
  109. assert_nothing_raised { require_dependency 'mutual_two' }
  110. assert_equal 2, $mutual_dependencies_count
  111. end
  112. end
  113. def test_module_loading
  114. with_autoloading_fixtures do
  115. assert_kind_of Module, A
  116. assert_kind_of Class, A::B
  117. assert_kind_of Class, A::C::D
  118. assert_kind_of Class, A::C::E::F
  119. end
  120. end
  121. def test_non_existing_const_raises_name_error
  122. with_autoloading_fixtures do
  123. assert_raise(NameError) { DoesNotExist }
  124. assert_raise(NameError) { NoModule::DoesNotExist }
  125. assert_raise(NameError) { A::DoesNotExist }
  126. assert_raise(NameError) { A::B::DoesNotExist }
  127. end
  128. end
  129. def test_directories_manifest_as_modules_unless_const_defined
  130. with_autoloading_fixtures do
  131. assert_kind_of Module, ModuleFolder
  132. Object.__send__ :remove_const, :ModuleFolder
  133. end
  134. end
  135. def test_module_with_nested_class
  136. with_autoloading_fixtures do
  137. assert_kind_of Class, ModuleFolder::NestedClass
  138. Object.__send__ :remove_const, :ModuleFolder
  139. end
  140. end
  141. def test_module_with_nested_inline_class
  142. with_autoloading_fixtures do
  143. assert_kind_of Class, ModuleFolder::InlineClass
  144. Object.__send__ :remove_const, :ModuleFolder
  145. end
  146. end
  147. def test_directories_may_manifest_as_nested_classes
  148. with_autoloading_fixtures do
  149. assert_kind_of Class, ClassFolder
  150. Object.__send__ :remove_const, :ClassFolder
  151. end
  152. end
  153. def test_class_with_nested_class
  154. with_autoloading_fixtures do
  155. assert_kind_of Class, ClassFolder::NestedClass
  156. Object.__send__ :remove_const, :ClassFolder
  157. end
  158. end
  159. def test_class_with_nested_inline_class
  160. with_autoloading_fixtures do
  161. assert_kind_of Class, ClassFolder::InlineClass
  162. Object.__send__ :remove_const, :ClassFolder
  163. end
  164. end
  165. def test_class_with_nested_inline_subclass_of_parent
  166. with_autoloading_fixtures do
  167. assert_kind_of Class, ClassFolder::ClassFolderSubclass
  168. assert_kind_of Class, ClassFolder
  169. assert_equal 'indeed', ClassFolder::ClassFolderSubclass::ConstantInClassFolder
  170. Object.__send__ :remove_const, :ClassFolder
  171. end
  172. end
  173. def test_nested_class_can_access_sibling
  174. with_autoloading_fixtures do
  175. sibling = ModuleFolder::NestedClass.class_eval "NestedSibling"
  176. assert defined?(ModuleFolder::NestedSibling)
  177. assert_equal ModuleFolder::NestedSibling, sibling
  178. Object.__send__ :remove_const, :ModuleFolder
  179. end
  180. end
  181. def test_doesnt_break_normal_require
  182. path = File.expand_path("../autoloading_fixtures/load_path", __FILE__)
  183. original_path = $:.dup
  184. original_features = $".dup
  185. $:.push(path)
  186. with_autoloading_fixtures do
  187. # The _ = assignments are to prevent warnings
  188. _ = RequiresConstant
  189. assert defined?(RequiresConstant)
  190. assert defined?(LoadedConstant)
  191. ActiveSupport::Dependencies.clear
  192. _ = RequiresConstant
  193. assert defined?(RequiresConstant)
  194. assert defined?(LoadedConstant)
  195. end
  196. ensure
  197. remove_constants(:RequiresConstant, :LoadedConstant, :LoadsConstant)
  198. $".replace(original_features)
  199. $:.replace(original_path)
  200. end
  201. def test_doesnt_break_normal_require_nested
  202. path = File.expand_path("../autoloading_fixtures/load_path", __FILE__)
  203. original_path = $:.dup
  204. original_features = $".dup
  205. $:.push(path)
  206. with_autoloading_fixtures do
  207. # The _ = assignments are to prevent warnings
  208. _ = LoadsConstant
  209. assert defined?(LoadsConstant)
  210. assert defined?(LoadedConstant)
  211. ActiveSupport::Dependencies.clear
  212. _ = LoadsConstant
  213. assert defined?(LoadsConstant)
  214. assert defined?(LoadedConstant)
  215. end
  216. ensure
  217. remove_constants(:RequiresConstant, :LoadedConstant, :LoadsConstant)
  218. $".replace(original_features)
  219. $:.replace(original_path)
  220. end
  221. def failing_test_access_thru_and_upwards_fails
  222. with_autoloading_fixtures do
  223. assert ! defined?(ModuleFolder)
  224. assert_raise(NameError) { ModuleFolder::Object }
  225. assert_raise(NameError) { ModuleFolder::NestedClass::Object }
  226. Object.__send__ :remove_const, :ModuleFolder
  227. end
  228. end
  229. def test_non_existing_const_raises_name_error_with_fully_qualified_name
  230. with_autoloading_fixtures do
  231. begin
  232. A::DoesNotExist.nil?
  233. flunk "No raise!!"
  234. rescue NameError => e
  235. assert_equal "uninitialized constant A::DoesNotExist", e.message
  236. end
  237. begin
  238. A::B::DoesNotExist.nil?
  239. flunk "No raise!!"
  240. rescue NameError => e
  241. assert_equal "uninitialized constant A::B::DoesNotExist", e.message
  242. end
  243. end
  244. end
  245. def test_smart_name_error_strings
  246. begin
  247. Object.module_eval "ImaginaryObject"
  248. flunk "No raise!!"
  249. rescue NameError => e
  250. assert e.message.include?("uninitialized constant ImaginaryObject")
  251. end
  252. end
  253. def test_loadable_constants_for_path_should_handle_empty_autoloads
  254. assert_equal [], ActiveSupport::Dependencies.loadable_constants_for_path('hello')
  255. end
  256. def test_loadable_constants_for_path_should_handle_relative_paths
  257. fake_root = 'dependencies'
  258. relative_root = File.dirname(__FILE__) + '/dependencies'
  259. ['', '/'].each do |suffix|
  260. with_loading fake_root + suffix do
  261. assert_equal ["A::B"], ActiveSupport::Dependencies.loadable_constants_for_path(relative_root + '/a/b')
  262. end
  263. end
  264. end
  265. def test_loadable_constants_for_path_should_provide_all_results
  266. fake_root = '/usr/apps/backpack'
  267. with_loading fake_root, fake_root + '/lib' do
  268. root = ActiveSupport::Dependencies.autoload_paths.first
  269. assert_equal ["Lib::A::B", "A::B"], ActiveSupport::Dependencies.loadable_constants_for_path(root + '/lib/a/b')
  270. end
  271. end
  272. def test_loadable_constants_for_path_should_uniq_results
  273. fake_root = '/usr/apps/backpack/lib'
  274. with_loading fake_root, fake_root + '/' do
  275. root = ActiveSupport::Dependencies.autoload_paths.first
  276. assert_equal ["A::B"], ActiveSupport::Dependencies.loadable_constants_for_path(root + '/a/b')
  277. end
  278. end
  279. def test_loadable_constants_with_load_path_without_trailing_slash
  280. path = File.dirname(__FILE__) + '/autoloading_fixtures/class_folder/inline_class.rb'
  281. with_loading 'autoloading_fixtures/class/' do
  282. assert_equal [], ActiveSupport::Dependencies.loadable_constants_for_path(path)
  283. end
  284. end
  285. def test_qualified_const_defined
  286. assert ActiveSupport::Dependencies.qualified_const_defined?("Object")
  287. assert ActiveSupport::Dependencies.qualified_const_defined?("::Object")
  288. assert ActiveSupport::Dependencies.qualified_const_defined?("::Object::Kernel")
  289. assert ActiveSupport::Dependencies.qualified_const_defined?("::Test::Unit::TestCase")
  290. end
  291. def test_qualified_const_defined_should_not_call_const_missing
  292. ModuleWithMissing.missing_count = 0
  293. assert ! ActiveSupport::Dependencies.qualified_const_defined?("ModuleWithMissing::A")
  294. assert_equal 0, ModuleWithMissing.missing_count
  295. assert ! ActiveSupport::Dependencies.qualified_const_defined?("ModuleWithMissing::A::B")
  296. assert_equal 0, ModuleWithMissing.missing_count
  297. end
  298. def test_qualified_const_defined_explodes_with_invalid_const_name
  299. assert_raises(NameError) { ActiveSupport::Dependencies.qualified_const_defined?("invalid") }
  300. end
  301. def test_autoloaded?
  302. with_autoloading_fixtures do
  303. assert ! ActiveSupport::Dependencies.autoloaded?("ModuleFolder")
  304. assert ! ActiveSupport::Dependencies.autoloaded?("ModuleFolder::NestedClass")
  305. assert ActiveSupport::Dependencies.autoloaded?(ModuleFolder)
  306. assert ActiveSupport::Dependencies.autoloaded?("ModuleFolder")
  307. assert ! ActiveSupport::Dependencies.autoloaded?("ModuleFolder::NestedClass")
  308. assert ActiveSupport::Dependencies.autoloaded?(ModuleFolder::NestedClass)
  309. assert ActiveSupport::Dependencies.autoloaded?("ModuleFolder")
  310. assert ActiveSupport::Dependencies.autoloaded?("ModuleFolder::NestedClass")
  311. assert ActiveSupport::Dependencies.autoloaded?("::ModuleFolder")
  312. assert ActiveSupport::Dependencies.autoloaded?(:ModuleFolder)
  313. # Anonymous modules aren't autoloaded.
  314. assert !ActiveSupport::Dependencies.autoloaded?(Module.new)
  315. nil_name = Module.new
  316. def nil_name.name() nil end
  317. assert !ActiveSupport::Dependencies.autoloaded?(nil_name)
  318. Object.class_eval { remove_const :ModuleFolder }
  319. end
  320. end
  321. def test_qualified_name_for
  322. assert_equal "A", ActiveSupport::Dependencies.qualified_name_for(Object, :A)
  323. assert_equal "A", ActiveSupport::Dependencies.qualified_name_for(:Object, :A)
  324. assert_equal "A", ActiveSupport::Dependencies.qualified_name_for("Object", :A)
  325. assert_equal "A", ActiveSupport::Dependencies.qualified_name_for("::Object", :A)
  326. assert_equal "ActiveSupport::Dependencies::A", ActiveSupport::Dependencies.qualified_name_for(:'ActiveSupport::Dependencies', :A)
  327. assert_equal "ActiveSupport::Dependencies::A", ActiveSupport::Dependencies.qualified_name_for(ActiveSupport::Dependencies, :A)
  328. end
  329. def test_file_search
  330. with_loading 'dependencies' do
  331. root = ActiveSupport::Dependencies.autoload_paths.first
  332. assert_equal nil, ActiveSupport::Dependencies.search_for_file('service_three')
  333. assert_equal nil, ActiveSupport::Dependencies.search_for_file('service_three.rb')
  334. assert_equal root + '/service_one.rb', ActiveSupport::Dependencies.search_for_file('service_one')
  335. assert_equal root + '/service_one.rb', ActiveSupport::Dependencies.search_for_file('service_one.rb')
  336. end
  337. end
  338. def test_file_search_uses_first_in_load_path
  339. with_loading 'dependencies', 'autoloading_fixtures' do
  340. deps, autoload = ActiveSupport::Dependencies.autoload_paths
  341. assert_match %r/dependencies/, deps
  342. assert_match %r/autoloading_fixtures/, autoload
  343. assert_equal deps + '/conflict.rb', ActiveSupport::Dependencies.search_for_file('conflict')
  344. end
  345. with_loading 'autoloading_fixtures', 'dependencies' do
  346. autoload, deps = ActiveSupport::Dependencies.autoload_paths
  347. assert_match %r/dependencies/, deps
  348. assert_match %r/autoloading_fixtures/, autoload
  349. assert_equal autoload + '/conflict.rb', ActiveSupport::Dependencies.search_for_file('conflict')
  350. end
  351. end
  352. def test_custom_const_missing_should_work
  353. Object.module_eval <<-end_eval, __FILE__, __LINE__ + 1
  354. module ModuleWithCustomConstMissing
  355. def self.const_missing(name)
  356. const_set name, name.to_s.hash
  357. end
  358. module A
  359. end
  360. end
  361. end_eval
  362. with_autoloading_fixtures do
  363. assert_kind_of Integer, ::ModuleWithCustomConstMissing::B
  364. assert_kind_of Module, ::ModuleWithCustomConstMissing::A
  365. assert_kind_of String, ::ModuleWithCustomConstMissing::A::B
  366. end
  367. end
  368. def test_const_missing_should_not_double_load
  369. $counting_loaded_times = 0
  370. with_autoloading_fixtures do
  371. require_dependency '././counting_loader'
  372. assert_equal 1, $counting_loaded_times
  373. assert_raise(ArgumentError) { ActiveSupport::Dependencies.load_missing_constant Object, :CountingLoader }
  374. assert_equal 1, $counting_loaded_times
  375. end
  376. end
  377. def test_const_missing_within_anonymous_module
  378. $counting_loaded_times = 0
  379. m = Module.new
  380. m.module_eval "def a() CountingLoader; end"
  381. extend m
  382. kls = nil
  383. with_autoloading_fixtures do
  384. kls = nil
  385. assert_nothing_raised { kls = a }
  386. assert_equal "CountingLoader", kls.name
  387. assert_equal 1, $counting_loaded_times
  388. assert_nothing_raised { kls = a }
  389. assert_equal 1, $counting_loaded_times
  390. end
  391. end
  392. def test_removal_from_tree_should_be_detected
  393. with_loading 'dependencies' do
  394. c = ServiceOne
  395. ActiveSupport::Dependencies.clear
  396. assert ! defined?(ServiceOne)
  397. begin
  398. ActiveSupport::Dependencies.load_missing_constant(c, :FakeMissing)
  399. flunk "Expected exception"
  400. rescue ArgumentError => e
  401. assert_match %r{ServiceOne has been removed from the module tree}i, e.message
  402. end
  403. end
  404. end
  405. def test_references_should_work
  406. with_loading 'dependencies' do
  407. c = ActiveSupport::Dependencies.ref("ServiceOne")
  408. service_one_first = ServiceOne
  409. assert_equal service_one_first, c.get
  410. ActiveSupport::Dependencies.clear
  411. assert ! defined?(ServiceOne)
  412. service_one_second = ServiceOne
  413. assert_not_equal service_one_first, c.get
  414. assert_equal service_one_second, c.get
  415. end
  416. end
  417. def test_constantize_shortcut_for_cached_constant_lookups
  418. with_loading 'dependencies' do
  419. assert_equal ServiceOne, ActiveSupport::Dependencies.constantize("ServiceOne")
  420. end
  421. end
  422. def test_nested_load_error_isnt_rescued
  423. with_loading 'dependencies' do
  424. assert_raise(MissingSourceFile) do
  425. RequiresNonexistent1
  426. end
  427. end
  428. end
  429. def test_autoload_once_paths_do_not_add_to_autoloaded_constants
  430. with_autoloading_fixtures do
  431. ActiveSupport::Dependencies.autoload_once_paths = ActiveSupport::Dependencies.autoload_paths.dup
  432. assert ! ActiveSupport::Dependencies.autoloaded?("ModuleFolder")
  433. assert ! ActiveSupport::Dependencies.autoloaded?("ModuleFolder::NestedClass")
  434. assert ! ActiveSupport::Dependencies.autoloaded?(ModuleFolder)
  435. 1 if ModuleFolder::NestedClass # 1 if to avoid warning
  436. assert ! ActiveSupport::Dependencies.autoloaded?(ModuleFolder::NestedClass)
  437. end
  438. ensure
  439. Object.class_eval { remove_const :ModuleFolder }
  440. ActiveSupport::Dependencies.autoload_once_paths = []
  441. end
  442. def test_application_should_special_case_application_controller
  443. with_autoloading_fixtures do
  444. require_dependency 'application'
  445. assert_equal 10, ApplicationController
  446. assert ActiveSupport::Dependencies.autoloaded?(:ApplicationController)
  447. end
  448. end
  449. def test_preexisting_constants_are_not_marked_as_autoloaded
  450. with_autoloading_fixtures do
  451. require_dependency 'e'
  452. assert ActiveSupport::Dependencies.autoloaded?(:E)
  453. ActiveSupport::Dependencies.clear
  454. end
  455. Object.const_set :E, Class.new
  456. with_autoloading_fixtures do
  457. require_dependency 'e'
  458. assert ! ActiveSupport::Dependencies.autoloaded?(:E), "E shouldn't be marked autoloaded!"
  459. ActiveSupport::Dependencies.clear
  460. end
  461. ensure
  462. Object.class_eval { remove_const :E }
  463. end
  464. def test_unloadable
  465. with_autoloading_fixtures do
  466. Object.const_set :M, Module.new
  467. M.unloadable
  468. ActiveSupport::Dependencies.clear
  469. assert ! defined?(M)
  470. Object.const_set :M, Module.new
  471. ActiveSupport::Dependencies.clear
  472. assert ! defined?(M), "Dependencies should unload unloadable constants each time"
  473. end
  474. end
  475. def test_unloadable_should_fail_with_anonymous_modules
  476. with_autoloading_fixtures do
  477. m = Module.new
  478. assert_raise(ArgumentError) { m.unloadable }
  479. end
  480. end
  481. def test_unloadable_should_return_change_flag
  482. with_autoloading_fixtures do
  483. Object.const_set :M, Module.new
  484. assert_equal true, M.unloadable
  485. assert_equal false, M.unloadable
  486. end
  487. end
  488. def test_new_contants_in_without_constants
  489. assert_equal [], (ActiveSupport::Dependencies.new_constants_in(Object) { })
  490. assert ActiveSupport::Dependencies.constant_watch_stack.all? {|k,v| v.empty? }
  491. end
  492. def test_new_constants_in_with_a_single_constant
  493. assert_equal ["Hello"], ActiveSupport::Dependencies.new_constants_in(Object) {
  494. Object.const_set :Hello, 10
  495. }.map(&:to_s)
  496. assert ActiveSupport::Dependencies.constant_watch_stack.all? {|k,v| v.empty? }
  497. ensure
  498. Object.class_eval { remove_const :Hello }
  499. end
  500. def test_new_constants_in_with_nesting
  501. outer = ActiveSupport::Dependencies.new_constants_in(Object) do
  502. Object.const_set :OuterBefore, 10
  503. assert_equal ["Inner"], ActiveSupport::Dependencies.new_constants_in(Object) {
  504. Object.const_set :Inner, 20
  505. }.map(&:to_s)
  506. Object.const_set :OuterAfter, 30
  507. end
  508. assert_equal ["OuterAfter", "OuterBefore"], outer.sort.map(&:to_s)
  509. assert ActiveSupport::Dependencies.constant_watch_stack.all? {|k,v| v.empty? }
  510. ensure
  511. %w(OuterBefore Inner OuterAfter).each do |name|
  512. Object.class_eval { remove_const name if const_defined?(name) }
  513. end
  514. end
  515. def test_new_constants_in_module
  516. Object.const_set :M, Module.new
  517. outer = ActiveSupport::Dependencies.new_constants_in(M) do
  518. M.const_set :OuterBefore, 10
  519. inner = ActiveSupport::Dependencies.new_constants_in(M) do
  520. M.const_set :Inner, 20
  521. end
  522. assert_equal ["M::Inner"], inner
  523. M.const_set :OuterAfter, 30
  524. end
  525. assert_equal ["M::OuterAfter", "M::OuterBefore"], outer.sort
  526. assert ActiveSupport::Dependencies.constant_watch_stack.all? {|k,v| v.empty? }
  527. ensure
  528. Object.class_eval { remove_const :M }
  529. end
  530. def test_new_constants_in_module_using_name
  531. outer = ActiveSupport::Dependencies.new_constants_in(:M) do
  532. Object.const_set :M, Module.new
  533. M.const_set :OuterBefore, 10
  534. inner = ActiveSupport::Dependencies.new_constants_in(:M) do
  535. M.const_set :Inner, 20
  536. end
  537. assert_equal ["M::Inner"], inner
  538. M.const_set :OuterAfter, 30
  539. end
  540. assert_equal ["M::OuterAfter", "M::OuterBefore"], outer.sort
  541. assert ActiveSupport::Dependencies.constant_watch_stack.all? {|k,v| v.empty? }
  542. ensure
  543. Object.class_eval { remove_const :M }
  544. end
  545. def test_new_constants_in_with_inherited_constants
  546. m = ActiveSupport::Dependencies.new_constants_in(:Object) do
  547. Object.class_eval { include ModuleWithConstant }
  548. end
  549. assert_equal [], m
  550. end
  551. def test_new_constants_in_with_illegal_module_name_raises_correct_error
  552. assert_raise(NameError) do
  553. ActiveSupport::Dependencies.new_constants_in("Illegal-Name") {}
  554. end
  555. end
  556. def test_file_with_multiple_constants_and_require_dependency
  557. with_autoloading_fixtures do
  558. assert ! defined?(MultipleConstantFile)
  559. assert ! defined?(SiblingConstant)
  560. require_dependency 'multiple_constant_file'
  561. assert defined?(MultipleConstantFile)
  562. assert defined?(SiblingConstant)
  563. assert ActiveSupport::Dependencies.autoloaded?(:MultipleConstantFile)
  564. assert ActiveSupport::Dependencies.autoloaded?(:SiblingConstant)
  565. ActiveSupport::Dependencies.clear
  566. assert ! defined?(MultipleConstantFile)
  567. assert ! defined?(SiblingConstant)
  568. end
  569. end
  570. def test_file_with_multiple_constants_and_auto_loading
  571. with_autoloading_fixtures do
  572. assert ! defined?(MultipleConstantFile)
  573. assert ! defined?(SiblingConstant)
  574. assert_equal 10, MultipleConstantFile
  575. assert defined?(MultipleConstantFile)
  576. assert defined?(SiblingConstant)
  577. assert ActiveSupport::Dependencies.autoloaded?(:MultipleConstantFile)
  578. assert ActiveSupport::Dependencies.autoloaded?(:SiblingConstant)
  579. ActiveSupport::Dependencies.clear
  580. assert ! defined?(MultipleConstantFile)
  581. assert ! defined?(SiblingConstant)
  582. end
  583. end
  584. def test_nested_file_with_multiple_constants_and_require_dependency
  585. with_autoloading_fixtures do
  586. assert ! defined?(ClassFolder::NestedClass)
  587. assert ! defined?(ClassFolder::SiblingClass)
  588. require_dependency 'class_folder/nested_class'
  589. assert defined?(ClassFolder::NestedClass)
  590. assert defined?(ClassFolder::SiblingClass)
  591. assert ActiveSupport::Dependencies.autoloaded?("ClassFolder::NestedClass")
  592. assert ActiveSupport::Dependencies.autoloaded?("ClassFolder::SiblingClass")
  593. ActiveSupport::Dependencies.clear
  594. assert ! defined?(ClassFolder::NestedClass)
  595. assert ! defined?(ClassFolder::SiblingClass)
  596. end
  597. end
  598. def test_nested_file_with_multiple_constants_and_auto_loading
  599. with_autoloading_fixtures do
  600. assert ! defined?(ClassFolder::NestedClass)
  601. assert ! defined?(ClassFolder::SiblingClass)
  602. assert_kind_of Class, ClassFolder::NestedClass
  603. assert defined?(ClassFolder::NestedClass)
  604. assert defined?(ClassFolder::SiblingClass)
  605. assert ActiveSupport::Dependencies.autoloaded?("ClassFolder::NestedClass")
  606. assert ActiveSupport::Dependencies.autoloaded?("ClassFolder::SiblingClass")
  607. ActiveSupport::Dependencies.clear
  608. assert ! defined?(ClassFolder::NestedClass)
  609. assert ! defined?(ClassFolder::SiblingClass)
  610. end
  611. end
  612. def test_autoload_doesnt_shadow_no_method_error_with_relative_constant
  613. with_autoloading_fixtures do
  614. assert !defined?(::RaisesNoMethodError), "::RaisesNoMethodError is defined but it hasn't been referenced yet!"
  615. 2.times do
  616. assert_raise(NoMethodError) { RaisesNoMethodError }
  617. assert !defined?(::RaisesNoMethodError), "::RaisesNoMethodError is defined but it should have failed!"
  618. end
  619. end
  620. ensure
  621. Object.class_eval { remove_const :RaisesNoMethodError if const_defined?(:RaisesNoMethodError) }
  622. end
  623. def test_autoload_doesnt_shadow_no_method_error_with_absolute_constant
  624. with_autoloading_fixtures do
  625. assert !defined?(::RaisesNoMethodError), "::RaisesNoMethodError is defined but it hasn't been referenced yet!"
  626. 2.times do
  627. assert_raise(NoMethodError) { ::RaisesNoMethodError }
  628. assert !defined?(::RaisesNoMethodError), "::RaisesNoMethodError is defined but it should have failed!"
  629. end
  630. end
  631. ensure
  632. Object.class_eval { remove_const :RaisesNoMethodError if const_defined?(:RaisesNoMethodError) }
  633. end
  634. def test_autoload_doesnt_shadow_error_when_mechanism_not_set_to_load
  635. with_autoloading_fixtures do
  636. ActiveSupport::Dependencies.mechanism = :require
  637. 2.times do
  638. assert_raise(NameError) { assert_equal 123, ::RaisesNameError::FooBarBaz }
  639. end
  640. end
  641. end
  642. def test_autoload_doesnt_shadow_name_error
  643. with_autoloading_fixtures do
  644. Object.send(:remove_const, :RaisesNameError) if defined?(::RaisesNameError)
  645. 2.times do |i|
  646. begin
  647. ::RaisesNameError::FooBarBaz.object_id
  648. flunk 'should have raised NameError when autoloaded file referenced FooBarBaz'
  649. rescue NameError => e
  650. assert_equal 'uninitialized constant RaisesNameError::FooBarBaz', e.message
  651. end
  652. assert !defined?(::RaisesNameError), "::RaisesNameError is defined but it should have failed!"
  653. end
  654. assert !defined?(::RaisesNameError)
  655. 2.times do
  656. assert_raise(NameError) { ::RaisesNameError }
  657. assert !defined?(::RaisesNameError), "::RaisesNameError is defined but it should have failed!"
  658. end
  659. end
  660. ensure
  661. Object.class_eval { remove_const :RaisesNoMethodError if const_defined?(:RaisesNoMethodError) }
  662. end
  663. def test_remove_constant_handles_double_colon_at_start
  664. Object.const_set 'DeleteMe', Module.new
  665. DeleteMe.const_set 'OrMe', Module.new
  666. ActiveSupport::Dependencies.remove_constant "::DeleteMe::OrMe"
  667. assert ! defined?(DeleteMe::OrMe)
  668. assert defined?(DeleteMe)
  669. ActiveSupport::Dependencies.remove_constant "::DeleteMe"
  670. assert ! defined?(DeleteMe)
  671. end
  672. def test_load_once_constants_should_not_be_unloaded
  673. with_autoloading_fixtures do
  674. ActiveSupport::Dependencies.autoload_once_paths = ActiveSupport::Dependencies.autoload_paths
  675. ::A.to_s
  676. assert defined?(A)
  677. ActiveSupport::Dependencies.clear
  678. assert defined?(A)
  679. end
  680. ensure
  681. ActiveSupport::Dependencies.autoload_once_paths = []
  682. Object.class_eval { remove_const :A if const_defined?(:A) }
  683. end
  684. def test_autoload_once_paths_should_behave_when_recursively_loading
  685. with_loading 'dependencies', 'autoloading_fixtures' do
  686. ActiveSupport::Dependencies.autoload_once_paths = [ActiveSupport::Dependencies.autoload_paths.last]
  687. assert !defined?(CrossSiteDependency)
  688. assert_nothing_raised { CrossSiteDepender.nil? }
  689. assert defined?(CrossSiteDependency)
  690. assert !ActiveSupport::Dependencies.autoloaded?(CrossSiteDependency),
  691. "CrossSiteDependency shouldn't be marked as autoloaded!"
  692. ActiveSupport::Dependencies.clear
  693. assert defined?(CrossSiteDependency),
  694. "CrossSiteDependency shouldn't have been unloaded!"
  695. end
  696. ensure
  697. ActiveSupport::Dependencies.autoload_once_paths = []
  698. end
  699. def test_hook_called_multiple_times
  700. assert_nothing_raised { ActiveSupport::Dependencies.hook! }
  701. end
  702. def test_unhook
  703. ActiveSupport::Dependencies.unhook!
  704. assert !Module.new.respond_to?(:const_missing_without_dependencies)
  705. assert !Module.new.respond_to?(:load_without_new_constant_marking)
  706. ensure
  707. ActiveSupport::Dependencies.hook!
  708. end
  709. private
  710. def remove_constants(*constants)
  711. constants.each do |constant|
  712. Object.send(:remove_const, constant) if Object.const_defined?(constant)
  713. end
  714. end
  715. end