Public/Tests/Edit-StringAtLine.Tests.ps1
|
BeforeAll { $env:TCS_CONFIG_ROOT = Join-Path -Path $TestDrive -ChildPath 'config' $env:TCS_SKIP_UPDATE_CHECK = '1' $env:TCS_TELEMETRY_OPTOUT = '1' $ModuleRoot = Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent Import-Module -Name (Join-Path -Path $ModuleRoot -ChildPath 'tcs.utils.psd1') -Force } AfterAll { Remove-Module -Name tcs.utils -Force -ErrorAction SilentlyContinue } Describe 'Edit-StringAtLine' { It 'Replaces only the first match' { 'a two b two' | Edit-StringAtLine -StringToMatch 'two' -ReplacementString 'X' | Should -BeExactly 'a X b two' } It 'Treats StringToMatch as a regular expression' { 'Version = 1.0' | Edit-StringAtLine -StringToMatch '\d+\.\d+' -ReplacementString '2.0' | Should -BeExactly 'Version = 2.0' } It 'Inserts the replacement literally (no $ substitutions)' { 'cost' | Edit-StringAtLine -StringToMatch 'cost' -ReplacementString '$5 $0' | Should -BeExactly '$5 $0' } It 'Replaces on the correct line of multi-line input' { $result = "one`ntwo`nthree" | Edit-StringAtLine -StringToMatch 'two' -ReplacementString 'TWO' -Multiline $result | Should -Be @('one', 'TWO', 'three') } It 'Indents additional replacement lines to the column of the match' { $result = "one`n key = old`nthree" | Edit-StringAtLine -StringToMatch 'key = old' -ReplacementString "key = new`nother = 1" -Multiline $result | Should -Be @('one', ' key = new', ' other = 1', 'three') } It 'Joins lines with CRLF when -Multiline is not used' { "a`nb" | Edit-StringAtLine -StringToMatch 'b' -ReplacementString 'B' | Should -BeExactly "a`r`nB" } It 'Returns the input unchanged when there is no match' { 'nothing here' | Edit-StringAtLine -StringToMatch 'zzz' -ReplacementString 'x' | Should -BeExactly 'nothing here' "a`nb" | Edit-StringAtLine -StringToMatch 'zzz' -ReplacementString 'x' -Multiline | Should -Be @('a', 'b') } It 'Handles a match at the very start of the input' { "abc`ndef" | Edit-StringAtLine -StringToMatch 'abc' -ReplacementString "X`nY" -Multiline | Should -Be @('X', 'Y', 'def') } It 'Processes each piped string' { 'a1', 'b1' | Edit-StringAtLine -StringToMatch '1' -ReplacementString '2' | Should -Be @('a2', 'b2') } It 'Accepts InputString by property name' { [PSCustomObject]@{ InputString = 'hello world' } | Edit-StringAtLine -StringToMatch 'world' -ReplacementString 'there' | Should -BeExactly 'hello there' } It 'Requires StringToMatch' { (Get-Command -Name Edit-StringAtLine).Parameters['StringToMatch'].Attributes.Where({ $_ -is [System.Management.Automation.ParameterAttribute] }).Mandatory | Should -BeTrue } Context 'Telemetry' { BeforeAll { Mock -ModuleName tcs.utils Invoke-TelemetryCollection { } } It 'Sends one Start and one End event for piped input' { 'a1', 'b1' | Edit-StringAtLine -StringToMatch '1' -ReplacementString '2' | Should -Be @('a2', 'b2') Should -Invoke -ModuleName tcs.utils Invoke-TelemetryCollection -Times 1 -Exactly -ParameterFilter { $Stage -eq 'Start' -and $CommandName -eq 'Edit-StringAtLine' } Should -Invoke -ModuleName tcs.utils Invoke-TelemetryCollection -Times 1 -Exactly -ParameterFilter { $Stage -eq 'End' -and -not $Failed } } It 'Sends one failed End event and still throws for an invalid regular expression' { { 'a(', 'b(' | Edit-StringAtLine -StringToMatch '(' -ReplacementString 'x' } | Should -Throw Should -Invoke -ModuleName tcs.utils Invoke-TelemetryCollection -Times 1 -Exactly -ParameterFilter { $Stage -eq 'End' -and $Failed -eq $true } Should -Invoke -ModuleName tcs.utils Invoke-TelemetryCollection -Times 0 -Exactly -ParameterFilter { $Stage -eq 'End' -and -not $Failed } } } } |