Background
VisioPowerShell.Commands.VisioCmdlet derives from System.Management.Automation.Cmdlet, not from PSCmdlet. The choice was deliberate: an early-version attempt with PSCmdlet made unit testing infeasible because the existing test infrastructure relies on direct cmdlet instantiation — var cmd = new SomeVisioCmdlet(); cmd.Invoke<T>() — rather than driving cmdlets through a Runspace. PSCmdlet exposes runspace-tied members (MyInvocation, ParameterSetName, SessionState, etc.) which aren't populated when a PSCmdlet instance is constructed and Invoke()d outside a real PowerShell runspace, so most existing tests would break.
The cost of the current choice is showing up: any cmdlet design that wants to know which parameter set bound (e.g. for cmdlets with both a positional and a pipeline form, like the #163 work on Connect-VisioShape) can't access ParameterSetName and has to use indirect discriminators (e.g. inspecting which property is null at BeginProcessing).
What to investigate
-
Re-validate the original blocker. Repro the testability problem with PSCmdlet on the current MSTest 4 / SDK-style csproj setup. Does direct cmdlet .Invoke<T>() still fail in the same ways it did circa initial commit, or has the surface improved (PSCmdlet-with-no-runspace-context, or test-friendly PSCmdletExtensions)?
-
Catalog what we'd actually gain from PSCmdlet. ParameterSetName is the obvious one. Also: MyInvocation.BoundParameters, SessionState, Stopping, WriteProgress overloads, ShouldProcess support. Some of these are nice-to-have, some unblock specific cmdlet designs — document concretely.
-
Catalog the current VTest.PowerShell test patterns that would break and what it'd take to migrate them. The two patterns in play are:
- direct-invoke (
Cmd_* helpers in VisioPS_Session.cs),
- runspace-invoke (
InvokeScript<T> helper, used for parameter-binding tests like the #143 audit).
The second already drives a runspace, so it'd survive a PSCmdlet base. The first is the at-risk pattern. Question: can it be adapted to drive a minimal runspace with the same ergonomics, or is there a wrapper that fills in MyInvocation for direct-invoked PSCmdlet instances?
-
Decide the migration shape if it goes ahead. All-at-once base swap, or PSCmdlet for new cmdlets only? If we keep both, any sister-class concerns?
Why now
This came up while implementing #163 (pipeline parameter set on Connect-VisioShape). The pipeline form worked when run from a real PowerShell session, but tests exercising the same path through VTest.PowerShell's InvokeScript<T> plumbing failed with a Visio session mismatch (CommandTarget: application does not match doc.application). That looked initially like a test-infrastructure quirk specific to runspace-invoked cmdlets that touch TargetPage.Auto, and one of the clean fixes (use ParameterSetName in the cmdlet to take a different code path) is the kind of thing PSCmdlet would unlock. So #163 is parked behind this investigation rather than worked around.
Acceptance
Effort
M. Mostly investigation and writing, but the test-pattern audit could surface unexpected migrations. ~half a day for the recommendation memo, more if migration is the answer.
Themed milestone
Milestone B (Test infrastructure).
Background
VisioPowerShell.Commands.VisioCmdletderives fromSystem.Management.Automation.Cmdlet, not fromPSCmdlet. The choice was deliberate: an early-version attempt withPSCmdletmade unit testing infeasible because the existing test infrastructure relies on direct cmdlet instantiation —var cmd = new SomeVisioCmdlet(); cmd.Invoke<T>()— rather than driving cmdlets through aRunspace. PSCmdlet exposes runspace-tied members (MyInvocation,ParameterSetName,SessionState, etc.) which aren't populated when a PSCmdlet instance is constructed andInvoke()d outside a real PowerShell runspace, so most existing tests would break.The cost of the current choice is showing up: any cmdlet design that wants to know which parameter set bound (e.g. for cmdlets with both a positional and a pipeline form, like the #163 work on
Connect-VisioShape) can't accessParameterSetNameand has to use indirect discriminators (e.g. inspecting which property is null atBeginProcessing).What to investigate
Re-validate the original blocker. Repro the testability problem with PSCmdlet on the current MSTest 4 / SDK-style csproj setup. Does direct cmdlet
.Invoke<T>()still fail in the same ways it did circa initial commit, or has the surface improved (PSCmdlet-with-no-runspace-context, or test-friendlyPSCmdletExtensions)?Catalog what we'd actually gain from PSCmdlet.
ParameterSetNameis the obvious one. Also:MyInvocation.BoundParameters,SessionState,Stopping,WriteProgressoverloads, ShouldProcess support. Some of these are nice-to-have, some unblock specific cmdlet designs — document concretely.Catalog the current
VTest.PowerShelltest patterns that would break and what it'd take to migrate them. The two patterns in play are:Cmd_*helpers inVisioPS_Session.cs),InvokeScript<T>helper, used for parameter-binding tests like the #143 audit).The second already drives a runspace, so it'd survive a PSCmdlet base. The first is the at-risk pattern. Question: can it be adapted to drive a minimal runspace with the same ergonomics, or is there a wrapper that fills in
MyInvocationfor direct-invoked PSCmdlet instances?Decide the migration shape if it goes ahead. All-at-once base swap, or PSCmdlet for new cmdlets only? If we keep both, any sister-class concerns?
Why now
This came up while implementing #163 (pipeline parameter set on
Connect-VisioShape). The pipeline form worked when run from a real PowerShell session, but tests exercising the same path throughVTest.PowerShell'sInvokeScript<T>plumbing failed with a Visio session mismatch (CommandTarget: application does not match doc.application). That looked initially like a test-infrastructure quirk specific to runspace-invoked cmdlets that touchTargetPage.Auto, and one of the clean fixes (useParameterSetNamein the cmdlet to take a different code path) is the kind of thing PSCmdlet would unlock. So #163 is parked behind this investigation rather than worked around.Acceptance
docs/decisions/) capturing: original blocker, today's repro / non-repro, the trade-off, and the recommendation.Connect-VisioShapesfor the bulk path) if the pipeline ergonomics goal is still wanted.Effort
M. Mostly investigation and writing, but the test-pattern audit could surface unexpected migrations. ~half a day for the recommendation memo, more if migration is the answer.
Themed milestone
Milestone B (Test infrastructure).