Update puppetlabs/stdlib module
[mirror/dsa-puppet.git] / 3rdparty / modules / stdlib / spec / unit / puppet / provider / file_line / ruby_spec.rb
old mode 100755 (executable)
new mode 100644 (file)
index dcca4a4..d0f653a
-#! /usr/bin/env ruby -S rspec
 require 'spec_helper'
-require 'tempfile'
+
 provider_class = Puppet::Type.type(:file_line).provider(:ruby)
-# These tests fail on windows when run as part of the rake task. Individually they pass
+#  These tests fail on windows when run as part of the rake task. Individually they pass
 describe provider_class, :unless => Puppet::Util::Platform.windows? do
-  context "when adding" do
-    let :tmpfile do
-      tmp = Tempfile.new('tmp')
-      path = tmp.path
-      tmp.close!
-      path
-    end
-    let :resource do
-      Puppet::Type::File_line.new(
-        {:name => 'foo', :path => tmpfile, :line => 'foo'}
-      )
-    end
-    let :provider do
-      provider_class.new(resource)
-    end
+  include PuppetlabsSpec::Files
 
-    it 'should detect if the line exists in the file' do
-      File.open(tmpfile, 'w') do |fh|
-        fh.write('foo')
-      end
-      expect(provider.exists?).to be_truthy
-    end
-    it 'should detect if the line does not exist in the file' do
-      File.open(tmpfile, 'w') do |fh|
-        fh.write('foo1')
-      end
-      expect(provider.exists?).to eql (false)
-    end
-    it 'should append to an existing file when creating' do
-      provider.create
-      expect(File.read(tmpfile).chomp).to eq('foo')
-    end
+  let :tmpfile do
+    tmpfilename('file_line_test')
+  end
+  let :content do
+    ''
+  end
+  let :params do
+    {}
+  end
+  let :resource do
+    Puppet::Type::File_line.new({
+      :name => 'foo',
+      :path => tmpfile,
+      :line => 'foo',
+    }.merge(params))
+  end
+  let :provider do
+    provider_class.new(resource)
   end
-  context 'when using replace' do
-    before :each do
-      # TODO: these should be ported over to use the PuppetLabs spec_helper
-      #  file fixtures once the following pull request has been merged:
-      # https://github.com/puppetlabs/puppetlabs-stdlib/pull/73/files
-      tmp = Tempfile.new('tmp')
-      @tmpfile = tmp.path
-      tmp.close!
-      @resource = Puppet::Type::File_line.new(
-        {
-          :name    => 'foo',
-          :path    => @tmpfile,
-          :line    => 'foo = bar',
-          :match   => '^foo\s*=.*$',
-          :replace => false,
-        }
-      )
-      @provider = provider_class.new(@resource)
-    end
 
-    it 'should not replace the matching line' do
-      File.open(@tmpfile, 'w') do |fh|
-        fh.write("foo1\nfoo=blah\nfoo2\nfoo3")
-      end
-      expect(@provider.exists?).to be_truthy
-      @provider.create
-      expect(File.read(@tmpfile).chomp).to eql("foo1\nfoo=blah\nfoo2\nfoo3")
+  before :each do
+    File.open(tmpfile, 'w') do |fh|
+      fh.write(content)
     end
+  end
+
+  describe 'line parameter' do
+    context 'when line exists' do
+      let(:content) { 'foo' }
 
-    it 'should append the line if no matches are found' do
-      File.open(@tmpfile, 'w') do |fh|
-        fh.write("foo1\nfoo2")
+      it 'detects the line' do
+        expect(provider).to be_exists
       end
-      expect(@provider.exists?).to eql (false)
-      @provider.create
-      expect(File.read(@tmpfile).chomp).to eql("foo1\nfoo2\nfoo = bar")
     end
+    context 'when line does not exist' do
+      let(:content) { 'foo bar' }
 
