diff --git a/.copilot/skills/apex-migration/SKILL.md b/.copilot/skills/apex-migration/SKILL.md index d850b9c2f97..387b9791100 100644 --- a/.copilot/skills/apex-migration/SKILL.md +++ b/.copilot/skills/apex-migration/SKILL.md @@ -263,13 +263,17 @@ using var testContext = new ApexTestContext(VisualStudio, ProjectTemplate.NetCor ## Style rules +Follow the repo-wide coding guidelines first — they apply to all code, not just migrations: +[`docs/coding-guidelines.md`](../../../docs/coding-guidelines.md) (e.g. no `#region` blocks, no +reflection, `var` usage, nullable enabled). Don't restate or duplicate those rules here; this section +only lists conventions **specific to test migration** that supplement the common guidelines: + - Use `using var` (inline using declaration), not `using (var ...) { }`. - Place migrated tests before the static helper methods (`GetNetCoreTemplates`, etc.) in the file. - Method names: `{Action}FromPMC{Scenario}[_Fails|Async]`. Suffix with `_Fails` for error tests, `Async` for async tests. - Always include `[Timeout(DefaultTimeout)]`. - Always include `nugetConsole.GetText()` in assertion failure messages for diagnostics. -- Use `var` for local variables except value tuples (use decomposed names). - The test class inherits `SharedVisualStudioHostTestClass` which provides `VisualStudio` and `Logger`. - Get PMC console via `GetConsole(testContext.Project)` helper method in the test class. - Don't use the method-delegates-to-async-helper pattern unless the helper is actually called from diff --git a/test/NuGet.Clients.Tests/NuGetConsole.Host.PowerShell.Test/Cmdlets/FindPackageCommandTests.cs b/test/NuGet.Clients.Tests/NuGetConsole.Host.PowerShell.Test/Cmdlets/FindPackageCommandTests.cs index e5639cd6db9..d4d240de62d 100644 --- a/test/NuGet.Clients.Tests/NuGetConsole.Host.PowerShell.Test/Cmdlets/FindPackageCommandTests.cs +++ b/test/NuGet.Clients.Tests/NuGetConsole.Host.PowerShell.Test/Cmdlets/FindPackageCommandTests.cs @@ -3,12 +3,7 @@ using System; using System.Collections.Generic; -using System.Globalization; using System.Linq; -using System.Management.Automation; -using System.Management.Automation.Host; -using System.Management.Automation.Runspaces; -using System.Threading; using System.Threading.Tasks; using FluentAssertions; using Microsoft.VisualStudio.ComponentModelHost; @@ -26,7 +21,6 @@ using NuGet.VisualStudio; using Test.Utility; using Xunit; -using PSCommand = System.Management.Automation.Runspaces.Command; namespace NuGetConsole.Host.PowerShell.Test { @@ -239,8 +233,6 @@ await SimpleTestPackageUtility.CreatePackagesAsync( package.Version.ToString().Should().Be("1.0.0-beta"); } - #region Helpers - private void SetupSourceRepositoryProvider(string localSourcePath) { var localSource = new PackageSource(localSourcePath); @@ -257,78 +249,5 @@ private void SetupSourceRepositoryProvider(string localSourcePath) return Task.FromResult(null); } - - #endregion - - #region Test Infrastructure - - /// - /// Encapsulates runspace and host setup for invoking the Find-Package cmdlet in tests. - /// - private sealed class CmdletRunspaceFixture : IDisposable - { - private readonly Runspace _runspace; - - public CmdletRunspaceFixture(string activeSource = "https://contoso.com/v3/index.json") - { - var host = new TestPSHost(activeSource); - var initialSessionState = InitialSessionState.CreateDefault(); - initialSessionState.Commands.Add( - new SessionStateCmdletEntry("Find-Package", typeof(FindPackageCommand), null)); - - _runspace = RunspaceFactory.CreateRunspace(host, initialSessionState); - _runspace.Open(); - } - - public IList Invoke(string cmdletName, Dictionary parameters) - { - using var pipeline = _runspace.CreatePipeline(); - var cmd = new PSCommand(cmdletName); - foreach (var kvp in parameters) - { - cmd.Parameters.Add(kvp.Key, kvp.Value); - } - pipeline.Commands.Add(cmd); - return pipeline.Invoke().ToList(); - } - - public void Dispose() - { - _runspace.Close(); - _runspace.Dispose(); - } - } - - /// - /// Minimal PSHost that provides PrivateData with properties expected by NuGet cmdlets. - /// - private sealed class TestPSHost : PSHost - { - private readonly Guid _instanceId = Guid.NewGuid(); - private readonly PSObject _privateData; - - public TestPSHost(string activeSource) - { - _privateData = new PSObject(); - _privateData.Properties.Add(new PSNoteProperty("activePackageSource", activeSource)); - _privateData.Properties.Add(new PSNoteProperty("CancellationTokenKey", CancellationToken.None)); - } - - public override CultureInfo CurrentCulture => CultureInfo.InvariantCulture; - public override CultureInfo CurrentUICulture => CultureInfo.InvariantCulture; - public override Guid InstanceId => _instanceId; - public override string Name => "TestNuGetHost"; - public override PSObject PrivateData => _privateData; - public override PSHostUserInterface? UI => null; - public override Version Version => new Version(1, 0); - - public override void EnterNestedPrompt() { } - public override void ExitNestedPrompt() { } - public override void NotifyBeginApplication() { } - public override void NotifyEndApplication() { } - public override void SetShouldExit(int exitCode) { } - } - - #endregion } } diff --git a/test/NuGet.Clients.Tests/NuGetConsole.Host.PowerShell.Test/Cmdlets/GetPackageCommandTests.cs b/test/NuGet.Clients.Tests/NuGetConsole.Host.PowerShell.Test/Cmdlets/GetPackageCommandTests.cs index 47336cf1450..19fd714ba03 100644 --- a/test/NuGet.Clients.Tests/NuGetConsole.Host.PowerShell.Test/Cmdlets/GetPackageCommandTests.cs +++ b/test/NuGet.Clients.Tests/NuGetConsole.Host.PowerShell.Test/Cmdlets/GetPackageCommandTests.cs @@ -3,11 +3,8 @@ using System; using System.Collections.Generic; -using System.Globalization; using System.Linq; using System.Management.Automation; -using System.Management.Automation.Host; -using System.Management.Automation.Runspaces; using System.Threading; using System.Threading.Tasks; using FluentAssertions; @@ -30,7 +27,6 @@ using NuGet.VisualStudio; using Test.Utility; using Xunit; -using PSCommand = System.Management.Automation.Runspaces.Command; namespace NuGetConsole.Host.PowerShell.Test { @@ -629,8 +625,6 @@ public void GetPackage_WithUnsavedSolution_Throws() .Contain("Solution is not saved."); } - #region Helpers - private void SetupSourceRepositoryProvider(string localSourcePath) { var localSource = new PackageSource(localSourcePath); @@ -688,78 +682,5 @@ private void SetupProjectWithInstalledPackage(string packageId, string packageVe return Task.FromResult(null); } - - #endregion - - #region Test Infrastructure - - /// - /// Encapsulates runspace and host setup for invoking NuGet PowerShell cmdlets in tests. - /// - private sealed class CmdletRunspaceFixture : IDisposable - { - private readonly Runspace _runspace; - - public CmdletRunspaceFixture(string activeSource = "https://contoso.com/v3/index.json") - { - var host = new TestPSHost(activeSource); - var initialSessionState = InitialSessionState.CreateDefault(); - initialSessionState.Commands.Add( - new SessionStateCmdletEntry("Get-Package", typeof(GetPackageCommand), null)); - - _runspace = RunspaceFactory.CreateRunspace(host, initialSessionState); - _runspace.Open(); - } - - public IList Invoke(string cmdletName, Dictionary parameters) - { - using var pipeline = _runspace.CreatePipeline(); - var cmd = new PSCommand(cmdletName); - foreach (var kvp in parameters) - { - cmd.Parameters.Add(kvp.Key, kvp.Value); - } - pipeline.Commands.Add(cmd); - return pipeline.Invoke().ToList(); - } - - public void Dispose() - { - _runspace.Close(); - _runspace.Dispose(); - } - } - - /// - /// Minimal PSHost that provides PrivateData with properties expected by NuGet cmdlets. - /// - private sealed class TestPSHost : PSHost - { - private readonly Guid _instanceId = Guid.NewGuid(); - private readonly PSObject _privateData; - - public TestPSHost(string activeSource) - { - _privateData = new PSObject(); - _privateData.Properties.Add(new PSNoteProperty("activePackageSource", activeSource)); - _privateData.Properties.Add(new PSNoteProperty("CancellationTokenKey", CancellationToken.None)); - } - - public override CultureInfo CurrentCulture => CultureInfo.InvariantCulture; - public override CultureInfo CurrentUICulture => CultureInfo.InvariantCulture; - public override Guid InstanceId => _instanceId; - public override string Name => "TestNuGetHost"; - public override PSObject PrivateData => _privateData; - public override PSHostUserInterface? UI => null; - public override Version Version => new Version(1, 0); - - public override void EnterNestedPrompt() { } - public override void ExitNestedPrompt() { } - public override void NotifyBeginApplication() { } - public override void NotifyEndApplication() { } - public override void SetShouldExit(int exitCode) { } - } - - #endregion } } diff --git a/test/NuGet.Clients.Tests/NuGetConsole.Host.PowerShell.Test/Fixtures/CmdletRunspaceFixture.cs b/test/NuGet.Clients.Tests/NuGetConsole.Host.PowerShell.Test/Fixtures/CmdletRunspaceFixture.cs new file mode 100644 index 00000000000..d1fbded0366 --- /dev/null +++ b/test/NuGet.Clients.Tests/NuGetConsole.Host.PowerShell.Test/Fixtures/CmdletRunspaceFixture.cs @@ -0,0 +1,85 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Management.Automation; +using System.Management.Automation.Host; +using System.Management.Automation.Runspaces; +using System.Threading; +using NuGet.PackageManagement.PowerShellCmdlets; +using PSCommand = System.Management.Automation.Runspaces.Command; + +namespace NuGetConsole.Host.PowerShell.Test +{ + /// + /// Encapsulates runspace and host setup for invoking NuGet PowerShell cmdlets in tests. + /// + internal sealed class CmdletRunspaceFixture : IDisposable + { + private readonly Runspace _runspace; + + public CmdletRunspaceFixture(string activeSource = "https://contoso.com/v3/index.json") + { + var host = new TestPSHost(activeSource); + var initialSessionState = InitialSessionState.CreateDefault(); + initialSessionState.Commands.Add( + new SessionStateCmdletEntry("Find-Package", typeof(FindPackageCommand), null)); + initialSessionState.Commands.Add( + new SessionStateCmdletEntry("Get-Package", typeof(GetPackageCommand), null)); + + _runspace = RunspaceFactory.CreateRunspace(host, initialSessionState); + _runspace.Open(); + } + + public IList Invoke(string cmdletName, Dictionary parameters) + { + using var pipeline = _runspace.CreatePipeline(); + var cmd = new PSCommand(cmdletName); + foreach (var kvp in parameters) + { + cmd.Parameters.Add(kvp.Key, kvp.Value); + } + pipeline.Commands.Add(cmd); + return pipeline.Invoke().ToList(); + } + + public void Dispose() + { + _runspace.Close(); + _runspace.Dispose(); + } + } + + /// + /// Minimal PSHost that provides PrivateData with properties expected by NuGet cmdlets. + /// + internal sealed class TestPSHost : PSHost + { + private readonly Guid _instanceId = Guid.NewGuid(); + private readonly PSObject _privateData; + + public TestPSHost(string activeSource) + { + _privateData = new PSObject(); + _privateData.Properties.Add(new PSNoteProperty("activePackageSource", activeSource)); + _privateData.Properties.Add(new PSNoteProperty("CancellationTokenKey", CancellationToken.None)); + } + + public override CultureInfo CurrentCulture => CultureInfo.InvariantCulture; + public override CultureInfo CurrentUICulture => CultureInfo.InvariantCulture; + public override Guid InstanceId => _instanceId; + public override string Name => "TestNuGetHost"; + public override PSObject PrivateData => _privateData; + public override PSHostUserInterface? UI => null; + public override Version Version => new Version(1, 0); + + public override void EnterNestedPrompt() { } + public override void ExitNestedPrompt() { } + public override void NotifyBeginApplication() { } + public override void NotifyEndApplication() { } + public override void SetShouldExit(int exitCode) { } + } +} diff --git a/test/NuGet.Tests.Apex/NuGet.Tests.Apex/NuGetEndToEndTests/GetPackageTestCase.cs b/test/NuGet.Tests.Apex/NuGet.Tests.Apex/NuGetEndToEndTests/GetPackageTestCase.cs index 58bef601347..d88adab6cb7 100644 --- a/test/NuGet.Tests.Apex/NuGet.Tests.Apex/NuGetEndToEndTests/GetPackageTestCase.cs +++ b/test/NuGet.Tests.Apex/NuGet.Tests.Apex/NuGetEndToEndTests/GetPackageTestCase.cs @@ -104,7 +104,7 @@ public async Task GetPackage_WithUpdates_ListsMultipleUpdatesAsync() /// /// Verifies that Get-Package -ListAvailable returns a package whose IsUpdate property - /// is not set (falsy). The original E2E test (Test-GetPackagesWithNoUpdatesReturnPackagesWithIsUpdateNotSet) + /// is not set (false). The original E2E test (Test-GetPackagesWithNoUpdatesReturnPackagesWithIsUpdateNotSet) /// called Assert-False on $package.IsUpdate — which succeeds because PowerShellRemotePackage /// does not have an IsUpdate property, so PowerShell returns $null (falsy). ///