Public/Tests/Convert-ModuleNameAndReferences.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 'Convert-ModuleNameAndReferences' { BeforeEach { $Source = Join-Path -Path $TestDrive -ChildPath ([guid]::NewGuid().ToString('N')) $ModuleSource = Join-Path -Path $Source -ChildPath 'abc.demo' $null = New-Item -Path (Join-Path -Path $ModuleSource -ChildPath 'Public') -ItemType Directory -Force Set-Content -Path (Join-Path -Path $ModuleSource -ChildPath 'abc.demo.psd1') -Value "@{ RootModule = 'abc.demo.psm1' }" -NoNewline Set-Content -Path (Join-Path -Path $ModuleSource -ChildPath 'abc.demo.psm1') -Value "# abc.demo loader`n" -NoNewline Set-Content -Path (Join-Path -Path $ModuleSource -ChildPath 'Public/Get-AbcThing.ps1') -Value "function Get-AbcThing { 'abc.demo' }" -NoNewline [System.IO.File]::WriteAllBytes((Join-Path -Path $ModuleSource -ChildPath 'icon.png'), [byte[]](0x89, 0x50, 0x00, 0x01, 0xFF)) $Output = Join-Path -Path $Source -ChildPath 'out' } It 'Copies the module under the new name and renames files named after the module' { Convert-ModuleNameAndReferences -ModulePaths $ModuleSource -OutputPath $Output -ReplaceFirstSegmentWith 'tcs' $destination = Join-Path -Path $Output -ChildPath 'tcs.demo' Test-Path -Path (Join-Path -Path $destination -ChildPath 'tcs.demo.psd1') | Should -BeTrue Test-Path -Path (Join-Path -Path $destination -ChildPath 'tcs.demo.psm1') | Should -BeTrue Test-Path -Path (Join-Path -Path $destination -ChildPath 'abc.demo.psd1') | Should -BeFalse } It 'Updates references and function names inside files without adding line breaks' { Convert-ModuleNameAndReferences -ModulePaths $ModuleSource -OutputPath $Output -ReplaceFirstSegmentWith 'tcs' $destination = Join-Path -Path $Output -ChildPath 'tcs.demo' Get-Content -Path (Join-Path -Path $destination -ChildPath 'tcs.demo.psd1') -Raw | Should -BeExactly "@{ RootModule = 'tcs.demo.psm1' }" Get-Content -Path (Join-Path -Path $destination -ChildPath 'tcs.demo.psm1') -Raw | Should -BeExactly "# tcs.demo loader`n" $functionFile = Join-Path -Path $destination -ChildPath 'Public/Get-TcsThing.ps1' Test-Path -Path $functionFile | Should -BeTrue Get-Content -Path $functionFile -Raw | Should -BeExactly "function Get-TcsThing { 'tcs.demo' }" } It 'Renames calls to the renamed functions, not only their definitions' { Set-Content -Path (Join-Path -Path $ModuleSource -ChildPath 'Public/Get-AbcWidget.ps1') -NoNewline -Value @' function Get-AbcWidget { # Calls Get-AbcHelper, not Get-AbcHelperX $helper = Get-AbcHelper & Get-AbcHelper | ForEach-Object { Get-AbcThing } $GetAbcHelper = 'Get-AbcHelperX' Write-Verbose "Using Get-AbcHelper" } '@ Set-Content -Path (Join-Path -Path $ModuleSource -ChildPath 'Public/helpers.ps1') -Value 'function Get-AbcHelper { }' -NoNewline Set-Content -Path (Join-Path -Path $ModuleSource -ChildPath 'abc.demo.psd1') -Value "@{ RootModule = 'abc.demo.psm1'; FunctionsToExport = @('Get-AbcThing', 'Get-AbcWidget') }" -NoNewline Set-Content -Path (Join-Path -Path $ModuleSource -ChildPath 'README.md') -Value "Run Get-AbcWidget (not Get-AbcWidgets).`n" -NoNewline Convert-ModuleNameAndReferences -ModulePaths $ModuleSource -OutputPath $Output -ReplaceFirstSegmentWith 'tcs' $destination = Join-Path -Path $Output -ChildPath 'tcs.demo' Get-Content -Path (Join-Path -Path $destination -ChildPath 'Public/Get-TcsWidget.ps1') -Raw | Should -BeExactly @' function Get-TcsWidget { # Calls Get-TcsHelper, not Get-AbcHelperX $helper = Get-TcsHelper & Get-TcsHelper | ForEach-Object { Get-TcsThing } $GetAbcHelper = 'Get-AbcHelperX' Write-Verbose "Using Get-TcsHelper" } '@ Get-Content -Path (Join-Path -Path $destination -ChildPath 'Public/helpers.ps1') -Raw | Should -BeExactly 'function Get-TcsHelper { }' Get-Content -Path (Join-Path -Path $destination -ChildPath 'tcs.demo.psd1') -Raw | Should -BeExactly "@{ RootModule = 'tcs.demo.psm1'; FunctionsToExport = @('Get-TcsThing', 'Get-TcsWidget') }" Get-Content -Path (Join-Path -Path $destination -ChildPath 'README.md') -Raw | Should -BeExactly "Run Get-TcsWidget (not Get-AbcWidgets).`n" } It 'Keeps the byte order mark of each file' { # '# <e-acute> abc.demo' with a BOM, and an ASCII function file without one $utf8Bom = New-Object -TypeName System.Text.UTF8Encoding -ArgumentList $true [System.IO.File]::WriteAllText((Join-Path -Path $ModuleSource -ChildPath 'Public/accent.ps1'), "# $([char]0x00E9) abc.demo", $utf8Bom) Convert-ModuleNameAndReferences -ModulePaths $ModuleSource -OutputPath $Output -ReplaceFirstSegmentWith 'tcs' $destination = Join-Path -Path $Output -ChildPath 'tcs.demo' [System.IO.File]::ReadAllBytes((Join-Path -Path $destination -ChildPath 'Public/accent.ps1')) | Should -Be ([byte[]](0xEF, 0xBB, 0xBF) + $utf8Bom.GetBytes("# $([char]0x00E9) tcs.demo")) $bytes = [System.IO.File]::ReadAllBytes((Join-Path -Path $destination -ChildPath 'Public/Get-TcsThing.ps1')) [System.Text.Encoding]::ASCII.GetString($bytes) | Should -BeExactly "function Get-TcsThing { 'tcs.demo' }" } It 'Copies binary files unchanged' { Convert-ModuleNameAndReferences -ModulePaths $ModuleSource -OutputPath $Output -ReplaceFirstSegmentWith 'tcs' $bytes = [System.IO.File]::ReadAllBytes((Join-Path -Path $Output -ChildPath 'tcs.demo/icon.png')) $bytes | Should -Be ([byte[]](0x89, 0x50, 0x00, 0x01, 0xFF)) } It 'Copies without renaming when no replacement is given' { Convert-ModuleNameAndReferences -ModulePaths $ModuleSource -OutputPath $Output Test-Path -Path (Join-Path -Path $Output -ChildPath 'abc.demo/abc.demo.psd1') | Should -BeTrue Test-Path -Path (Join-Path -Path $Output -ChildPath 'abc.demo/Public/Get-AbcThing.ps1') | Should -BeTrue } It 'Refuses to overwrite an existing destination without -Force' { Convert-ModuleNameAndReferences -ModulePaths $ModuleSource -OutputPath $Output -ReplaceFirstSegmentWith 'tcs' Convert-ModuleNameAndReferences -ModulePaths $ModuleSource -OutputPath $Output -ReplaceFirstSegmentWith 'tcs' -ErrorVariable conversionErrors -ErrorAction SilentlyContinue $conversionErrors | Should -Not -BeNullOrEmpty { Convert-ModuleNameAndReferences -ModulePaths $ModuleSource -OutputPath $Output -ReplaceFirstSegmentWith 'tcs' -Force -ErrorAction Stop } | Should -Not -Throw } It 'Warns and continues when a module path does not exist' { Convert-ModuleNameAndReferences -ModulePaths (Join-Path -Path $Source -ChildPath 'missing') -OutputPath $Output -WarningVariable conversionWarnings -WarningAction SilentlyContinue $conversionWarnings | Should -Not -BeNullOrEmpty } It 'Makes no changes with -WhatIf' { Convert-ModuleNameAndReferences -ModulePaths $ModuleSource -OutputPath $Output -ReplaceFirstSegmentWith 'tcs' -WhatIf Test-Path -Path $Output | Should -BeFalse } } |