-    it 'should raise an error with invalid values' do
-      expect {
-        @resource = Puppet::Type::File_line.new(
-          {
-            :name     => 'foo',
-            :path     => @tmpfile,
-            :line     => 'foo = bar',
-            :match    => '^foo\s*=.*$',
-            :replace  => 'asgadga',
-          }
-        )
-      }.to raise_error(Puppet::Error, /Invalid value "asgadga"\. Valid values are true, false\./)
+      it 'requests changes' do
+        expect(provider).not_to be_exists
+      end
+      it 'appends the line' do
+        provider.create
+        expect(File.read(tmpfile).chomp).to eq("foo bar\nfoo")
+      end
     end
   end
-  context "when matching" do
-    before :each do
-      # TODO: these should be ported over to use the PuppetLabs spec_helper
-      #  file fixtures once the following pull request has been merged:
-      # https://github.com/puppetlabs/puppetlabs-stdlib/pull/73/files
-      tmp = Tempfile.new('tmp')
-      @tmpfile = tmp.path
-      tmp.close!
-      @resource = Puppet::Type::File_line.new(
-        {
-          :name  => 'foo',
-          :path  => @tmpfile,
-          :line  => 'foo = bar',
-          :match => '^foo\s*=.*$',
-        }
-      )
-      @provider = provider_class.new(@resource)
-    end
 
-    describe 'using match' do
-      it 'should raise an error if more than one line matches, and should not have modified the file' do
-        File.open(@tmpfile, 'w') do |fh|
-          fh.write("foo1\nfoo=blah\nfoo2\nfoo=baz")
-        end
-        expect(@provider.exists?).to eql(false)
-        expect { @provider.create }.to raise_error(Puppet::Error, /More than one line.*matches/)
-        expect(File.read(@tmpfile)).to eql("foo1\nfoo=blah\nfoo2\nfoo=baz")
-      end
+  describe 'match parameter' do
+    let(:params) { { :match => '^bar' } }
 
-      it 'should replace all lines that matches' do
-        @resource = Puppet::Type::File_line.new(
-          {
-            :name     => 'foo',
-            :path     => @tmpfile,
-            :line     => 'foo = bar',
-            :match    => '^foo\s*=.*$',
-            :multiple => true,
-          }
-        )
-        @provider = provider_class.new(@resource)
-        File.open(@tmpfile, 'w') do |fh|
-          fh.write("foo1\nfoo=blah\nfoo2\nfoo=baz")
-        end
-        expect(@provider.exists?).to eql(false)
-        @provider.create
-        expect(File.read(@tmpfile).chomp).to eql("foo1\nfoo = bar\nfoo2\nfoo = bar")
-      end
+    describe 'does not match line - line does not exist - replacing' do
+      let(:content) { "foo bar\nbar" }
 
-      it 'should replace all lines that match, even when some lines are correct' do
-        @resource = Puppet::Type::File_line.new(
-          {
-            :name     => 'neil',
-            :path     => @tmpfile,
-            :line     => "\thard\tcore\t0\n",
-            :match    => '^[ \t]hard[ \t]+core[ \t]+.*',
-            :multiple => true,
-          }
-        )
-        @provider = provider_class.new(@resource)
-        File.open(@tmpfile, 'w') do |fh|
-          fh.write("\thard\tcore\t90\n\thard\tcore\t0\n")
-        end
-        expect(@provider.exists?).to eql(false)
-        @provider.create
-        expect(File.read(@tmpfile).chomp).to eql("\thard\tcore\t0\n\thard\tcore\t0")
+      it 'requests changes' do
+        expect(provider).not_to be_exists
       end
-
-      it 'should raise an error with invalid values' do
-        expect {
-          @resource = Puppet::Type::File_line.new(
-            {
-              :name     => 'foo',
-              :path     => @tmpfile,
-              :line     => 'foo = bar',
-              :match    => '^foo\s*=.*$',
-              :multiple => 'asgadga',
-            }
-          )
-        }.to raise_error(Puppet::Error, /Invalid value "asgadga"\. Valid values are true, false\./)
+      it 'replaces the match' do
+        provider.create
+        expect(File.read(tmpfile).chomp).to eq("foo bar\nfoo")
       end
