From 045b49a5d6b64f69aa08e3d2fd78ca5721458f3d Mon Sep 17 00:00:00 2001 From: mkht Date: Sun, 27 Oct 2024 01:01:49 +0900 Subject: [PATCH] Add `UTF8BOM` and `UTF8NoBOM` for Encoding parameter of the KeyValuePairFile and ReplaceText --- CHANGELOG.md | 1 + .../DSC_KeyValuePairFile.psm1 | 81 +++- .../DSC_KeyValuePairFile.schema.mof | 2 +- .../DSC_ReplaceText/DSC_ReplaceText.psm1 | 91 +++-- .../DSC_ReplaceText.schema.mof | 2 +- .../FileContentDsc.Common.psm1 | 112 +++++- tests/TestHelpers/CommonTestHelper.psm1 | 26 +- tests/Unit/DSC_KeyValuePairFile.Tests.ps1 | 354 +++++++++--------- tests/Unit/DSC_ReplaceText.Tests.ps1 | 20 +- tests/Unit/FileContentDsc.Common.tests.ps1 | 115 +++++- 10 files changed, 556 insertions(+), 248 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ca66bb..3861293 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 coverage - Fixes [Issue #50](https://github.com/dsccommunity/FileContentDsc/issues/50). - Automatically publish documentation to GitHub Wiki - Fixes [Issue #51](https://github.com/dsccommunity/FileContentDsc/issues/51). - Renamed `master` branch to `main` - Fixes [Issue #53](https://github.com/dsccommunity/FileContentDsc/issues/53). +- Added `UTF8BOM` and `UTF8NoBOM` for Encoding parameter of the KeyValuePairFile and ReplaceText - Fixes [Issue #56](https://github.com/dsccommunity/FileContentDsc/issues/56). - Updated `GitVersion.yml` to latest pattern - Fixes [Issue #57](https://github.com/dsccommunity/FileContentDsc/issues/57). - Updated build to use `Sampler.GitHubTasks` - Fixes [Issue #60](https://github.com/dsccommunity/FileContentDsc/issues/60). - Added support for publishing code coverage to `CodeCov.io` and diff --git a/source/DSCResources/DSC_KeyValuePairFile/DSC_KeyValuePairFile.psm1 b/source/DSCResources/DSC_KeyValuePairFile/DSC_KeyValuePairFile.psm1 index ea831d3..faed4b3 100644 --- a/source/DSCResources/DSC_KeyValuePairFile/DSC_KeyValuePairFile.psm1 +++ b/source/DSCResources/DSC_KeyValuePairFile/DSC_KeyValuePairFile.psm1 @@ -47,8 +47,19 @@ function Get-TargetResource if (Test-Path -Path $Path) { - $fileContent = Get-Content -Path $Path -Raw - $fileEncoding = Get-FileEncoding -Path $Path + $fileEncoding = Get-FileEncoding $Path -ErrorAction SilentlyContinue + if ($null -eq $fileEncoding) + { + $fileContent = Get-Content -Path $Path -Raw + } + elseif ($fileEncoding -like 'UTF8*') + { + $fileContent = Get-Content -Path $Path -Raw -Encoding 'UTF8' + } + else + { + $fileContent = Get-Content -Path $Path -Raw -Encoding $fileEncoding + } if ($null -ne $fileContent) { @@ -180,15 +191,26 @@ function Set-TargetResource $IgnoreValueCase = $false, [Parameter()] - [ValidateSet('ASCII', 'BigEndianUnicode', 'BigEndianUTF32', 'UTF8', 'UTF32')] + [ValidateSet('ASCII', 'BigEndianUnicode', 'BigEndianUTF32', 'UTF8', 'UTF8BOM', 'UTF8NoBOM', 'UTF32')] [System.String] $Encoding ) Assert-ParametersValid @PSBoundParameters - $fileContent = Get-Content -Path $Path -Raw -ErrorAction SilentlyContinue - $fileEncoding = Get-FileEncoding -Path $Path -ErrorAction SilentlyContinue + $fileEncoding = Get-FileEncoding $Path -ErrorAction SilentlyContinue + if ($null -eq $fileEncoding) + { + $fileContent = Get-Content -Path $Path -Raw -ErrorAction SilentlyContinue + } + elseif ($fileEncoding -like 'UTF8*') + { + $fileContent = Get-Content -Path $Path -Raw -Encoding 'UTF8' -ErrorAction SilentlyContinue + } + else + { + $fileContent = Get-Content -Path $Path -Raw -Encoding $fileEncoding -ErrorAction SilentlyContinue + } $fileProperties = @{ Path = $Path @@ -248,10 +270,13 @@ function Set-TargetResource { if ($results.Count -eq 0) { - if ($PSBoundParameters.ContainsKey('Encoding') -and ($Encoding -eq $fileEncoding)) + if ($PSBoundParameters.ContainsKey('Encoding') -and ` + (($Encoding -eq $fileEncoding) -or ` + ($Encoding -eq 'UTF8' -and $fileEncoding -like 'UTF8*') -or ` + ($Encoding -eq 'UTF8NoBOM' -and $fileEncoding -eq 'ASCII'))) { - # The Key does not exists and should not, and encoding is in the desired state, so don't do anything - return + # The Key does not exists and should not, and encoding is in the desired state, so don't do anything + return } else { @@ -281,7 +306,7 @@ function Set-TargetResource $fileProperties.Add('Encoding', $Encoding) } - Set-Content @fileProperties + Set-TextContent @fileProperties } <# @@ -362,7 +387,7 @@ function Test-TargetResource $IgnoreValueCase = $false, [Parameter()] - [ValidateSet('ASCII', 'BigEndianUnicode', 'BigEndianUTF32', 'UTF8', 'UTF32')] + [ValidateSet('ASCII', 'BigEndianUnicode', 'BigEndianUTF32', 'UTF8', 'UTF8BOM', 'UTF8NoBOM', 'UTF32')] [System.String] $Encoding ) @@ -380,7 +405,19 @@ function Test-TargetResource return ($Ensure -eq 'Absent') } - $fileContent = Get-Content -Path $Path -Raw + $fileEncoding = Get-FileEncoding $Path -ErrorAction SilentlyContinue + if ($null -eq $fileEncoding) + { + $fileContent = Get-Content -Path $Path -Raw + } + elseif ($fileEncoding -like 'UTF8*') + { + $fileContent = Get-Content -Path $Path -Raw -Encoding 'UTF8' + } + else + { + $fileContent = Get-Content -Path $Path -Raw -Encoding $fileEncoding + } if ($null -eq $fileContent) { @@ -390,7 +427,6 @@ function Test-TargetResource } $desiredConfigurationMatch = $true - $fileEncoding = Get-FileEncoding -Path $Path $regExOptions = [System.Text.RegularExpressions.RegexOptions]::Multiline Write-Verbose -Message ($script:localizedData.SearchForKeyMessage -f $Path, $Name) @@ -456,10 +492,23 @@ function Test-TargetResource if ($PSBoundParameters.ContainsKey('Encoding') -and ($Encoding -ne $fileEncoding)) { - # File encoding is not in desired state - Write-Verbose -Message ($script:localizedData.FileEncodingNotInDesiredState -f $fileEncoding, $Encoding) + if ($Encoding -eq 'UTF8' -and $fileEncoding -like 'UTF8*') + { + #If the Encoding specified as UTF8, Either UTF8NoBOM or UTF8BOM is acceptable + $desiredConfigurationMatch = $true + } + elseif ($Encoding -eq 'UTF8NoBOM' -and $fileEncoding -eq 'ASCII') + { + #If the Encoding specified as UTF8NoBOM, Either UTF8NoBOM or ASCII is acceptable + $desiredConfigurationMatch = $true + } + else + { + # File encoding is not in desired state + Write-Verbose -Message ($script:localizedData.FileEncodingNotInDesiredState -f $fileEncoding, $Encoding) - $desiredConfigurationMatch = $false + $desiredConfigurationMatch = $false + } } return $desiredConfigurationMatch @@ -543,7 +592,7 @@ function Assert-ParametersValid $IgnoreValueCase = $false, [Parameter()] - [ValidateSet('ASCII', 'BigEndianUnicode', 'BigEndianUTF32', 'UTF8', 'UTF32')] + [ValidateSet('ASCII', 'BigEndianUnicode', 'BigEndianUTF32', 'UTF8', 'UTF8BOM', 'UTF8NoBOM', 'UTF32')] [System.String] $Encoding ) diff --git a/source/DSCResources/DSC_KeyValuePairFile/DSC_KeyValuePairFile.schema.mof b/source/DSCResources/DSC_KeyValuePairFile/DSC_KeyValuePairFile.schema.mof index f27bbc1..5358ef0 100644 --- a/source/DSCResources/DSC_KeyValuePairFile/DSC_KeyValuePairFile.schema.mof +++ b/source/DSCResources/DSC_KeyValuePairFile/DSC_KeyValuePairFile.schema.mof @@ -9,5 +9,5 @@ class DSC_KeyValuePairFile : OMI_BaseResource [write, Description("The secret text to replace the value with in the identified key. Only used when Type is set to 'Secret'."),EmbeddedInstance("MSFT_Credential")] String Secret; [Write, Description("Ignore the case of the name of the key. Defaults to $False.")] Boolean IgnoreNameCase; [Write, Description("Ignore the case of any text or secret when determining if it they need to be updated. Defaults to $False.")] Boolean IgnoreValueCase; - [Write, Description("Specifies the file encoding. Defaults to ASCII"),ValueMap{"ASCII", "BigEndianUnicode", "BigEndianUTF32", "UTF8", "UTF32"},Values{"ASCII", "BigEndianUnicode", "BigEndianUTF32", "UTF8", "UTF32"}] String Encoding; + [Write, Description("Specifies the file encoding. Defaults to ASCII"),ValueMap{"ASCII", "BigEndianUnicode", "BigEndianUTF32", "UTF8", "UTF8BOM", "UTF8NoBOM", "UTF32"},Values{"ASCII", "BigEndianUnicode", "BigEndianUTF32", "UTF8", "UTF8BOM", "UTF8NoBOM", "UTF32"}] String Encoding; }; diff --git a/source/DSCResources/DSC_ReplaceText/DSC_ReplaceText.psm1 b/source/DSCResources/DSC_ReplaceText/DSC_ReplaceText.psm1 index cf65be9..1473e49 100644 --- a/source/DSCResources/DSC_ReplaceText/DSC_ReplaceText.psm1 +++ b/source/DSCResources/DSC_ReplaceText/DSC_ReplaceText.psm1 @@ -41,11 +41,22 @@ function Get-TargetResource Assert-ParametersValid @PSBoundParameters - $fileContent = Get-Content -Path $Path -Raw - $fileEncoding = Get-FileEncoding $Path + $fileEncoding = Get-FileEncoding $Path -ErrorAction SilentlyContinue + if ($null -eq $fileEncoding) + { + $fileContent = Get-Content -Path $Path -Raw + } + elseif ($fileEncoding -like 'UTF8*') + { + $fileContent = Get-Content -Path $Path -Raw -Encoding 'UTF8' + } + else + { + $fileContent = Get-Content -Path $Path -Raw -Encoding $fileEncoding + } Write-Verbose -Message ($script:localizedData.SearchForTextMessage -f ` - $Path, $Search) + $Path, $Search) $text = '' @@ -56,14 +67,14 @@ function Get-TargetResource { # No matches found - already in state Write-Verbose -Message ($script:localizedData.StringNotFoundMessage -f ` - $Path, $Search) + $Path, $Search) } else { $text = ($results.Value -join ',') Write-Verbose -Message ($script:localizedData.StringMatchFoundMessage -f ` - $Path, $Search, $text) + $Path, $Search, $text) } # if return @{ @@ -136,15 +147,26 @@ function Set-TargetResource $AllowAppend = $false, [Parameter()] - [ValidateSet("ASCII", "BigEndianUnicode", "BigEndianUTF32", "UTF8", "UTF32")] + [ValidateSet('ASCII', 'BigEndianUnicode', 'BigEndianUTF32', 'UTF8', 'UTF8BOM', 'UTF8NoBOM', 'UTF32')] [System.String] $Encoding ) Assert-ParametersValid @PSBoundParameters - $fileContent = Get-Content -Path $Path -Raw -ErrorAction SilentlyContinue - $fileEncoding = Get-FileEncoding $Path + $fileEncoding = Get-FileEncoding $Path -ErrorAction SilentlyContinue + if ($null -eq $fileEncoding) + { + $fileContent = Get-Content -Path $Path -Raw + } + elseif ($fileEncoding -like 'UTF8*') + { + $fileContent = Get-Content -Path $Path -Raw -Encoding 'UTF8' + } + else + { + $fileContent = Get-Content -Path $Path -Raw -Encoding $fileEncoding + } $fileProperties = @{ Path = $Path @@ -155,25 +177,17 @@ function Set-TargetResource if ($Type -eq 'Secret') { Write-Verbose -Message ($script:localizedData.StringReplaceSecretMessage -f ` - $Path) + $Path) $Text = $Secret.GetNetworkCredential().Password } elseif ($PSBoundParameters.ContainsKey('Encoding')) { - if ($Encoding -eq $fileEncoding) - { - Write-Verbose -Message ($script:localizedData.StringReplaceTextMessage -f ` - $Path, $Text) - } - else - { - Write-Verbose -Message ($script:localizedData.StringReplaceTextMessage -f ` - $Path, $Text) + Write-Verbose -Message ($script:localizedData.StringReplaceTextMessage -f ` + $Path, $Text) - # Add encoding parameter and value to the hashtable - $fileProperties.Add('Encoding', $Encoding) - } + # Add encoding parameter and value to the hashtable + $fileProperties.Add('Encoding', $Encoding) } if ($null -eq $fileContent) @@ -194,7 +208,7 @@ function Set-TargetResource $fileProperties.Add('Value', $fileContent) - Set-Content @fileProperties + Set-TextContent @fileProperties } <# @@ -259,7 +273,7 @@ function Test-TargetResource $AllowAppend = $false, [Parameter()] - [ValidateSet("ASCII", "BigEndianUnicode", "BigEndianUTF32", "UTF8", "UTF32")] + [ValidateSet('ASCII', 'BigEndianUnicode', 'BigEndianUTF32', 'UTF8', 'UTF8BOM', 'UTF8NoBOM', 'UTF32')] [System.String] $Encoding ) @@ -272,11 +286,22 @@ function Test-TargetResource return $false } - $fileContent = Get-Content -Path $Path -Raw - $fileEncoding = Get-FileEncoding $Path + $fileEncoding = Get-FileEncoding $Path -ErrorAction SilentlyContinue + if ($null -eq $fileEncoding) + { + $fileContent = Get-Content -Path $Path -Raw + } + elseif ($fileEncoding -like 'UTF8*') + { + $fileContent = Get-Content -Path $Path -Raw -Encoding 'UTF8' + } + else + { + $fileContent = Get-Content -Path $Path -Raw -Encoding $fileEncoding + } Write-Verbose -Message ($script:localizedData.SearchForTextMessage -f ` - $Path, $Search) + $Path, $Search) # Search the file content for any matches $results = [regex]::Matches($fileContent, $Search) @@ -293,11 +318,13 @@ function Test-TargetResource } if ($PSBoundParameters.ContainsKey('Encoding')) { - if ($Encoding -eq $fileEncoding) + if (($Encoding -eq $fileEncoding) -or ` + ($Encoding -eq 'UTF8' -and $fileEncoding -like 'UTF8*') -or ` + ($Encoding -eq 'UTF8NoBOM' -and $fileEncoding -eq 'ASCII')) { # No matches found and encoding is in desired state Write-Verbose -Message ($script:localizedData.StringNotFoundMessage -f ` - $Path, $Search) + $Path, $Search) return $true } @@ -305,7 +332,7 @@ function Test-TargetResource { # No matches found but encoding is not in desired state Write-Verbose -Message ($script:localizedData.FileEncodingNotInDesiredState -f ` - $fileEncoding, $Encoding) + $fileEncoding, $Encoding) return $false } @@ -331,12 +358,12 @@ function Test-TargetResource if ($desiredConfigurationMatch) { Write-Verbose -Message ($script:localizedData.StringNoReplacementMessage -f ` - $Path, $Search) + $Path, $Search) } else { Write-Verbose -Message ($script:localizedData.StringReplacementRequiredMessage -f ` - $Path, $Search) + $Path, $Search) } # if return $desiredConfigurationMatch @@ -401,7 +428,7 @@ function Assert-ParametersValid $AllowAppend = $false, [Parameter()] - [ValidateSet("ASCII", "BigEndianUnicode", "BigEndianUTF32", "UTF8", "UTF32")] + [ValidateSet('ASCII', 'BigEndianUnicode', 'BigEndianUTF32', 'UTF8', 'UTF8BOM', 'UTF8NoBOM', 'UTF32')] [System.String] $Encoding ) diff --git a/source/DSCResources/DSC_ReplaceText/DSC_ReplaceText.schema.mof b/source/DSCResources/DSC_ReplaceText/DSC_ReplaceText.schema.mof index 11f7333..8cf89a6 100644 --- a/source/DSCResources/DSC_ReplaceText/DSC_ReplaceText.schema.mof +++ b/source/DSCResources/DSC_ReplaceText/DSC_ReplaceText.schema.mof @@ -7,5 +7,5 @@ class DSC_ReplaceText : OMI_BaseResource [Write, Description("The text to replace the text identified by the RegEx. Only used when Type is set to 'Text'.")] String Text; [Write, Description("The secret text to replace the text identified by the RegEx. Only used when Type is set to 'Secret'."),EmbeddedInstance("MSFT_Credential")] String Secret; [Write, Description("Specifies to append text to the file being modified. Adds the ability to add a configuration entry.")] Boolean AllowAppend; - [Write, Description("Specifies the file encoding. Defaults to ASCII"),ValueMap{"ASCII", "BigEndianUnicode", "BigEndianUTF32", "UTF8", "UTF32"},Values{"ASCII", "BigEndianUnicode", "BigEndianUTF32", "UTF8", "UTF32"}] String Encoding; + [Write, Description("Specifies the file encoding. Defaults to ASCII"),ValueMap{"ASCII", "BigEndianUnicode", "BigEndianUTF32", "UTF8", "UTF8BOM", "UTF8NoBOM", "UTF32"},Values{"ASCII", "BigEndianUnicode", "BigEndianUTF32", "UTF8", "UTF8BOM", "UTF8NoBOM", "UTF32"}] String Encoding; }; diff --git a/source/Modules/FileContentDsc.Common/FileContentDsc.Common.psm1 b/source/Modules/FileContentDsc.Common/FileContentDsc.Common.psm1 index 44bf8dd..6fe0ad6 100644 --- a/source/Modules/FileContentDsc.Common/FileContentDsc.Common.psm1 +++ b/source/Modules/FileContentDsc.Common/FileContentDsc.Common.psm1 @@ -174,11 +174,20 @@ function Get-FileEncoding $Path ) - [System.Byte[]] $byte = Get-Content -Encoding byte -ReadCount 4 -TotalCount 4 -Path $Path + # The parameter for reading a file as a byte stream are different between PSv6 and later and earlier. + $ByteParam = if ($PSVersionTable.PSVersion.Major -ge 6) + { + @{AsByteStream = $true } + } + else + { + @{Encoding = 'byte' } + } + [System.Byte[]] $byte = Get-Content @ByteParam -ReadCount 4 -TotalCount 4 -Path $Path if ($byte[0] -eq 0xef -and $byte[1] -eq 0xbb -and $byte[2] -eq 0xbf) { - return 'UTF8' + return 'UTF8BOM' } elseif ($byte[0] -eq 0xff -and $byte[1] -eq 0xfe) { @@ -194,8 +203,104 @@ function Get-FileEncoding } else { - return 'ASCII' + # Read all bytes for guessing encoding. + [System.Byte[]] $byte = Get-Content @ByteParam -ReadCount 0 -Path $Path + + # If a text file includes code after 0x7f, which should not exist in ASCII, it is determined as UTF8NoBOM. + if ($byte -gt 0x7f) + { + return 'UTF8NoBOM' + } + else + { + return 'ASCII' + } + } +} + +<# + .SYNOPSIS + Writes or replaces the content in an item with new content. + This is an enhanced version of the Set-Content that allows UTF8BOM and UTF8NoBOM encodings in PS v5.1 and earlier. + + .DESCRIPTION + Writes or replaces the content in an item with new content. + This is an enhanced version of the Set-Content that allows UTF8BOM and UTF8NoBOM encodings in PS v5.1 and earlier. + + .EXAMPLE + Set-TextContent -Path 'C:\hello.txt' -Value 'Hello World' -Encoding UTF8NoBOM + This command creates a text file encoded in UTF-8 without BOM (Byte Order Mark). +#> +function Set-TextContent +{ + [CmdletBinding()] + [OutputType([void])] + param + ( + [Parameter(Position = 0, Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [System.String[]] + $Path, + + [Parameter(Position = 1, Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)] + [Object[]] + $Value, + + [Parameter()] + [ValidateSet('ASCII', 'BigEndianUnicode', 'BigEndianUTF32', 'UTF8', 'UTF8BOM', 'UTF8NoBOM', 'UTF32')] + [System.String] + $Encoding, + + [Parameter()] + [switch] + $NoNewLine, + + [Parameter()] + [switch] + $Force + ) + + $setContentParams = @{ + Path = $Path + Force = $Force + NoNewLine = $NoNewLine + } + + $EncodingParam = $null + if ($PSBoundParameters.ContainsKey('Encoding')) + { + # PS v6+ can handle all Encoding parameters natively + if ($PSVersionTable.PSVersion.Major -ge 6) + { + $EncodingParam = $Encoding + } + else + { + if ($Encoding -eq 'UTF8BOM') + { + $EncodingParam = 'utf8' + } + # PS v5.1 and earlier can not handle UTF8 without BOM + # We need to convert Value to Bytes. + elseif ($Encoding -eq 'UTF8NoBOM') + { + $EncodingParam = 'Byte' + $Value = [System.Text.Encoding]::UTF8.GetBytes($Value) + } + else + { + $EncodingParam = $Encoding + } + } } + + if ($null -ne $EncodingParam) + { + $setContentParams.Add('Encoding', $EncodingParam) + } + + $setContentParams.Add('Value', $Value) + + Set-Content @setContentParams } Export-ModuleMember -Function @( @@ -203,4 +308,5 @@ Export-ModuleMember -Function @( 'Set-IniSettingFileValue', 'Get-IniSettingFileValue', 'Get-FileEncoding' + 'Set-TextContent' ) diff --git a/tests/TestHelpers/CommonTestHelper.psm1 b/tests/TestHelpers/CommonTestHelper.psm1 index ef44873..9eaf783 100644 --- a/tests/TestHelpers/CommonTestHelper.psm1 +++ b/tests/TestHelpers/CommonTestHelper.psm1 @@ -109,11 +109,20 @@ function Get-FileEncoding $Path ) - [System.Byte[]] $byte = Get-Content -Encoding byte -ReadCount 4 -TotalCount 4 -Path $Path + # The parameter for reading a file as a byte stream are different between PSv6 and later and earlier. + $ByteParam = if ($PSVersionTable.PSVersion.Major -ge 6) + { + @{AsByteStream = $true } + } + else + { + @{Encoding = 'byte' } + } + [System.Byte[]] $byte = Get-Content @ByteParam -ReadCount 4 -TotalCount 4 -Path $Path if ($byte[0] -eq 0xef -and $byte[1] -eq 0xbb -and $byte[2] -eq 0xbf) { - return 'UTF8' + return 'UTF8BOM' } elseif ($byte[0] -eq 0xff -and $byte[1] -eq 0xfe) { @@ -129,7 +138,18 @@ function Get-FileEncoding } else { - return 'ASCII' + # Read all bytes for guessing encoding. + [System.Byte[]] $byte = Get-Content @ByteParam -ReadCount 0 -Path $Path + + # If a text file includes code after 0x7f, which should not exist in ASCII, it is determined as UTF8NoBOM. + if ($byte -gt 0x7f) + { + return 'UTF8NoBOM' + } + else + { + return 'ASCII' + } } } diff --git a/tests/Unit/DSC_KeyValuePairFile.Tests.ps1 b/tests/Unit/DSC_KeyValuePairFile.Tests.ps1 index 8a2398d..2f803e7 100644 --- a/tests/Unit/DSC_KeyValuePairFile.Tests.ps1 +++ b/tests/Unit/DSC_KeyValuePairFile.Tests.ps1 @@ -127,9 +127,9 @@ $($script:testAddedName)=$($script:testText) It 'Should not throw an exception' { { $script:result = Get-TargetResource ` - -Path $script:testTextFile ` - -Name $script:testName ` - -Verbose + -Path $script:testTextFile ` + -Name $script:testName ` + -Verbose } | Should -Not -Throw } @@ -172,9 +172,9 @@ $($script:testAddedName)=$($script:testText) It 'Should not throw an exception' { { $script:result = Get-TargetResource ` - -Path $script:testTextFile ` - -Name $script:testName ` - -Verbose + -Path $script:testTextFile ` + -Name $script:testName ` + -Verbose } | Should -Not -Throw } @@ -222,9 +222,9 @@ $($script:testAddedName)=$($script:testText) It 'Should not throw an exception' { { $script:result = Get-TargetResource ` - -Path $script:testTextFile ` - -Name $script:testName ` - -Verbose + -Path $script:testTextFile ` + -Name $script:testName ` + -Verbose } | Should -Not -Throw } @@ -272,9 +272,9 @@ $($script:testAddedName)=$($script:testText) It 'Should not throw an exception' { { $script:result = Get-TargetResource ` - -Path $script:testTextFile ` - -Name $script:testName.ToUpper() ` - -Verbose + -Path $script:testTextFile ` + -Name $script:testName.ToUpper() ` + -Verbose } | Should -Not -Throw } @@ -320,15 +320,15 @@ $($script:testAddedName)=$($script:testText) Mock -CommandName Get-FileEncoding ` -MockWith { $script:testCompliantEncoding.Encoding } - Mock -CommandName Set-Content + Mock -CommandName Set-TextContent It 'Should not throw an exception' { { Set-TargetResource ` - -Path $script:testTextFile ` - -Name $script:testName ` - -Ensure 'Present' ` - -Text $script:testText ` - -Verbose + -Path $script:testTextFile ` + -Name $script:testName ` + -Ensure 'Present' ` + -Text $script:testText ` + -Verbose } | Should -Not -Throw } @@ -347,12 +347,12 @@ $($script:testAddedName)=$($script:testText) -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 - Assert-MockCalled -CommandName Set-Content ` + Assert-MockCalled -CommandName Set-TextContent ` -Scope Context ` -ParameterFilter { - ($path -eq $script:testTextFile) -and ` - ($value -eq "$script:testName=$script:testText") - } ` + ($path -eq $script:testTextFile) -and ` + ($value -eq "$script:testName=$script:testText") + } ` -Exactly -Times 1 } } @@ -363,15 +363,15 @@ $($script:testAddedName)=$($script:testText) Mock -CommandName Get-FileEncoding ` -MockWith { $script:testCompliantEncoding.Encoding } - Mock -CommandName Set-Content + Mock -CommandName Set-TextContent It 'Should not throw an exception' { { Set-TargetResource ` - -Path $script:testTextFile ` - -Name $script:testName ` - -Ensure 'Present' ` - -Text $script:testText ` - -Verbose + -Path $script:testTextFile ` + -Name $script:testName ` + -Ensure 'Present' ` + -Text $script:testText ` + -Verbose } | Should -Not -Throw } @@ -390,12 +390,12 @@ $($script:testAddedName)=$($script:testText) -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 - Assert-MockCalled -CommandName Set-Content ` + Assert-MockCalled -CommandName Set-TextContent ` -Scope Context ` -ParameterFilter { - ($path -eq $script:testTextFile) -and ` - ($value -eq "$script:testName=$script:testText") - } ` + ($path -eq $script:testTextFile) -and ` + ($value -eq "$script:testName=$script:testText") + } ` -Exactly -Times 1 } } @@ -407,15 +407,15 @@ $($script:testAddedName)=$($script:testText) Mock -CommandName Get-FileEncoding ` -MockWith { $script:testCompliantEncoding.Encoding } - Mock -CommandName Set-Content + Mock -CommandName Set-TextContent It 'Should not throw an exception' { { Set-TargetResource ` - -Path $script:testTextFile ` - -Name $script:testName ` - -Ensure 'Present' ` - -Text $script:testText ` - -Verbose + -Path $script:testTextFile ` + -Name $script:testName ` + -Ensure 'Present' ` + -Text $script:testText ` + -Verbose } | Should -Not -Throw } @@ -434,12 +434,12 @@ $($script:testAddedName)=$($script:testText) -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 - Assert-MockCalled -CommandName Set-Content ` + Assert-MockCalled -CommandName Set-TextContent ` -Scope Context ` -ParameterFilter { - ($path -eq $script:testTextFile) -and ` - ($value -eq $script:testFileExpectedTextContent) - } ` + ($path -eq $script:testTextFile) -and ` + ($value -eq $script:testFileExpectedTextContent) + } ` -Exactly -Times 1 } } @@ -451,16 +451,16 @@ $($script:testAddedName)=$($script:testText) Mock -CommandName Get-FileEncoding ` -MockWith { $script:testCompliantEncoding.Encoding } - Mock -CommandName Set-Content + Mock -CommandName Set-TextContent It 'Should not throw an exception' { { Set-TargetResource ` - -Path $script:testTextFile ` - -Name $script:testName ` - -Ensure 'Present' ` - -Type 'Secret' ` - -Secret $script:testSecretCredential ` - -Verbose + -Path $script:testTextFile ` + -Name $script:testName ` + -Ensure 'Present' ` + -Type 'Secret' ` + -Secret $script:testSecretCredential ` + -Verbose } | Should -Not -Throw } @@ -479,12 +479,12 @@ $($script:testAddedName)=$($script:testText) -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 - Assert-MockCalled -CommandName Set-Content ` + Assert-MockCalled -CommandName Set-TextContent ` -Scope Context ` -ParameterFilter { - ($path -eq $script:testTextFile) -and ` - ($value -eq $script:testFileExpectedSecretContent) - } ` + ($path -eq $script:testTextFile) -and ` + ($value -eq $script:testFileExpectedSecretContent) + } ` -Exactly -Times 1 } } @@ -496,19 +496,19 @@ $($script:testAddedName)=$($script:testText) Mock -CommandName Get-FileEncoding ` -MockWith { $script:testCompliantEncoding.Encoding } - Mock -CommandName Set-Content ` + Mock -CommandName Set-TextContent ` -ParameterFilter { - ($path -eq $script:testTextFile) -and ` - ($value -eq $script:testFileExpectedTextContentAdded) - } + ($path -eq $script:testTextFile) -and ` + ($value -eq $script:testFileExpectedTextContentAdded) + } It 'Should not throw an exception' { { Set-TargetResource ` - -Path $script:testTextFile ` - -Name $script:testAddedName ` - -Ensure 'Present' ` - -Text $script:testText ` - -Verbose + -Path $script:testTextFile ` + -Name $script:testAddedName ` + -Ensure 'Present' ` + -Text $script:testText ` + -Verbose } | Should -Not -Throw } @@ -527,12 +527,12 @@ $($script:testAddedName)=$($script:testText) -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 - Assert-MockCalled -CommandName Set-Content ` + Assert-MockCalled -CommandName Set-TextContent ` -Scope Context ` -ParameterFilter { - ($path -eq $script:testTextFile) -and ` - ($value -eq $script:testFileExpectedTextContentAdded) - } ` + ($path -eq $script:testTextFile) -and ` + ($value -eq $script:testFileExpectedTextContentAdded) + } ` -Exactly -Times 1 } } @@ -544,16 +544,16 @@ $($script:testAddedName)=$($script:testText) Mock -CommandName Get-FileEncoding ` -MockWith { $script:testCompliantEncoding.Encoding } - Mock -CommandName Set-Content + Mock -CommandName Set-TextContent It 'Should not throw an exception' { { Set-TargetResource ` - -Path $script:testTextFile ` - -Name $script:testName.ToUpper() ` - -Ensure 'Present' ` - -Text $script:testText ` - -IgnoreNameCase:$true ` - -Verbose + -Path $script:testTextFile ` + -Name $script:testName.ToUpper() ` + -Ensure 'Present' ` + -Text $script:testText ` + -IgnoreNameCase:$true ` + -Verbose } | Should -Not -Throw } @@ -572,12 +572,12 @@ $($script:testAddedName)=$($script:testText) -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 - Assert-MockCalled -CommandName Set-Content ` + Assert-MockCalled -CommandName Set-TextContent ` -Scope Context ` -ParameterFilter { - ($path -eq $script:testTextFile) -and ` - ($value -eq $script:testFileExpectedTextContentUpper) - } ` + ($path -eq $script:testTextFile) -and ` + ($value -eq $script:testFileExpectedTextContentUpper) + } ` -Exactly -Times 1 } } @@ -589,15 +589,15 @@ $($script:testAddedName)=$($script:testText) Mock -CommandName Get-FileEncoding ` -MockWith { $script:testCompliantEncoding.Encoding } - Mock -CommandName Set-Content + Mock -CommandName Set-TextContent It 'Should not throw an exception' { { Set-TargetResource ` - -Path $script:testTextFile ` - -Name $script:testName.ToUpper() ` - -Encoding $script:fileEncodingParameters.Encoding ` - -Ensure 'Absent' ` - -Verbose + -Path $script:testTextFile ` + -Name $script:testName.ToUpper() ` + -Encoding $script:fileEncodingParameters.Encoding ` + -Ensure 'Absent' ` + -Verbose } | Should -Not -Throw } @@ -616,7 +616,7 @@ $($script:testAddedName)=$($script:testText) -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 - Assert-MockCalled -CommandName Set-Content ` + Assert-MockCalled -CommandName Set-TextContent ` -Scope Context ` -Exactly -Times 0 } @@ -629,15 +629,15 @@ $($script:testAddedName)=$($script:testText) Mock -CommandName Get-FileEncoding ` -MockWith { $script:testCompliantEncoding.Encoding } - Mock -CommandName Set-Content + Mock -CommandName Set-TextContent It 'Should not throw an exception' { { Set-TargetResource ` - -Path $script:testTextFile ` - -Name $script:testName ` - -Ensure 'Absent' ` - -IgnoreNameCase:$true ` - -Verbose + -Path $script:testTextFile ` + -Name $script:testName ` + -Ensure 'Absent' ` + -IgnoreNameCase:$true ` + -Verbose } | Should -Not -Throw } @@ -656,12 +656,12 @@ $($script:testAddedName)=$($script:testText) -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 - Assert-MockCalled -CommandName Set-Content ` + Assert-MockCalled -CommandName Set-TextContent ` -Scope Context ` -ParameterFilter { - ($path -eq $script:testTextFile) -and ` - ($value -eq $script:testFileExpectedAbsentContent) - } ` + ($path -eq $script:testTextFile) -and ` + ($value -eq $script:testFileExpectedAbsentContent) + } ` -Exactly -Times 1 } } @@ -681,11 +681,11 @@ $($script:testAddedName)=$($script:testText) It 'Should not throw an exception' { { $script:result = Test-TargetResource ` - -Path $script:testTextFile ` - -Name $script:testName.ToUpper() ` - -Ensure 'Present' ` - -Text $script:testText ` - -Verbose + -Path $script:testTextFile ` + -Name $script:testName.ToUpper() ` + -Ensure 'Present' ` + -Text $script:testText ` + -Verbose } | Should -Not -Throw } @@ -717,11 +717,11 @@ $($script:testAddedName)=$($script:testText) It 'Should not throw an exception' { { $script:result = Test-TargetResource ` - -Path $script:testTextFile ` - -Name $script:testName.ToUpper() ` - -Ensure 'Absent' ` - -Text $script:testText ` - -Verbose + -Path $script:testTextFile ` + -Name $script:testName.ToUpper() ` + -Ensure 'Absent' ` + -Text $script:testText ` + -Verbose } | Should -Not -Throw } @@ -753,11 +753,11 @@ $($script:testAddedName)=$($script:testText) It 'Should not throw an exception' { { $script:result = Test-TargetResource ` - -Path $script:testTextFile ` - -Name $script:testName.ToUpper() ` - -Ensure 'Present' ` - -Text $script:testText ` - -Verbose + -Path $script:testTextFile ` + -Name $script:testName.ToUpper() ` + -Ensure 'Present' ` + -Text $script:testText ` + -Verbose } | Should -Not -Throw } @@ -777,7 +777,7 @@ $($script:testAddedName)=$($script:testText) Assert-MockCalled -CommandName Get-FileEncoding ` -Scope Context ` - -Exactly -Times 0 + -Exactly -Times 1 } } @@ -790,11 +790,11 @@ $($script:testAddedName)=$($script:testText) It 'Should not throw an exception' { { $script:result = Test-TargetResource ` - -Path $script:testTextFile ` - -Name $script:testName.ToUpper() ` - -Ensure 'Absent' ` - -Text $script:testText ` - -Verbose + -Path $script:testTextFile ` + -Name $script:testName.ToUpper() ` + -Ensure 'Absent' ` + -Text $script:testText ` + -Verbose } | Should -Not -Throw } @@ -814,7 +814,7 @@ $($script:testAddedName)=$($script:testText) Assert-MockCalled -CommandName Get-FileEncoding ` -Scope Context ` - -Exactly -Times 0 + -Exactly -Times 1 } } @@ -830,11 +830,11 @@ $($script:testAddedName)=$($script:testText) It 'Should not throw an exception' { { $script:result = Test-TargetResource ` - -Path $script:testTextFile ` - -Name $script:testName.ToUpper() ` - -Ensure 'Present' ` - -Text $script:testText ` - -Verbose + -Path $script:testTextFile ` + -Name $script:testName.ToUpper() ` + -Ensure 'Present' ` + -Text $script:testText ` + -Verbose } | Should -Not -Throw } @@ -871,11 +871,11 @@ $($script:testAddedName)=$($script:testText) It 'Should not throw an exception' { { $script:result = Test-TargetResource ` - -Path $script:testTextFile ` - -Name $script:testName.ToUpper() ` - -Ensure 'Absent' ` - -Encoding $script:fileEncodingParameters.Encoding ` - -Verbose + -Path $script:testTextFile ` + -Name $script:testName.ToUpper() ` + -Ensure 'Absent' ` + -Encoding $script:fileEncodingParameters.Encoding ` + -Verbose } | Should -Not -Throw } @@ -912,11 +912,11 @@ $($script:testAddedName)=$($script:testText) It 'Should not throw an exception' { { $script:result = Test-TargetResource ` - -Path $script:testTextFile ` - -Name $script:testName.ToUpper() ` - -Encoding $script:fileEncodingParameters.Encoding ` - -Ensure 'Absent' ` - -Verbose + -Path $script:testTextFile ` + -Name $script:testName.ToUpper() ` + -Encoding $script:fileEncodingParameters.Encoding ` + -Ensure 'Absent' ` + -Verbose } | Should -Not -Throw } @@ -953,11 +953,11 @@ $($script:testAddedName)=$($script:testText) It 'Should not throw an exception' { { $script:result = Test-TargetResource ` - -Path $script:testTextFile ` - -Name $script:testName ` - -Ensure 'Present' ` - -Text $script:testText ` - -Verbose + -Path $script:testTextFile ` + -Name $script:testName ` + -Ensure 'Present' ` + -Text $script:testText ` + -Verbose } | Should -Not -Throw } @@ -994,12 +994,12 @@ $($script:testAddedName)=$($script:testText) It 'Should not throw an exception' { { $script:result = Test-TargetResource ` - -Path $script:testTextFile ` - -Name $script:testName ` - -Ensure 'Present' ` - -Text $script:testText ` - -Encoding $script:fileEncodingParameters.Encoding ` - -Verbose + -Path $script:testTextFile ` + -Name $script:testName ` + -Ensure 'Present' ` + -Text $script:testText ` + -Encoding $script:fileEncodingParameters.Encoding ` + -Verbose } | Should -Not -Throw } @@ -1036,12 +1036,12 @@ $($script:testAddedName)=$($script:testText) It 'Should not throw an exception' { { $script:result = Test-TargetResource ` - -Path $script:testTextFile ` - -Name $script:testName ` - -Ensure 'Present' ` - -Type 'Secret' ` - -Secret $script:testSecretCredential ` - -Verbose + -Path $script:testTextFile ` + -Name $script:testName ` + -Ensure 'Present' ` + -Type 'Secret' ` + -Secret $script:testSecretCredential ` + -Verbose } | Should -Not -Throw } @@ -1078,12 +1078,12 @@ $($script:testAddedName)=$($script:testText) It 'Should not throw an exception' { { $script:result = Test-TargetResource ` - -Path $script:testTextFile ` - -Name $script:testName ` - -Ensure 'Present' ` - -Type 'Secret' ` - -Secret $script:testSecretCredential ` - -Verbose + -Path $script:testTextFile ` + -Name $script:testName ` + -Ensure 'Present' ` + -Type 'Secret' ` + -Secret $script:testSecretCredential ` + -Verbose } | Should -Not -Throw } @@ -1120,13 +1120,13 @@ $($script:testAddedName)=$($script:testText) It 'Should not throw an exception' { { $script:result = Test-TargetResource ` - -Path $script:testTextFile ` - -Name $script:testName ` - -Ensure 'Present' ` - -Type 'Secret' ` - -Secret $script:testSecretCredential ` - -Encoding $script:fileEncodingParameters.Encoding ` - -Verbose + -Path $script:testTextFile ` + -Name $script:testName ` + -Ensure 'Present' ` + -Type 'Secret' ` + -Secret $script:testSecretCredential ` + -Encoding $script:fileEncodingParameters.Encoding ` + -Verbose } | Should -Not -Throw } @@ -1163,12 +1163,12 @@ $($script:testAddedName)=$($script:testText) It 'Should not throw an exception' { { $script:result = Test-TargetResource ` - -Path $script:testTextFile ` - -Name $script:testName.ToUpper() ` - -Ensure 'Present' ` - -Text $script:testText ` - -IgnoreNameCase:$true ` - -Verbose + -Path $script:testTextFile ` + -Name $script:testName.ToUpper() ` + -Ensure 'Present' ` + -Text $script:testText ` + -IgnoreNameCase:$true ` + -Verbose } | Should -Not -Throw } @@ -1205,11 +1205,11 @@ $($script:testAddedName)=$($script:testText) It 'Should not throw an exception' { { $script:result = Test-TargetResource ` - -Path $script:testTextFile ` - -Name $script:testName ` - -Ensure 'Present' ` - -Text $script:testText.ToUpper() ` - -Verbose + -Path $script:testTextFile ` + -Name $script:testName ` + -Ensure 'Present' ` + -Text $script:testText.ToUpper() ` + -Verbose } | Should -Not -Throw } @@ -1288,11 +1288,11 @@ $($script:testAddedName)=$($script:testText) It 'Should not throw an exception' { { $script:result = Test-TargetResource ` - -Path $script:testTextFile ` - -Name $script:testName ` - -Ensure 'Absent' ` - -Text $script:testText ` - -Verbose + -Path $script:testTextFile ` + -Name $script:testName ` + -Ensure 'Absent' ` + -Text $script:testText ` + -Verbose } | Should -Not -Throw } diff --git a/tests/Unit/DSC_ReplaceText.Tests.ps1 b/tests/Unit/DSC_ReplaceText.Tests.ps1 index 13e75ff..d2c9668 100644 --- a/tests/Unit/DSC_ReplaceText.Tests.ps1 +++ b/tests/Unit/DSC_ReplaceText.Tests.ps1 @@ -333,7 +333,7 @@ Setting3.Test=Value4 -Verifiable Mock ` - -CommandName Set-Content ` + -CommandName Set-TextContent ` -ParameterFilter { ($path -eq $script:testTextFile) -and ` ($value -eq $script:testFileExpectedTextContent) @@ -359,7 +359,7 @@ Setting3.Test=Value4 -Exactly 1 Assert-MockCalled ` - -CommandName Set-Content ` + -CommandName Set-TextContent ` -ParameterFilter { ($path -eq $script:testTextFile) -and ` ($value -eq $script:testFileExpectedTextContent) @@ -388,7 +388,7 @@ Setting3.Test=Value4 -Verifiable Mock ` - -CommandName Set-Content ` + -CommandName Set-TextContent ` -ParameterFilter { ($path -eq $script:testTextFile) -and ` ($value -eq $script:testFileExpectedTextContentNewKey) @@ -415,7 +415,7 @@ Setting3.Test=Value4 -Exactly 1 Assert-MockCalled ` - -CommandName Set-Content ` + -CommandName Set-TextContent ` -ParameterFilter { ($path -eq $script:testTextFile) -and ` ($value -eq $script:testFileExpectedTextContentNewKey) @@ -443,7 +443,7 @@ Setting3.Test=Value4 -Verifiable Mock ` - -CommandName Set-Content ` + -CommandName Set-TextContent ` -ParameterFilter { ($path -eq $script:testTextFile) -and ` ($value -eq $script:testFileContent) @@ -470,7 +470,7 @@ Setting3.Test=Value4 -Exactly 1 Assert-MockCalled ` - -CommandName Set-Content ` + -CommandName Set-TextContent ` -ParameterFilter { ($path -eq $script:testTextFile) -and ` ($value -eq $script:testFileContent) @@ -499,7 +499,7 @@ Setting3.Test=Value4 -Verifiable Mock ` - -CommandName Set-Content ` + -CommandName Set-TextContent ` -ParameterFilter { ($path -eq $script:testTextFile) -and ` ($value -eq $script:testFileExpectedSecretContent) @@ -526,7 +526,7 @@ Setting3.Test=Value4 -Exactly 1 Assert-MockCalled ` - -CommandName Set-Content ` + -CommandName Set-TextContent ` -ParameterFilter { ($path -eq $script:testTextFile) -and ` ($value -eq $script:testFileExpectedSecretContent) @@ -555,7 +555,7 @@ Setting3.Test=Value4 -Verifiable Mock ` - -CommandName Set-Content ` + -CommandName Set-TextContent ` -ParameterFilter { ($path -eq $script:testTextFile) -and ` ($value -eq $script:testTextReplace) @@ -581,7 +581,7 @@ Setting3.Test=Value4 -Exactly 1 Assert-MockCalled ` - -CommandName Set-Content ` + -CommandName Set-TextContent ` -ParameterFilter { ($path -eq $script:testTextFile) -and ` ($value -eq $script:testTextReplace) diff --git a/tests/Unit/FileContentDsc.Common.tests.ps1 b/tests/Unit/FileContentDsc.Common.tests.ps1 index 40ef9e5..5ec0e4e 100644 --- a/tests/Unit/FileContentDsc.Common.tests.ps1 +++ b/tests/Unit/FileContentDsc.Common.tests.ps1 @@ -57,23 +57,35 @@ InModuleScope $script:subModuleName { } Describe 'FileContentDsc.Common\Get-FileEncoding' { - $testTextFile = "TestDrive:\TestFile.txt" - $value = 'testText' + $testTextFile = "$TestDrive\TestFile.txt" $testCases = @( @{ encoding = 'ASCII' + value = [byte[]](97, 98, 99) }, @{ encoding = 'BigEndianUnicode' + value = [byte[]](254, 255, 0, 97, 0, 98, 0, 99) }, @{ encoding = 'BigEndianUTF32' + value = [byte[]](0, 0, 254, 255, 0, 0, 0, 97, 0, 0, 0, 98, 0, 0, 0, 99) }, @{ encoding = 'UTF8' + value = [byte[]](239, 187, 191, 97, 98, 99) + }, + @{ + encoding = 'UTF8BOM' + value = [byte[]](239, 187, 191, 97, 98, 99) + }, + @{ + encoding = 'UTF8NoBOM' + value = [byte[]](97, 98, 99, 226, 157, 164) }, @{ encoding = 'UTF32' + value = [byte[]](255, 254, 0, 0, 97, 0, 0, 0, 98, 0, 0, 0, 99, 0, 0, 0) } ) @@ -83,11 +95,104 @@ InModuleScope $script:subModuleName { ( [Parameter()] [System.String] - $Encoding + $Encoding, + + [Parameter()] + [byte[]] + $value + ) + + # Create a test file in byte format so that it does not depend on the PowerShell version. + [SYstem.IO.File]::WriteAllBytes($testTextFile, $value) + + if ($Encoding -eq 'UTF8') + { + Get-FileEncoding -Path $testTextFile | Should -Be 'UTF8BOM' + } + else + { + Get-FileEncoding -Path $testTextFile | Should -Be $Encoding + } + } + } + } + + Describe 'FileContentDsc.Common\Set-TextContent' { + $testTextFile = "TestDrive:\TestFile.txt" + $value = [string][char]0x0398 #Non-Ascii character + $testCases = @( + @{ + encoding = 'ASCII' + expectedValueInBytes = [byte[]](63) + }, + @{ + encoding = 'BigEndianUnicode' + expectedValueInBytes = [byte[]](254, 255, 3, 152) + }, + @{ + encoding = 'BigEndianUTF32' + expectedValueInBytes = [byte[]](0, 0, 254, 255, 0, 0, 3, 152) + }, + @{ + encoding = 'UTF8' + }, + @{ + encoding = 'UTF8BOM' + expectedValueInBytes = [byte[]](239, 187, 191, 206, 152) + }, + @{ + encoding = 'UTF8NoBOM' + expectedValueInBytes = [byte[]](206, 152) + }, + @{ + encoding = 'UTF32' + expectedValueInBytes = [byte[]](255, 254, 0, 0, 152, 3, 0, 0) + } + ) + + Context 'When save text file' { + It "Should create a text file with '' encoding" -TestCases $testCases { + param + ( + [Parameter()] + [System.String] + $Encoding, + + [Parameter()] + [byte[]] + $ExpectedValueInBytes ) - Set-Content $testTextFile -Value $value -Encoding $Encoding - Get-FileEncoding -Path $testTextFile | Should -Be $Encoding + Set-TextContent -Path $testTextFile -Value $value -Encoding $Encoding -Force -NoNewLine + + # PowerShell 6 or later + if ($PSVersionTable.PSVersion.Major -ge 6) + { + $result = Get-Content -Path $testTextFile -Raw -AsByteStream + if ($Encoding -eq 'UTF8') + { + # In the PowerShell v6+, UTF8 has not BOM by default. + $result | Should -Be ([byte[]](206, 152)) + } + else + { + $result | Should -Be $ExpectedValueInBytes + } + } + # PowerShell 5.1 or earlier + else + { + $result = Get-Content -Path $testTextFile -Raw -Encoding Byte + if ($Encoding -eq 'UTF8') + { + # In the PowerShell v5, UTF8 has BOM by default. + $result | Should -Be ([byte[]](239, 187, 191, 206, 152)) + } + else + { + $result | Should -Be $ExpectedValueInBytes + } + } } } }