Skip to content

Commit 59aa50a

Browse files
committed
feat(#203): mirror CLI helper tests
Closes Migrate CLI domain tests (4) Fixes #203
1 parent 87db820 commit 59aa50a

48 files changed

Lines changed: 1170 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
2424
- Added a non-blocking `scripts/build/Get-TestMirrorStatus.ps1` helper that reports `src/**/*.ps1` files without a matching mirrored test file under `tests/`, to support the migration to the source-mirrored, dot-source-first test layout.
2525
- Added mirrored, dot-source-first Pester test files for scaffold and update private helpers (`src/private/scaffold/*.ps1` and `src/private/update/*.ps1`), so each unit-level helper now has a focused test file under `tests/private/scaffold/` or `tests/private/update/` instead of being covered only through broad legacy coverage files.
2626
- Added mirrored, dot-source-first Pester test files for build and shared private helpers (`src/private/build/*.ps1`, `src/private/build/manifest/*.ps1`, and `src/private/shared/*.ps1`), so each unit-level helper now has a focused test file under `tests/private/build/`, `tests/private/build/manifest/`, or `tests/private/shared/` instead of being covered only through broad legacy coverage files.
27+
- 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.
2728

2829

2930
### Changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
BeforeAll {
2+
$projectRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $PSScriptRoot))
3+
. (Join-Path $projectRoot 'src/private/cli/AddNovaCliHeaderOption.ps1')
4+
5+
function Stop-NovaOperation {param([string]$Message, [string]$ErrorId, $Category, $TargetObject) throw $Message}
6+
}
7+
8+
Describe 'Add-NovaCliHeaderOption' {
9+
It 'parses Name=Value into the Headers map' {
10+
$options = @{}
11+
Add-NovaCliHeaderOption -Options $options -HeaderArgument 'X-Trace=abc'
12+
$options.Headers['X-Trace'] | Should -Be 'abc'
13+
}
14+
15+
It 'preserves values that contain "=" after the first separator' {
16+
$options = @{}
17+
Add-NovaCliHeaderOption -Options $options -HeaderArgument 'X-Token=a=b=c'
18+
$options.Headers['X-Token'] | Should -Be 'a=b=c'
19+
}
20+
21+
It 'rejects header arguments without a name part' {
22+
{Add-NovaCliHeaderOption -Options @{} -HeaderArgument '=value'} | Should -Throw '*Invalid header argument*'
23+
}
24+
25+
It 'rejects header arguments without a separator' {
26+
{Add-NovaCliHeaderOption -Options @{} -HeaderArgument 'noseparator'} | Should -Throw '*Invalid header argument*'
27+
}
28+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
BeforeAll {
2+
$projectRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $PSScriptRoot))
3+
. (Join-Path $projectRoot 'src/private/cli/AddNovaCliOptionValue.ps1')
4+
}
5+
6+
Describe 'Add-NovaCliOptionValue' {
7+
It 'creates a single-entry array when the option is new' {
8+
$options = @{}
9+
Add-NovaCliOptionValue -Options $options -Name 'PackagePath' -Value 'a'
10+
,$options.PackagePath | Should -BeOfType ([System.Array])
11+
$options.PackagePath.Count | Should -Be 1
12+
$options.PackagePath[0] | Should -Be 'a'
13+
}
14+
15+
It 'appends additional values into the existing option array' {
16+
$options = @{PackagePath = 'a'}
17+
Add-NovaCliOptionValue -Options $options -Name 'PackagePath' -Value 'b'
18+
$options.PackagePath.Count | Should -Be 2
19+
$options.PackagePath[1] | Should -Be 'b'
20+
}
21+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
BeforeAll {
2+
$projectRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $PSScriptRoot))
3+
. (Join-Path $projectRoot 'src/private/cli/ConvertFromNovaBuildCliArgument.ps1')
4+
5+
function ConvertFrom-NovaCliSwitchArgument {param([string[]]$Arguments, [hashtable]$TokenMap) return @{TokenMap = $TokenMap; Arguments = $Arguments}}
6+
}
7+
8+
Describe 'ConvertFrom-NovaBuildCliArgument' {
9+
It 'maps build switches to canonical options' {
10+
$result = ConvertFrom-NovaBuildCliArgument -Arguments @('-i')
11+
$result.TokenMap['--continuous-integration'] | Should -Be 'ContinuousIntegration'
12+
$result.TokenMap['-o'] | Should -Be 'OverrideWarning'
13+
$result.TokenMap['--override-warning'] | Should -Be 'OverrideWarning'
14+
}
15+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
BeforeAll {
2+
$projectRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $PSScriptRoot))
3+
. (Join-Path $projectRoot 'src/private/cli/ConvertFromNovaBumpCliArgument.ps1')
4+
5+
function ConvertFrom-NovaCliSwitchArgument {param([string[]]$Arguments, [hashtable]$TokenMap) return $TokenMap}
6+
}
7+
8+
Describe 'ConvertFrom-NovaBumpCliArgument' {
9+
It 'maps bump switches to canonical options' {
10+
$tokenMap = ConvertFrom-NovaBumpCliArgument -Arguments @()
11+
$tokenMap['--preview'] | Should -Be 'Preview'
12+
$tokenMap['-p'] | Should -Be 'Preview'
13+
$tokenMap['--continuous-integration'] | Should -Be 'ContinuousIntegration'
14+
$tokenMap['--override-warning'] | Should -Be 'OverrideWarning'
15+
}
16+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
BeforeAll {
2+
$projectRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $PSScriptRoot))
3+
. (Join-Path $projectRoot 'src/private/cli/ConvertFromNovaCliArgument.ps1')
4+
. (Join-Path $projectRoot 'src/private/cli/GetNovaCliRequiredArgumentValue.ps1')
5+
6+
function ConvertTo-NovaCliArgumentArray {param([hashtable]$BoundParameters, [string[]]$Arguments) return @($Arguments | Where-Object {$_})}
7+
function Stop-NovaOperation {param([string]$Message, [string]$ErrorId, $Category, $TargetObject) throw $Message}
8+
}
9+
10+
Describe 'Add-NovaCliDeliveryOption' {
11+
It 'adds the option when allowed' {
12+
$options = @{}
13+
Add-NovaCliDeliveryOption -Options $options -AllowedOptionNameList @('Local') -Option ([pscustomobject]@{Name='Local';Value=$true}) -Token '--local'
14+
$options.Local | Should -BeTrue
15+
}
16+
17+
It 'throws when option is not in allowed list' {
18+
{Add-NovaCliDeliveryOption -Options @{} -AllowedOptionNameList @('Other') -Option ([pscustomobject]@{Name='Local';Value=$true}) -Token '--local'} | Should -Throw '*Unknown argument: --local*'
19+
}
20+
}
21+
22+
Describe 'ConvertFrom-NovaCliArgument' {
23+
It 'parses common delivery flags using the default allowed list' {
24+
$options = ConvertFrom-NovaCliArgument -Arguments @('--local', '--repository', 'feed', '--api-key', 'KEY', '--skip-tests')
25+
$options.Local | Should -BeTrue
26+
$options.Repository | Should -Be 'feed'
27+
$options.ApiKey | Should -Be 'KEY'
28+
$options.SkipTests | Should -BeTrue
29+
}
30+
31+
It 'throws when a flag is not in the allowed list' {
32+
{ConvertFrom-NovaCliArgument -Arguments @('--local') -AllowedOptionNameList @('Other')} | Should -Throw '*Unknown argument*'
33+
}
34+
35+
It 'throws for unknown flags' {
36+
{ConvertFrom-NovaCliArgument -Arguments @('--bogus')} | Should -Throw '*Unknown argument: --bogus*'
37+
}
38+
}
39+
40+
Describe 'ConvertFrom-NovaPackageCliArgument' {
41+
It 'restricts the allowed options to package-relevant flags' {
42+
$options = ConvertFrom-NovaPackageCliArgument -Arguments @('--skip-tests', '--override-warning')
43+
$options.SkipTests | Should -BeTrue
44+
$options.OverrideWarning | Should -BeTrue
45+
}
46+
47+
It 'rejects flags outside the package allow list' {
48+
{ConvertFrom-NovaPackageCliArgument -Arguments @('--local')} | Should -Throw '*Unknown argument*'
49+
}
50+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
BeforeAll {
2+
$projectRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $PSScriptRoot))
3+
. (Join-Path $projectRoot 'src/private/cli/ConvertFromNovaCliModeArgument.ps1')
4+
5+
function ConvertTo-NovaCliArgumentArray {param([hashtable]$BoundParameters, [string[]]$Arguments) return ,@(@($Arguments) | Where-Object {$_})}
6+
function Stop-NovaOperation {param([string]$Message, [string]$ErrorId, $Category, $TargetObject) throw $Message}
7+
}
8+
9+
Describe 'Get-NovaCliModeArgumentValue' {
10+
BeforeEach {
11+
$script:def = [pscustomobject]@{
12+
EmptyResult = 'empty'
13+
TokenMap = @{'--on' = 'on'; '--off' = 'off'}
14+
Usage = [pscustomobject]@{Message = 'usage failure'; ErrorId = 'Nova.Test.Usage'}
15+
UnknownArgumentUsesUsageError = $true
16+
}
17+
}
18+
19+
It 'returns EmptyResult when no arguments are provided' {
20+
Get-NovaCliModeArgumentValue -Arguments @() -Definition $script:def | Should -Be 'empty'
21+
}
22+
23+
It 'returns the mapped token value for a known argument' {
24+
Get-NovaCliModeArgumentValue -Arguments @('--on') -Definition $script:def | Should -Be 'on'
25+
}
26+
27+
It 'throws the usage error when too many arguments are given' {
28+
{Get-NovaCliModeArgumentValue -Arguments @('--on', '--off') -Definition $script:def} | Should -Throw '*usage failure*'
29+
}
30+
31+
It 'throws the usage error for unknown arguments when configured' {
32+
{Get-NovaCliModeArgumentValue -Arguments @('--unknown') -Definition $script:def} | Should -Throw '*usage failure*'
33+
}
34+
35+
It 'throws a generic unknown argument error when usage routing is disabled' {
36+
$script:def.UnknownArgumentUsesUsageError = $false
37+
{Get-NovaCliModeArgumentValue -Arguments @('--bogus') -Definition $script:def} | Should -Throw '*Unknown argument: --bogus*'
38+
}
39+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
BeforeAll {
2+
$projectRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $PSScriptRoot))
3+
. (Join-Path $projectRoot 'src/private/cli/ConvertFromNovaCliSwitchArgument.ps1')
4+
5+
function ConvertTo-NovaCliArgumentArray {param([hashtable]$BoundParameters, [string[]]$Arguments) return @($Arguments | Where-Object {$_})}
6+
function Stop-NovaOperation {param([string]$Message, [string]$ErrorId, $Category, $TargetObject) throw $Message}
7+
}
8+
9+
Describe 'Get-NovaCliSwitchOptionName' {
10+
It 'returns the mapped option name' {
11+
Get-NovaCliSwitchOptionName -TokenMap @{'-x' = 'Foo'} -Token '-x' | Should -Be 'Foo'
12+
}
13+
14+
It 'throws for unknown tokens' {
15+
{Get-NovaCliSwitchOptionName -TokenMap @{} -Token '-y'} | Should -Throw '*Unknown argument: -y*'
16+
}
17+
}
18+
19+
Describe 'ConvertFrom-NovaCliSwitchArgument' {
20+
It 'sets each token-mapped option to $true' {
21+
$tokenMap = @{'-a' = 'AOpt'; '-b' = 'BOpt'}
22+
$options = ConvertFrom-NovaCliSwitchArgument -Arguments @('-a', '-b') -TokenMap $tokenMap
23+
$options.AOpt | Should -BeTrue
24+
$options.BOpt | Should -BeTrue
25+
}
26+
27+
It 'throws when an argument is not in the token map' {
28+
{ConvertFrom-NovaCliSwitchArgument -Arguments @('-z') -TokenMap @{}} | Should -Throw '*Unknown argument*'
29+
}
30+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
BeforeAll {
2+
$projectRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $PSScriptRoot))
3+
. (Join-Path $projectRoot 'src/private/cli/ConvertFromNovaDeployCliArgument.ps1')
4+
. (Join-Path $projectRoot 'src/private/cli/AddNovaCliOptionValue.ps1')
5+
. (Join-Path $projectRoot 'src/private/cli/AddNovaCliHeaderOption.ps1')
6+
. (Join-Path $projectRoot 'src/private/cli/GetNovaCliRequiredArgumentValue.ps1')
7+
8+
function ConvertTo-NovaCliArgumentArray {param([hashtable]$BoundParameters, [string[]]$Arguments) return @($Arguments | Where-Object {$_})}
9+
function Stop-NovaOperation {param([string]$Message, [string]$ErrorId, $Category, $TargetObject) throw $Message}
10+
}
11+
12+
Describe 'ConvertFrom-NovaDeployCliArgument' {
13+
It 'parses all known deploy flags' {
14+
$options = ConvertFrom-NovaDeployCliArgument -Arguments @(
15+
'--repository', 'feed',
16+
'--url', 'https://nuget',
17+
'--path', 'a.nupkg',
18+
'--type', 'NuGet',
19+
'--upload-path', '/sub',
20+
'--token', 'tok',
21+
'--token-env', 'TOK',
22+
'--auth-scheme', 'Bearer',
23+
'--header', 'X-A=1'
24+
)
25+
$options.Repository | Should -Be 'feed'
26+
$options.Url | Should -Be 'https://nuget'
27+
$options.PackagePath[0] | Should -Be 'a.nupkg'
28+
$options.PackageType[0] | Should -Be 'NuGet'
29+
$options.UploadPath | Should -Be '/sub'
30+
$options.Token | Should -Be 'tok'
31+
$options.TokenEnvironmentVariable | Should -Be 'TOK'
32+
$options.AuthenticationScheme | Should -Be 'Bearer'
33+
$options.Headers['X-A'] | Should -Be '1'
34+
}
35+
36+
It 'throws for unknown flags' {
37+
{ConvertFrom-NovaDeployCliArgument -Arguments @('--bogus')} | Should -Throw '*Unknown argument*'
38+
}
39+
}
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 (Split-Path -Parent $PSScriptRoot))
3+
. (Join-Path $projectRoot 'src/private/cli/ConvertFromNovaInitCliArgument.ps1')
4+
. (Join-Path $projectRoot 'src/private/cli/GetNovaCliRequiredArgumentValue.ps1')
5+
6+
function ConvertTo-NovaCliArgumentArray {param([hashtable]$BoundParameters, [string[]]$Arguments) return @($Arguments | Where-Object {$_})}
7+
function Stop-NovaOperation {param([string]$Message, [string]$ErrorId, $Category, $TargetObject) throw $Message}
8+
}
9+
10+
Describe 'ConvertFrom-NovaInitCliArgument' {
11+
It 'reads --path value' {
12+
$options = ConvertFrom-NovaInitCliArgument -Arguments @('--path', '/tmp/x')
13+
$options.Path | Should -Be '/tmp/x'
14+
}
15+
16+
It 'sets Example when --example/-e provided' {
17+
(ConvertFrom-NovaInitCliArgument -Arguments @('-e')).Example | Should -BeTrue
18+
}
19+
20+
It 'throws for unknown switches' {
21+
{ConvertFrom-NovaInitCliArgument -Arguments @('--bogus')} | Should -Throw '*Unknown argument*'
22+
}
23+
24+
It 'rejects positional path tokens with a guided message' {
25+
{ConvertFrom-NovaInitCliArgument -Arguments @('positional')} | Should -Throw '*positional paths are no longer accepted*'
26+
}
27+
}

0 commit comments

Comments
 (0)