+    end
 
-      it 'should replace a line that matches' do
-        File.open(@tmpfile, 'w') do |fh|
-          fh.write("foo1\nfoo=blah\nfoo2")
-        end
-        expect(@provider.exists?).to eql(false)
-        @provider.create
-        expect(File.read(@tmpfile).chomp).to eql("foo1\nfoo = bar\nfoo2")
-      end
-      it 'should add a new line if no lines match' do
-        File.open(@tmpfile, 'w') do |fh|
-          fh.write("foo1\nfoo2")
-        end
-        expect(@provider.exists?).to eql(false)
-        @provider.create
-        expect(File.read(@tmpfile)).to eql("foo1\nfoo2\nfoo = bar\n")
-      end
-      it 'should do nothing if the exact line already exists' do
-        File.open(@tmpfile, 'w') do |fh|
-          fh.write("foo1\nfoo = bar\nfoo2")
-        end
-        expect(@provider.exists?).to eql(true)
-        @provider.create
-        expect(File.read(@tmpfile).chomp).to eql("foo1\nfoo = bar\nfoo2")
-      end
+    describe 'does not match line - line does not exist - appending' do
+      let(:params) { super().merge(:replace => false) }
+      let(:content) { "foo bar\nbar" }
 
-      it 'should not add line after no matches found' do
-        @resource = Puppet::Type::File_line.new(
-          {
-            :name               => 'foo',
-            :path               => @tmpfile,
-            :line               => 'inserted = line',
-            :match              => '^foo3$',
-            :append_on_no_match => false,
-          }
-        )
-        @provider = provider_class.new(@resource)
-        File.open(@tmpfile, 'w') do |fh|
-          fh.write("foo1\nfoo = blah\nfoo2\nfoo = baz")
-        end
-        expect(@provider.exists?).to be true
-        expect(File.read(@tmpfile).chomp).to eql("foo1\nfoo = blah\nfoo2\nfoo = baz")
+      it 'does not request changes' do
+        expect(provider).to be_exists
       end
     end
 
-    describe 'using after' do
-      let :resource do
-        Puppet::Type::File_line.new(
-          {
-            :name  => 'foo',
-            :path  => @tmpfile,
-            :line  => 'inserted = line',
-            :after => '^foo1',
-          }
-        )
-      end
+    context 'when does not match line - line exists' do
+      let(:content) { "foo\nbar" }
 
-      let :provider do
-        provider_class.new(resource)
-      end
-      context 'match and after set' do
-        shared_context 'resource_create' do
-          let(:match) { '^foo2$' }
-          let(:after) { '^foo1$' }
-          let(:resource) {
-            Puppet::Type::File_line.new(
-              {
-                :name  => 'foo',
-                :path  => @tmpfile,
-                :line  => 'inserted = line',
-                :after => after,
-                :match => match,
-              }
-            )
-          }
-        end
-        before :each do
-          File.open(@tmpfile, 'w') do |fh|
-            fh.write("foo1\nfoo2\nfoo = baz")
-          end
-        end
-        describe 'inserts at match' do
-          include_context 'resource_create'
-          it {
-            provider.create
-            expect(File.read(@tmpfile).chomp).to eq("foo1\ninserted = line\nfoo = baz")
-          }
-        end
-        describe 'inserts a new line after when no match' do
-          include_context 'resource_create' do
-            let(:match) { '^nevergoingtomatch$' }
-          end
-          it {
-            provider.create
-            expect(File.read(@tmpfile).chomp).to eq("foo1\ninserted = line\nfoo2\nfoo = baz")
-          }
-        end
-        describe 'append to end of file if no match for both after and match' do
-          include_context 'resource_create' do
-            let(:match) { '^nevergoingtomatch$' }
-            let(:after) { '^stillneverafter' }
-          end
-          it {
-            provider.create
-            expect(File.read(@tmpfile).chomp).to eq("foo1\nfoo2\nfoo = baz\ninserted = line")
-          }
-        end
-      end
-      context 'with one line matching the after expression' do
-        before :each do
-          File.open(@tmpfile, 'w') do |fh|
-            fh.write("foo1\nfoo = blah\nfoo2\nfoo = baz")
-          end
-        end
-
-        it 'inserts the specified line after the line matching the "after" expression' do
-          provider.create
-          expect(File.read(@tmpfile).chomp).to eql("foo1\ninserted = line\nfoo = blah\nfoo2\nfoo = baz")
-        end
+      it 'detects the line' do
+        expect(provider).to be_exists
       end
