mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-08-29 10:09:43 +02:00
## Summary of the Pull Request Adds `PowerToys.PowerDisplay.Cli.exe`, a scriptable interface for controlling monitors through the running PowerDisplay process. It supports `list`, `get`, `set`, `up`, `down`, `capabilities`, `profiles`, and `apply-profile`. The CLI communicates over an authenticated, per-session named pipe; PowerDisplay remains responsible for DDC/CI and WMI access. ## PR Checklist - [x] Closes: #48713 - [x] **Communication:** Discussed with core contributors - [x] **Tests:** Added/updated and all pass - [x] **Localization:** Core errors are localizable; some help and output text remains English-only - [ ] **Dev docs:** N/A; built-in CLI help is the command reference - [x] **New binaries:** Added on the required places - [x] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) - [x] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetupVNext/Resources.wxs) - [x] **YML for CI pipeline:** N/A; test assemblies are auto-discovered - [x] **YML for signed pipeline:** N/A; signing is driven by `ESRPSigning_core.json` - [ ] **Documentation updated:** N/A ## Detailed Description of the Pull Request / Additional comments - Adds an AOT-compatible CLI and shared request/response contracts. - Uses a secured named-pipe server in PowerDisplay, with stable exit codes and a bounded request timeout. - Supports saved profiles by their existing stable profile IDs. - Adds solution, signing, installer, and unit-test project integration. ## Validation Steps Performed - PowerDisplay Lib, Contracts, CLI, and IPC unit-test suites pass. - Native AOT publish completes without analyzer warnings. - Manually validated the CLI on two DDC/CI monitors, including the PowerDisplay-unavailable path. - Rebuilt the PowerDisplay GUI after the shared-library changes. --------- Co-authored-by: Yu Leng <yuleng@microsoft.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
61 lines
2.6 KiB
C#
61 lines
2.6 KiB
C#
// Copyright (c) Microsoft Corporation
|
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
|
// See the LICENSE file in the project root for more information.
|
|
|
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
using PowerDisplay.Cli.Options;
|
|
using PowerDisplay.Cli.Properties;
|
|
|
|
namespace PowerDisplay.Cli.UnitTests;
|
|
|
|
[TestClass]
|
|
public class ResourcesTests
|
|
{
|
|
private const string ExecutableName = "PowerToys.PowerDisplay.Cli.exe";
|
|
|
|
[TestMethod]
|
|
public void CommandHints_ReferenceShippedExecutable()
|
|
{
|
|
StringAssert.Contains(Resources.Hint_UseSetForAbsolute, ExecutableName);
|
|
StringAssert.Contains(Resources.Hint_UseHexVcp, ExecutableName);
|
|
StringAssert.Contains(Resources.Hint_RunList, ExecutableName);
|
|
StringAssert.Contains(Resources.Hint_SelectorMissing, ExecutableName);
|
|
StringAssert.Contains(Resources.Hint_RunProfiles, ExecutableName);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void OptionDescriptions_ReferenceShippedExecutable()
|
|
{
|
|
StringAssert.Contains(CliOptions.MonitorNumber.Description, ExecutableName);
|
|
StringAssert.Contains(CliOptions.ColorTemperature.Description, ExecutableName);
|
|
StringAssert.Contains(CliOptions.InputSource.Description, ExecutableName);
|
|
StringAssert.Contains(CliOptions.PowerState.Description, ExecutableName);
|
|
StringAssert.Contains(CliOptions.ProfileId.Description, ExecutableName);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void SafeFormat_PlaceholderIndexOutOfRange_DoesNotThrow_ReturnsTemplate()
|
|
{
|
|
// A translation that renumbers a placeholder ({0} -> {1}) leaves an index with no argument;
|
|
// the guarantee is "degrade to the template, never throw".
|
|
Assert.AreEqual("value {1}", Resources.SafeFormat("value {1}", "x"));
|
|
}
|
|
|
|
[TestMethod]
|
|
public void SafeFormat_UnescapedBrace_DoesNotThrow_ReturnsTemplate()
|
|
{
|
|
// A translation with an unescaped brace is also a malformed format string.
|
|
Assert.AreEqual("oops {", Resources.SafeFormat("oops {", "x"));
|
|
}
|
|
|
|
[TestMethod]
|
|
public void SafeFormat_WellFormedTemplate_SubstitutesArgument()
|
|
{
|
|
// The success path must actually substitute — without this, a regression to `return template;`
|
|
// would silently drop every {0}/{1} from localized messages while the malformed-template tests
|
|
// above stayed green (a malformed template returns unchanged either way).
|
|
Assert.AreEqual("value x", Resources.SafeFormat("value {0}", "x"));
|
|
Assert.AreEqual("a then b", Resources.SafeFormat("{0} then {1}", "a", "b"));
|
|
}
|
|
}
|