summaryrefslogtreecommitdiff
path: root/spec/shared_behaviours/path_parameters.rb
blob: d5f06875b5e35a3a873c52b9f14c4fca90b98142 (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
# 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"            => %q{/foo/bar},
    "unix relative"            => %q{foo/bar},
    "win32 non-drive absolute" => %q{\foo\bar},
    "win32 non-drive relative" => %q{foo\bar},
    "win32 drive absolute"     => %q{c:\foo\bar},
    "win32 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

        has_relative = set.find { |k| k =~ /relative/ or k =~ /non-drive/ }
        has_windows = set.find { |k| k =~ /win32/ }
        has_unix = set.find { |k| k =~ /unix/ }

        if has_relative or (has_windows and !win32) or (has_unix and win32)
          reject = true
        else
          reject = false
        end

        it "should #{reject ? 'reject' : 'accept'} #{set.join(", ")}" do
          if reject then
            expect { instance(data) }.
              to 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) }.
              to 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

  describe "on a Unix-like platform it", :as_platform => :posix do
    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) }.
        to 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) }.
            to raise_error Puppet::Error, /fully qualified/
        end
      end
    end
  end

  describe "on a Windows-like platform it", :as_platform => :windows do
    if array then
      it_should_behave_like "all pathname parameters with arrays", true
    end

    it "should reject a fully qualified unix path" do
      path = '/foo'
      expect { instance(path) }.to raise_error(Puppet::Error, /fully qualified/)
    end

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

    it "also accepts Unix style path separators" do
      path = 'C:/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