+    end
+
+    context 'when matches line - line exists' do
+      let(:params) { { :match => '^foo' } }
+      let(:content) { "foo\nbar" }
 
-      context 'with multiple lines matching the after expression' do
-        before :each do
-          File.open(@tmpfile, 'w') do |fh|
-            fh.write("foo1\nfoo = blah\nfoo2\nfoo1\nfoo = baz")
-          end
-        end
-
-        it 'errors out stating "One or no line must match the pattern"' do
-          expect { provider.create }.to raise_error(Puppet::Error, /One or no line must match the pattern/)
-        end
-
-        it 'adds the line after all lines matching the after expression' do
-          @resource = Puppet::Type::File_line.new(
-            {
-              :name     => 'foo',
-              :path     => @tmpfile,
-              :line     => 'inserted = line',
-              :after    => '^foo1$',
-              :multiple => true,
-            }
-          )
-          @provider = provider_class.new(@resource)
-          expect(@provider.exists?).to eql (false) 
-          @provider.create
-          expect(File.read(@tmpfile).chomp).to eql("foo1\ninserted = line\nfoo = blah\nfoo2\nfoo1\ninserted = line\nfoo = baz")
-        end
+      it 'detects the line' do
+        expect(provider).to be_exists
       end
+    end
 
-      context 'with no lines matching the after expression' do
-        let :content do
-          "foo3\nfoo = blah\nfoo2\nfoo = baz\n"
-        end
-
-        before :each do
-          File.open(@tmpfile, 'w') do |fh|
-            fh.write(content)
-          end
-        end
-
-        it 'appends the specified line to the file' do
-          provider.create
-          expect(File.read(@tmpfile)).to eq(content << resource[:line] << "\n")
-        end
+    context 'when matches line - line does not exist' do
+      let(:params) { { :match => '^foo' } }
+      let(:content) { "foo bar\nbar" }
+
+      it 'requests changes' do
+        expect(provider).not_to be_exists
+      end
+      it 'replaces the match' do
+        provider.create
+        expect(File.read(tmpfile).chomp).to eq("foo\nbar")
       end
     end
   end
 
-  context "when removing" do
-    before :each do
-      # TODO: these should be ported over to use the PuppetLabs spec_helper
-      #  file fixtures once the following pull request has been merged:
-      # https://github.com/puppetlabs/puppetlabs-stdlib/pull/73/files
-      tmp = Tempfile.new('tmp')
-      @tmpfile = tmp.path
-      tmp.close!
-      @resource = Puppet::Type::File_line.new(
-        {
-          :name   => 'foo',
-          :path   => @tmpfile,
-          :line   => 'foo',
-          :ensure => 'absent',
-        }
-      )
-      @provider = provider_class.new(@resource)
-    end
-    it 'should remove the line if it exists' do
-      File.open(@tmpfile, 'w') do |fh|
-        fh.write("foo1\nfoo\nfoo2")
-      end
-      @provider.destroy
-      expect(File.read(@tmpfile)).to eql("foo1\nfoo2")
+  describe 'append_on_no_match' do
+    let(:params) do
+      {
+        :append_on_no_match => false,
+        :match => '^foo1$',
+      }
     end
 
