From 045b49a5d6b64f69aa08e3d2fd78ca5721458f3d Mon Sep 17 00:00:00 2001 From: mkht Date: Sun, 27 Oct 2024 01:01:49 +0900 Subject: [PATCH 1/8] 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 + } + } } } } From b701fefa332edee67370d6e1bffd1da4dfe6c762 Mon Sep 17 00:00:00 2001 From: mkht Date: Sun, 27 Oct 2024 02:08:32 +0900 Subject: [PATCH 2/8] Fix build pipeline --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 1357164..376589d 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -27,7 +27,7 @@ stages: vmImage: 'windows-latest' steps: - pwsh: | - dotnet tool install --global GitVersion.Tool + dotnet tool install --global GitVersion.Tool --version 5.* $gitVersionObject = dotnet-gitversion | ConvertFrom-Json $gitVersionObject.PSObject.Properties.ForEach{ Write-Host -Object "Setting Task Variable '$($_.Name)' with value '$($_.Value)'." From b3d65bb23ce6edb440cc4aaf59d783940cf396cc Mon Sep 17 00:00:00 2001 From: mkht Date: Sun, 27 Oct 2024 14:06:38 +0900 Subject: [PATCH 3/8] Update CHANGELOG --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3861293..fb805c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,7 +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). +- Added `UTF8BOM` and `UTF8NoBOM` options to the 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 @@ -38,6 +38,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - CI Pipeline - Updated pipeline files to match current DSC Community patterns - fixes [Issue #71](https://github.com/dsccommunity/FileContentDsc/issues/71). - Updated HQRM and build steps to use windows-latest image. + - Keep GitVersion.Tool as v5 ### Fixed From 5145a31e5df055e079bd706fab7a471466f8581d Mon Sep 17 00:00:00 2001 From: mkht Date: Sun, 27 Oct 2024 14:08:01 +0900 Subject: [PATCH 4/8] Adjust formatting of hashtable to fix the HQRM tests --- .../FileContentDsc.Common/FileContentDsc.Common.psm1 | 8 ++++++-- tests/TestHelpers/CommonTestHelper.psm1 | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/source/Modules/FileContentDsc.Common/FileContentDsc.Common.psm1 b/source/Modules/FileContentDsc.Common/FileContentDsc.Common.psm1 index 6fe0ad6..36749b6 100644 --- a/source/Modules/FileContentDsc.Common/FileContentDsc.Common.psm1 +++ b/source/Modules/FileContentDsc.Common/FileContentDsc.Common.psm1 @@ -177,11 +177,15 @@ function Get-FileEncoding # 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 } + @{ + AsByteStream = $true + } } else { - @{Encoding = 'byte' } + @{ + Encoding = 'byte' + } } [System.Byte[]] $byte = Get-Content @ByteParam -ReadCount 4 -TotalCount 4 -Path $Path diff --git a/tests/TestHelpers/CommonTestHelper.psm1 b/tests/TestHelpers/CommonTestHelper.psm1 index 9eaf783..5474bfd 100644 --- a/tests/TestHelpers/CommonTestHelper.psm1 +++ b/tests/TestHelpers/CommonTestHelper.psm1 @@ -112,11 +112,15 @@ function Get-FileEncoding # 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 } + @{ + AsByteStream = $true + } } else { - @{Encoding = 'byte' } + @{ + Encoding = 'byte' + } } [System.Byte[]] $byte = Get-Content @ByteParam -ReadCount 4 -TotalCount 4 -Path $Path From b3c209442c1b4859e2493076affc824cd24dab75 Mon Sep 17 00:00:00 2001 From: mkht Date: Sun, 27 Oct 2024 15:07:56 +0900 Subject: [PATCH 5/8] Refactor dup codes to a Get-FileContent function --- .../DSC_KeyValuePairFile.psm1 | 43 +------ .../DSC_ReplaceText/DSC_ReplaceText.psm1 | 39 +----- .../FileContentDsc.Common.psm1 | 47 +++++++- tests/Unit/DSC_KeyValuePairFile.Tests.ps1 | 112 +++++++++--------- tests/Unit/DSC_ReplaceText.Tests.ps1 | 68 +++++------ tests/Unit/FileContentDsc.Common.tests.ps1 | 71 ++++++++++- 6 files changed, 214 insertions(+), 166 deletions(-) diff --git a/source/DSCResources/DSC_KeyValuePairFile/DSC_KeyValuePairFile.psm1 b/source/DSCResources/DSC_KeyValuePairFile/DSC_KeyValuePairFile.psm1 index faed4b3..fa65efa 100644 --- a/source/DSCResources/DSC_KeyValuePairFile/DSC_KeyValuePairFile.psm1 +++ b/source/DSCResources/DSC_KeyValuePairFile/DSC_KeyValuePairFile.psm1 @@ -48,20 +48,9 @@ function Get-TargetResource if (Test-Path -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 - } + $fileContent = Get-FileContent -Path $Path -Encoding $fileEncoding - if ($null -ne $fileContent) + if (-not [string]::IsNullOrEmpty($fileContent)) { Write-Verbose -Message ($script:localizedData.SearchForKeyMessage -f $Path, $Name) @@ -199,18 +188,7 @@ function Set-TargetResource Assert-ParametersValid @PSBoundParameters $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 - } + $fileContent = Get-FileContent -Path $Path -Encoding $fileEncoding -ErrorAction SilentlyContinue $fileProperties = @{ Path = $Path @@ -406,20 +384,9 @@ function Test-TargetResource } $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 - } + $fileContent = Get-FileContent -Path $Path -Encoding $fileEncoding - if ($null -eq $fileContent) + if ([string]::IsNullOrEmpty($fileContent)) { Write-Verbose -Message ($script:localizedData.KeyValuePairFileIsEmpty -f $Path) diff --git a/source/DSCResources/DSC_ReplaceText/DSC_ReplaceText.psm1 b/source/DSCResources/DSC_ReplaceText/DSC_ReplaceText.psm1 index 1473e49..71cb59a 100644 --- a/source/DSCResources/DSC_ReplaceText/DSC_ReplaceText.psm1 +++ b/source/DSCResources/DSC_ReplaceText/DSC_ReplaceText.psm1 @@ -42,18 +42,7 @@ function Get-TargetResource Assert-ParametersValid @PSBoundParameters $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 - } + $fileContent = Get-FileContent -Path $Path -Encoding $fileEncoding Write-Verbose -Message ($script:localizedData.SearchForTextMessage -f ` $Path, $Search) @@ -155,18 +144,7 @@ function Set-TargetResource Assert-ParametersValid @PSBoundParameters $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 - } + $fileContent = Get-FileContent -Path $Path -Encoding $fileEncoding -ErrorAction SilentlyContinue $fileProperties = @{ Path = $Path @@ -287,18 +265,7 @@ function Test-TargetResource } $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 - } + $fileContent = Get-FileContent -Path $Path -Encoding $fileEncoding Write-Verbose -Message ($script:localizedData.SearchForTextMessage -f ` $Path, $Search) diff --git a/source/Modules/FileContentDsc.Common/FileContentDsc.Common.psm1 b/source/Modules/FileContentDsc.Common/FileContentDsc.Common.psm1 index 36749b6..5a56b29 100644 --- a/source/Modules/FileContentDsc.Common/FileContentDsc.Common.psm1 +++ b/source/Modules/FileContentDsc.Common/FileContentDsc.Common.psm1 @@ -222,6 +222,50 @@ function Get-FileEncoding } } +<# + .SYNOPSIS + Gets file content with specified file encoding. + + .DESCRIPTION + The function Get-FileContent function reads the contents of a text file with specified encoding. + + .EXAMPLE + Get-FileContent -Path C:\text.txt -Encoding UTF8 + This command returns the contents of a text file read as UTF8 encoded. +#> +function Get-FileContent +{ + [CmdletBinding()] + [OutputType([System.String])] + param + ( + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [System.String] + $Path, + + [Parameter(ValueFromPipelineByPropertyName = $true)] + [AllowEmptyString()] + [System.String] + $Encoding + ) + + $GetContentParam = @{ + Path = $Path + Raw = $true + } + + if ($Encoding -like 'UTF8*') + { + $GetContentParam = 'UTF8' + } + elseif (-not [string]::IsNullOrEmpty($Encoding)) + { + $GetContentParam = $Encoding + } + + Get-Content @GetContentParam +} + <# .SYNOPSIS Writes or replaces the content in an item with new content. @@ -311,6 +355,7 @@ Export-ModuleMember -Function @( 'Get-TextEolCharacter', 'Set-IniSettingFileValue', 'Get-IniSettingFileValue', - 'Get-FileEncoding' + 'Get-FileEncoding', + 'Get-FileContent', 'Set-TextContent' ) diff --git a/tests/Unit/DSC_KeyValuePairFile.Tests.ps1 b/tests/Unit/DSC_KeyValuePairFile.Tests.ps1 index 2f803e7..627cce3 100644 --- a/tests/Unit/DSC_KeyValuePairFile.Tests.ps1 +++ b/tests/Unit/DSC_KeyValuePairFile.Tests.ps1 @@ -120,7 +120,7 @@ $($script:testAddedName)=$($script:testText) Mock -CommandName Test-Path ` -MockWith { $false } - Mock -CommandName Get-Content + Mock -CommandName Get-FileContent Mock -CommandName Get-FileEncoding $script:result = $null @@ -151,7 +151,7 @@ $($script:testAddedName)=$($script:testText) -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 - Assert-MockCalled -CommandName Get-Content ` + Assert-MockCalled -CommandName Get-FileContent ` -Scope Context ` -Exactly -Times 0 @@ -165,7 +165,7 @@ $($script:testAddedName)=$($script:testText) Mock -CommandName Test-Path ` -MockWith { $true } - Mock -CommandName Get-Content + Mock -CommandName Get-FileContent Mock -CommandName Get-FileEncoding $script:result = $null @@ -196,7 +196,7 @@ $($script:testAddedName)=$($script:testText) -Scope Context ` -Exactly -Times 1 - Assert-MockCalled -CommandName Get-Content ` + Assert-MockCalled -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -Scope Context ` -Exactly -Times 1 @@ -212,7 +212,7 @@ $($script:testAddedName)=$($script:testText) Mock -CommandName Test-Path ` -MockWith { $true } - Mock -CommandName Get-Content ` + Mock -CommandName Get-FileContent ` -MockWith { $script:testFileExpectedTextContent } Mock -CommandName Get-FileEncoding ` @@ -246,7 +246,7 @@ $($script:testAddedName)=$($script:testText) -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 - Assert-MockCalled -CommandName Get-Content ` + Assert-MockCalled -CommandName Get-FileContent ` -Scope Context ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 @@ -262,7 +262,7 @@ $($script:testAddedName)=$($script:testText) Mock -CommandName Test-Path ` -MockWith { $true } - Mock -CommandName Get-Content ` + Mock -CommandName Get-FileContent ` -MockWith { $script:testFileExpectedTextContent } Mock -CommandName Get-FileEncoding ` @@ -296,7 +296,7 @@ $($script:testAddedName)=$($script:testText) -Scope Context ` -Exactly -Times 1 - Assert-MockCalled -CommandName Get-Content ` + Assert-MockCalled -CommandName Get-FileContent ` -Scope Context ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 @@ -315,7 +315,7 @@ $($script:testAddedName)=$($script:testText) } Context 'When the file does not exist' { - Mock -CommandName Get-Content + Mock -CommandName Get-FileContent Mock -CommandName Get-FileEncoding ` -MockWith { $script:testCompliantEncoding.Encoding } @@ -337,7 +337,7 @@ $($script:testAddedName)=$($script:testText) -Scope Context ` -Exactly -Times 1 - Assert-MockCalled -CommandName Get-Content ` + Assert-MockCalled -CommandName Get-FileContent ` -Scope Context ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 @@ -358,7 +358,7 @@ $($script:testAddedName)=$($script:testText) } Context 'When the file is empty' { - Mock -CommandName Get-Content + Mock -CommandName Get-FileContent Mock -CommandName Get-FileEncoding ` -MockWith { $script:testCompliantEncoding.Encoding } @@ -380,7 +380,7 @@ $($script:testAddedName)=$($script:testText) -Scope Context ` -Exactly -Times 1 - Assert-MockCalled -CommandName Get-Content ` + Assert-MockCalled -CommandName Get-FileContent ` -Scope Context ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 @@ -401,7 +401,7 @@ $($script:testAddedName)=$($script:testText) } Context 'When the file exists and contains a matching key that should exist' { - Mock -CommandName Get-Content ` + Mock -CommandName Get-FileContent ` -MockWith { $script:testFileContent } Mock -CommandName Get-FileEncoding ` @@ -424,7 +424,7 @@ $($script:testAddedName)=$($script:testText) -Scope Context ` -Exactly -Times 1 - Assert-MockCalled -CommandName Get-Content ` + Assert-MockCalled -CommandName Get-FileContent ` -Scope Context ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 @@ -445,7 +445,7 @@ $($script:testAddedName)=$($script:testText) } Context 'When the file exists and contains a matching key that should exist and contain a secret' { - Mock -CommandName Get-Content ` + Mock -CommandName Get-FileContent ` -MockWith { $script:testFileContent } Mock -CommandName Get-FileEncoding ` @@ -469,7 +469,7 @@ $($script:testAddedName)=$($script:testText) -Scope Context ` -Exactly -Times 1 - Assert-MockCalled -CommandName Get-Content ` + Assert-MockCalled -CommandName Get-FileContent ` -Scope Context ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 @@ -490,7 +490,7 @@ $($script:testAddedName)=$($script:testText) } Context 'When the file exists does not contain a matching key but key should exist' { - Mock -CommandName Get-Content ` + Mock -CommandName Get-FileContent ` -MockWith { $script:testFileContent } Mock -CommandName Get-FileEncoding ` @@ -517,7 +517,7 @@ $($script:testAddedName)=$($script:testText) -Scope Context ` -Exactly -Times 1 - Assert-MockCalled -CommandName Get-Content ` + Assert-MockCalled -CommandName Get-FileContent ` -Scope Context ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 @@ -538,7 +538,7 @@ $($script:testAddedName)=$($script:testText) } Context 'When the file exists and contains a key with a different case that should exist and IgnoreNameCase is True' { - Mock -CommandName Get-Content ` + Mock -CommandName Get-FileContent ` -MockWith { $script:testFileContent } Mock -CommandName Get-FileEncoding ` @@ -562,7 +562,7 @@ $($script:testAddedName)=$($script:testText) -Scope Context ` -Exactly -Times 1 - Assert-MockCalled -CommandName Get-Content ` + Assert-MockCalled -CommandName Get-FileContent ` -Scope Context ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 @@ -583,7 +583,7 @@ $($script:testAddedName)=$($script:testText) } Context 'When the file exists and does not contain a key with matching case and should not' { - Mock -CommandName Get-Content ` + Mock -CommandName Get-FileContent ` -MockWith { $script:testFileContent } Mock -CommandName Get-FileEncoding ` @@ -606,7 +606,7 @@ $($script:testAddedName)=$($script:testText) -Scope Context ` -Exactly -Times 1 - Assert-MockCalled -CommandName Get-Content ` + Assert-MockCalled -CommandName Get-FileContent ` -Scope Context ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 @@ -623,7 +623,7 @@ $($script:testAddedName)=$($script:testText) } Context 'When the file exists and contains a key with a different case but should not and IgnoreNameCase is True' { - Mock -CommandName Get-Content ` + Mock -CommandName Get-FileContent ` -MockWith { $script:testFileContent } Mock -CommandName Get-FileEncoding ` @@ -646,7 +646,7 @@ $($script:testAddedName)=$($script:testText) -Scope Context ` -Exactly -Times 1 - Assert-MockCalled -CommandName Get-Content ` + Assert-MockCalled -CommandName Get-FileContent ` -Scope Context ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 @@ -676,7 +676,7 @@ $($script:testAddedName)=$($script:testText) Mock -CommandName Test-Path ` -MockWith { $false } - Mock -CommandName Get-Content + Mock -CommandName Get-FileContent Mock -CommandName Get-FileEncoding It 'Should not throw an exception' { @@ -698,7 +698,7 @@ $($script:testAddedName)=$($script:testText) -Scope Context ` -Exactly -Times 1 - Assert-MockCalled -CommandName Get-Content ` + Assert-MockCalled -CommandName Get-FileContent ` -Scope Context ` -Exactly -Times 0 @@ -712,7 +712,7 @@ $($script:testAddedName)=$($script:testText) Mock -CommandName Test-Path ` -MockWith { $false } - Mock -CommandName Get-Content + Mock -CommandName Get-FileContent Mock -CommandName Get-FileEncoding It 'Should not throw an exception' { @@ -734,7 +734,7 @@ $($script:testAddedName)=$($script:testText) -Scope Context ` -Exactly -Times 1 - Assert-MockCalled -CommandName Get-Content ` + Assert-MockCalled -CommandName Get-FileContent ` -Scope Context ` -Exactly -Times 0 @@ -748,7 +748,7 @@ $($script:testAddedName)=$($script:testText) Mock -CommandName Test-Path ` -MockWith { $true } - Mock -CommandName Get-Content + Mock -CommandName Get-FileContent Mock -CommandName Get-FileEncoding It 'Should not throw an exception' { @@ -770,7 +770,7 @@ $($script:testAddedName)=$($script:testText) -Scope Context ` -Exactly -Times 1 - Assert-MockCalled -CommandName Get-Content ` + Assert-MockCalled -CommandName Get-FileContent ` -Scope Context ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 @@ -785,7 +785,7 @@ $($script:testAddedName)=$($script:testText) Mock -CommandName Test-Path ` -MockWith { $true } - Mock -CommandName Get-Content + Mock -CommandName Get-FileContent Mock -CommandName Get-FileEncoding It 'Should not throw an exception' { @@ -807,7 +807,7 @@ $($script:testAddedName)=$($script:testText) -Scope Context ` -Exactly -Times 1 - Assert-MockCalled -CommandName Get-Content ` + Assert-MockCalled -CommandName Get-FileContent ` -Scope Context ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 @@ -822,7 +822,7 @@ $($script:testAddedName)=$($script:testText) Mock -CommandName Test-Path ` -MockWith { $true } - Mock -CommandName Get-Content ` + Mock -CommandName Get-FileContent ` -MockWith { $script:testFileContent } Mock -CommandName Get-FileEncoding ` @@ -847,7 +847,7 @@ $($script:testAddedName)=$($script:testText) -Scope Context ` -Exactly -Times 1 - Assert-MockCalled -CommandName Get-Content ` + Assert-MockCalled -CommandName Get-FileContent ` -Scope Context ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 @@ -863,7 +863,7 @@ $($script:testAddedName)=$($script:testText) Mock -CommandName Test-Path ` -MockWith { $true } - Mock -CommandName Get-Content ` + Mock -CommandName Get-FileContent ` -MockWith { $script:testFileContent } Mock -CommandName Get-FileEncoding ` @@ -888,7 +888,7 @@ $($script:testAddedName)=$($script:testText) -Scope Context ` -Exactly -Times 1 - Assert-MockCalled -CommandName Get-Content ` + Assert-MockCalled -CommandName Get-FileContent ` -Scope Context ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 @@ -904,7 +904,7 @@ $($script:testAddedName)=$($script:testText) Mock -CommandName Test-Path ` -MockWith { $true } - Mock -CommandName Get-Content ` + Mock -CommandName Get-FileContent ` -MockWith { $script:testFileContent } Mock -CommandName Get-FileEncoding ` @@ -929,7 +929,7 @@ $($script:testAddedName)=$($script:testText) -Scope Context ` -Exactly -Times 1 - Assert-MockCalled -CommandName Get-Content ` + Assert-MockCalled -CommandName Get-FileContent ` -Scope Context ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 @@ -945,7 +945,7 @@ $($script:testAddedName)=$($script:testText) Mock -CommandName Test-Path ` -MockWith { $true } - Mock -CommandName Get-Content ` + Mock -CommandName Get-FileContent ` -MockWith { $script:testFileExpectedTextContent } Mock -CommandName Get-FileEncoding ` @@ -970,7 +970,7 @@ $($script:testAddedName)=$($script:testText) -Scope Context ` -Exactly -Times 1 - Assert-MockCalled -CommandName Get-Content ` + Assert-MockCalled -CommandName Get-FileContent ` -Scope Context ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 @@ -986,7 +986,7 @@ $($script:testAddedName)=$($script:testText) Mock -CommandName Test-Path ` -MockWith { $true } - Mock -CommandName Get-Content ` + Mock -CommandName Get-FileContent ` -MockWith { $script:testFileExpectedTextContent } Mock -CommandName Get-FileEncoding ` @@ -1012,7 +1012,7 @@ $($script:testAddedName)=$($script:testText) -Scope Context ` -Exactly -Times 1 - Assert-MockCalled -CommandName Get-Content ` + Assert-MockCalled -CommandName Get-FileContent ` -Scope Context ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 @@ -1028,7 +1028,7 @@ $($script:testAddedName)=$($script:testText) Mock -CommandName Test-Path ` -MockWith { $true } - Mock -CommandName Get-Content ` + Mock -CommandName Get-FileContent ` -MockWith { $script:testFileContent } Mock -CommandName Get-FileEncoding ` @@ -1054,7 +1054,7 @@ $($script:testAddedName)=$($script:testText) -Scope Context ` -Exactly -Times 1 - Assert-MockCalled -CommandName Get-Content ` + Assert-MockCalled -CommandName Get-FileContent ` -Scope Context ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 @@ -1070,7 +1070,7 @@ $($script:testAddedName)=$($script:testText) Mock -CommandName Test-Path ` -MockWith { $true } - Mock -CommandName Get-Content ` + Mock -CommandName Get-FileContent ` -MockWith { $script:testFileExpectedSecretContent } Mock -CommandName Get-FileEncoding ` @@ -1096,7 +1096,7 @@ $($script:testAddedName)=$($script:testText) -Scope Context ` -Exactly -Times 1 - Assert-MockCalled -CommandName Get-Content ` + Assert-MockCalled -CommandName Get-FileContent ` -Scope Context ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 @@ -1112,7 +1112,7 @@ $($script:testAddedName)=$($script:testText) Mock -CommandName Test-Path ` -MockWith { $true } - Mock -CommandName Get-Content ` + Mock -CommandName Get-FileContent ` -MockWith { $script:testFileExpectedSecretContent } Mock -CommandName Get-FileEncoding ` @@ -1139,7 +1139,7 @@ $($script:testAddedName)=$($script:testText) -Scope Context ` -Exactly -Times 1 - Assert-MockCalled -CommandName Get-Content ` + Assert-MockCalled -CommandName Get-FileContent ` -Scope Context ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 @@ -1155,7 +1155,7 @@ $($script:testAddedName)=$($script:testText) Mock -CommandName Test-Path ` -MockWith { $true } - Mock -CommandName Get-Content ` + Mock -CommandName Get-FileContent ` -MockWith { $script:testFileExpectedTextContent } Mock -CommandName Get-FileEncoding ` @@ -1181,7 +1181,7 @@ $($script:testAddedName)=$($script:testText) -Scope Context ` -Exactly -Times 1 - Assert-MockCalled -CommandName Get-Content ` + Assert-MockCalled -CommandName Get-FileContent ` -Scope Context ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 @@ -1197,7 +1197,7 @@ $($script:testAddedName)=$($script:testText) Mock -CommandName Test-Path ` -MockWith { $true } - Mock -CommandName Get-Content ` + Mock -CommandName Get-FileContent ` -MockWith { $script:testFileExpectedTextContent } Mock -CommandName Get-FileEncoding ` @@ -1222,7 +1222,7 @@ $($script:testAddedName)=$($script:testText) -Scope Context ` -Exactly -Times 1 - Assert-MockCalled -CommandName Get-Content ` + Assert-MockCalled -CommandName Get-FileContent ` -Scope Context ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 @@ -1238,7 +1238,7 @@ $($script:testAddedName)=$($script:testText) Mock -CommandName Test-Path ` -MockWith { $true } - Mock -CommandName Get-Content ` + Mock -CommandName Get-FileContent ` -MockWith { $script:testFileExpectedTextContent } Mock -CommandName Get-FileEncoding ` @@ -1264,7 +1264,7 @@ $($script:testAddedName)=$($script:testText) -Scope Context ` -Exactly -Times 1 - Assert-MockCalled -CommandName Get-Content ` + Assert-MockCalled -CommandName Get-FileContent ` -Scope Context ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 @@ -1280,7 +1280,7 @@ $($script:testAddedName)=$($script:testText) Mock -CommandName Test-Path ` -MockWith { $true } - Mock -CommandName Get-Content ` + Mock -CommandName Get-FileContent ` -MockWith { $script:testFileExpectedTextContent } Mock -CommandName Get-FileEncoding ` @@ -1305,7 +1305,7 @@ $($script:testAddedName)=$($script:testText) -Scope Context ` -Exactly -Times 1 - Assert-MockCalled -CommandName Get-Content ` + Assert-MockCalled -CommandName Get-FileContent ` -Scope Context ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly -Times 1 diff --git a/tests/Unit/DSC_ReplaceText.Tests.ps1 b/tests/Unit/DSC_ReplaceText.Tests.ps1 index d2c9668..ee76758 100644 --- a/tests/Unit/DSC_ReplaceText.Tests.ps1 +++ b/tests/Unit/DSC_ReplaceText.Tests.ps1 @@ -107,7 +107,7 @@ Setting3.Test=Value4 -Verifiable Mock ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -MockWith { $script:testFileExpectedTextContent } ` -Verifiable @@ -141,7 +141,7 @@ Setting3.Test=Value4 Assert-MockCalled -CommandName Assert-ParametersValid -Exactly 1 Assert-MockCalled ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly 1 @@ -160,7 +160,7 @@ Setting3.Test=Value4 -Verifiable Mock ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -MockWith { $script:testFileExpectedTextContent } ` -Verifiable @@ -194,7 +194,7 @@ Setting3.Test=Value4 Assert-MockCalled -CommandName Assert-ParametersValid -Exactly 1 Assert-MockCalled ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly 1 @@ -213,7 +213,7 @@ Setting3.Test=Value4 -Verifiable Mock ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -MockWith { $script:testFileExpectedTextContent } ` -Verifiable @@ -247,7 +247,7 @@ Setting3.Test=Value4 Assert-MockCalled -CommandName Assert-ParametersValid -Exactly 1 Assert-MockCalled ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly 1 @@ -266,7 +266,7 @@ Setting3.Test=Value4 -Verifiable Mock ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -MockWith { $script:testFileExpectedTextContent } ` -Verifiable @@ -300,7 +300,7 @@ Setting3.Test=Value4 Assert-MockCalled -CommandName Assert-ParametersValid -Exactly 1 Assert-MockCalled ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly 1 @@ -321,7 +321,7 @@ Setting3.Test=Value4 -Verifiable Mock ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -MockWith { $script:testFileContent } ` -Verifiable @@ -354,7 +354,7 @@ Setting3.Test=Value4 Assert-MockCalled -CommandName Assert-ParametersValid -Exactly 1 Assert-MockCalled ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly 1 @@ -376,7 +376,7 @@ Setting3.Test=Value4 -Verifiable Mock ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -MockWith { $script:testFileContent } ` -Verifiable @@ -410,7 +410,7 @@ Setting3.Test=Value4 Assert-MockCalled -CommandName Assert-ParametersValid -Exactly 1 Assert-MockCalled ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly 1 @@ -431,7 +431,7 @@ Setting3.Test=Value4 -Verifiable Mock ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -MockWith { $script:testFileContent } ` -Verifiable @@ -465,7 +465,7 @@ Setting3.Test=Value4 Assert-MockCalled -CommandName Assert-ParametersValid -Exactly 1 Assert-MockCalled ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly 1 @@ -487,7 +487,7 @@ Setting3.Test=Value4 -Verifiable Mock ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -MockWith { $script:testFileContent } ` -Verifiable @@ -521,7 +521,7 @@ Setting3.Test=Value4 Assert-MockCalled -CommandName Assert-ParametersValid -Exactly 1 Assert-MockCalled ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly 1 @@ -543,7 +543,7 @@ Setting3.Test=Value4 -Verifiable Mock ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -MockWith { $null } ` -Verifiable @@ -576,7 +576,7 @@ Setting3.Test=Value4 Assert-MockCalled -CommandName Assert-ParametersValid -Exactly 1 Assert-MockCalled ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly 1 @@ -606,7 +606,7 @@ Setting3.Test=Value4 -Verifiable Mock ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -MockWith { $script:testFileContent } ` -Verifiable @@ -638,7 +638,7 @@ Setting3.Test=Value4 Assert-MockCalled -CommandName Assert-ParametersValid -Exactly 1 Assert-MockCalled ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly 1 @@ -663,7 +663,7 @@ Setting3.Test=Value4 -Verifiable Mock ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -MockWith { $script:testFileContent } ` -Verifiable @@ -696,7 +696,7 @@ Setting3.Test=Value4 Assert-MockCalled -CommandName Assert-ParametersValid -Exactly 1 Assert-MockCalled ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly 1 @@ -721,7 +721,7 @@ Setting3.Test=Value4 -Verifiable Mock ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -MockWith { $script:testFileContent } ` -Verifiable @@ -754,7 +754,7 @@ Setting3.Test=Value4 Assert-MockCalled -CommandName Assert-ParametersValid -Exactly 1 Assert-MockCalled ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly 1 @@ -779,7 +779,7 @@ Setting3.Test=Value4 -Verifiable Mock ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -MockWith { $script:testFileContent } ` -Verifiable @@ -809,7 +809,7 @@ Setting3.Test=Value4 Assert-MockCalled -CommandName Assert-ParametersValid -Exactly 1 Assert-MockCalled ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly 1 } @@ -829,7 +829,7 @@ Setting3.Test=Value4 -Verifiable Mock ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -MockWith { $script:testFileExpectedTextContent } ` -Verifiable @@ -859,7 +859,7 @@ Setting3.Test=Value4 Assert-MockCalled -CommandName Assert-ParametersValid -Exactly 1 Assert-MockCalled ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly 1 } @@ -879,7 +879,7 @@ Setting3.Test=Value4 -Verifiable Mock ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -MockWith { $script:testFileContent } ` -Verifiable @@ -910,7 +910,7 @@ Setting3.Test=Value4 Assert-MockCalled -CommandName Assert-ParametersValid -Exactly 1 Assert-MockCalled ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly 1 } @@ -930,7 +930,7 @@ Setting3.Test=Value4 -Verifiable Mock ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -MockWith { $script:testFileExpectedSecretContent } ` -Verifiable @@ -961,7 +961,7 @@ Setting3.Test=Value4 Assert-MockCalled -CommandName Assert-ParametersValid -Exactly 1 Assert-MockCalled ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -Exactly 1 } @@ -981,7 +981,7 @@ Setting3.Test=Value4 -Verifiable Mock ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -ParameterFilter { $path -eq $script:testTextFile } ` -MockWith { $script:testFileContent } @@ -1005,7 +1005,7 @@ Setting3.Test=Value4 Assert-MockCalled -CommandName Assert-ParametersValid -Exactly 1 Assert-MockCalled ` - -CommandName Get-Content ` + -CommandName Get-FileContent ` -Exactly 0 } } diff --git a/tests/Unit/FileContentDsc.Common.tests.ps1 b/tests/Unit/FileContentDsc.Common.tests.ps1 index 5ec0e4e..2940e2a 100644 --- a/tests/Unit/FileContentDsc.Common.tests.ps1 +++ b/tests/Unit/FileContentDsc.Common.tests.ps1 @@ -117,8 +117,77 @@ InModuleScope $script:subModuleName { } } + Describe 'FileContentDsc.Common\Get-FileContent' { + $testTextFile = "$TestDrive\TestFile.txt" + $testCases = @( + @{ + encoding = 'ASCII' + value = [byte[]](97, 98, 99) + expect = 'abc' + }, + @{ + encoding = 'BigEndianUnicode' + value = [byte[]](254, 255, 0, 97, 0, 98, 0, 99) + expect = 'abc' + }, + @{ + encoding = 'BigEndianUTF32' + value = [byte[]](0, 0, 254, 255, 0, 0, 0, 97, 0, 0, 0, 98, 0, 0, 0, 99) + expect = 'abc' + }, + @{ + encoding = 'UTF8' + value = [byte[]](239, 187, 191, 97, 98, 99) + expect = 'abc' + }, + @{ + encoding = 'UTF8BOM' + value = [byte[]](239, 187, 191, 97, 98, 99) + expect = 'abc' + }, + @{ + encoding = 'UTF8NoBOM' + value = [byte[]](97, 98, 99, 226, 157, 164) + expect = 'abc' + }, + @{ + encoding = 'UTF32' + value = [byte[]](255, 254, 0, 0, 97, 0, 0, 0, 98, 0, 0, 0, 99, 0, 0, 0) + expect = 'abc' + }, + @{ + encoding = '' # Not specified + value = [byte[]](97, 98, 99) + expect = 'abc' + } + ) + + Context 'When reading file contnet' { + It "Should return '' for file with '' encoding" -TestCases $testCases { + param + ( + [Parameter()] + [System.String] + $Encoding, + + [Parameter()] + [byte[]] + $value, + + [Parameter()] + [System.String] + $expect + ) + + # Create a test file in byte format so that it does not depend on the PowerShell version. + [SYstem.IO.File]::WriteAllBytes($testTextFile, $value) + (Get-FileContent -Path $testTextFile -Encoding $Encoding) | Should -Be $expect + } + } + } + Describe 'FileContentDsc.Common\Set-TextContent' { - $testTextFile = "TestDrive:\TestFile.txt" + $testTextFile = 'TestDrive:\TestFile.txt' $value = [string][char]0x0398 #Non-Ascii character $testCases = @( @{ From 33f27d3a9caf94e7c24cb21d00b18f5f81a7bd88 Mon Sep 17 00:00:00 2001 From: mkht Date: Sun, 27 Oct 2024 15:53:40 +0900 Subject: [PATCH 6/8] Refactor comparison logic to a Test-FileEncodingEqual --- .../DSC_KeyValuePairFile.psm1 | 5 +- .../DSC_ReplaceText/DSC_ReplaceText.psm1 | 4 +- .../FileContentDsc.Common.psm1 | 34 +++++++- tests/Unit/FileContentDsc.Common.tests.ps1 | 78 +++++++++++++++++++ 4 files changed, 114 insertions(+), 7 deletions(-) diff --git a/source/DSCResources/DSC_KeyValuePairFile/DSC_KeyValuePairFile.psm1 b/source/DSCResources/DSC_KeyValuePairFile/DSC_KeyValuePairFile.psm1 index fa65efa..3916c9d 100644 --- a/source/DSCResources/DSC_KeyValuePairFile/DSC_KeyValuePairFile.psm1 +++ b/source/DSCResources/DSC_KeyValuePairFile/DSC_KeyValuePairFile.psm1 @@ -249,9 +249,8 @@ function Set-TargetResource if ($results.Count -eq 0) { if ($PSBoundParameters.ContainsKey('Encoding') -and ` - (($Encoding -eq $fileEncoding) -or ` - ($Encoding -eq 'UTF8' -and $fileEncoding -like 'UTF8*') -or ` - ($Encoding -eq 'UTF8NoBOM' -and $fileEncoding -eq 'ASCII'))) + (Test-FileEncodingEqual -FileEncoding $fileEncoding -ExpectedEncoding $Encoding) + ) { # The Key does not exists and should not, and encoding is in the desired state, so don't do anything return diff --git a/source/DSCResources/DSC_ReplaceText/DSC_ReplaceText.psm1 b/source/DSCResources/DSC_ReplaceText/DSC_ReplaceText.psm1 index 71cb59a..821d2db 100644 --- a/source/DSCResources/DSC_ReplaceText/DSC_ReplaceText.psm1 +++ b/source/DSCResources/DSC_ReplaceText/DSC_ReplaceText.psm1 @@ -285,9 +285,7 @@ function Test-TargetResource } if ($PSBoundParameters.ContainsKey('Encoding')) { - if (($Encoding -eq $fileEncoding) -or ` - ($Encoding -eq 'UTF8' -and $fileEncoding -like 'UTF8*') -or ` - ($Encoding -eq 'UTF8NoBOM' -and $fileEncoding -eq 'ASCII')) + if (Test-FileEncodingEqual -FileEncoding $fileEncoding -ExpectedEncoding $Encoding) { # No matches found and encoding is in desired state Write-Verbose -Message ($script:localizedData.StringNotFoundMessage -f ` diff --git a/source/Modules/FileContentDsc.Common/FileContentDsc.Common.psm1 b/source/Modules/FileContentDsc.Common/FileContentDsc.Common.psm1 index 5a56b29..344c9a1 100644 --- a/source/Modules/FileContentDsc.Common/FileContentDsc.Common.psm1 +++ b/source/Modules/FileContentDsc.Common/FileContentDsc.Common.psm1 @@ -351,11 +351,43 @@ function Set-TextContent Set-Content @setContentParams } +<# + .SYNOPSIS + Tests if the file encoding matches the expected value. + + .DESCRIPTION + Tests if the file encoding matches the expected value. + Note: This command returns a permissive test result for the presence or absence of a UTF8 BOM. + This means that if you expect "UTF8", the test will succeed with or without a BOM. + + .EXAMPLE + Test-FileEncodingEqual -FileEncoding 'UTF8BOM' -ExpectedEncoding 'UTF8' +#> +function Test-FileEncodingEqual +{ + [CmdletBinding()] + [OutputType([bool])] + param ( + [Parameter(Mandatory)] + [System.String] + $FileEncoding, + + [Parameter(Mandatory)] + [System.String] + $ExpectedEncoding + ) + + ($ExpectedEncoding -eq $FileEncoding) -or ` + ($ExpectedEncoding -eq 'UTF8' -and $FileEncoding -like 'UTF8*') -or ` + ($ExpectedEncoding -eq 'UTF8NoBOM' -and $FileEncoding -eq 'ASCII') +} + Export-ModuleMember -Function @( 'Get-TextEolCharacter', 'Set-IniSettingFileValue', 'Get-IniSettingFileValue', 'Get-FileEncoding', 'Get-FileContent', - 'Set-TextContent' + 'Set-TextContent', + 'Test-FileEncodingEqual' ) diff --git a/tests/Unit/FileContentDsc.Common.tests.ps1 b/tests/Unit/FileContentDsc.Common.tests.ps1 index 2940e2a..d520495 100644 --- a/tests/Unit/FileContentDsc.Common.tests.ps1 +++ b/tests/Unit/FileContentDsc.Common.tests.ps1 @@ -265,4 +265,82 @@ InModuleScope $script:subModuleName { } } } + + Describe 'FileContentDsc.Common\Test-FileEncodingEqual' { + $testSuccessCases = @( + @{ + file = 'ASCII' + expect = 'ASCII' + }, + @{ + file = 'BigEndianUnicode' + expect = 'BigEndianUnicode' + }, + @{ + file = 'UTF8BOM' + expect = 'UTF8BOM' + }, + @{ + file = 'UTF8BOM' + expect = 'UTF8' + }, + @{ + file = 'ASCII' + expect = 'UTF8NoBOM' + } + ) + + $testFailCases = @( + @{ + file = 'ASCII' + expect = 'BigEndianUnicode' + }, + @{ + file = 'ASCII' + expect = 'UTF8BOM' + }, + @{ + file = 'UTF8BOM' + expect = 'UTF8NoBOM' + }, + @{ + file = 'UTF8BOM' + expect = 'UTF32' + } + ) + + Context 'When the file encoding matches the expected.' { + It "Should return True when the file is '' and expected is ''" -TestCases $testSuccessCases { + param + ( + [Parameter()] + [System.String] + $File, + + [Parameter()] + [System.String] + $Expect + ) + + Test-FileEncodingEqual -FileEncoding $File -ExpectedEncoding $Expect | Should -BeTrue + } + } + + Context 'When the file encoding does not matche the expected.' { + It "Should return False when the file is '' and expected is ''" -TestCases $testFailCases { + param + ( + [Parameter()] + [System.String] + $File, + + [Parameter()] + [System.String] + $Expect + ) + + Test-FileEncodingEqual -FileEncoding $File -ExpectedEncoding $Expect | Should -BeFalse + } + } + } } From dffcaaecc86b3851e3a7938ff96f9dcbfa1d0f50 Mon Sep 17 00:00:00 2001 From: mkht Date: Sun, 27 Oct 2024 15:54:27 +0900 Subject: [PATCH 7/8] Format codes --- .../FileContentDsc.Common.psm1 | 6 +-- tests/Unit/FileContentDsc.Common.tests.ps1 | 48 +++++++++---------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/source/Modules/FileContentDsc.Common/FileContentDsc.Common.psm1 b/source/Modules/FileContentDsc.Common/FileContentDsc.Common.psm1 index 344c9a1..6255849 100644 --- a/source/Modules/FileContentDsc.Common/FileContentDsc.Common.psm1 +++ b/source/Modules/FileContentDsc.Common/FileContentDsc.Common.psm1 @@ -5,7 +5,7 @@ Import-Module -Name (Join-Path -Path $modulePath -ChildPath 'DscResource.Common' $script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' # Add the types for reading/writing INI files -Add-Type -TypeDefinition @" +Add-Type -TypeDefinition @' using System.IO; using System.Runtime.InteropServices; using System.Text; @@ -36,7 +36,7 @@ Add-Type -TypeDefinition @" return sb.ToString(); } } -"@ +'@ <# .SYNOPSIS @@ -251,7 +251,7 @@ function Get-FileContent $GetContentParam = @{ Path = $Path - Raw = $true + Raw = $true } if ($Encoding -like 'UTF8*') diff --git a/tests/Unit/FileContentDsc.Common.tests.ps1 b/tests/Unit/FileContentDsc.Common.tests.ps1 index d520495..d7419b4 100644 --- a/tests/Unit/FileContentDsc.Common.tests.ps1 +++ b/tests/Unit/FileContentDsc.Common.tests.ps1 @@ -121,44 +121,44 @@ InModuleScope $script:subModuleName { $testTextFile = "$TestDrive\TestFile.txt" $testCases = @( @{ - encoding = 'ASCII' - value = [byte[]](97, 98, 99) - expect = 'abc' + encoding = 'ASCII' + value = [byte[]](97, 98, 99) + expect = 'abc' }, @{ - encoding = 'BigEndianUnicode' - value = [byte[]](254, 255, 0, 97, 0, 98, 0, 99) - expect = 'abc' + encoding = 'BigEndianUnicode' + value = [byte[]](254, 255, 0, 97, 0, 98, 0, 99) + expect = 'abc' }, @{ - encoding = 'BigEndianUTF32' - value = [byte[]](0, 0, 254, 255, 0, 0, 0, 97, 0, 0, 0, 98, 0, 0, 0, 99) - expect = 'abc' + encoding = 'BigEndianUTF32' + value = [byte[]](0, 0, 254, 255, 0, 0, 0, 97, 0, 0, 0, 98, 0, 0, 0, 99) + expect = 'abc' }, @{ - encoding = 'UTF8' - value = [byte[]](239, 187, 191, 97, 98, 99) - expect = 'abc' + encoding = 'UTF8' + value = [byte[]](239, 187, 191, 97, 98, 99) + expect = 'abc' }, @{ - encoding = 'UTF8BOM' - value = [byte[]](239, 187, 191, 97, 98, 99) - expect = 'abc' + encoding = 'UTF8BOM' + value = [byte[]](239, 187, 191, 97, 98, 99) + expect = 'abc' }, @{ - encoding = 'UTF8NoBOM' - value = [byte[]](97, 98, 99, 226, 157, 164) - expect = 'abc' + encoding = 'UTF8NoBOM' + value = [byte[]](97, 98, 99, 226, 157, 164) + expect = 'abc' }, @{ - encoding = 'UTF32' - value = [byte[]](255, 254, 0, 0, 97, 0, 0, 0, 98, 0, 0, 0, 99, 0, 0, 0) - expect = 'abc' + encoding = 'UTF32' + value = [byte[]](255, 254, 0, 0, 97, 0, 0, 0, 98, 0, 0, 0, 99, 0, 0, 0) + expect = 'abc' }, @{ - encoding = '' # Not specified - value = [byte[]](97, 98, 99) - expect = 'abc' + encoding = '' # Not specified + value = [byte[]](97, 98, 99) + expect = 'abc' } ) From d30f23cc9182a325752989a540f44cabccf39094 Mon Sep 17 00:00:00 2001 From: mkht Date: Sun, 27 Oct 2024 16:12:23 +0900 Subject: [PATCH 8/8] Fix incorrect parameters --- .../FileContentDsc.Common/FileContentDsc.Common.psm1 | 8 ++++---- tests/Unit/FileContentDsc.Common.tests.ps1 | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/source/Modules/FileContentDsc.Common/FileContentDsc.Common.psm1 b/source/Modules/FileContentDsc.Common/FileContentDsc.Common.psm1 index 6255849..45e70b8 100644 --- a/source/Modules/FileContentDsc.Common/FileContentDsc.Common.psm1 +++ b/source/Modules/FileContentDsc.Common/FileContentDsc.Common.psm1 @@ -256,11 +256,11 @@ function Get-FileContent if ($Encoding -like 'UTF8*') { - $GetContentParam = 'UTF8' + $GetContentParam.Encoding = 'UTF8' } elseif (-not [string]::IsNullOrEmpty($Encoding)) { - $GetContentParam = $Encoding + $GetContentParam.Encoding = $Encoding } Get-Content @GetContentParam @@ -368,11 +368,11 @@ function Test-FileEncodingEqual [CmdletBinding()] [OutputType([bool])] param ( - [Parameter(Mandatory)] + [Parameter(Mandatory = $true)] [System.String] $FileEncoding, - [Parameter(Mandatory)] + [Parameter(Mandatory = $true)] [System.String] $ExpectedEncoding ) diff --git a/tests/Unit/FileContentDsc.Common.tests.ps1 b/tests/Unit/FileContentDsc.Common.tests.ps1 index d7419b4..8958aff 100644 --- a/tests/Unit/FileContentDsc.Common.tests.ps1 +++ b/tests/Unit/FileContentDsc.Common.tests.ps1 @@ -147,7 +147,7 @@ InModuleScope $script:subModuleName { }, @{ encoding = 'UTF8NoBOM' - value = [byte[]](97, 98, 99, 226, 157, 164) + value = [byte[]](97, 98, 99) expect = 'abc' }, @{