#!/usr/bin/env ruby require File.dirname(__FILE__) + '/../lib/puppettest' require 'puppettest' require 'puppet/util/subclass_loader' class TestPuppetUtilSubclassLoader < Test::Unit::TestCase include PuppetTest class LoadTest extend Puppet::Util::SubclassLoader handle_subclasses :faker, "puppet/fakeloaders" end def mk_subclass(name, path, parent) # Make a fake client unless defined?(@basedir) @basedir ||= tempfile() $: << @basedir cleanup { $:.delete(@basedir) if $:.include?(@basedir) } end libdir = File.join([@basedir, path.split(File::SEPARATOR)].flatten) FileUtils.mkdir_p(libdir) file = File.join(libdir, "#{name}.rb") File.open(file, "w") do |f| f.puts %{class #{parent}::#{name.to_s.capitalize} < #{parent}; end} end end def test_subclass_loading # Make a fake client mk_subclass("fake", "puppet/fakeloaders", "TestPuppetUtilSubclassLoader::LoadTest") fake = nil assert_nothing_raised do fake = LoadTest.faker(:fake) end assert_nothing_raised do assert_equal(fake, LoadTest.fake, "Did not get subclass back from main method") end assert(fake, "did not load subclass") # Now make sure the subclass behaves correctly assert_equal(:Fake, fake.name, "name was not calculated correctly") end def test_multiple_subclasses sub1 = Class.new(LoadTest) Object.const_set("Sub1", sub1) sub2 = Class.new(sub1) Object.const_set("Sub2", sub2) assert_equal(sub2, LoadTest.sub2, "did not get subclass of subclass") end # I started out using a class variable to mark the loader, # but it's shared among all classes that include this module, # so it didn't work. This is testing whether I get the behaviour # that I want. def test_multiple_classes_using_module other = Class.new do extend Puppet::Util::SubclassLoader handle_subclasses :other, "puppet/other" end Object.const_set("OtherLoader", other) mk_subclass("multipletest", "puppet/other", "OtherLoader") mk_subclass("multipletest", "puppet/fakeloaders", "TestPuppetUtilSubclassLoader::LoadTest") #system("find %s" % @basedir) #puts File.read(File.join(@basedir, "puppet/fakeloaders/multipletest.rb")) #puts File.read(File.join(@basedir, "puppet/other/multipletest.rb")) othersub = mainsub = nil assert_nothing_raised("Could not look up other sub") do othersub = OtherLoader.other(:multipletest) end assert_nothing_raised("Could not look up main sub") do mainsub = LoadTest.faker(:multipletest) end assert(othersub, "did not get other sub") assert(mainsub, "did not get main sub") assert(othersub.ancestors.include?(OtherLoader), "othersub is not a subclass of otherloader") assert(mainsub.ancestors.include?(LoadTest), "mainsub is not a subclass of loadtest") end end