-    it 'should remove the line without touching the last new line' do
-      File.open(@tmpfile, 'w') do |fh|
-        fh.write("foo1\nfoo\nfoo2\n")
+    context 'when matching' do
+      let(:content) { "foo1\nbar" }
+
+      it 'requests changes' do
+        expect(provider).not_to be_exists
+      end
+      it 'replaces the match' do
+        provider.create
+        expect(File.read(tmpfile).chomp).to eql("foo\nbar")
       end
-      @provider.destroy
-      expect(File.read(@tmpfile)).to eql("foo1\nfoo2\n")
     end
+    context 'when not matching' do
+      let(:content) { "foo3\nbar" }
 
-    it 'should remove any occurence of the line' do
-      File.open(@tmpfile, 'w') do |fh|
-        fh.write("foo1\nfoo\nfoo2\nfoo\nfoo")
+      it 'does not affect the file' do
+        expect(provider).to be_exists
       end
-      @provider.destroy
-      expect(File.read(@tmpfile)).to eql("foo1\nfoo2\n")
     end
   end
 
-  context "when removing with a match" do
-    before :each do
-      # TODO: these should be ported over to use the PuppetLabs spec_helper
-      #  file fixtures once the following pull request has been merged:
-      # https://github.com/puppetlabs/puppetlabs-stdlib/pull/73/files
-      tmp = Tempfile.new('tmp')
-      @tmpfile = tmp.path
-      tmp.close!
-      @resource = Puppet::Type::File_line.new(
+  describe 'replace_all_matches_not_matching_line' do
+    context 'when replace is false' do
+      let(:params) do
         {
-          :name              => 'foo',
-          :path              => @tmpfile,
-          :line              => 'foo2',
-          :ensure            => 'absent',
-          :match             => 'o$',
-          :match_for_absence => true,
+          :replace_all_matches_not_matching_line => true,
+          :replace => false,
         }
-      )
-      @provider = provider_class.new(@resource)
-    end
+      end
 
-    it 'should find a line to match' do
-      File.open(@tmpfile, 'w') do |fh|
-        fh.write("foo1\nfoo\nfoo2")
+      it 'raises an error' do
+        expect { provider.exists? }.to raise_error(Puppet::Error, %r{replace must be true})
       end
-      expect(@provider.exists?).to eql (true)
     end
 
-    it 'should remove one line if it matches' do
-      File.open(@tmpfile, 'w') do |fh|
-        fh.write("foo1\nfoo\nfoo2")
+    context 'when match matches line - when there are more matches than lines' do
+      let(:params) do
+        {
+          :replace_all_matches_not_matching_line => true,
+          :match => '^foo',
+          :multiple => true,
+        }
       end
-      @provider.destroy
-      expect(File.read(@tmpfile)).to eql("foo1\nfoo2")
-    end
+      let(:content) { "foo\nfoo bar\nbar\nfoo baz" }
 
-    it 'should raise an error if more than one line matches' do
-      File.open(@tmpfile, 'w') do |fh|
-        fh.write("foo1\nfoo\nfoo2\nfoo\nfoo")
+      it 'requests changes' do
+        expect(provider).not_to be_exists
+      end
+      it 'replaces the matches' do
+        provider.create
+        expect(File.read(tmpfile).chomp).to eql("foo\nfoo\nbar\nfoo")
       end
-      expect { @provider.destroy }.to raise_error(Puppet::Error, /More than one line/)
     end
 
