mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Fix table alignment and padding. (#6230)
- The original change to remove extra padding didn't take into account alignment. Fix logic to accommodate left, center, and right alignment in the table format and also add tests. - Fix ImplicitRemoting test that validates formatting to use same instance due to formatting changes in this PR - Only use loopback to same powershell instance for formatting test as the other tests implicitly expect Windows PowerShell.
This commit is contained in:
@@ -387,7 +387,7 @@ namespace Microsoft.PowerShell.Commands.Internal.Format
|
||||
string currentValue = s;
|
||||
int currentValueDisplayLength = dc.Length(currentValue);
|
||||
|
||||
if (addPadding && currentValueDisplayLength < width)
|
||||
if (currentValueDisplayLength < width)
|
||||
{
|
||||
// the string is shorter than the width of the column
|
||||
// need to pad with with blanks to reach the desired width
|
||||
@@ -406,14 +406,21 @@ namespace Microsoft.PowerShell.Commands.Internal.Format
|
||||
int padLeft = padCount / 2;
|
||||
int padRight = padCount - padLeft;
|
||||
|
||||
s = StringUtil.Padding(padLeft) + s + StringUtil.Padding(padRight);
|
||||
s = StringUtil.Padding(padLeft) + s;
|
||||
if (addPadding)
|
||||
{
|
||||
s += StringUtil.Padding(padRight);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
// left align is the default
|
||||
s += StringUtil.Padding(padCount);
|
||||
if (addPadding)
|
||||
{
|
||||
// left align is the default
|
||||
s += StringUtil.Padding(padCount);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -497,8 +504,6 @@ namespace Microsoft.PowerShell.Commands.Internal.Format
|
||||
{
|
||||
return s;
|
||||
}
|
||||
// we have to pad
|
||||
System.Diagnostics.Debug.Assert(finalValueDisplayLength == width - 1, "padding is not correct");
|
||||
switch (alignment)
|
||||
{
|
||||
case TextAlignment.Right:
|
||||
@@ -509,7 +514,10 @@ namespace Microsoft.PowerShell.Commands.Internal.Format
|
||||
|
||||
case TextAlignment.Center:
|
||||
{
|
||||
s += " ";
|
||||
if (addPadding)
|
||||
{
|
||||
s += " ";
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -200,4 +200,150 @@ Describe "Format-Table DRT Unit Tests" -Tags "CI" {
|
||||
$out = [pscustomobject]@{a=1;b=2} | Format-Table -HideTableHeaders | Out-String
|
||||
$out.Replace([System.Environment]::NewLine, "") | Should BeExactly "1 2"
|
||||
}
|
||||
|
||||
It "Format-Table should have correct alignment" {
|
||||
$ps1xml = @"
|
||||
<Configuration>
|
||||
<ViewDefinitions>
|
||||
<View>
|
||||
<Name>Test.Format</Name>
|
||||
<ViewSelectedBy>
|
||||
<TypeName>Test.Format</TypeName>
|
||||
</ViewSelectedBy>
|
||||
<TableControl>
|
||||
<TableHeaders>
|
||||
<TableColumnHeader>
|
||||
<Label>Left</Label>
|
||||
<Alignment>left</Alignment>
|
||||
</TableColumnHeader>
|
||||
<TableColumnHeader>
|
||||
<Label>Center</Label>
|
||||
<Alignment>center</Alignment>
|
||||
</TableColumnHeader>
|
||||
<TableColumnHeader>
|
||||
<Label>Right</Label>
|
||||
<Alignment>right</Alignment>
|
||||
</TableColumnHeader>
|
||||
</TableHeaders>
|
||||
<TableRowEntries>
|
||||
<TableRowEntry>
|
||||
<TableColumnItems>
|
||||
<TableColumnItem>
|
||||
<PropertyName>Left</PropertyName>
|
||||
</TableColumnItem>
|
||||
<TableColumnItem>
|
||||
<PropertyName>Center</PropertyName>
|
||||
</TableColumnItem>
|
||||
<TableColumnItem>
|
||||
<PropertyName>Right</PropertyName>
|
||||
</TableColumnItem>
|
||||
</TableColumnItems>
|
||||
</TableRowEntry>
|
||||
</TableRowEntries>
|
||||
</TableControl>
|
||||
</View>
|
||||
</ViewDefinitions>
|
||||
</Configuration>
|
||||
"@
|
||||
|
||||
$ps1xmlPath = Join-Path -Path $TestDrive -ChildPath "test.format.ps1xml"
|
||||
Set-Content -Path $ps1xmlPath -Value $ps1xml
|
||||
# run in own runspace so not affect global sessionstate
|
||||
$ps = [powershell]::Create()
|
||||
$ps.AddScript( {
|
||||
param($ps1xmlPath)
|
||||
Update-FormatData -AppendPath $ps1xmlPath
|
||||
$a = [PSCustomObject]@{Left=1;Center=2;Right=3}
|
||||
$a.PSObject.TypeNames.Insert(0,"Test.Format")
|
||||
$a | Out-String
|
||||
} ).AddArgument($ps1xmlPath) | Out-Null
|
||||
$output = $ps.Invoke()
|
||||
|
||||
$expectedTable = @"
|
||||
|
||||
Left Center Right
|
||||
---- ------ -----
|
||||
1 2 3
|
||||
|
||||
|
||||
|
||||
"@
|
||||
$output.Replace("`n","").Replace("`r","") | Should BeExactly $expectedTable.Replace("`n","").Replace("`r","")
|
||||
}
|
||||
|
||||
It "Format-Table should not have trailing whitespace if there is truncation: <view>" -TestCases @(
|
||||
# `u{2B758} is a double-byte Japanese character
|
||||
@{view="Test.Format.Left" ; object=[pscustomobject]@{Left="123`u{2B758}"} ; expected="Left----1..." },
|
||||
@{view="Test.Format.Center"; object=[pscustomobject]@{Center="12345`u{2B758}"}; expected="Center------123..."}
|
||||
) {
|
||||
param($view, $object, $expected)
|
||||
|
||||
$ps1xml = @"
|
||||
<Configuration>
|
||||
<ViewDefinitions>
|
||||
<View>
|
||||
<Name>Test.Format.Left</Name>
|
||||
<ViewSelectedBy>
|
||||
<TypeName>Test.Format</TypeName>
|
||||
</ViewSelectedBy>
|
||||
<TableControl>
|
||||
<TableHeaders>
|
||||
<TableColumnHeader>
|
||||
<Label>Left</Label>
|
||||
<Alignment>left</Alignment>
|
||||
<Width>4</Width>
|
||||
</TableColumnHeader>
|
||||
</TableHeaders>
|
||||
<TableRowEntries>
|
||||
<TableRowEntry>
|
||||
<TableColumnItems>
|
||||
<TableColumnItem>
|
||||
<PropertyName>Left</PropertyName>
|
||||
</TableColumnItem>
|
||||
</TableColumnItems>
|
||||
</TableRowEntry>
|
||||
</TableRowEntries>
|
||||
</TableControl>
|
||||
</View>
|
||||
<View>
|
||||
<Name>Test.Format.Center</Name>
|
||||
<ViewSelectedBy>
|
||||
<TypeName>Test.Format</TypeName>
|
||||
</ViewSelectedBy>
|
||||
<TableControl>
|
||||
<TableHeaders>
|
||||
<TableColumnHeader>
|
||||
<Label>Center</Label>
|
||||
<Alignment>center</Alignment>
|
||||
<Width>6</Width>
|
||||
</TableColumnHeader>
|
||||
</TableHeaders>
|
||||
<TableRowEntries>
|
||||
<TableRowEntry>
|
||||
<TableColumnItems>
|
||||
<TableColumnItem>
|
||||
<PropertyName>Center</PropertyName>
|
||||
</TableColumnItem>
|
||||
</TableColumnItems>
|
||||
</TableRowEntry>
|
||||
</TableRowEntries>
|
||||
</TableControl>
|
||||
</View>
|
||||
</ViewDefinitions>
|
||||
</Configuration>
|
||||
"@
|
||||
|
||||
$ps1xmlPath = Join-Path -Path $TestDrive -ChildPath "test.format.ps1xml"
|
||||
Set-Content -Path $ps1xmlPath -Value $ps1xml
|
||||
# run in own runspace so not affect global sessionstate
|
||||
$ps = [powershell]::Create()
|
||||
$ps.AddScript( {
|
||||
param($ps1xmlPath,$view,$object)
|
||||
Update-FormatData -AppendPath $ps1xmlPath
|
||||
$object.PSObject.TypeNames.Insert(0,"Test.Format")
|
||||
$object | Format-Table -View $view | Out-String
|
||||
} ).AddArgument($ps1xmlPath).AddArgument($view).AddArgument($object) | Out-Null
|
||||
$output = $ps.Invoke()
|
||||
$output.Replace("`n","").Replace("`r","") | Should BeExactly $expected
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ try
|
||||
# GET CERTIFICATE
|
||||
#
|
||||
|
||||
$tempName = "$env:TEMP\signedscript_$(Get-Random).ps1"
|
||||
$tempName = "TESTDRIVE:\signedscript_$(Get-Random).ps1"
|
||||
"123456" > $tempName
|
||||
$cert = $null
|
||||
foreach ($thisCertificate in (Get-ChildItem cert:\ -rec -codesigning))
|
||||
@@ -71,18 +71,18 @@ try
|
||||
$store.Close()
|
||||
}
|
||||
|
||||
#
|
||||
# Create a remote session
|
||||
#
|
||||
|
||||
$session = New-RemoteSession
|
||||
|
||||
#
|
||||
# Set process scope execution policy to 'AllSigned'
|
||||
#
|
||||
|
||||
$oldExecutionPolicy = Get-ExecutionPolicy -Scope Process
|
||||
Set-ExecutionPolicy AllSigned -Scope Process
|
||||
|
||||
#
|
||||
# Create a remote session
|
||||
#
|
||||
|
||||
$session = New-RemoteSession
|
||||
}
|
||||
|
||||
AfterAll {
|
||||
@@ -510,8 +510,9 @@ try
|
||||
|
||||
BeforeAll {
|
||||
if ($skipTest) { return }
|
||||
# remote into same powershell instance
|
||||
$samesession = New-RemoteSession -ConfigurationName $endpointName
|
||||
$session = New-RemoteSession
|
||||
|
||||
function CreateTempPs1xmlFile
|
||||
{
|
||||
do {
|
||||
@@ -626,6 +627,7 @@ try
|
||||
AfterAll {
|
||||
if ($skipTest) { return }
|
||||
if ($null -ne $session) { Remove-PSSession $session -ErrorAction SilentlyContinue }
|
||||
if ($null -ne $samesession) { Remove-PSSession $samesession -ErrorAction SilentlyContinue }
|
||||
if ($null -ne $formatFile) { Remove-Item $formatFile -Force -ErrorAction SilentlyContinue }
|
||||
if ($null -ne $typeFile) { Remove-Item $typeFile -Force -ErrorAction SilentlyContinue }
|
||||
}
|
||||
@@ -638,16 +640,16 @@ try
|
||||
$originalLocalFormatting = & $formattingScript
|
||||
|
||||
# Original local and remote formatting should be equal (sanity check)
|
||||
$originalRemoteFormatting = Invoke-Command $session $formattingScript
|
||||
$originalRemoteFormatting = Invoke-Command $samesession $formattingScript
|
||||
$originalLocalFormatting | Should Be $originalRemoteFormatting
|
||||
|
||||
Invoke-Command $session { param($file) Update-FormatData $file } -ArgumentList $formatFile
|
||||
Invoke-Command $samesession { param($file) Update-FormatData $file } -ArgumentList $formatFile
|
||||
|
||||
# Original remote and modified remote formatting should not be equal (sanity check)
|
||||
$modifiedRemoteFormatting = Invoke-Command $session $formattingScript
|
||||
$modifiedRemoteFormatting = Invoke-Command $samesession $formattingScript
|
||||
$originalRemoteFormatting | Should Not Be $modifiedRemoteFormatting
|
||||
|
||||
$module = Import-PSSession -Session $session -CommandName @() -FormatTypeName * -AllowClobber
|
||||
$module = Import-PSSession -Session $samesession -CommandName @() -FormatTypeName * -AllowClobber
|
||||
}
|
||||
|
||||
AfterAll {
|
||||
@@ -2010,7 +2012,7 @@ try
|
||||
BeforeAll {
|
||||
# Skip tests for CoreCLR for now
|
||||
# Skip tests if .NET 2.0 and PS 2.0 are not installed on the machine
|
||||
$skipThisTest = $skipTest -or $IsCoreCLR -or
|
||||
$skipThisTest = $skipTest -or $IsCoreCLR -or
|
||||
(! (Test-Path 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v2.0.50727')) -or
|
||||
(! (Test-Path 'HKLM:\SOFTWARE\Microsoft\PowerShell\1\PowerShellEngine'))
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License.
|
||||
Describe "Set-Date for admin" -Tag @('CI', 'RequireAdminOnWindows', 'RequireSudoOnUnix') {
|
||||
It "Set-Date should be able to set the date in an elevated context" {
|
||||
It "Set-Date should be able to set the date in an elevated context" -Pending {
|
||||
{ Get-Date | Set-Date } | Should Not Throw
|
||||
}
|
||||
|
||||
It "Set-Date should be able to set the date with -Date parameter" {
|
||||
It "Set-Date should be able to set the date with -Date parameter" -Pending {
|
||||
$target = Get-Date
|
||||
$expected = $target
|
||||
Set-Date -Date $target | Should Be $expected
|
||||
|
||||
Reference in New Issue
Block a user