summaryrefslogtreecommitdiff
path: root/spec/unit/provider/package/gem_spec.rb
blob: 23aa2798ded4a60aa7c4f6a8ea1ec8f5dcd8fc1d (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
186
187
#! /usr/bin/env ruby
require 'spec_helper'

provider_class = Puppet::Type.type(:package).provider(:gem)

describe provider_class do
  let(:resource) do
    Puppet::Type.type(:package).new(
      :name     => 'myresource',
      :ensure   => :installed
    )
  end

  let(:provider) do
    provider = provider_class.new
    provider.resource = resource
    provider
  end

  before :each do
    resource.provider = provider
  end

  describe "when installing" do
    it "should use the path to the gem" do
      provider_class.stubs(:command).with(:gemcmd).returns "/my/gem"
      provider.expects(:execute).with { |args| args[0] == "/my/gem" }.returns ""
      provider.install
    end

    it "should specify that the gem is being installed" do
      provider.expects(:execute).with { |args| args[1] == "install" }.returns ""
      provider.install
    end

    it "should specify that documentation should not be included" do
      provider.expects(:execute).with { |args| args[2] == "--no-rdoc" }.returns ""
      provider.install
    end

    it "should specify that RI should not be included" do
      provider.expects(:execute).with { |args| args[3] == "--no-ri" }.returns ""
      provider.install
    end

    it "should specify the package name" do
      provider.expects(:execute).with { |args| args[4] == "myresource" }.returns ""
      provider.install
    end

    it "should not append install_options by default" do
      provider.expects(:execute).with { |args| args.length == 5 }.returns ""
      provider.install
    end

    it "should allow setting an install_options parameter" do
      resource[:install_options] = [ '--force', {'--bindir' => '/usr/bin' } ]
      provider.expects(:execute).with { |args| args[5] == '--force' && args[6] == '--bindir=/usr/bin' }.returns ''
      provider.install
    end

    describe "when a source is specified" do
      describe "as a normal file" do
        it "should use the file name instead of the gem name" do
          resource[:source] = "/my/file"
          provider.expects(:execute).with { |args| args[2] == "/my/file" }.returns ""
          provider.install
        end
      end
      describe "as a file url" do
        it "should use the file name instead of the gem name" do
          resource[:source] = "file:///my/file"
          provider.expects(:execute).with { |args| args[2] == "/my/file" }.returns ""
          provider.install
        end
      end
      describe "as a puppet url" do
        it "should fail" do
          resource[:source] = "puppet://my/file"
          lambda { provider.install }.should raise_error(Puppet::Error)
        end
      end
      describe "as a non-file and non-puppet url" do
        it "should treat the source as a gem repository" do
          resource[:source] = "http://host/my/file"
          provider.expects(:execute).with { |args| args[2..4] == ["--source", "http://host/my/file", "myresource"] }.returns ""
          provider.install
        end
      end
      describe "with an invalid uri" do
        it "should fail" do
          URI.expects(:parse).raises(ArgumentError)
          resource[:source] = "http:::::uppet:/:/my/file"
          lambda { provider.install }.should raise_error(Puppet::Error)
        end
      end
    end
  end

  describe "#latest" do
    it "should return a single value for 'latest'" do
      #gemlist is used for retrieving both local and remote version numbers, and there are cases
      # (particularly local) where it makes sense for it to return an array.  That doesn't make
      # sense for '#latest', though.
      provider.class.expects(:gemlist).with({ :justme => 'myresource'}).returns({
          :name     => 'myresource',
          :ensure   => ["3.0"],
          :provider => :gem,
          })
      provider.latest.should == "3.0"
    end

    it "should list from the specified source repository" do
      resource[:source] = "http://foo.bar.baz/gems"
      provider.class.expects(:gemlist).
        with({:justme => 'myresource', :source => "http://foo.bar.baz/gems"}).
        returns({
          :name     => 'myresource',
          :ensure   => ["3.0"],
          :provider => :gem,
          })
      provider.latest.should == "3.0"
    end
  end

  describe "#instances" do
    before do
      provider_class.stubs(:command).with(:gemcmd).returns "/my/gem"
    end

    it "should return an empty array when no gems installed" do
      provider_class.expects(:execute).with(%w{/my/gem list --local}).returns("\n")
      provider_class.instances.should == []
    end

    it "should return ensure values as an array of installed versions" do
      provider_class.expects(:execute).with(%w{/my/gem list --local}).returns <<-HEREDOC.gsub(/        /, '')
        systemu (1.2.0)
        vagrant (0.8.7, 0.6.9)
      HEREDOC

      provider_class.instances.map {|p| p.properties}.should == [
        {:ensure => ["1.2.0"],          :provider => :gem, :name => 'systemu'},
        {:ensure => ["0.8.7", "0.6.9"], :provider => :gem, :name => 'vagrant'}
      ]
    end

    it "should ignore platform specifications" do
      provider_class.expects(:execute).with(%w{/my/gem list --local}).returns <<-HEREDOC.gsub(/        /, '')
        systemu (1.2.0)
        nokogiri (1.6.1 ruby java x86-mingw32 x86-mswin32-60, 1.4.4.1 x86-mswin32)
      HEREDOC

      provider_class.instances.map {|p| p.properties}.should == [
        {:ensure => ["1.2.0"],          :provider => :gem, :name => 'systemu'},
        {:ensure => ["1.6.1", "1.4.4.1"], :provider => :gem, :name => 'nokogiri'}
      ]
    end

    it "should not fail when an unmatched line is returned" do
      provider_class.expects(:execute).with(%w{/my/gem list --local}).
        returns(File.read(my_fixture('line-with-1.8.5-warning')))

      provider_class.instances.map {|p| p.properties}.
        should == [{:provider=>:gem, :ensure=>["0.3.2"], :name=>"columnize"},
                   {:provider=>:gem, :ensure=>["1.1.3"], :name=>"diff-lcs"},
                   {:provider=>:gem, :ensure=>["0.0.1"], :name=>"metaclass"},
                   {:provider=>:gem, :ensure=>["0.10.5"], :name=>"mocha"},
                   {:provider=>:gem, :ensure=>["0.8.7"], :name=>"rake"},
                   {:provider=>:gem, :ensure=>["2.9.0"], :name=>"rspec-core"},
                   {:provider=>:gem, :ensure=>["2.9.1"], :name=>"rspec-expectations"},
                   {:provider=>:gem, :ensure=>["2.9.0"], :name=>"rspec-mocks"},
                   {:provider=>:gem, :ensure=>["0.9.0"], :name=>"rubygems-bundler"},
                   {:provider=>:gem, :ensure=>["1.11.3.3"], :name=>"rvm"}]
    end
  end

  describe "listing gems" do
    describe "searching for a single package" do
      it "searches for an exact match" do
        provider_class.expects(:execute).with(includes('^bundler$')).returns(File.read(my_fixture('gem-list-single-package')))
        expected = {:name => 'bundler', :ensure => %w[1.6.2], :provider => :gem}
        expect(provider_class.gemlist({:justme => 'bundler'})).to eq(expected)
      end
    end
  end
end