diff --git a/tests/Build-PSBuildMarkdown.tests.ps1 b/tests/Build-PSBuildMarkdown.tests.ps1 new file mode 100644 index 0000000..324cd7d --- /dev/null +++ b/tests/Build-PSBuildMarkdown.tests.ps1 @@ -0,0 +1,103 @@ +Describe 'Build-PSBuildMarkdown' { + BeforeAll { + . "$PSScriptRoot/../PowerShellBuild/Public/Build-PSBuildMarkdown.ps1" + } + + BeforeEach { + $script:LocalizedData = @{ + NoCommandsExported = 'No commands exported.' + FailedToGenerateMarkdownHelp = 'Failed to generate markdown help: {0}' + } + + $script:newMarkdownParams = $null + $script:updateMarkdownParams = @() + } + + It 'warns and exits when module exports no commands' { + Mock Import-Module { + [pscustomobject]@{ ExportedCommands = @() } + } + Mock Write-Warning {} + Mock New-MarkdownHelp {} + Mock Remove-Module {} + + Build-PSBuildMarkdown \ + -ModulePath '/tmp/module' \ + -ModuleName 'MyModule' \ + -DocsPath '/tmp/docs' \ + -Locale 'en-US' \ + -Overwrite:$false \ + -AlphabeticParamsOrder:$true \ + -ExcludeDontShow:$false \ + -UseFullTypeName:$false + + Should -Invoke Write-Warning -Times 1 + Should -Invoke New-MarkdownHelp -Times 0 + Should -Invoke Remove-Module -Times 1 -ParameterFilter { $Name -eq 'MyModule' } + } + + It 'generates markdown help without force when overwrite is false' { + Mock Import-Module { + [pscustomobject]@{ ExportedCommands = @{ Test = 'Test-Command' } } + } + Mock Test-Path { $false } + Mock New-Item {} + Mock Get-ChildItem { @() } + Mock New-MarkdownHelp { + $script:newMarkdownParams = $PSBoundParameters + } + Mock Remove-Module {} + + Build-PSBuildMarkdown \ + -ModulePath '/tmp/module' \ + -ModuleName 'MyModule' \ + -DocsPath '/tmp/docs' \ + -Locale 'en-US' \ + -Overwrite:$false \ + -AlphabeticParamsOrder:$true \ + -ExcludeDontShow:$true \ + -UseFullTypeName:$false + + Should -Invoke New-Item -Times 1 -ParameterFilter { $Path -eq '/tmp/docs' -and $ItemType -eq 'Directory' } + $script:newMarkdownParams.Module | Should -Be 'MyModule' + $script:newMarkdownParams.Locale | Should -Be 'en-US' + $script:newMarkdownParams.OutputFolder | Should -Be ([IO.Path]::Combine('/tmp/docs', 'en-US')) + $script:newMarkdownParams.ErrorAction | Should -Be 'SilentlyContinue' + $script:newMarkdownParams.ContainsKey('Force') | Should -BeFalse + } + + It 'updates existing markdown and forces generation when overwrite is true' { + Mock Import-Module { + [pscustomobject]@{ ExportedCommands = @{ Test = 'Test-Command' } } + } + Mock Test-Path { $true } + Mock Get-ChildItem { + @('existing.md') + } -ParameterFilter { $LiteralPath -eq '/tmp/docs' -and $Filter -eq '*.md' -and $Recurse } + Mock Get-ChildItem { + @([pscustomobject]@{ FullName = '/tmp/docs/en-US' }) + } -ParameterFilter { $LiteralPath -eq '/tmp/docs' -and $Directory } + Mock Update-MarkdownHelp { + $script:updateMarkdownParams += $PSBoundParameters + } + Mock New-MarkdownHelp { + $script:newMarkdownParams = $PSBoundParameters + } + Mock Remove-Module {} + + Build-PSBuildMarkdown \ + -ModulePath '/tmp/module' \ + -ModuleName 'MyModule' \ + -DocsPath '/tmp/docs' \ + -Locale 'en-US' \ + -Overwrite:$true \ + -AlphabeticParamsOrder:$false \ + -ExcludeDontShow:$false \ + -UseFullTypeName:$true + + Should -Invoke Update-MarkdownHelp -Times 1 -ParameterFilter { $Path -eq '/tmp/docs/en-US' } + $script:newMarkdownParams.ContainsKey('Force') | Should -BeTrue + $script:newMarkdownParams.Force | Should -BeTrue + $script:newMarkdownParams.ContainsKey('ErrorAction') | Should -BeFalse + } +} diff --git a/tests/Build-PSBuildModule.tests.ps1 b/tests/Build-PSBuildModule.tests.ps1 new file mode 100644 index 0000000..0a454a6 --- /dev/null +++ b/tests/Build-PSBuildModule.tests.ps1 @@ -0,0 +1,76 @@ +Describe 'Build-PSBuildModule' { + BeforeAll { + . "$PSScriptRoot/../PowerShellBuild/Public/Build-PSBuildModule.ps1" + } + + BeforeEach { + $script:LocalizedData = @{ + AddingFileToPsm1 = 'Adding file {0}' + } + } + + It 'copies README into culture about-help file when ReadMePath is provided' { + Mock Test-Path { + if ($LiteralPath -eq '/tmp/out') { return $false } + if ($Path -eq '/tmp/out/en-US' -and $PathType -eq 'Container') { return $false } + return $false + } + Mock New-Item {} + Mock Get-ChildItem { @() } + Mock Copy-Item {} + Mock Update-Metadata {} + + Build-PSBuildModule \ + -Path '/tmp/src' \ + -DestinationPath '/tmp/out' \ + -ModuleName 'TestModule' \ + -ReadMePath '/tmp/src/README.md' \ + -Culture 'en-US' + + Should -Invoke New-Item -Times 1 -ParameterFilter { $Path -eq '/tmp/out' -and $ItemType -eq 'Directory' } + Should -Invoke New-Item -Times 1 -ParameterFilter { $Path -eq '/tmp/out/en-US' -and $Type -eq 'Directory' -and $Force } + Should -Invoke Copy-Item -Times 1 -ParameterFilter { + $LiteralPath -eq '/tmp/src/README.md' -and + $Destination -eq '/tmp/out/en-US/about_TestModule.help.txt' -and + $Force + } + } + + It 'updates manifest FunctionsToExport from Public/*.ps1 basenames' { + Mock Test-Path { $true } + Mock Copy-Item {} + Mock Remove-Item {} + Mock Update-Metadata {} + + Mock Get-ChildItem { + @() + } -ParameterFilter { $Path -eq '/tmp/src' -and $Include -contains '*.psm1' } + + Mock Get-ChildItem { + @( + [pscustomobject]@{ Name = 'skip.tmp'; FullName = '/tmp/out/skip.tmp' } + ) + } -ParameterFilter { $Path -eq '/tmp/out' -and $Recurse } + + Mock Get-ChildItem { + @( + [pscustomobject]@{ BaseName = 'Get-Foo' }, + [pscustomobject]@{ BaseName = 'Set-Bar' } + ) + } -ParameterFilter { $Path -eq '/tmp/src/Public/*.ps1' -and $Recurse } + + Build-PSBuildModule \ + -Path '/tmp/src' \ + -DestinationPath '/tmp/out' \ + -ModuleName 'TestModule' \ + -Exclude @('\\.tmp$') + + Should -Invoke Update-Metadata -Times 1 -ParameterFilter { + $Path -eq '/tmp/out/TestModule.psd1' -and + $PropertyName -eq 'FunctionsToExport' -and + $Value.Count -eq 2 -and + $Value[0] -eq 'Get-Foo' -and + $Value[1] -eq 'Set-Bar' + } + } +} diff --git a/tests/Build-PSBuildUpdatableHelp.tests.ps1 b/tests/Build-PSBuildUpdatableHelp.tests.ps1 new file mode 100644 index 0000000..34ee470 --- /dev/null +++ b/tests/Build-PSBuildUpdatableHelp.tests.ps1 @@ -0,0 +1,87 @@ +Describe 'Build-PSBuildUpdatableHelp' { + BeforeAll { + . "$PSScriptRoot/../PowerShellBuild/Public/Build-PSBuildUpdatableHelp.ps1" + } + + BeforeEach { + $script:LocalizedData = @{ + MakeCabNotAvailable = 'MakeCab not available on this platform.' + DirectoryAlreadyExists = 'Directory {0} already exists.' + } + + $script:ModuleName = 'PSBuildModule' + $script:moduleOutDir = '/tmp/module-out' + $script:newCabCalls = @() + } + + It 'warns and exits early when running on non-Windows hosts' { + Mock Write-Warning {} + Mock Get-ChildItem { throw 'should not be called' } + Mock New-Item {} + Mock New-ExternalHelpCab {} + + $script:IsWindows = $false + + Build-PSBuildUpdatableHelp -DocsPath '/tmp/docs' -OutputPath '/tmp/out' + + Should -Invoke Write-Warning -Times 1 -ParameterFilter { $Message -eq 'MakeCab not available on this platform.' } + Should -Invoke Get-ChildItem -Times 0 + Should -Invoke New-ExternalHelpCab -Times 0 + } + + It 'creates output folder and generates one cab per locale on Windows' { + Mock Test-Path { $false } + Mock New-Item {} + Mock Get-ChildItem { + @( + [pscustomobject]@{ Name = 'en-US' }, + [pscustomobject]@{ Name = 'fr-FR' } + ) + } -ParameterFilter { $Path -eq '/tmp/docs' -and $Directory } + Mock New-ExternalHelpCab { + $script:newCabCalls += $PSBoundParameters + } + + $script:IsWindows = $true + + Build-PSBuildUpdatableHelp -DocsPath '/tmp/docs' -OutputPath '/tmp/out' -Module 'MyModule' + + Should -Invoke New-Item -Times 1 -ParameterFilter { $Path -eq '/tmp/out' -and $ItemType -eq 'Directory' } + $script:newCabCalls.Count | Should -Be 2 + + $script:newCabCalls[0].CabFilesFolder | Should -Be ([IO.Path]::Combine('/tmp/module-out', 'en-US')) + $script:newCabCalls[0].LandingPagePath | Should -Be ([IO.Path]::Combine('/tmp/docs', 'en-US', 'MyModule.md')) + $script:newCabCalls[0].OutputFolder | Should -Be '/tmp/out' + + $script:newCabCalls[1].CabFilesFolder | Should -Be ([IO.Path]::Combine('/tmp/module-out', 'fr-FR')) + $script:newCabCalls[1].LandingPagePath | Should -Be ([IO.Path]::Combine('/tmp/docs', 'fr-FR', 'MyModule.md')) + $script:newCabCalls[1].OutputFolder | Should -Be '/tmp/out' + } + + It 'cleans existing output folder before generating cabs on Windows' { + Mock Test-Path { $true } + Mock Get-ChildItem { + @( + [pscustomobject]@{ Name = 'en-US' } + ) + } -ParameterFilter { $Path -eq '/tmp/docs' -and $Directory } + Mock Get-ChildItem { + @( + [pscustomobject]@{ FullName = '/tmp/out/existing.cab' } + ) + } -ParameterFilter { $Path -eq '/tmp/out' } + Mock Remove-Item {} + Mock New-ExternalHelpCab { + $script:newCabCalls += $PSBoundParameters + } + Mock Write-Verbose {} + + $script:IsWindows = $true + + Build-PSBuildUpdatableHelp -DocsPath '/tmp/docs' -OutputPath '/tmp/out' -Module 'MyModule' + + Should -Invoke Write-Verbose -Times 1 + Should -Invoke Remove-Item -Times 1 -ParameterFilter { $Recurse -and $Force } + Should -Invoke New-ExternalHelpCab -Times 1 + } +}