1 #! /usr/bin/env ruby -S rspec
4 provider_class = Puppet::Type.type(:file_line).provider(:ruby)
5 # These tests fail on windows when run as part of the rake task. Individually they pass
6 describe provider_class, :unless => Puppet::Util::Platform.windows? do
7 context "when adding" do
9 tmp = Tempfile.new('tmp')
15 Puppet::Type::File_line.new(
16 {:name => 'foo', :path => tmpfile, :line => 'foo'}
20 provider_class.new(resource)
23 it 'should detect if the line exists in the file' do
24 File.open(tmpfile, 'w') do |fh|
27 expect(provider.exists?).to be_truthy
29 it 'should detect if the line does not exist in the file' do
30 File.open(tmpfile, 'w') do |fh|
33 expect(provider.exists?).to eql (false)
35 it 'should append to an existing file when creating' do
37 expect(File.read(tmpfile).chomp).to eq('foo')
40 context 'when using replace' do
42 # TODO: these should be ported over to use the PuppetLabs spec_helper
43 # file fixtures once the following pull request has been merged:
44 # https://github.com/puppetlabs/puppetlabs-stdlib/pull/73/files
45 tmp = Tempfile.new('tmp')
48 @resource = Puppet::Type::File_line.new(
53 :match => '^foo\s*=.*$',
57 @provider = provider_class.new(@resource)
60 it 'should not replace the matching line' do
61 File.open(@tmpfile, 'w') do |fh|
62 fh.write("foo1\nfoo=blah\nfoo2\nfoo3")
64 expect(@provider.exists?).to be_truthy
66 expect(File.read(@tmpfile).chomp).to eql("foo1\nfoo=blah\nfoo2\nfoo3")
69 it 'should append the line if no matches are found' do
70 File.open(@tmpfile, 'w') do |fh|
71 fh.write("foo1\nfoo2")
73 expect(@provider.exists?).to eql (false)
75 expect(File.read(@tmpfile).chomp).to eql("foo1\nfoo2\nfoo = bar")
78 it 'should raise an error with invalid values' do
80 @resource = Puppet::Type::File_line.new(
85 :match => '^foo\s*=.*$',
86 :replace => 'asgadga',
89 }.to raise_error(Puppet::Error, /Invalid value "asgadga"\. Valid values are true, false\./)
92 context "when matching" do
94 # TODO: these should be ported over to use the PuppetLabs spec_helper
95 # file fixtures once the following pull request has been merged:
96 # https://github.com/puppetlabs/puppetlabs-stdlib/pull/73/files
97 tmp = Tempfile.new('tmp')
100 @resource = Puppet::Type::File_line.new(
104 :line => 'foo = bar',
105 :match => '^foo\s*=.*$',
108 @provider = provider_class.new(@resource)
111 describe 'using match' do
112 it 'should raise an error if more than one line matches, and should not have modified the file' do
113 File.open(@tmpfile, 'w') do |fh|
114 fh.write("foo1\nfoo=blah\nfoo2\nfoo=baz")
116 expect(@provider.exists?).to eql(false)
117 expect { @provider.create }.to raise_error(Puppet::Error, /More than one line.*matches/)
118 expect(File.read(@tmpfile)).to eql("foo1\nfoo=blah\nfoo2\nfoo=baz")
121 it 'should replace all lines that matches' do
122 @resource = Puppet::Type::File_line.new(
126 :line => 'foo = bar',
127 :match => '^foo\s*=.*$',
131 @provider = provider_class.new(@resource)
132 File.open(@tmpfile, 'w') do |fh|
133 fh.write("foo1\nfoo=blah\nfoo2\nfoo=baz")
135 expect(@provider.exists?).to eql(false)
137 expect(File.read(@tmpfile).chomp).to eql("foo1\nfoo = bar\nfoo2\nfoo = bar")
140 it 'should replace all lines that match, even when some lines are correct' do
141 @resource = Puppet::Type::File_line.new(
145 :line => "\thard\tcore\t0\n",
146 :match => '^[ \t]hard[ \t]+core[ \t]+.*',
150 @provider = provider_class.new(@resource)
151 File.open(@tmpfile, 'w') do |fh|
152 fh.write("\thard\tcore\t90\n\thard\tcore\t0\n")
154 expect(@provider.exists?).to eql(false)
156 expect(File.read(@tmpfile).chomp).to eql("\thard\tcore\t0\n\thard\tcore\t0")
159 it 'should raise an error with invalid values' do
161 @resource = Puppet::Type::File_line.new(
165 :line => 'foo = bar',
166 :match => '^foo\s*=.*$',
167 :multiple => 'asgadga',
170 }.to raise_error(Puppet::Error, /Invalid value "asgadga"\. Valid values are true, false\./)
173 it 'should replace a line that matches' do
174 File.open(@tmpfile, 'w') do |fh|
175 fh.write("foo1\nfoo=blah\nfoo2")
177 expect(@provider.exists?).to eql(false)
179 expect(File.read(@tmpfile).chomp).to eql("foo1\nfoo = bar\nfoo2")
181 it 'should add a new line if no lines match' do
182 File.open(@tmpfile, 'w') do |fh|
183 fh.write("foo1\nfoo2")
185 expect(@provider.exists?).to eql(false)
187 expect(File.read(@tmpfile)).to eql("foo1\nfoo2\nfoo = bar\n")
189 it 'should do nothing if the exact line already exists' do
190 File.open(@tmpfile, 'w') do |fh|
191 fh.write("foo1\nfoo = bar\nfoo2")
193 expect(@provider.exists?).to eql(true)
195 expect(File.read(@tmpfile).chomp).to eql("foo1\nfoo = bar\nfoo2")
198 it 'should not add line after no matches found' do
199 @resource = Puppet::Type::File_line.new(
203 :line => 'inserted = line',
205 :append_on_no_match => false,
208 @provider = provider_class.new(@resource)
209 File.open(@tmpfile, 'w') do |fh|
210 fh.write("foo1\nfoo = blah\nfoo2\nfoo = baz")
212 expect(@provider.exists?).to be true
213 expect(File.read(@tmpfile).chomp).to eql("foo1\nfoo = blah\nfoo2\nfoo = baz")
217 describe 'using after' do
219 Puppet::Type::File_line.new(
223 :line => 'inserted = line',
230 provider_class.new(resource)
232 context 'match and after set' do
233 shared_context 'resource_create' do
234 let(:match) { '^foo2$' }
235 let(:after) { '^foo1$' }
237 Puppet::Type::File_line.new(
241 :line => 'inserted = line',
249 File.open(@tmpfile, 'w') do |fh|
250 fh.write("foo1\nfoo2\nfoo = baz")
253 describe 'inserts at match' do
254 include_context 'resource_create'
257 expect(File.read(@tmpfile).chomp).to eq("foo1\ninserted = line\nfoo = baz")
260 describe 'inserts a new line after when no match' do
261 include_context 'resource_create' do
262 let(:match) { '^nevergoingtomatch$' }
266 expect(File.read(@tmpfile).chomp).to eq("foo1\ninserted = line\nfoo2\nfoo = baz")
269 describe 'append to end of file if no match for both after and match' do
270 include_context 'resource_create' do
271 let(:match) { '^nevergoingtomatch$' }
272 let(:after) { '^stillneverafter' }
276 expect(File.read(@tmpfile).chomp).to eq("foo1\nfoo2\nfoo = baz\ninserted = line")
280 context 'with one line matching the after expression' do
282 File.open(@tmpfile, 'w') do |fh|
283 fh.write("foo1\nfoo = blah\nfoo2\nfoo = baz")
287 it 'inserts the specified line after the line matching the "after" expression' do
289 expect(File.read(@tmpfile).chomp).to eql("foo1\ninserted = line\nfoo = blah\nfoo2\nfoo = baz")
293 context 'with multiple lines matching the after expression' do
295 File.open(@tmpfile, 'w') do |fh|
296 fh.write("foo1\nfoo = blah\nfoo2\nfoo1\nfoo = baz")
300 it 'errors out stating "One or no line must match the pattern"' do
301 expect { provider.create }.to raise_error(Puppet::Error, /One or no line must match the pattern/)
304 it 'adds the line after all lines matching the after expression' do
305 @resource = Puppet::Type::File_line.new(
309 :line => 'inserted = line',
314 @provider = provider_class.new(@resource)
315 expect(@provider.exists?).to eql (false)
317 expect(File.read(@tmpfile).chomp).to eql("foo1\ninserted = line\nfoo = blah\nfoo2\nfoo1\ninserted = line\nfoo = baz")
321 context 'with no lines matching the after expression' do
323 "foo3\nfoo = blah\nfoo2\nfoo = baz\n"
327 File.open(@tmpfile, 'w') do |fh|
332 it 'appends the specified line to the file' do
334 expect(File.read(@tmpfile)).to eq(content << resource[:line] << "\n")
340 context "when removing" do
342 # TODO: these should be ported over to use the PuppetLabs spec_helper
343 # file fixtures once the following pull request has been merged:
344 # https://github.com/puppetlabs/puppetlabs-stdlib/pull/73/files
345 tmp = Tempfile.new('tmp')
348 @resource = Puppet::Type::File_line.new(
356 @provider = provider_class.new(@resource)
358 it 'should remove the line if it exists' do
359 File.open(@tmpfile, 'w') do |fh|
360 fh.write("foo1\nfoo\nfoo2")
363 expect(File.read(@tmpfile)).to eql("foo1\nfoo2")
366 it 'should remove the line without touching the last new line' do
367 File.open(@tmpfile, 'w') do |fh|
368 fh.write("foo1\nfoo\nfoo2\n")
371 expect(File.read(@tmpfile)).to eql("foo1\nfoo2\n")
374 it 'should remove any occurence of the line' do
375 File.open(@tmpfile, 'w') do |fh|
376 fh.write("foo1\nfoo\nfoo2\nfoo\nfoo")
379 expect(File.read(@tmpfile)).to eql("foo1\nfoo2\n")
383 context "when removing with a match" do
385 # TODO: these should be ported over to use the PuppetLabs spec_helper
386 # file fixtures once the following pull request has been merged:
387 # https://github.com/puppetlabs/puppetlabs-stdlib/pull/73/files
388 tmp = Tempfile.new('tmp')
391 @resource = Puppet::Type::File_line.new(
398 :match_for_absence => true,
401 @provider = provider_class.new(@resource)
404 it 'should find a line to match' do
405 File.open(@tmpfile, 'w') do |fh|
406 fh.write("foo1\nfoo\nfoo2")
408 expect(@provider.exists?).to eql (true)
411 it 'should remove one line if it matches' do
412 File.open(@tmpfile, 'w') do |fh|
413 fh.write("foo1\nfoo\nfoo2")
416 expect(File.read(@tmpfile)).to eql("foo1\nfoo2")
419 it 'should raise an error if more than one line matches' do
420 File.open(@tmpfile, 'w') do |fh|
421 fh.write("foo1\nfoo\nfoo2\nfoo\nfoo")
423 expect { @provider.destroy }.to raise_error(Puppet::Error, /More than one line/)
426 it 'should remove multiple lines if :multiple is true' do
427 @resource = Puppet::Type::File_line.new(
435 :match_for_absence => true,
438 @provider = provider_class.new(@resource)
439 File.open(@tmpfile, 'w') do |fh|
440 fh.write("foo1\nfoo\nfoo2\nfoo\nfoo")
443 expect(File.read(@tmpfile)).to eql("foo1\nfoo2\n")
446 it 'should ignore the match if match_for_absence is not specified' do
447 @resource = Puppet::Type::File_line.new(
456 @provider = provider_class.new(@resource)
457 File.open(@tmpfile, 'w') do |fh|
458 fh.write("foo1\nfoo\nfoo2")
461 expect(File.read(@tmpfile)).to eql("foo1\nfoo\n")
464 it 'should ignore the match if match_for_absence is false' do
465 @resource = Puppet::Type::File_line.new(
472 :match_for_absence => false,
475 @provider = provider_class.new(@resource)
476 File.open(@tmpfile, 'w') do |fh|
477 fh.write("foo1\nfoo\nfoo2")
480 expect(File.read(@tmpfile)).to eql("foo1\nfoo\n")