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 '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
    }
}