Skip to content

Commit fe905f1

Browse files
committed
feat(#133): enhance test coverage and improve CLI console read handling
- Add native console read helpers for coverage-safe testing - Refactor console read key retrieval to use a dedicated function - Update tests to validate new console read functionality
1 parent 16767fa commit fe905f1

5 files changed

Lines changed: 78 additions & 83 deletions

File tree

CHANGELOG.md

Lines changed: 26 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1717
entrypoint instead of exporting a `nova` PowerShell alias.
1818
- Add optional `Preamble` support in `project.json` to write module-level setup lines at the top of generated `.psm1`
1919
files.
20-
- Add `Initialize-NovaModule -Example` and GNU-style `% nova init --example` / `% nova init -e` support to scaffold a
21-
full
22-
working project from the packaged
23-
example resources.
24-
- git initialization failures so more build and release paths now expose stable error ids and categories.
25-
- Runs the normal init flow
26-
- Applies the metadata entered during init to the generated `project.json`
27-
- Always creates the example test structure without prompting to enable tests
28-
- The packaged example `project.json` now keeps the current project, manifest, package, and raw-upload settings
29-
visible in one place so users can see the full supported configuration surface
3020
- Add native `-WhatIf` and `-Confirm` support across mutating Nova commands, including GNU-style routed CLI support for
3121
`--verbose`/`-v`, `--what-if`/`-w`, and `--confirm`/`-c` on `build`, `test`, `bump`, `publish`, and `release`.
3222
- Routed CLI confirmation now stays inside the `nova` experience instead of exposing PowerShell's `Suspend` prompt.
@@ -45,13 +35,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4535
- Uses the stored prerelease update preference to decide whether prerelease self-updates are eligible.
4636
- Requires explicit confirmation before a prerelease self-update proceeds.
4737
- Add `% nova version --installed` / `% nova version -i` so users can compare the locally installed version of the
48-
current
49-
project/module with
50-
the current project version from `project.json`, while keeping `% nova --version` / `% nova -v` dedicated to the
51-
installed
52-
NovaModuleTools version.
53-
- Add build-before-test support to the test workflow so `Test-NovaBuild -Build`, `% nova test --build`, and `% nova
54-
test -b` rebuild the project before running Pester.
38+
current project/module with the current project version from `project.json`, while keeping `% nova --version` /
39+
`% nova -v` dedicated to the installed NovaModuleTools version.
40+
- Add build-before-test support to the test workflow so `Test-NovaBuild -Build`, `% nova test --build`, and
41+
`% nova test -b` rebuild the project before running Pester.
5542
- Add an opt-in `-Preview` mode to `Update-NovaModuleVersion` / GNU-style `% nova bump --preview` / `% nova bump -p` for
5643
explicit preview iteration.
5744
- Stable versions still use the normal semantic bump target first, then append `-preview`.
@@ -60,8 +47,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6047
`rc -> rc01`, `rc1 -> rc2`, `SNAPSHOT -> SNAPSHOT01`, and `SNAPSHOT1 -> SNAPSHOT2`.
6148
- Add `New-NovaModulePackage` and `% nova package` so projects can build, test, and package the built module output as a
6249
`.nupkg` artifact by using generic metadata from `project.json`, including repositories whose test runs reload or
63-
remove
64-
`NovaModuleTools` before the final package step.
50+
remove `NovaModuleTools` before the final package step.
6551
- Package output supports `Package.Types` with case-insensitive `NuGet`, `Zip`, `.nupkg`, and `.zip` values.
6652
- Omitting `Package.Types` still defaults packaging to a `.nupkg` artifact.
6753
- Selecting both `NuGet` and `Zip` creates both package formats in the configured output directory.
@@ -78,15 +64,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7864
`latest` files in the configured package output directory.
7965
- Add opt-in skip-test support to the package, publish, and release workflows for CI/CD-oriented delivery paths where
8066
tests already ran earlier in the pipeline.
81-
82-
### Fixed
83-
84-
- Fix unsupported `nova` help invocations so they now return Nova's structured CLI validation error instead of a
85-
PowerShell parameter-binding failure.
86-
- Keep manifest/package helper edge cases aligned with their intended behavior.
87-
- Manifest settings resolution now accepts ordered dictionary metadata shapes in addition to plain hashtables.
88-
- `New-NovaPackageArtifacts` now accepts an empty metadata list and returns an empty artifact result instead of
89-
failing during parameter binding.
9067
- Centralize delivery configuration resolution so raw package upload, update notification settings, and PSGallery
9168
publishing now follow one explicit precedence model without surfacing configured secrets in error text.
9269
- Raw upload now resolves command overrides before named repository settings, then package defaults.
@@ -107,22 +84,32 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
10784
and `nova release` while keeping `nova version -i` dedicated to the installed-version view.
10885
- Build re-activates the freshly built module after the build succeeds, bump re-activates it before the version
10986
update starts, and publish/release restore the built module again after publish completes.
110-
- Repository publish no longer forces verbose `Publish-PSResource` output unless verbose logging was explicitly
111-
requested.
112-
- CI bump now reuses the already activated built-module command when the current session is already running from
113-
`dist/`, so publish-then-bump prerelease automation can continue in the same session without losing private helper
114-
bindings.
87+
- Repository publish no longer forces verbose `Publish-PSResource` output unless verbose logging was explicitly
88+
requested.
89+
- CI bump now reuses the already activated built-module command when the current session is already running from
90+
`dist/`, so publish-then-bump prerelease automation can continue in the same session without losing private helper
91+
bindings.
11592
- Keep standalone `nova bump` output stable by formatting version-update results in the CLI layer instead of relying on
11693
PowerShell's default object rendering.
11794
- `nova bump --what-if` and `% run.ps1` now surface a predictable summary for previous version, new version, label,
11895
and commit count.
11996

97+
### Fixed
98+
99+
- Fix unsupported `nova` help invocations so they now return Nova's structured CLI validation error instead of a
100+
PowerShell parameter-binding failure.
101+
- Keep manifest/package helper edge cases aligned with their intended behavior.
102+
- Manifest settings resolution now accepts ordered dictionary metadata shapes in addition to plain hashtables.
103+
- `New-NovaPackageArtifacts` now accepts an empty metadata list and returns an empty artifact result instead of
104+
failing during parameter binding.
105+
- Fix configuration and validation errors so empty `project.json` files and unsupported `Manifest` keys fail fast with
106+
clear messages.
107+
120108
### Changed
121109

122110
- Change the project to a Nova command model, replacing the previous mixed MT/Nova workflow.
123111
- All public commands are now Nova commands, and the `nova` CLI / `Invoke-NovaCli` command surface is the primary
124-
entry point for all
125-
operations.
112+
entry point for all operations.
126113
- Change `nova` help to a dedicated CLI-native help system with both short and long command help forms.
127114
- Isolate external workflow execution behind smaller internal adapters so git, raw package upload, repository publish,
128115
self-update, settings-file I/O, and CLI environment access have clearer change points and smaller test seams.
@@ -132,63 +119,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
132119
stays focused on command syntax and options.
133120
- CLI help no longer delegates to PowerShell `Get-Help` and now consistently shows CLI option spellings such as
134121
`--repository` and `-r`.
135-
- Refactor `tests/NovaCommandModel.TestSupport.ps1` into smaller, focused support scripts so the shared Nova command
136-
model
137-
test helpers are easier to maintain without changing test behavior.
138-
- **BREAKING CHANGE**: Rename the public Nova scaffold cmdlets to approved verbs.
122+
- **BREAKING CHANGE**: Rename the public Nova scaffold cmdlets.
139123
- `New-NovaModule``Initialize-NovaModule`
140124
- No compatibility aliases are exported for the retired cmdlet names or CLI subcommands.
141125
- Change `CopyResourcesToModuleRoot` to the canonical project setting name while keeping the default value `false`.
142126
- Change `Publish-NovaModule -Local` and `% nova publish --local` so a successful local publish also reloads the
143-
published
144-
module from the local install path into the active PowerShell session.
145-
- Refactor the simple routed `nova` parsers to use shared declarative parser helpers while keeping the existing CLI
146-
syntax, validation, and routed command behavior unchanged.
147-
- `nova build`, `nova test`, and `nova bump` now share one switch-parser pattern.
148-
- `nova update`, `nova version`, and `nova notification` now share one mode-parser pattern.
149-
150-
### Fixed
151-
152-
- Fix configuration and validation errors so empty `project.json` files and unsupported `Manifest` keys fail fast with
153-
clear messages.
154-
- Fix GitHub Pages guide fragment links so section anchors such as `#pack` scroll fully into view instead of hiding the
155-
section heading behind the sticky top navigation.
127+
published module from the local install path into the active PowerShell session.
156128

157129
### Documentation
158130

159131
- Split documentation into contributor-focused repository docs and task-oriented GitHub Pages user guides.
160132
- Expand the public site into a fuller developer end-user manual with rewritten getting started, core workflows, working
161133
with modules, troubleshooting, concepts, release notes, and license pages plus new reference-style pages for
162134
commands, `project.json`, packaging/delivery, and versioning/update behavior.
163-
- Improve page spacing, card padding, code-block separation, and responsive layout density so the documentation is
164-
easier to scan and less visually cramped.
165-
- The getting started and core workflows guides now let readers switch between PowerShell and command-line
166-
examples, including the local-publish-plus-`pwsh` handoff for `Get-ExampleGreeting` and fresh-process `pwsh`
167-
135+
- The guides now let readers switch between PowerShell and command-line examples, including the local-publish-plus-
136+
`pwsh` handoff for `Get-ExampleGreeting` and fresh-process `pwsh`
168137
- Clean the generated PowerShell cmdlet help so `Get-Help` pages no longer mix in `nova` launcher syntax or GNU-style
169138
CLI options.
170-
import/reload validation from the command-line path.
171-
- The command reference, working-with-modules, packaging-and-delivery, versioning-and-updates, and troubleshooting
172-
guides now use the same centered command-surface header and PowerShell/command-line example switching model.
173-
- The command-surface toggle sits centered in the top navigation area on the switched guides, with the `Menu`
174-
control aligned separately to the right and the header buttons tightened to match the menu height more closely.
175-
- The home page now presents its recommended first-path command examples in PowerShell form to match the default
176-
quickstart orientation.
177-
- The shared docs layout now keeps the same readable content width in PowerShell and command-line modes, while long
178-
command examples stay contained inside their own blocks instead of stretching the page.
179-
- All public pages now use the wider large-screen shell, and the single-column release-notes and license layouts use
180-
a broader centered content width that matches the updated site scale.
181-
- The public docs header logo is now larger so the NovaModuleTools brand is more prominent across the site.
182139
- Refresh public `Get-Help` content and examples for the Nova commands, including CLI usage and preview/confirmation
183140
scenarios.
184141
- Simplify `Invoke-NovaCli` help so it matches the launcher-vs-cmdlet split cleanly and PlatyPS can generate command
185142
help without failing during local builds.
186143
- Update the `nova` CLI documentation and help text to use POSIX/GNU-style long and short options while keeping
187144
PowerShell cmdlet examples in their native PowerShell form.
188-
- Document the CLI-native short-help and long-help forms in the root help text, README, and `Invoke-NovaCli`
189-
reference.
190-
- Clarify the documentation split between the `nova` launcher-oriented CLI surface and the explicit PowerShell
191-
`Invoke-NovaCli` cmdlet entrypoint, and mark examples consistently with `PS>` for PowerShell and `%` for CLI.
192145

193146
### Removed
194147

src/private/cli/ConfirmNovaCliAction.ps1

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,18 @@ function Invoke-NovaCliConsoleReadKey {
4141
return & $consoleReader
4242
}
4343

44+
function Invoke-NovaCliNativeConsoleReadKey {
45+
[CmdletBinding()]
46+
param([scriptblock]$Reader = {[Console]::ReadKey($true)})
47+
48+
return & $Reader
49+
}
50+
4451
function Get-NovaCliConsoleReadKeyReader {
4552
[CmdletBinding()]
4653
param()
4754

48-
return {[Console]::ReadKey($true)}
55+
return {Invoke-NovaCliNativeConsoleReadKey}
4956
}
5057

5158
function Read-NovaCliPromptKey {

tests/CliHelperCoverage.Tests.ps1

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,4 +127,23 @@ Describe 'Targeted coverage for smaller CLI helper internals' {
127127
Get-NovaCliInstalledVersion -Module $missingPrereleaseModule | Should -Be '2.0.1'
128128
}
129129
}
130+
131+
It 'native console read helpers remain injectable for coverage-safe testing' {
132+
InModuleScope $script:moduleName {
133+
$result = Invoke-NovaCliNativeConsoleReadKey -Reader {
134+
[pscustomobject]@{KeyChar = [char]'y'}
135+
}
136+
Mock Invoke-NovaCliNativeConsoleReadKey {
137+
[pscustomobject]@{KeyChar = [char]'y'}
138+
}
139+
140+
$reader = Get-NovaCliConsoleReadKeyReader
141+
142+
$result.KeyChar | Should -Be ([char]'y')
143+
$reader | Should -BeOfType 'scriptblock'
144+
($reader.ToString()).Trim() | Should -Be 'Invoke-NovaCliNativeConsoleReadKey'
145+
(& $reader).KeyChar | Should -Be ([char]'y')
146+
Assert-MockCalled Invoke-NovaCliNativeConsoleReadKey -Times 1
147+
}
148+
}
130149
}

