summaryrefslogtreecommitdiffstats
path: root/spec/shared_behaviours/path_parameters.rb
blob: b5a907900ad0f431d2d7306125565ceed56abff7 (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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# In order to use this correctly you must define a method to get an instance
# of the type being tested, so that this code can remain generic:
#
#    it_should_behave_like "all path parameters", :path do
#      def instance(path)
#        Puppet::Type.type(:example).new(
#          :name => 'foo', :require => 'bar', :path_param => path
#        )
#      end
#
# That method will be invoked for each test to create the instance that we
# subsequently test through the system; you should ensure that the minimum of
# possible attributes are set to keep the tests clean.
#
# You must also pass the symbolic name of the parameter being tested to the
# block, and optionally can pass a hash of additional options to the block.
#
# The known options are:
#  :array :: boolean, does this support arrays of paths, default true.

shared_examples_for "all pathname parameters with arrays" do |win32|
  path_types = {
    "unix absolute"  => "/foo/bar",
    "unix relative"  => "foo/bar",
    "win32 absolute" => %q{\foo\bar},
    "win32 relative" => %q{foo\bar},
    "drive absolute" => %q{c:\foo\bar},
    "drive relative" => %q{c:foo\bar}
  }

  describe "when given an array of paths" do
    (1..path_types.length).each do |n|
      path_types.keys.combination(n) do |set|
        data = path_types.collect { |k, v| set.member?(k) ? v : nil } .compact
        reject = true
        only_absolute = set.find { |k| k =~ /relative/ } .nil?
        only_unix     = set.reject { |k| k =~ /unix/ } .length == 0

        if only_absolute and (only_unix or win32) then
          reject = false
        end

        it "should #{reject ? 'reject' : 'accept'} #{set.join(", ")}" do
          if reject then
            expect { instance(data) }.
              should raise_error Puppet::Error, /fully qualified/
          else
            instance = instance(data)
            instance[@param].should == data
          end
        end

        it "should #{reject ? 'reject' : 'accept'} #{set.join(", ")} doubled" do
          if reject then
            expect { instance(data + data) }.
              should raise_error Puppet::Error, /fully qualified/
          else
            instance = instance(data + data)
            instance[@param].should == (data + data)
          end
        end
      end
    end
  end
end


shared_examples_for "all path parameters" do |param, options|
  # Extract and process options to the block.
  options ||= {}
  array = options[:array].nil? ? true : options.delete(:array)
  if options.keys.length > 0 then
    fail "unknown options for 'all path parameters': " +
      options.keys.sort.join(', ')
  end

  def instance(path)
    fail "we didn't implement the 'instance(path)' method in the it_should_behave_like block"
  end

  ########################################################################
  # The actual testing code...
  before :all do
    @param = param
  end

  before :each do
    @file_separator = File::SEPARATOR
  end
  after :each do
    with_verbose_disabled do
      verbose, $VERBOSE = $VERBOSE, nil
      File::SEPARATOR = @file_separator
      $VERBOSE = verbose
    end
  end

  describe "on a Unix-like platform it" do
    before :each do
      with_verbose_disabled do
        File::SEPARATOR = '/'
      end
      Puppet.features.stubs(:microsoft_windows?).returns(false)
      Puppet.features.stubs(:posix?).returns(true)
    end

    if array then
      it_should_behave_like "all pathname parameters with arrays", false
    end

    it "should accept a fully qualified path" do
      path = File.join('', 'foo')
      instance = instance(path)
      instance[@param].should == path
    end

    it "should give a useful error when the path is not absolute" do
      path = 'foo'
      expect { instance(path) }.
        should raise_error Puppet::Error, /fully qualified/
    end

    { "Unix" => '/', "Win32" => '\\' }.each do |style, slash|
      %w{q Q a A z Z c C}.sort.each do |drive|
        it "should reject drive letter '#{drive}' with #{style} path separators" do
          path = "#{drive}:#{slash}Program Files"
          expect { instance(path) }.
            should raise_error Puppet::Error, /fully qualified/
        end
      end
    end
  end

  describe "on a Windows-like platform it" do
    before :each do
      with_verbose_disabled do
        File::SEPARATOR = '\\'
      end
      Puppet.features.stubs(:microsoft_windows?).returns(true)
      Puppet.features.stubs(:posix?).returns(false)
    end

    if array then
      it_should_behave_like "all pathname parameters with arrays", true
    end

    it "should accept a fully qualified path" do
      path = File.join('', 'foo')
      instance = instance(path)
      instance[@param].should == path
    end

    it "should give a useful error when the path is not absolute" do
      path = 'foo'
      expect { instance(path) }.
        should raise_error Puppet::Error, /fully qualified/
    end

    it "also accepts Unix style path separators" do
      path = '/Program Files'
      instance = instance(path)
      instance[@param].should == path
    end

    { "Unix" => '/', "Win32" => '\\' }.each do |style, slash|
      %w{q Q a A z Z c C}.sort.each do |drive|
        it "should accept drive letter '#{drive}' with #{style} path separators " do
          path = "#{drive}:#{slash}Program Files"
          instance = instance(path)
          instance[@param].should == path
        end
      end
    end

    { "UNC paths"            => %q{\\foo\bar},
      "unparsed local paths" => %q{\\?\c:\foo},
      "unparsed UNC paths"   => %q{\\?\foo\bar}
    }.each do |name, path|
      it "should accept #{name} as absolute" do
        instance = instance(path)
        instance[@param].should == path
      end
    end
  end
end