--- /dev/null
+require 'spec_helper_acceptance'
+
+describe 'replacement of' do
+ before(:all) do
+ @basedir = setup_test_directory
+ end
+
+ describe 'file' do
+ let(:pp) do
+ <<-MANIFEST
+ concat { '#{@basedir}/file':
+ replace => false,
+ }
+
+ concat::fragment { '1':
+ target => '#{@basedir}/file',
+ content => '1',
+ }
+
+ concat::fragment { '2':
+ target => '#{@basedir}/file',
+ content => '2',
+ }
+
+ concat { '#{@basedir}/file2':
+ replace => true,
+ }
+
+ concat::fragment { 'file2_1':
+ target => '#{@basedir}/file2',
+ content => '1',
+ }
+
+ concat::fragment { 'file2_2':
+ target => '#{@basedir}/file2',
+ content => '2',
+ }
+ MANIFEST
+ end
+
+ it 'when file should not succeed' do
+ idempotent_apply(pp)
+ expect(file("#{@basedir}/file")).to be_file
+ expect(file("#{@basedir}/file").content).to match 'file exists'
+ expect(file("#{@basedir}/file").content).not_to match '1'
+ expect(file("#{@basedir}/file").content).not_to match '2'
+ end
+ it 'when file should succeed' do
+ expect(file("#{@basedir}/file2")).to be_file
+ expect(file("#{@basedir}/file2").content).not_to match 'file exists'
+ expect(file("#{@basedir}/file2").content).to match '1'
+ expect(file("#{@basedir}/file2").content).to match '2'
+ end
+ end
+
+ describe 'symlink', unless: (os[:family] == 'windows') do
+ # XXX the core puppet file type will replace a symlink with a plain file
+ # when using ensure => present and source => ... but it will not when using
+ # ensure => present and content => ...; this is somewhat confusing behavior
+ before(:all) do
+ pp = <<-MANIFEST
+ file { '#{@basedir}':
+ ensure => directory,
+ }
+ file { '#{@basedir}/file':
+ ensure => link,
+ target => '#{@basedir}/dangling',
+ }
+ MANIFEST
+ apply_manifest(pp)
+ end
+
+ let(:pp) do
+ <<-MANIFEST
+ concat { '#{@basedir}/file':
+ replace => false,
+ }
+
+ concat::fragment { '1':
+ target => '#{@basedir}/file',
+ content => '1',
+ }
+
+ concat::fragment { '2':
+ target => '#{@basedir}/file',
+ content => '2',
+ }
+
+ concat { '#{@basedir}/file2':
+ replace => true,
+ }
+
+ concat::fragment { 'file2_1':
+ target => '#{@basedir}/file2',
+ content => '1',
+ }
+
+ concat::fragment { 'file2_2':
+ target => '#{@basedir}/file2',
+ content => '2',
+ }
+ MANIFEST
+ end
+
+ it 'when symlink should not succeed' do
+ idempotent_apply(pp)
+ expect(file("#{@basedir}/file")).to be_linked_to "#{@basedir}/dangling" unless os[:family] == 'aix' || os[:family] == 'windows'
+ expect(file("#{@basedir}/dangling")).not_to be_file
+ expect(file("#{@basedir}/dangling")).not_to be_directory
+ end
+ it 'when symlink should succeed' do
+ expect(file("#{@basedir}/file2")).to be_file
+ expect(file("#{@basedir}/file2").content).to match '1'
+ expect(file("#{@basedir}/file2").content).to match '2'
+ end
+ end
+
+ describe 'when directory should not succeed' do
+ before(:all) do
+ pp = <<-MANIFEST
+ file { '#{@basedir}':
+ ensure => directory,
+ }
+ file { '#{@basedir}/file':
+ ensure => directory,
+ }
+ MANIFEST
+ apply_manifest(pp)
+ end
+ let(:pp) do
+ <<-MANIFEST
+ concat { '#{@basedir}/file': }
+
+ concat::fragment { '1':
+ target => '#{@basedir}/file',
+ content => '1',
+ }
+
+ concat::fragment { '2':
+ target => '#{@basedir}/file',
+ content => '2',
+ }
+ MANIFEST
+ end
+
+ it 'applies the manifest twice with stderr' do
+ expect(apply_manifest(pp, expect_failures: true).stderr).to match(%r{change from '?directory'? to '?file'? failed})
+ expect(apply_manifest(pp, expect_failures: true).stderr).to match(%r{change from '?directory'? to '?file'? failed})
+ expect(file("#{@basedir}/file")).to be_directory
+ end
+ end
+
+ # XXX
+ # when there are no fragments, and the replace param will only replace
+ # files and symlinks, not directories. The semantics either need to be
+ # changed, extended, or a new param introduced to control directory
+ # replacement.
+ describe 'when directory should succeed', pending: 'not yet implemented' do
+ let(:pp) do
+ <<-MANIFEST
+ concat { '#{@basedir}/file':
+ }
+
+ concat::fragment { '1':
+ target => '#{@basedir}/file',
+ content => '1',
+ }
+
+ concat::fragment { '2':
+ target => '#{@basedir}/file',
+ content => '2',
+ }
+ MANIFEST
+ end
+
+ it 'applies the manifest twice with no stderr' do
+ idempotent_apply(pp)
+ expect(file("#{@basedir}/file")).to be_file
+ expect(file("#{@basedir}/file").content).to match '1'
+ end
+ end
+end