mirror of
https://github.com/ChrisTitusTech/winutil.git
synced 2026-08-12 02:51:16 +10:00
Make MPO tweak a three-state control (#4897)
* refactor: make MPO tweak a three-state control * docs: explain MPO tweak states * docs: address code review comments * refactor: make Multiplane Overlay config-driven
This commit is contained in:
@@ -189,6 +189,14 @@ Describe "Tweaks config" {
|
||||
foreach ($registryEntry in @($tweak.Value.registry)) {
|
||||
if ($null -eq $registryEntry) { continue }
|
||||
|
||||
if ($registryEntry.Values) {
|
||||
if ($registryEntry.PSObject.Properties.Name -notcontains "DefaultValue" -or
|
||||
[string]::IsNullOrWhiteSpace([string]$registryEntry.DefaultValue)) {
|
||||
$invalidTweaks.Add("$($tweak.Name),registry")
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if ($registryEntry.PSObject.Properties.Name -notcontains "OriginalValue" -or
|
||||
[string]::IsNullOrWhiteSpace([string]$registryEntry.OriginalValue)) {
|
||||
$invalidTweaks.Add("$($tweak.Name),registry")
|
||||
@@ -429,6 +437,19 @@ Describe "UI-rendered config entries" {
|
||||
if (-not (Test-WinUtilHasNonEmptyProperty -Object $entry.Value -Name "ComboItems")) {
|
||||
$invalidEntries.Add("$($entry.Name) combobox missing ComboItems")
|
||||
}
|
||||
$statefulRegistry = @($entry.Value.registry | Where-Object Values)
|
||||
if ($statefulRegistry.Count -gt 0) {
|
||||
$comboItems = @($entry.Value.ComboItems)
|
||||
if ($statefulRegistry.Count -ne @($entry.Value.registry).Count) {
|
||||
$invalidEntries.Add("$($entry.Name) registry states must all use Values")
|
||||
} else {
|
||||
foreach ($setting in $statefulRegistry) {
|
||||
if (Compare-Object $comboItems @($setting.Values.PSObject.Properties.Name)) {
|
||||
$invalidEntries.Add("$($entry.Name) ComboItems and registry states do not match")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (-not (Test-WinUtilHasNonEmptyProperty -Object $entry.Value -Name "Description")) {
|
||||
$invalidEntries.Add("$($entry.Name) missing Description")
|
||||
@@ -442,7 +463,12 @@ Describe "UI-rendered config entries" {
|
||||
foreach ($registryEntry in @($entry.Value.registry)) {
|
||||
if ($null -eq $registryEntry) { continue }
|
||||
|
||||
foreach ($missingField in (Get-WinUtilMissingRequiredFields -EntryName "$($entry.Name),registry" -Entry $registryEntry -RequiredFields @("Path", "Name", "Type", "Value", "OriginalValue"))) {
|
||||
$requiredRegistryFields = if ($entry.Value.Type -eq "Combobox" -and $statefulRegistry.Count -gt 0) {
|
||||
@("Path", "Name", "Type", "DefaultValue", "Values")
|
||||
} else {
|
||||
@("Path", "Name", "Type", "Value", "OriginalValue")
|
||||
}
|
||||
foreach ($missingField in (Get-WinUtilMissingRequiredFields -EntryName "$($entry.Name),registry" -Entry $registryEntry -RequiredFields $requiredRegistryFields)) {
|
||||
$invalidEntries.Add($missingField)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
#===========================================================================
|
||||
# Tests - Multiplane Overlay
|
||||
#===========================================================================
|
||||
|
||||
BeforeAll {
|
||||
$script:repoRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path
|
||||
$script:config = Get-Content (Join-Path $script:repoRoot "config\tweaks.json") -Raw | ConvertFrom-Json
|
||||
$script:states = $script:config.WPFMultiplaneOverlay.registry
|
||||
. (Join-Path $script:repoRoot "functions\private\Get-WinUtilRegistryComboState.ps1")
|
||||
. (Join-Path $script:repoRoot "functions\private\Get-WinUtilRegistryComboValue.ps1")
|
||||
. (Join-Path $script:repoRoot "functions\private\Set-WinUtilRegistryComboState.ps1")
|
||||
|
||||
function Set-WinUtilRegistry {
|
||||
param($Name, $Path, $Type, $Value)
|
||||
}
|
||||
}
|
||||
|
||||
Describe "Multiplane Overlay configuration" {
|
||||
It "keeps every state and registry action in tweaks.json" {
|
||||
$script:config.WPFMultiplaneOverlay.Type | Should -Be "Combobox"
|
||||
$script:config.WPFMultiplaneOverlay.ComboItems | Should -Be @("Enabled", "Disabled (Compatibility)", "Fully Disabled")
|
||||
$script:states.Count | Should -Be 2
|
||||
$script:states[0].Values.PSObject.Properties.Name | Should -Be $script:config.WPFMultiplaneOverlay.ComboItems
|
||||
$script:states[0].Values.PSObject.Properties.Value | Should -Be @("<RemoveEntry>", "5", "5")
|
||||
$script:states[1].Values.PSObject.Properties.Value | Should -Be @("<RemoveEntry>", "<RemoveEntry>", "1")
|
||||
}
|
||||
|
||||
It "uses the generic combo registry handler" {
|
||||
$renderer = Get-Content (Join-Path $script:repoRoot "functions\public\Invoke-WPFUIElements.ps1") -Raw
|
||||
|
||||
$renderer | Should -Match 'Get-WinUtilRegistryComboState'
|
||||
$renderer | Should -Match 'Set-WinUtilRegistryComboState'
|
||||
$renderer | Should -Not -Match 'WPFMultiplaneOverlay'
|
||||
}
|
||||
}
|
||||
|
||||
Describe "Get-WinUtilRegistryComboState" {
|
||||
It "treats missing registry properties and paths as absent" -TestCases @(
|
||||
@{ Exception = [System.Management.Automation.PSArgumentException]::new("Property is missing") }
|
||||
@{ Exception = [System.Management.Automation.ItemNotFoundException]::new("Path is missing") }
|
||||
) {
|
||||
param($Exception)
|
||||
Mock Get-ItemProperty { throw $Exception }
|
||||
|
||||
Get-WinUtilRegistryComboState -Registry $script:states | Should -Be "Enabled"
|
||||
}
|
||||
|
||||
It "reports Enabled when the values are absent or zero" -TestCases @(
|
||||
@{ OverlayTestMode = $null; DisableOverlays = $null }
|
||||
@{ OverlayTestMode = 0; DisableOverlays = 0 }
|
||||
) {
|
||||
param($OverlayTestMode, $DisableOverlays)
|
||||
Mock Get-ItemProperty {
|
||||
if ($Name -eq "OverlayTestMode") {
|
||||
return [pscustomobject]@{ OverlayTestMode = $OverlayTestMode }
|
||||
}
|
||||
[pscustomobject]@{ DisableOverlays = $DisableOverlays }
|
||||
}
|
||||
|
||||
Get-WinUtilRegistryComboState -Registry $script:states | Should -Be "Enabled"
|
||||
}
|
||||
|
||||
It "reports each disabled state" -TestCases @(
|
||||
@{ OverlayTestMode = 5; DisableOverlays = $null; Expected = "Disabled (Compatibility)" }
|
||||
@{ OverlayTestMode = 5; DisableOverlays = 1; Expected = "Fully Disabled" }
|
||||
) {
|
||||
param($OverlayTestMode, $DisableOverlays, $Expected)
|
||||
Mock Get-ItemProperty {
|
||||
if ($Name -eq "OverlayTestMode") {
|
||||
return [pscustomobject]@{ OverlayTestMode = $OverlayTestMode }
|
||||
}
|
||||
[pscustomobject]@{ DisableOverlays = $DisableOverlays }
|
||||
}
|
||||
|
||||
Get-WinUtilRegistryComboState -Registry $script:states | Should -Be $Expected
|
||||
}
|
||||
|
||||
It "rejects an unsupported combination" {
|
||||
Mock Get-ItemProperty {
|
||||
if ($Name -eq "OverlayTestMode") {
|
||||
return [pscustomobject]@{ OverlayTestMode = 0 }
|
||||
}
|
||||
[pscustomobject]@{ DisableOverlays = 1 }
|
||||
}
|
||||
|
||||
{ Get-WinUtilRegistryComboState -Registry $script:states } | Should -Throw "Registry values do not match a supported state."
|
||||
}
|
||||
}
|
||||
|
||||
Describe "Set-WinUtilRegistryComboState" {
|
||||
BeforeEach {
|
||||
$script:registryValues = @{ OverlayTestMode = 0; DisableOverlays = 0 }
|
||||
Mock Get-ItemProperty {
|
||||
param($Path, $Name)
|
||||
$registryName = [string]$Name
|
||||
if ($script:registryValues.ContainsKey($registryName)) {
|
||||
$result = [pscustomobject]@{}
|
||||
$result | Add-Member -NotePropertyName $registryName -NotePropertyValue $script:registryValues[$registryName]
|
||||
return $result
|
||||
}
|
||||
[pscustomobject]@{}
|
||||
}
|
||||
Mock Set-WinUtilRegistry {
|
||||
param($Name, $Path, $Type, $Value)
|
||||
if ($Value -eq "<RemoveEntry>") {
|
||||
$script:registryValues.Remove($Name)
|
||||
} else {
|
||||
$script:registryValues[$Name] = [int]$Value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
It "applies each configured state" -TestCases @(
|
||||
@{ State = "Enabled"; OverlayTestMode = $null; DisableOverlays = $null }
|
||||
@{ State = "Disabled (Compatibility)"; OverlayTestMode = 5; DisableOverlays = $null }
|
||||
@{ State = "Fully Disabled"; OverlayTestMode = 5; DisableOverlays = 1 }
|
||||
) {
|
||||
param($State, $OverlayTestMode, $DisableOverlays)
|
||||
|
||||
Set-WinUtilRegistryComboState -Registry $script:states -State $State
|
||||
|
||||
$script:registryValues.OverlayTestMode | Should -Be $OverlayTestMode
|
||||
$script:registryValues.DisableOverlays | Should -Be $DisableOverlays
|
||||
}
|
||||
|
||||
It "restores previous values when verification fails" {
|
||||
Mock Set-WinUtilRegistry {
|
||||
param($Name, $Path, $Type, $Value)
|
||||
if ($Name -eq "DisableOverlays" -and $Value -eq 1) {
|
||||
return
|
||||
}
|
||||
if ($Value -eq "<RemoveEntry>") {
|
||||
$script:registryValues.Remove($Name)
|
||||
} else {
|
||||
$script:registryValues[$Name] = [int]$Value
|
||||
}
|
||||
}
|
||||
|
||||
{ Set-WinUtilRegistryComboState -Registry $script:states -State "Fully Disabled" } | Should -Throw "Unable to apply registry state*"
|
||||
$script:registryValues.OverlayTestMode | Should -Be 0
|
||||
$script:registryValues.DisableOverlays | Should -Be 0
|
||||
}
|
||||
|
||||
It "restores absence when a state cannot be applied" {
|
||||
$script:registryValues.Clear()
|
||||
Mock Set-WinUtilRegistry {
|
||||
param($Name, $Path, $Type, $Value)
|
||||
if ($Name -eq "DisableOverlays" -and $Value -eq 1) {
|
||||
return
|
||||
}
|
||||
if ($Value -eq "<RemoveEntry>") {
|
||||
$script:registryValues.Remove($Name)
|
||||
} else {
|
||||
$script:registryValues[$Name] = [int]$Value
|
||||
}
|
||||
}
|
||||
|
||||
{ Set-WinUtilRegistryComboState -Registry $script:states -State "Fully Disabled" } | Should -Throw "Unable to apply registry state*"
|
||||
$script:registryValues.ContainsKey("OverlayTestMode") | Should -BeFalse
|
||||
$script:registryValues.ContainsKey("DisableOverlays") | Should -BeFalse
|
||||
}
|
||||
|
||||
It "reports when the previous values cannot be restored" {
|
||||
Mock Set-WinUtilRegistry {
|
||||
param($Name, $Path, $Type, $Value)
|
||||
if (($Name -eq "DisableOverlays" -and $Value -eq 1) -or ($Name -eq "OverlayTestMode" -and $Value -eq 0)) {
|
||||
return
|
||||
}
|
||||
if ($Value -eq "<RemoveEntry>") {
|
||||
$script:registryValues.Remove($Name)
|
||||
} else {
|
||||
$script:registryValues[$Name] = [int]$Value
|
||||
}
|
||||
}
|
||||
|
||||
{ Set-WinUtilRegistryComboState -Registry $script:states -State "Fully Disabled" } | Should -Throw "*previous registry state could not be restored*"
|
||||
}
|
||||
}
|
||||
@@ -148,7 +148,6 @@ Describe "Set-WinUtilRegistry" {
|
||||
$registryPath = "HKLM:\Software\WinUtilTest"
|
||||
$script:testPathResults["HKU:\"] = $true
|
||||
$script:testPathResults[$registryPath] = $true
|
||||
|
||||
Set-WinUtilRegistry -Path $registryPath -Name "ObsoleteValue" -Type "String" -Value "<RemoveEntry>"
|
||||
|
||||
Should -Invoke -CommandName Set-ItemProperty -Times 0 -Exactly
|
||||
@@ -159,6 +158,7 @@ Describe "Set-WinUtilRegistry" {
|
||||
$ErrorAction -eq "Stop"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Describe "Set-WinUtilService" {
|
||||
|
||||
@@ -169,6 +169,7 @@ Describe "Invoke-WinUtilTweaks" {
|
||||
$Name -eq "DiagTrack" -and $StartupType -eq "Disabled"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Describe "Invoke-WPFtweaksbutton" {
|
||||
|
||||
Reference in New Issue
Block a user