tests/CoverageGaps.Cli.Tests.ps1

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -887,14 +887,6 @@ Describe 'Coverage gaps for CLI and installed-version internals' {
887887
}
888888
}
889889

890-
It 'Get-NovaCliConsoleReadKeyReader returns the default console read delegate' {
891-
InModuleScope $script:moduleName {
892-
$reader = Get-NovaCliConsoleReadKeyReader
893-
894-
$reader | Should -BeOfType 'scriptblock'
895-
($reader.ToString()).Trim() | Should -Be '[Console]::ReadKey($true)'
896-
}
897-
}
898890

899891
It 'Invoke-NovaCliConsoleReadKey invokes the shared console reader delegate' {
900892
InModuleScope $script:moduleName {

tests/RemainingHelperCoverage.Tests.ps1

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,11 +451,20 @@ Describe 'Coverage for remaining manifest, JSON, and help-locale helpers' {
451451
It 'Get-NovaPackageAuthorList normalizes string and enumerable author values' {
452452
InModuleScope $script:moduleName {
453453
@(Get-NovaPackageAuthorList -AuthorValue $null) | Should -Be @()
454+
@(Get-NovaPackageAuthorList -AuthorValue ' ') | Should -Be @()
454455
@(Get-NovaPackageAuthorList -AuthorValue ' Nova Author ') | Should -Be @('Nova Author')
455456
@(Get-NovaPackageAuthorList -AuthorValue @(' Author A ', 'Author B', 'Author A', ' ')) | Should -Be @('Author A', 'Author B')
456457
}
457458
}
458459

460+
It 'Get-NovaManifestValue reads dictionaries, objects, and returns null for missing object properties' {
461+
InModuleScope $script:moduleName {
462+
Get-NovaManifestValue -Manifest @{Author = 'Dictionary Author'} -Name 'Author' | Should -Be 'Dictionary Author'
463+
Get-NovaManifestValue -Manifest ([pscustomobject]@{Author = 'Object Author'}) -Name 'Author' | Should -Be 'Object Author'
464+
Get-NovaManifestValue -Manifest ([pscustomobject]@{Author = 'Object Author'}) -Name 'Tags' | Should -BeNullOrEmpty
465+
}
466+
}
467+
459468
It 'Get-NovaPackageAuthorList rejects unsupported author value types' {
460469
InModuleScope $script:moduleName {
461470
$thrown = $null
@@ -641,7 +650,7 @@ Describe 'Coverage for remaining manifest, JSON, and help-locale helpers' {
641650
Get-NovaPackageArtifactType -PackagePath '/tmp/Nova.Package.nupkg' | Should -Be 'NuGet'
642651
Get-NovaPackageArtifactType -PackagePath '/tmp/Nova.Package.zip' | Should -Be 'Zip'
643652

644-
foreach ($packagePath in @('/tmp/Nova.Package', '/tmp/Nova.Package.tar.gz')) {
653+
foreach ($packagePath in @('/tmp/package', '/tmp/Nova.Package', '/tmp/Nova.Package.tar.gz')) {
645654
$thrown = $null
646655
try {
647656
Get-NovaPackageArtifactType -PackagePath $packagePath
@@ -1194,6 +1203,21 @@ Locale: en-US
11941203
Assert-TestNovaZipPackageArtifactContent -PackagePath $result[1].PackagePath
11951204
}
11961205

1206+
It 'New-NovaPackageArtifacts returns an empty list when no package metadata was requested' {
1207+
InModuleScope $script:moduleName {
1208+
Mock Assert-NovaPackageMetadata {throw 'Package metadata validation should not run for an empty list.'}
1209+
Mock Initialize-NovaPackageOutputDirectory {throw 'Output directory initialization should not run for an empty list.'}
1210+
Mock New-NovaPackageArtifact {throw 'Package creation should not run for an empty list.'}
1211+
1212+
$result = @(New-NovaPackageArtifacts -ProjectInfo ([pscustomobject]@{ProjectRoot = '/tmp/project'}) -PackageMetadataList @())
1213+
1214+
$result | Should -Be @()
1215+
Assert-MockCalled Assert-NovaPackageMetadata -Times 0
1216+
Assert-MockCalled Initialize-NovaPackageOutputDirectory -Times 0
1217+
Assert-MockCalled New-NovaPackageArtifact -Times 0
1218+
}
1219+
}
1220+
11971221
It 'New-NovaPackageArtifact rejects unsupported package types with a structured validation error' {
11981222
InModuleScope $script:moduleName {
11991223
Mock Assert-NovaPackageMetadata {}

0 commit comments

Comments
 (0)