Skip to content

Add tests verifying OutputType alignment between [OutputType] attributes, parameter sets, and .OUTPUTS help #413

Description

Modules processed by Process-PSModule declare output types via [OutputType()] attributes and document them in .OUTPUTS sections of comment-based help. When a function has multiple parameter sets that return different types, each [OutputType] should be scoped to its parameter set using ParameterSetName. There is currently no automated check that these three declarations stay in sync, which means drift goes undetected until a caller or a tool is surprised by an incorrect type.

Request

Desired capability

Process-PSModule should include Pester tests that, for every exported command in the processed module, verify:

  • When a function has a single output type across all parameter sets, [OutputType] appears without ParameterSetName scoping and the listed type matches .OUTPUTS in the comment-based help.
  • When a function's parameter sets return different types, each [OutputType] is scoped to a ParameterSetName and every declared parameter set that produces output has a corresponding [OutputType].
  • The full set of types listed across all [OutputType] attributes on a function matches the full set of types documented in .OUTPUTS — no type present in one but absent in the other.

Acceptance criteria

  • A Pester test file covers all exported commands of the loaded module.
  • Each test case inspects (Get-Command ).OutputType and (Get-Help ).returnValues and asserts their types are equivalent.
  • When a function declares parameter-set-scoped [OutputType] attributes, the test confirms every named parameter set that is not __AllParameterSets has an explicit [OutputType] entry.
  • A function whose [OutputType] lists a type not mentioned in .OUTPUTS causes the test to fail with a clear message identifying the command and the mismatched type.
  • A function whose .OUTPUTS documents a type not covered by any [OutputType] attribute also fails the test.
  • The test suite runs as part of the standard Process-PSModule test step, against the built module artifact.

Technical decisions

Inspection approach: Use (Get-Command ).OutputType for [OutputType] data and (Get-Help \ -Full).returnValues.returnValue.type.name for .OUTPUTS data. Both are available after the module is loaded, requiring no source parsing.

Scope: Exported commands only (Get-Command -Module ). Private functions are excluded — they are covered by their own unit tests and do not carry a public contract.

Type name normalization: Strip surrounding brackets and namespace aliases (e.g., [System.String] and [string] and System.String all resolve to System.String) before comparison to avoid false failures from formatting differences.

Parameter set handling: A function with a single logical output type may legitimately use an unscoped [OutputType] even when it has multiple parameter sets. The test should only require per-set scoping when the declared types actually differ across sets. Detecting this correctly means grouping OutputType entries by ParameterSetName and checking whether all non-__AllParameterSets entries agree on the same type set.

Test placement: Add a new file OutputType.Tests.ps1 (or extend an existing shared test file) under the test fixtures in ests/srcTestRepo/tests/ and apply the same pattern to ests/srcWithManifestTestRepo/tests/. The real enforcement runs on the caller's module during the Process-PSModule workflow.

Framework: Pester 5 — consistent with the existing test infrastructure.


Implementation plan

Core test logic

  • Add OutputType.Tests.ps1 to the shared test fixtures that iterates all exported commands and asserts [OutputType] types match .OUTPUTS types after normalization.
  • Add a helper function (or BeforeAll block) that normalizes type name strings to a canonical form for comparison.
  • Add a test case that verifies per-set scoping: when a function's OutputType entries carry differing ParameterSetName values, every named parameter set that is not __AllParameterSets has a corresponding entry.

Fixture functions

  • Add a fixture function with mismatched [OutputType] and .OUTPUTS to ests/srcTestRepo/src/ to serve as a negative test case, and confirm the test fails on it.
  • Add a fixture function with correct per-set [OutputType] scoping to serve as a positive test case.

Validation

  • Run the full test suite against the test fixtures and confirm new tests pass for correct functions and fail for the intentionally broken fixture.
  • Confirm the test output message on failure identifies the command name and the specific type discrepancy.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions