summaryrefslogtreecommitdiffstats
path: root/test/util/subclass_loader.rb
blob: ca2522dbfaf4f1497b2aade4362f0b92bb49e1fc (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
#!/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