-    it 'should remove multiple lines if :multiple is true' do
-      @resource = Puppet::Type::File_line.new(
+    context 'when match matches line - when there are the same matches and lines' do
+      let(:params) do
         {
-          :name              => 'foo',
-          :path              => @tmpfile,
-          :line              => 'foo2',
-          :ensure            => 'absent',
-          :match             => 'o$',
-          :multiple          => true,
-          :match_for_absence => true,
+          :replace_all_matches_not_matching_line => true,
+          :match => '^foo',
+          :multiple => true,
         }
-      )
-      @provider = provider_class.new(@resource)
-      File.open(@tmpfile, 'w') do |fh|
-        fh.write("foo1\nfoo\nfoo2\nfoo\nfoo")
       end
-      @provider.destroy
-      expect(File.read(@tmpfile)).to eql("foo1\nfoo2\n")
+      let(:content) { "foo\nfoo\nbar" }
+
+      it 'does not request changes' do
+        expect(provider).to be_exists
+      end
     end
 
-    it 'should ignore the match if match_for_absence is not specified' do
-      @resource = Puppet::Type::File_line.new(
+    context 'when match does not match line - when there are more matches than lines' do
+      let(:params) do
         {
-          :name     => 'foo',
-          :path     => @tmpfile,
-          :line     => 'foo2',
-          :ensure   => 'absent',
-          :match    => 'o$',
+          :replace_all_matches_not_matching_line => true,
+          :match => '^bar',
+          :multiple => true,
         }
-      )
-      @provider = provider_class.new(@resource)
-      File.open(@tmpfile, 'w') do |fh|
-        fh.write("foo1\nfoo\nfoo2")
       end
-      @provider.destroy
-      expect(File.read(@tmpfile)).to eql("foo1\nfoo\n")
+      let(:content) { "foo\nfoo bar\nbar\nbar baz" }
+
+      it 'requests changes' do
+        expect(provider).not_to be_exists
+      end
+      it 'replaces the matches' do
+        provider.create
+        expect(File.read(tmpfile).chomp).to eql("foo\nfoo bar\nfoo\nfoo")
+      end
     end
 
-    it 'should ignore the match if match_for_absence is false' do
-      @resource = Puppet::Type::File_line.new(
+    context 'when match does not match line - when there are the same matches and lines' do
+      let(:params) do
         {
-          :name              => 'foo',
-          :path              => @tmpfile,
-          :line              => 'foo2',
-          :ensure            => 'absent',
-          :match             => 'o$',
-          :match_for_absence => false,
+          :replace_all_matches_not_matching_line => true,
+          :match => '^bar',
+          :multiple => true,
         }
-      )
-      @provider = provider_class.new(@resource)
-      File.open(@tmpfile, 'w') do |fh|
-        fh.write("foo1\nfoo\nfoo2")
       end
-      @provider.destroy
-      expect(File.read(@tmpfile)).to eql("foo1\nfoo\n")
+      let(:content) { "foo\nfoo\nbar\nbar baz" }
+
+      it 'requests changes' do
+        expect(provider).not_to be_exists
+      end
+      it 'replaces the matches' do
+        provider.create
+        expect(File.read(tmpfile).chomp).to eql("foo\nfoo\nfoo\nfoo")
+      end
+    end
+  end
+
+  context 'when match does not match line - when there are no matches' do
+    let(:params) do
+      {
+        :replace_all_matches_not_matching_line => true,
+        :match => '^bar',
+        :multiple => true,
+      }
     end
+    let(:content) { "foo\nfoo bar" }
 
+    it 'does not request changes' do
+      expect(provider).to be_exists
+    end
   end
 
+  context 'when match does not match line - when there are no matches or lines' do
+    let(:params) do
+      {
+        :replace_all_matches_not_matching_line => true,
+        :match => '^bar',
+        :multiple => true,
+      }
+    end
+    let(:content) { 'foo bar' }
+
+    it 'requests changes' do
+      expect(provider).not_to be_exists
+    end
+    it 'appends the line' do
+      provider.create
+      expect(File.read(tmpfile).chomp).to eql("foo bar\nfoo")
+    end
+  end
 end