Skip to content

tests: VTest.PowerShell two-Client mismatch blocks some cmdlet-binding tests #190

Description

@saveenr

Background

VTest.PowerShell has two paths for invoking cmdlets:

  1. Direct path (VisioPSSession.Cmd_* helpers): instantiates a cmdlet object in C# and calls cmd.Invoke() directly. Bypasses PowerShell's parameter binder.
  2. Runspace path (VisioPSSession.InvokeScript<T>): goes through PowerShell's actual binder via _powershell.AddScript(...).Invoke(). Required for binding tests (the whole point of #173).

Each path operates with its own VisioScripting.Client instance. When a single test mixes the two paths, those Clients disagree on which Visio app / document is "active." Cmdlets that call TargetShapes.ResolveToSelection (which routes through Client.GetCommandTarget) trip the application does not match doc.application consistency check and throw.

End users in a real PowerShell session never hit this: there's only one Client per session. It's a test-infrastructure-only quirk.

Concrete evidence

VTest.PowerShell/CmdletBindingTests.cs's ExportVisioShape_TargetExists_WithOverwrite_ReplacesFile is currently [Ignore]'d for exactly this reason. It hits CommandTarget: application does not match doc.application because:

  • Test setup creates a doc and shape via Cmd_* helpers (direct path → Client A).
  • Test action calls Export-VisioShape ... -Overwrite via InvokeScript (runspace path → Client B).
  • Export-VisioShape's success path reaches TargetShapes.ResolveToSelection, which makes the mismatched Client B see Client A's doc and reject the call.

The companion test ExportVisioShape_TargetExists_NoOverwrite_Throws in the same file works fine because the cmdlet throws at the file-existence check before reaching ResolveToSelection. So the issue specifically affects success-path tests for cmdlets that touch the active selection.

This is the same constraint that blocked #163 and led to filing #164.

Options

Option 1: All-runspace setup pattern

The mismatch goes away if setup + action all happen inside one InvokeScript call (or successive calls that share the runspace's SessionState). One Client, one consistent view. Concretely the [Ignore]'d test would change setup from Cmd_New_VisioDocument / Cmd_New_VisioShape_rectangle to in-script New-VisioDocument / New-VisioShape -Rectangle ....

If it works: we re-enable the test AND establish "all-runspace" as the canonical pattern for future binding tests, without touching VisioCmdlet / VisioPSSession infrastructure. Effort: S.

If it doesn't: the issue is deeper than test-method-level mixing (it's at the session level), and the proper fix really does need #164.

Option 2: Make VisioPSSession share a single Client across paths

Re-architect the test session so the Cmd_* helpers and the runspace cmdlets resolve to the same VisioScripting.Client instance. Likely requires touching VisioCmdlet base class to accept an externally-injected Client, or having VisioPSSession configure the runspace's Client to match the direct-path Client.

This is the structural fix. May overlap significantly with whatever #164 ends up doing.

Effort: M.

Option 3: Defer entirely to #164

Treat the mismatch as a known limitation; track it on #164; accept that some binding tests stay [Ignore]'d until #164 lands. Effort: zero (just close this issue as "duplicate of #164").

Suggested approach when picked up

Try Option 1 first since it's small. If the all-runspace pattern works:

  • Re-enable the [Ignore]'d test.
  • Add a paragraph to docs/TESTING.md on the all-runspace pattern for cmdlet-binding tests.
  • File a sibling issue (or a comment on #173) noting that future cmdlet-binding tests should use the all-runspace pattern by default.

If Option 1 doesn't work (the mismatch is deeper than method-level mixing), escalate to Option 2 or #164.

Cross-refs

  • #164 - Investigate switching VisioCmdlet base from Cmdlet to PSCmdlet (related architectural question).
  • #163 - The original bug report that surfaced this mismatch.
  • #173 - Cmdlet-binding test coverage; the [Ignore]'d test came out of the first slice.
  • memory: feedback_pscmdlet_avoid - The constraint that motivated keeping VisioCmdlet : Cmdlet rather than PSCmdlet.

Effort

S to investigate Option 1. M if Option 2 is needed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions