Skip to content

Commit b7543dc

Browse files
committed
feat(#206): mirror public command tests
Add focused, dot-source-first Pester tests under tests/public/ for every public command (Invoke-NovaBuild, Test-NovaBuild, New-NovaModulePackage, Initialize-NovaModule, Get-NovaProjectInfo, Get-/Set-NovaUpdateNotificationPreference, Install-NovaCli, Invoke-NovaCli, Update-NovaModuleTool, Update-NovaModuleVersion, Deploy-NovaPackage, Publish-NovaModule, Invoke-NovaRelease). Tests stay command-focused: parameter forwarding, delegation to context/workflow helpers, and ShouldProcess / -WhatIf behavior, without duplicating private helper coverage. Closes Migrate public command tests (7) Fixes #206
1 parent 3f7b93c commit b7543dc

15 files changed

Lines changed: 457 additions & 0 deletions

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
2727
- Added mirrored, dot-source-first Pester test files for CLI private helpers (`src/private/cli/*.ps1`), so most CLI argument parsers, prompt helpers, and per-command CLI wrappers now have a focused test file under `tests/private/cli/`. Large cross-cutting CLI orchestrators (`InvokeNovaCliCommandRoute.ps1`, `GetNovaCliArgumentRoutingState.ps1`, `FormatNovaCliCommandHelp.ps1`, `ConfirmNovaCliAction.ps1`, `GetNovaCliInvocationContext.ps1`) stay covered by the existing cross-cutting CLI tests.
2828
- Added mirrored, dot-source-first Pester test files for release private helpers (`src/private/release/*.ps1`), so most release, publish, and version-update helpers (local publish path resolution, publish parameter mapping, version label inference, version part calculation, prerelease label handling, release request shaping, and per-step write/import helpers) now have a focused test file under `tests/private/release/`. Multi-step release/publish/version-update workflow orchestrators (`InvokeNovaReleaseWorkflow.ps1`, `InvokeNovaPublishWorkflow.ps1`, `GetNovaVersionUpdateWorkflowContext.ps1`) stay covered by the existing cross-cutting release tests.
2929
- Added mirrored, dot-source-first Pester test files for package private helpers (`src/private/package/*.ps1`), so most package metadata, archive-content, NuGet/Zip artifact, upload option, upload target, upload header/auth, upload file-resolution, upload request, and per-type upload helpers now have a focused test file under `tests/private/package/`. Multi-step package workflow orchestrators (`InvokeNovaPackageWorkflow.ps1`, `InvokeNovaPackageUploadWorkflow.ps1`, `GetNovaPackageWorkflowContext.ps1`, `GetNovaPackageUploadWorkflowContext.ps1`, `InvokeNovaPackageArtifactCreation.ps1`, `NewNovaPackageArtifacts.ps1`) stay covered by the existing cross-cutting package tests.
30+
- Added mirrored, dot-source-first Pester test files for every public command (`src/public/*.ps1`), so each command (`Invoke-NovaBuild`, `Test-NovaBuild`, `New-NovaModulePackage`, `Initialize-NovaModule`, `Get-NovaProjectInfo`, `Get-/Set-NovaUpdateNotificationPreference`, `Install-NovaCli`, `Invoke-NovaCli`, `Update-NovaModuleTool`, `Update-NovaModuleVersion`, `Deploy-NovaPackage`, `Publish-NovaModule`, `Invoke-NovaRelease`) now has a focused command-surface test under `tests/public/` covering parameter forwarding, delegation to its workflow context/workflow helpers, and `ShouldProcess` / `-WhatIf` behavior without duplicating private helper coverage.
3031

3132

3233
### Changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
BeforeAll {
2+
$projectRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
3+
. (Join-Path $projectRoot 'src/public/DeployNovaPackage.ps1')
4+
5+
function New-NovaPackageUploadDynamicParameterDictionary {return New-Object 'System.Management.Automation.RuntimeDefinedParameterDictionary'}
6+
function Get-NovaProjectInfo {return [pscustomobject]@{Name='X'}}
7+
function New-NovaPackageUploadOption {param($BoundParameters) return [pscustomobject]@{BoundCount=$BoundParameters.Count}}
8+
function Get-NovaPackageUploadWorkflowContext {param($BoundParameters, $ProjectInfo, $UploadOption)
9+
return [pscustomobject]@{Target='https://x/repo'; Operation='Upload'; UploadArtifactList=@([pscustomobject]@{Name='a.nupkg'})}
10+
}
11+
function Invoke-NovaPackageUploadWorkflow {param($WorkflowContext, $UploadArtifactList)
12+
$script:invoked = $true
13+
return @([pscustomobject]@{StatusCode=201})
14+
}
15+
}
16+
17+
Describe 'Deploy-NovaPackage' {
18+
BeforeEach {$script:invoked = $false}
19+
20+
It 'invokes the upload workflow and returns its results' {
21+
$result = Deploy-NovaPackage -PackagePath '/o/a.nupkg' -Url 'https://x' -Repository 'Nexus'
22+
$script:invoked | Should -BeTrue
23+
@($result).Count | Should -Be 1
24+
$result[0].StatusCode | Should -Be 201
25+
}
26+
27+
It 'returns an empty array and does not invoke the workflow when -WhatIf is set' {
28+
$result = Deploy-NovaPackage -PackagePath '/o/a.nupkg' -WhatIf
29+
$script:invoked | Should -BeFalse
30+
@($result).Count | Should -Be 0
31+
}
32+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
BeforeAll {
2+
$projectRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
3+
. (Join-Path $projectRoot 'src/public/GetNovaProjectInfo.ps1')
4+
5+
function Get-NovaCliInstalledVersion {param($Module) return '1.2.3'}
6+
function Format-NovaCliVersionString {param($Name, $Version) return "$Name $Version"}
7+
function Get-NovaProjectInfoContext {param($Path) return [pscustomobject]@{Path=$Path}}
8+
function Get-NovaProjectInfoResult {param($WorkflowContext, [switch]$Version)
9+
if ($Version) {return '9.9.9'}
10+
return [pscustomobject]@{Name='X'; Path=$WorkflowContext.Path}
11+
}
12+
}
13+
14+
Describe 'Get-NovaProjectInfo' {
15+
It 'returns a formatted installed version when -Installed is set' {
16+
Get-NovaProjectInfo -Installed | Should -Match 'NovaModuleTools 1\.2\.3|.+1\.2\.3'
17+
}
18+
19+
It 'returns the project info result when -Version is not set' {
20+
$result = Get-NovaProjectInfo -Path '/proj'
21+
$result.Path | Should -Be '/proj'
22+
}
23+
24+
It 'returns the version string when -Version is set' {
25+
Get-NovaProjectInfo -Path '/proj' -Version | Should -Be '9.9.9'
26+
}
27+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
BeforeAll {
2+
$projectRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
3+
. (Join-Path $projectRoot 'src/public/GetNovaUpdateNotificationPreference.ps1')
4+
5+
function Get-NovaUpdateNotificationPreferenceStatus {return [pscustomobject]@{PrereleaseNotificationsEnabled=$true}}
6+
}
7+
8+
Describe 'Get-NovaUpdateNotificationPreference' {
9+
It 'returns the status from Get-NovaUpdateNotificationPreferenceStatus' {
10+
(Get-NovaUpdateNotificationPreference).PrereleaseNotificationsEnabled | Should -BeTrue
11+
}
12+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
BeforeAll {
2+
$projectRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
3+
. (Join-Path $projectRoot 'src/public/InitializeNovaModule.ps1')
4+
5+
function Get-NovaModuleInitializationWorkflowContext {param($Path, [switch]$Example)
6+
$script:ctxArgs = @{Path=$Path; Example=[bool]$Example}
7+
return [pscustomobject]@{Target=$Path; Action='Initialize'}
8+
}
9+
function Invoke-NovaModuleInitializationWorkflow {param($WorkflowContext) $script:workflowCalled = $true}
10+
}
11+
12+
Describe 'Initialize-NovaModule' {
13+
BeforeEach {$script:ctxArgs = $null; $script:workflowCalled = $false}
14+
15+
It 'forwards Path and Example to the workflow context' {
16+
Initialize-NovaModule -Path '/tmp/x' -Example
17+
$script:ctxArgs.Path | Should -Be '/tmp/x'
18+
$script:ctxArgs.Example | Should -BeTrue
19+
$script:workflowCalled | Should -BeTrue
20+
}
21+
22+
It 'returns without invoking the workflow when -WhatIf is set' {
23+
Initialize-NovaModule -Path '/tmp/x' -WhatIf
24+
$script:workflowCalled | Should -BeFalse
25+
}
26+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
BeforeAll {
2+
$projectRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
3+
. (Join-Path $projectRoot 'src/public/InstallNovaCli.ps1')
4+
5+
function Get-NovaCliInstallWorkflowContext {param($DestinationDirectory, [switch]$Force)
6+
$script:ctxArgs = @{Destination=$DestinationDirectory; Force=[bool]$Force}
7+
return [pscustomobject]@{TargetPath='/usr/local/bin/nova'; Action='Install'}
8+
}
9+
function Invoke-NovaCliInstallWorkflow {param($WorkflowContext)
10+
$script:invoked = $true
11+
return [pscustomobject]@{ReleaseNotesUri='https://x/rel'}
12+
}
13+
function Write-NovaModuleReleaseNotesLink {param($ReleaseNotesUri) $script:notesUri = $ReleaseNotesUri}
14+
}
15+
16+
Describe 'Install-NovaCli' {
17+
BeforeEach {$script:ctxArgs = $null; $script:invoked = $false; $script:notesUri = $null}
18+
19+
It 'forwards parameters and writes the release notes link' {
20+
$result = Install-NovaCli -DestinationDirectory '/dest' -Force
21+
$script:ctxArgs.Destination | Should -Be '/dest'
22+
$script:ctxArgs.Force | Should -BeTrue
23+
$script:invoked | Should -BeTrue
24+
$script:notesUri | Should -Be 'https://x/rel'
25+
$result.ReleaseNotesUri | Should -Be 'https://x/rel'
26+
}
27+
28+
It 'returns without invoking the workflow when -WhatIf is set' {
29+
Install-NovaCli -WhatIf
30+
$script:invoked | Should -BeFalse
31+
}
32+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
BeforeAll {
2+
$projectRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
3+
. (Join-Path $projectRoot 'src/public/InvokeNovaBuild.ps1')
4+
5+
function Get-NovaBuildWorkflowContext {param([switch]$ContinuousIntegrationRequested, [switch]$OverrideWarningRequested)
6+
$script:contextArgs = @{CI=[bool]$ContinuousIntegrationRequested; Override=[bool]$OverrideWarningRequested}
7+
return [pscustomobject]@{Target='/proj'; Operation='Build'}
8+
}
9+
function Invoke-NovaBuildWorkflow {param($WorkflowContext) $script:workflowCalled = $true}
10+
}
11+
12+
Describe 'Invoke-NovaBuild' {
13+
BeforeEach {
14+
$script:contextArgs = $null
15+
$script:workflowCalled = $false
16+
}
17+
18+
It 'forwards switch parameters to the workflow context' {
19+
Invoke-NovaBuild -ContinuousIntegration -OverrideWarning
20+
$script:contextArgs.CI | Should -BeTrue
21+
$script:contextArgs.Override | Should -BeTrue
22+
$script:workflowCalled | Should -BeTrue
23+
}
24+
25+
It 'skips the workflow when -WhatIf is set' {
26+
Invoke-NovaBuild -WhatIf
27+
$script:workflowCalled | Should -BeFalse
28+
}
29+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
BeforeAll {
2+
$projectRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
3+
. (Join-Path $projectRoot 'src/public/InvokeNovaCli.ps1')
4+
5+
function Get-NovaCliInvocationContext {param($InvocationRequest, [switch]$WhatIfEnabled)
6+
$script:request = $InvocationRequest
7+
return [pscustomobject]@{Request=$InvocationRequest; WhatIf=[bool]$WhatIfEnabled}
8+
}
9+
function Invoke-NovaCliCommandRoute {param($InvocationContext) return [pscustomobject]@{Routed=$true; Command=$InvocationContext.Request.Command}}
10+
}
11+
12+
Describe 'Invoke-NovaCli' {
13+
It 'defaults to --help when no command is provided' {
14+
(Invoke-NovaCli).Command | Should -Be '--help'
15+
}
16+
17+
It 'forwards command and remaining arguments to the invocation context' {
18+
Invoke-NovaCli 'build' '--ci' '--override-warning' | Out-Null
19+
$script:request.Command | Should -Be 'build'
20+
$script:request.Arguments | Should -Be @('--ci','--override-warning')
21+
}
22+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
BeforeAll {
2+
$projectRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
3+
. (Join-Path $projectRoot 'src/public/InvokeNovaRelease.ps1')
4+
5+
function Get-NovaDynamicReleaseParameterDictionary {return New-Object 'System.Management.Automation.RuntimeDefinedParameterDictionary'}
6+
function Get-NovaReleaseRequestedPath {param($BoundParameters) return (Get-Location).Path}
7+
function Get-NovaReleaseRequest {param($BoundParameters, $ParameterSetName)
8+
$script:parameterSet = $ParameterSetName
9+
return [pscustomobject]@{ParameterSetName=$ParameterSetName}
10+
}
11+
function Get-NovaReleasePublishOption {param($ReleaseParameters) return [pscustomobject]@{Local=$true}}
12+
function Get-NovaProjectInfo {return [pscustomobject]@{Name='X'}}
13+
function Get-NovaShouldProcessForwardingParameter {param([switch]$WhatIfEnabled) return @{WhatIf=[bool]$WhatIfEnabled}}
14+
function Get-NovaPublishWorkflowContext {param($ProjectInfo, $PublishOption, $WorkflowParams, $WorkflowSettings)
15+
$script:settings = $WorkflowSettings
16+
return [pscustomobject]@{Target='nuget.org'; Operation='Release'}
17+
}
18+
function Write-NovaPublishWorkflowContext {param($WorkflowContext) $script:wrote = $true}
19+
function Invoke-NovaReleaseWorkflow {param($WorkflowContext)
20+
$script:invoked = $true
21+
return [pscustomobject]@{Released=$true}
22+
}
23+
}
24+
25+
Describe 'Invoke-NovaRelease' {
26+
BeforeEach {
27+
$script:parameterSet = $null; $script:settings = $null
28+
$script:wrote = $false; $script:invoked = $false
29+
}
30+
31+
It 'runs the release workflow with release-flavored settings' {
32+
$result = Invoke-NovaRelease -Local
33+
$script:parameterSet | Should -Be 'Local'
34+
$script:settings.WorkflowName | Should -Be 'release'
35+
$script:settings.Release | Should -BeTrue
36+
$script:wrote | Should -BeTrue
37+
$script:invoked | Should -BeTrue
38+
$result.Released | Should -BeTrue
39+
}
40+
41+
It 'still invokes the release workflow when -WhatIf is set so it can render its plan' {
42+
Invoke-NovaRelease -Local -WhatIf | Out-Null
43+
$script:invoked | Should -BeTrue
44+
}
45+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
BeforeAll {
2+
$projectRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
3+
. (Join-Path $projectRoot 'src/public/NewNovaModulePackage.ps1')
4+
5+
function Get-NovaShouldProcessForwardingParameter {param([switch]$WhatIfEnabled) return @{WhatIf=[bool]$WhatIfEnabled}}
6+
function Get-NovaPackageWorkflowContext {param($WorkflowParams, [switch]$SkipTestsRequested, [switch]$OverrideWarningRequested)
7+
$script:ctxArgs = @{SkipTests=[bool]$SkipTestsRequested; Override=[bool]$OverrideWarningRequested}
8+
return [pscustomobject]@{Target='/proj'; Operation='Package'}
9+
}
10+
function Invoke-NovaPackageWorkflow {param($WorkflowContext, [switch]$ShouldRun)
11+
$script:shouldRun = [bool]$ShouldRun
12+
return 'packaged'
13+
}
14+
}
15+
16+
Describe 'New-NovaModulePackage' {
17+
BeforeEach {$script:ctxArgs = $null; $script:shouldRun = $null}
18+
19+
It 'forwards switch parameters to the workflow context and returns the workflow result' {
20+
$result = New-NovaModulePackage -SkipTests -OverrideWarning
21+
$script:ctxArgs.SkipTests | Should -BeTrue
22+
$script:ctxArgs.Override | Should -BeTrue
23+
$script:shouldRun | Should -BeTrue
24+
$result | Should -Be 'packaged'
25+
}
26+
27+
It 'passes ShouldRun=$false when -WhatIf is set' {
28+
New-NovaModulePackage -WhatIf | Out-Null
29+
$script:shouldRun | Should -BeFalse
30+
}
31+
}

0 commit comments

Comments
 (0)