Skip to content

Commit 4e548a7

Browse files
committed
feat(#99): enhance adapter architecture for external dependencies
- Isolate external workflow execution behind smaller internal adapters for clearer change points. - Refactor CLI environment access and Git command interactions for improved maintainability. - Introduce shared JSON file handling functions for better configuration management.
1 parent a0794c1 commit 4e548a7

5 files changed

Lines changed: 104 additions & 4 deletions

src/private/cli/ConfirmNovaCliAction.ps1

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,15 @@ function Invoke-NovaCliConsoleReadKey {
3737
[CmdletBinding()]
3838
param()
3939

40-
return [Console]::ReadKey($true)
40+
$consoleReader = Get-NovaCliConsoleReadKeyReader
41+
return & $consoleReader
42+
}
43+
44+
function Get-NovaCliConsoleReadKeyReader {
45+
[CmdletBinding()]
46+
param()
47+
48+
return {[Console]::ReadKey($true)}
4149
}
4250

4351
function Read-NovaCliPromptKey {
@@ -140,4 +148,3 @@ function Confirm-NovaCliCommandAction {
140148
return
141149
} while ($true)
142150
}
143-

tests/CoverageGaps.Cli.Tests.ps1

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,23 @@ Describe 'Coverage gaps for CLI and installed-version internals' {
852852
}
853853
}
854854

855+
It 'Invoke-NovaCliConsoleReadKey invokes the shared console reader delegate' {
856+
InModuleScope $script:moduleName {
857+
Mock Get-NovaCliConsoleReadKeyReader {
858+
$delegate = {
859+
[pscustomobject]@{KeyChar = [char]'y'}
860+
}
861+
862+
return $delegate
863+
}
864+
865+
$result = Invoke-NovaCliConsoleReadKey
866+
867+
$result.KeyChar | Should -Be ([char]'y')
868+
Assert-MockCalled Get-NovaCliConsoleReadKeyReader -Times 1
869+
}
870+
}
871+
855872
It 'Invoke-NovaCliConsoleReadKey executes the console read path when standard input is redirected' {
856873
$runnerPath = Join-Path $TestDrive 'Invoke-NovaCliConsoleReadKey.Runner.ps1'
857874
$stdinPath = Join-Path $TestDrive 'Invoke-NovaCliConsoleReadKey.stdin.txt'

tests/CoverageGaps.ReleaseInternals.Tests.ps1

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,31 @@ Describe 'Coverage gaps for release and git internals' {
470470
}
471471
}
472472

473+
It 'Get-NovaVersionLabelForBump returns Patch when the repository has commits but no tags yet' {
474+
InModuleScope $script:moduleName {
475+
$projectRoot = Join-Path $TestDrive 'mocked-git-without-tags'
476+
New-Item -ItemType Directory -Path (Join-Path $projectRoot '.git') -Force | Out-Null
477+
478+
Mock Invoke-NovaGitCommand {
479+
switch ($Arguments[0]) {
480+
'rev-parse' {
481+
return [pscustomobject]@{ExitCode = 0; Output = @('.git')}
482+
}
483+
'describe' {
484+
return [pscustomobject]@{ExitCode = 1; Output = @()}
485+
}
486+
default {
487+
throw "Unexpected git args: $( $Arguments -join ' ' )"
488+
}
489+
}
490+
}
491+
492+
Get-NovaVersionLabelForBump -ProjectRoot $projectRoot | Should -Be 'Patch'
493+
Assert-MockCalled Invoke-NovaGitCommand -Times 1 -ParameterFilter {$Arguments[0] -eq 'describe' -and $Arguments[1] -eq '--tags'}
494+
Assert-MockCalled Invoke-NovaGitCommand -Times 0 -ParameterFilter {$Arguments[0] -eq 'rev-list'}
495+
}
496+
}
497+
473498
It 'Get-NovaVersionLabelForBump throws a clear error when the repository has no commits yet' {
474499
if (-not (Get-Command git -ErrorAction SilentlyContinue)) {
475500
Set-ItResult -Skipped -Because 'git is not available in this environment'
@@ -601,5 +626,3 @@ Describe 'Coverage gaps for release and git internals' {
601626
}
602627
}
603628
}
604-
605-

tests/RemainingCommandCoverage.Tests.ps1

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,48 @@ Describe 'Coverage for remaining command and filesystem branches' {
131131
}
132132
}
133133

134+
It 'New-InitiateGitRepo stops with a default failure message when git init returns no details' {
135+
$repoPath = Join-Path $TestDrive 'git-init-nonzero'
136+
New-Item -ItemType Directory -Path $repoPath -Force | Out-Null
137+
138+
InModuleScope $script:moduleName -Parameters @{RepoPath = $repoPath} {
139+
param($RepoPath)
140+
141+
Mock Get-Command {[pscustomobject]@{Name = 'git'}} -ParameterFilter {$Name -eq 'git'}
142+
Mock Invoke-NovaGitCommand {
143+
[pscustomobject]@{
144+
ExitCode = 1
145+
Output = @()
146+
}
147+
}
148+
149+
$thrown = $null
150+
try {
151+
New-InitiateGitRepo -DirectoryPath $RepoPath -Confirm:$false
152+
}
153+
catch {
154+
$thrown = $_
155+
}
156+
157+
$thrown | Should -Not -BeNullOrEmpty
158+
$thrown.Exception.Message | Should -Be 'Failed to initialize Git repo.'
159+
$thrown.FullyQualifiedErrorId | Should -Be 'Nova.Dependency.GitRepositoryInitializationFailed'
160+
$thrown.CategoryInfo.Category | Should -Be ([System.Management.Automation.ErrorCategory]::OpenError)
161+
$thrown.TargetObject | Should -Be $RepoPath
162+
}
163+
}
164+
165+
It 'Get-NovaGitInitializationFailureMessage includes git output details when they are available' {
166+
InModuleScope $script:moduleName {
167+
$result = [pscustomobject]@{
168+
ExitCode = 1
169+
Output = @('permission denied')
170+
}
171+
172+
Get-NovaGitInitializationFailureMessage -Result $result | Should -Be 'Failed to initialize Git repo: permission denied'
173+
}
174+
}
175+
134176
It 'Get-NovaTestWorkflowContext prepares the Pester workflow state and resolves the report writers' -ForEach @(
135177
@{Build = $false; ExpectedOperation = 'Run Pester tests and write test results'}
136178
@{Build = $true; ExpectedOperation = 'Build project, run Pester tests, and write test results'}

tests/RemainingHelperCoverage.Tests.ps1

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,17 @@ function Get-Second {
464464
}
465465
}
466466

467+
It 'Read-NovaJsonFileData returns null when the file content is not valid JSON' {
468+
$jsonPath = Join-Path $TestDrive 'invalid-settings.json'
469+
'{ invalid json }' | Set-Content -LiteralPath $jsonPath -Encoding utf8
470+
471+
InModuleScope $script:moduleName -Parameters @{JsonPath = $jsonPath} {
472+
param($JsonPath)
473+
474+
Read-NovaJsonFileData -LiteralPath $JsonPath | Should -BeNullOrEmpty
475+
}
476+
}
477+
467478
It 'Write-ProjectJsonData preserves nested objects, arrays, and unicode text when writing project.json' {
468479
$projectJsonPath = Join-Path $TestDrive 'written-project.json'
469480

0 commit comments

Comments
 (0)