Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
Format-Table.Tests.ps11001 linesDownload Raw Back to Microsoft.PowerShell.Utility
1# Copyright (c) Microsoft Corporation.2# Licensed under the MIT License.3Describe "Format-Table" -Tags "CI" {4    BeforeAll {5        if ($null -ne $PSStyle) {6            $outputRendering = $PSStyle.OutputRendering7            $PSStyle.OutputRendering = 'plaintext'8        }9        $noConsole = $true10        try {11            if ([Console]::WindowHeight -ne 0) {12                $noConsole = $false13            }14        } catch {15        }16    }17 18    AfterAll {19        if ($null -ne $PSStyle) {20            $PSStyle.OutputRendering = $outputRendering21        }22    }23 24        It "Should call format table on piped input without error" {25                { Get-Date | Format-Table } | Should -Not -Throw26        }27 28        It "Should return a format object data type" {29                $val = Get-Date | Format-Table | Get-Member30                $val2 = Get-Date | Format-Table | Get-Member31 32                $val.TypeName | Should -Match "Microsoft.Powershell.Commands.Internal.Format"33                $val2.TypeName | Should -Match "Microsoft.Powershell.Commands.Internal.Format"34        }35 36        It "Should be able to be called with optional parameters" {37                $v1 = Get-Date | Format-Table *38                $v2 = Get-Date | Format-Table -Property Hour39                $v3 = Get-Date | Format-Table -GroupBy Hour40        }41 42        It "Format-Table with not existing table with force should throw PipelineStoppedException"{43                $obj = New-Object -TypeName PSObject44                $e = { $obj | Format-Table -View bar -Force -ErrorAction Stop } |45                    Should -Throw -ErrorId "FormatViewNotFound,Microsoft.PowerShell.Commands.FormatTableCommand" -PassThru46                $e.CategoryInfo | Should -Match "PipelineStoppedException"47        }48 49        It "Format-Table with array should work" {50                $al = (0..255)51                $info = @{}52                $info.array = $al53                $result = $info | Format-Table | Out-String54                $result | Should -Match "array\s+{0, 1, 2, 3`u{2026}}" # ellipsis55        }56 57        It "Format-Table with Negative Count should work" {58                $FormatEnumerationLimit = -159                $result = Format-Table -InputObject @{'test'= 1, 2}60                $resultStr = $result | Out-String61                $resultStr | Should -Match "test\s+{1, 2}"62        }63 64        # Pending on issue#88865        It "Format-Table with Zero Count should work" -Pending {66                $FormatEnumerationLimit = 067                $result = Format-Table -InputObject @{'test'= 1, 2}68                $resultStr = $result | Out-String69                $resultStr | Should -Match "test\s+{...}"70        }71 72        It "Format-Table with Less Count should work" {73                $FormatEnumerationLimit = 174                $result = Format-Table -InputObject @{'test'= 1, 2}75                $resultStr = $result | Out-String76                $resultStr | Should -Match "test\s+{1...}"77        }78 79        It "Format-Table with More Count should work" {80                $FormatEnumerationLimit = 1081                $result = Format-Table -InputObject @{'test'= 1, 2}82                $resultStr = $result | Out-String83                $resultStr | Should -Match "test\s+{1, 2}"84        }85 86        It "Format-Table with Equal Count should work" {87                $FormatEnumerationLimit = 288                $result = Format-Table -InputObject @{'test'= 1, 2}89                $resultStr = $result | Out-String90                $resultStr | Should -Match "test\s+{1, 2}"91        }92 93        # Pending on issue#88894        It "Format-Table with Bogus Count should throw Exception" -Pending {95                $FormatEnumerationLimit = "abc"96                $result = Format-Table -InputObject @{'test'= 1, 2}97                $resultStr = $result|Out-String98                $resultStr | Should -Match "test\s+{1, 2}"99        }100 101        # Pending on issue#888102        It "Format-Table with Var Deleted should throw Exception" -Pending {103                $FormatEnumerationLimit = 2104                Remove-Variable FormatEnumerationLimit105                $result = Format-Table -InputObject @{'test'= 1, 2}106                $resultStr = $result | Out-String107                $resultStr | Should -Match "test\s+{1, 2}"108        }109 110        It "Format-Table with new line should work" {111                $info = @{}112                $info.name = "1\n2"113                $result = $info | Format-Table | Out-String114                $result | Should -Match "name\s+1.+2"115        }116 117        It "Format-Table with ExposeBug920454 should work" {118                $IP1 = [System.Net.IPAddress]::Parse("1.1.1.1")119                $IP2 = [System.Net.IPAddress]::Parse("4fde:0000:0000:0002:0022:f376:255.59.171.63")120                $IPs = New-Object System.Collections.ArrayList121                $IPs.Add($IP1)122                $IPs.Add($IP2)123                $info = @{}124                $info.test = $IPs125                $result = $info | Format-Table | Out-String126                $result | Should -Match "test\s+{1.1.1.1, 4fde::2:22:f376:ff3b:ab3f}"127        }128 129        It "Format-Table with Autosize should work" {130                $IP1 = [PSCustomObject]@{'name'='Bob';'size'=1234;'booleanValue'=$true;}131                $IP2 = [PSCustomObject]@{'name'='Jim';'size'=5678;'booleanValue'=$false;}132                $IPs = New-Object System.Collections.ArrayList133                $IPs.Add($IP1)134                $IPs.Add($IP2)135                $result = $IPs | Format-Table -AutoSize | Out-String136                $result | Should -Match "name size booleanValue"137                $result | Should -Match "---- ---- ------------"138                $result | Should -Match "Bob\s+1234\s+True"139                $result | Should -Match "Jim\s+5678\s+False"140        }141 142        It "Format-Table with '<testName>' should return `$null" -TestCases @(143            @{ testName = "empty array"; testObject = @{}   },144            @{ testName = "null"       ; testObject = $null }145        ) {146            param ($testObject)147                $result = $testObject | Format-Table -Property "foo","bar" | Out-String148                $result | Should -BeNullOrEmpty149        }150 151        It "Format-Table with '<testName>' string and -Force should output table with requested properties" -TestCases @(152            @{ testName = "single line"; testString = "single line string" },153            @{ testName = "multi line" ; testString = "line1`nline2"       },154            @{ testName = "array"      ; testString = "line1","line2"      }155        ) {156            param ($testString)157            $result = $testString | Format-Table -Property "fox","bar" -Force | Out-String158            $result.Replace(" ","").Replace([Environment]::NewLine,"") | Should -BeExactly "foxbar------"159        }160 161        It "Format-Table with complex object for End-To-End should work" {162                Add-Type -TypeDefinition "public enum MyDayOfWeek{Sun,Mon,Tue,Wed,Thu,Fri,Sat}"163                $eto = New-Object MyDayOfWeek164                $info = @{}165                $info.intArray = 1,2,3,4166                $info.arrayList = "string1","string2"167                $info.enumerable = [MyDayOfWeek]$eto168                $info.enumerableTestObject = $eto169                $result = $info|Format-Table|Out-String170                $result | Should -Match "intArray\s+{1, 2, 3, 4}"171                $result | Should -Match "arrayList\s+{string1, string2}"172                $result | Should -Match "enumerable\s+Sun"173                $result | Should -Match "enumerableTestObject\s+Sun"174        }175 176        It "Format-Table with Expand Enumerable should work" {177                $obj1 = "x 0","y 0"178                $obj2 = "x 1","y 1"179                $objs = New-Object System.Collections.ArrayList180                $objs.Add($obj1)181                $objs.Add($obj2)182                $mo = [PSCustomObject]@{name = "this is name";sub = $objs}183                $result1 = $mo|Format-Table -Expand CoreOnly|Out-String184                $result1 | Should -Match "name\s+sub"185                $result1 | Should -Match "this is name"186 187                $result2 = $mo|Format-Table -Expand EnumOnly|Out-String188                $result2 | Should -Match "name\s+sub"189                $result2 | Should -Match "this is name\s+{x 0 y 0, x 1 y 1}"190 191                $result3 = $mo|Format-Table -Expand Both|Out-String192                $result3 | Should -Match "name\s+sub"193                $result3 | Should -Match "this is name\s+{x 0 y 0, x 1 y 1}"194        }195 196        It "Format-Table should not add trailing whitespace to the header" {197            $out = "hello" | Format-Table -Property foo -Force | Out-String198            $out.Replace([System.Environment]::NewLine, "") | Should -BeExactly "foo---"199        }200 201        It "Format-Table should not add trailing whitespace to rows" {202            $out = [pscustomobject]@{a=1;b=2} | Format-Table -HideTableHeaders | Out-String203            $out.Replace([System.Environment]::NewLine, "") | Should -BeExactly "1 2"204        }205 206        It "Format-Table should have correct alignment" {207            $ps1xml = @"208<Configuration>209    <ViewDefinitions>210        <View>211            <Name>Test.Format</Name>212            <ViewSelectedBy>213                <TypeName>Test.Format</TypeName>214            </ViewSelectedBy>215            <TableControl>216                <TableHeaders>217                    <TableColumnHeader>218                        <Label>Left</Label>219                        <Alignment>left</Alignment>220                    </TableColumnHeader>221                    <TableColumnHeader>222                        <Label>Center</Label>223                        <Alignment>center</Alignment>224                    </TableColumnHeader>225                    <TableColumnHeader>226                        <Label>Right</Label>227                        <Alignment>right</Alignment>228                    </TableColumnHeader>229                </TableHeaders>230                <TableRowEntries>231                    <TableRowEntry>232                        <TableColumnItems>233                            <TableColumnItem>234                                <PropertyName>Left</PropertyName>235                            </TableColumnItem>236                            <TableColumnItem>237                                <PropertyName>Center</PropertyName>238                            </TableColumnItem>239                            <TableColumnItem>240                                <PropertyName>Right</PropertyName>241                            </TableColumnItem>242                        </TableColumnItems>243                    </TableRowEntry>244                </TableRowEntries>245            </TableControl>246        </View>247    </ViewDefinitions>248</Configuration>249"@250 251            $ps1xmlPath = Join-Path -Path $TestDrive -ChildPath "alignment.format.ps1xml"252            Set-Content -Path $ps1xmlPath -Value $ps1xml253            # run in own runspace so not affect global sessionstate254            $ps = [powershell]::Create()255            $ps.AddScript( {256                param($ps1xmlPath)257                Update-FormatData -AppendPath $ps1xmlPath258                $a = [PSCustomObject]@{Left=1;Center=2;Right=3}259                $a.PSObject.TypeNames.Insert(0,"Test.Format")260                $a | Out-String261            } ).AddArgument($ps1xmlPath) | Out-Null262            $output = $ps.Invoke()263 264            $expectedTable = @"265 266Left Center Right267---- ------ -----2681      2        3269 270 271 272"@273            $output.Replace("`n","").Replace("`r","") | Should -BeExactly $expectedTable.Replace("`n","").Replace("`r","")274        }275 276        It "Format-Table should not have trailing whitespace if there is truncation: <view>" -TestCases @(277            # `u{2B758} is a double-byte Japanese character278            # `u{2026} is the ellipsis279            @{view="Test.Format.Left"  ; object=[pscustomobject]@{Left="123`u{2B758}"}    ; expected="Left----123`u{2026}"      },280            @{view="Test.Format.Center"; object=[pscustomobject]@{Center="12345`u{2B758}"}; expected="Center------12345`u{2026}"}281        ) {282            param($view, $object, $expected)283 284            $ps1xml = @"285<Configuration>286    <ViewDefinitions>287        <View>288            <Name>Test.Format.Left</Name>289            <ViewSelectedBy>290                <TypeName>Test.Format</TypeName>291            </ViewSelectedBy>292            <TableControl>293                <TableHeaders>294                    <TableColumnHeader>295                        <Label>Left</Label>296                        <Alignment>left</Alignment>297                        <Width>4</Width>298                    </TableColumnHeader>299                </TableHeaders>300                <TableRowEntries>301                    <TableRowEntry>302                        <TableColumnItems>303                            <TableColumnItem>304                                <PropertyName>Left</PropertyName>305                            </TableColumnItem>306                        </TableColumnItems>307                    </TableRowEntry>308                </TableRowEntries>309            </TableControl>310        </View>311        <View>312            <Name>Test.Format.Center</Name>313            <ViewSelectedBy>314                <TypeName>Test.Format</TypeName>315            </ViewSelectedBy>316            <TableControl>317                <TableHeaders>318                    <TableColumnHeader>319                        <Label>Center</Label>320                        <Alignment>center</Alignment>321                        <Width>6</Width>322                    </TableColumnHeader>323                </TableHeaders>324                <TableRowEntries>325                    <TableRowEntry>326                        <TableColumnItems>327                            <TableColumnItem>328                                <PropertyName>Center</PropertyName>329                            </TableColumnItem>330                        </TableColumnItems>331                    </TableRowEntry>332                </TableRowEntries>333            </TableControl>334        </View>335    </ViewDefinitions>336</Configuration>337"@338 339            $ps1xmlPath = Join-Path -Path $TestDrive -ChildPath "truncation.format.ps1xml"340            Set-Content -Path $ps1xmlPath -Value $ps1xml341            # run in own runspace so not affect global sessionstate342            $ps = [powershell]::Create()343            $ps.AddScript( {344                param($ps1xmlPath,$view,$object)345                Update-FormatData -AppendPath $ps1xmlPath346                $object.PSObject.TypeNames.Insert(0,"Test.Format")347                $object | Format-Table -View $view | Out-String348            } ).AddArgument($ps1xmlPath).AddArgument($view).AddArgument($object) | Out-Null349            $output = $ps.Invoke()350            $output.Replace("`n","").Replace("`r","") | Should -BeExactly $expected351        }352 353        It "Format-Table should correctly render headers that span multiple rows: <variation>" -TestCases @(354            @{ view = "Default"; widths = 7,7,7; variation = "2 row, 1 row, 1 row"; expectedTable = @"355 356LongLon Header2 Header3357gHeader358------- ------- -------3591       2       3360 361 362"@ },363            @{ view = "Default"; widths = 4,7,4; variation = "4 row, 1 row, 2 row"; expectedTable = @"364 365Long Header2 Head366Long         er3367Head368er369---- ------- ----3701    2       3371 372 373"@ },374            @{ view = "Default"; widths = 4,4,7; variation = "4 row, 2 row, 1 row"; expectedTable = @"375 376Long Head Header3377Long er2378Head379er380---- ---- -------3811    2    3382 383 384"@ },385            @{ view = "Default"; widths = 14,7,3; variation = "1 row, 1 row, 3 row"; expectedTable = @"386 387LongLongHeader Header2 Hea388                       der389                       3390-------------- ------- ---3911              2       3392 393 394"@ },395            @{ view = "One"; widths = 4,1,1; variation = "1 column"; expectedTable = @"396 397Long398Long399Head400er401----4021403 404 405"@ }406        ) {407            param($view, $widths, $expectedTable)408            $ps1xml = @"409<Configuration>410    <ViewDefinitions>411        <View>412            <Name>Default</Name>413            <ViewSelectedBy>414                <TypeName>Test.Format</TypeName>415            </ViewSelectedBy>416            <TableControl>417                <TableHeaders>418                    <TableColumnHeader>419                        <Label>LongLongHeader</Label>420                        <Width>{0}</Width>421                    </TableColumnHeader>422                    <TableColumnHeader>423                        <Label>Header2</Label>424                        <Width>{1}</Width>425                    </TableColumnHeader>426                    <TableColumnHeader>427                        <Label>Header3</Label>428                        <Width>{2}</Width>429                    </TableColumnHeader>430                </TableHeaders>431                <TableRowEntries>432                    <TableRowEntry>433                        <TableColumnItems>434                            <TableColumnItem>435                                <PropertyName>First</PropertyName>436                            </TableColumnItem>437                            <TableColumnItem>438                                <PropertyName>Second</PropertyName>439                            </TableColumnItem>440                            <TableColumnItem>441                                <PropertyName>Third</PropertyName>442                            </TableColumnItem>443                        </TableColumnItems>444                    </TableRowEntry>445                </TableRowEntries>446            </TableControl>447        </View>448        <View>449            <Name>One</Name>450            <ViewSelectedBy>451                <TypeName>Test.Format</TypeName>452            </ViewSelectedBy>453            <TableControl>454                <TableHeaders>455                    <TableColumnHeader>456                        <Label>LongLongHeader</Label>457                        <Width>{0}</Width>458                    </TableColumnHeader>459                </TableHeaders>460                <TableRowEntries>461                    <TableRowEntry>462                        <TableColumnItems>463                            <TableColumnItem>464                                <PropertyName>First</PropertyName>465                            </TableColumnItem>466                        </TableColumnItems>467                    </TableRowEntry>468                </TableRowEntries>469            </TableControl>470        </View>471    </ViewDefinitions>472</Configuration>473"@474            $ps1xml = $ps1xml.Replace("{0}", $widths[0]).Replace("{1}", $widths[1]).Replace("{2}", $widths[2])475            $ps1xmlPath = Join-Path -Path $TestDrive -ChildPath "span.format.ps1xml"476            Set-Content -Path $ps1xmlPath -Value $ps1xml477            # run in own runspace so not affect global sessionstate478            $ps = [powershell]::Create()479            $ps.AddScript( {480                param($ps1xmlPath, $view)481                Update-FormatData -AppendPath $ps1xmlPath482                $a = [PSCustomObject]@{First=1;Second=2;Third=3}483                $a.PSObject.TypeNames.Insert(0,"Test.Format")484                $a | Format-Table -View $view | Out-String485            } ).AddArgument($ps1xmlPath).AddArgument($view) | Out-Null486            $output = $ps.Invoke()487            foreach ($e in $ps.Streams.Error)488            {489                Write-Verbose $e.ToString() -Verbose490            }491            $ps.HadErrors | Should -BeFalse492            $output.Replace("`r","").Replace(" ",".").Replace("`n","^") | Should -BeExactly $expectedTable.Replace("`r","").Replace(" ",".").Replace("`n","^")493        }494 495        It "Format-Table should correctly render rows: <variation>" -TestCases @(496            @{ view = "Default"; widths = 4,7,5; variation = "narrow values"; values = [PSCustomObject]@{First=1;Second=2;Third=3}; wrap = $false; expectedTable = @"497 498Long*Header2*Heade499Long**********r3500Head501er502----*-------*-----5031**********2***3504 505 506"@ },507            @{ view = "Default"; widths = 4,7,5; variation = "narrow values with wrap"; values = [PSCustomObject]@{First=1;Second=2;Third=3}; wrap = $true; expectedTable = @"508 509Long*Header2*Heade510Long**********r3511Head512er513----*-------*-----5141**********2***3515 516 517"@ },518            @{ view = "Default"; widths = 4,7,5; variation = "wide values"; values = [PSCustomObject]@{First="12345";Second="12345678";Third="123456"}; wrap = $false; expectedTable = @"519 520Long*Header2*Heade521Long**********r3522Head523er524----*-------*-----525123`u{2026}*`u{2026}345678*1234`u{2026}526 527 528"@ },529            @{ view = "One"; widths = 3,1,1; variation = "wide values, 1 column"; values = [PSCustomObject]@{First="12345";Second="12345678";Third="123456"}; wrap = $false; expectedTable = @"530 531Lon532gLo533ngH534ead535er536---53712`u{2026}538 539 540"@ },541            @{ view = "Default"; widths = 4,8,6; variation = "wide values with wrap, 1st column"; values = [PSCustomObject]@{First="12345";Second="12345678";Third="123456"}; wrap = $true; expectedTable = @"542 543Long**Header2*Header544Long************3545Head546er547----**-------*------5481234*12345678*1234565495550 551 552"@ },553            @{ view = "Default"; widths = 5,7,6; variation = "wide values with wrap, 2nd column"; values = [PSCustomObject]@{First="12345";Second="12345678";Third="123456"}; wrap = $true; expectedTable = @"554 555LongL*Header2*Header556ongHe***********3557ader558-----*-------*------55912345*1234567*123456560************8561 562 563"@ },564            @{ view = "Default"; widths = 5,8,5; variation = "wide values with wrap, 3rd column"; values = [PSCustomObject]@{First="12345";Second="12345678";Third="123456"}; wrap = $true; expectedTable = @"565 566LongL**Header2*Heade567ongHe***********r3568ader569-----**-------*-----57012345*12345678*12345571*****************6572 573 574"@ },575            @{ view = "Default"; widths = 4,7,5; variation = "wide values with wrap, all 3 columns"; values = [PSCustomObject]@{First="12345";Second="12345678";Third="123456"}; wrap = $true; expectedTable = @"576 577Long*Header2*Heade578Long**********r3579Head580er581----*-------*-----5821234*1234567*123455835**********8***6584 585 586"@ },587            @{ view = "One"; widths = 3,1,1; variation = "wide values with wrap, with 1 column"; values = [PSCustomObject]@{First="12345";Second="12345678";Third="123456"}; wrap = $true; expectedTable = @"588 589Lon590gLo591ngH592ead593er594---59512359645597 598 599"@ }600        ) {601            param($view, $widths, $values, $wrap, $expectedTable)602            $ps1xml = @"603<Configuration>604    <ViewDefinitions>605        <View>606            <Name>Default</Name>607            <ViewSelectedBy>608                <TypeName>Test.Format</TypeName>609            </ViewSelectedBy>610            <TableControl>611                <TableHeaders>612                    <TableColumnHeader>613                        <Alignment>left</Alignment>614                        <Label>LongLongHeader</Label>615                        <Width>{0}</Width>616                    </TableColumnHeader>617                    <TableColumnHeader>618                        <Alignment>right</Alignment>619                        <Label>Header2</Label>620                        <Width>{1}</Width>621                    </TableColumnHeader>622                    <TableColumnHeader>623                        <Alignment>center</Alignment>624                        <Label>Header3</Label>625                        <Width>{2}</Width>626                    </TableColumnHeader>627                </TableHeaders>628                <TableRowEntries>629                    <TableRowEntry>630                        <TableColumnItems>631                            <TableColumnItem>632                                <PropertyName>First</PropertyName>633                            </TableColumnItem>634                            <TableColumnItem>635                                <PropertyName>Second</PropertyName>636                            </TableColumnItem>637                            <TableColumnItem>638                                <PropertyName>Third</PropertyName>639                            </TableColumnItem>640                        </TableColumnItems>641                    </TableRowEntry>642                </TableRowEntries>643            </TableControl>644        </View>645        <View>646            <Name>One</Name>647            <ViewSelectedBy>648                <TypeName>Test.Format</TypeName>649            </ViewSelectedBy>650            <TableControl>651                <TableHeaders>652                    <TableColumnHeader>653                        <Label>LongLongHeader</Label>654                        <Width>{0}</Width>655                    </TableColumnHeader>656                </TableHeaders>657                <TableRowEntries>658                    <TableRowEntry>659                        <TableColumnItems>660                            <TableColumnItem>661                                <PropertyName>First</PropertyName>662                            </TableColumnItem>663                        </TableColumnItems>664                    </TableRowEntry>665                </TableRowEntries>666            </TableControl>667        </View>668    </ViewDefinitions>669</Configuration>670"@671            $ps1xml = $ps1xml.Replace("{0}", $widths[0]).Replace("{1}", $widths[1]).Replace("{2}", $widths[2])672            $ps1xmlPath = Join-Path -Path $TestDrive -ChildPath "render.format.ps1xml"673            Set-Content -Path $ps1xmlPath -Value $ps1xml674            # run in own runspace so not affect global sessionstate675            $ps = [powershell]::Create()676            $ps.AddScript( {677                param($ps1xmlPath, $view, $values, $wrap)678                Update-FormatData -AppendPath $ps1xmlPath679                $values.PSObject.TypeNames.Insert(0,"Test.Format")680                $values | Format-Table -View $view -Wrap:$wrap | Out-String681            } ).AddArgument($ps1xmlPath).AddArgument($view).AddArgument($values).AddArgument($wrap) | Out-Null682            $output = $ps.Invoke()683            foreach ($e in $ps.Streams.Error)684            {685                Write-Verbose $e.ToString() -Verbose686            }687            $ps.HadErrors | Should -BeFalse688            $output.Replace("`r","").Replace(" ","*").Replace("`n","^") | Should -BeExactly $expectedTable.Replace("`r","").Replace(" ",".").Replace("`n","^")689        }690 691        It "Should render header/row correctly where values are wider than header w/ implicit autosize: <variation>" -TestCases @(692            @{ variation = "first column"; obj = [pscustomobject]@{abc="1234";bcd="123"},[pscustomobject]@{abc="1";bcd="1234"}; expectedTable = @"693 694abc  bcd695---  ---6961234 1236971    1234698 699 700"@ },701            @{ variation = "both columns"; obj = [pscustomobject]@{abc="1234";bcd="1234"},[pscustomobject]@{abc="1";bcd="1"}; expectedTable = @"702 703abc  bcd704---  ---7051234 12347061    1707 708 709"@ },710            @{ variation = "second column"; obj = [pscustomobject]@{abc="123";bcd="1234"},[pscustomobject]@{abc="1";bcd="123"}; expectedTable = @"711 712abc bcd713--- ---714123 12347151   123716 717 718"@ }719        ) {720            param($obj, $expectedTable)721            $output = $obj | Format-Table | Out-String722            $output.Replace("`r","").Replace(" ",".").Replace("`n","^") | Should -BeExactly $expectedTable.Replace("`r","").Replace(" ",".").Replace("`n","^")723        }724 725        It "Should render header correctly where header is shorter than column width with justification: <variation>" -TestCases @(726            @{ variation = "left/right"; obj = [PSCustomObject]@{a="abc";b=123}; expectedTable = @"727 728a     b729-     -730abc 123731 732 733"@ },734            @{ variation = "left/left"; obj = [PSCustomObject]@{a="abc";b="abc"}; expectedTable = @"735 736a   b737-   -738abc abc739 740 741"@ },742            @{ variation = "right/left"; obj = [PSCustomObject]@{a=123;b="abc"}; expectedTable = @"743 744  a b745  - -746123 abc747 748 749"@ },750            @{ variation = "right/right"; obj = [PSCustomObject]@{a=123;b=123}; expectedTable = @"751 752  a   b753  -   -754123 123755 756 757"@ }758        ) {759            param($obj, $expectedTable)760            $output = $obj | Format-Table | Out-String761            $output.Replace("`r","").Replace(" ",".").Replace("`n","^") | Should -BeExactly $expectedTable.Replace("`r","").Replace(" ",".").Replace("`n","^")762        }763 764        It "Should render rows correctly when wrapped: <variation>" -TestCases @(765            @{ variation = "right"; obj = [pscustomobject] @{A=1;B=2;Name="This`nIs some random`nmultiline content"}; expectedTable = @"766 767A B Name768- - ----7691 2 This770    Is some random771    multiline content772 773 774"@ },775            @{ variation = "left"; obj = [pscustomobject] @{Name="This`nIs some random`nmultiline content";A=1;B=2}; expectedTable = @"776 777Name                                  A B778----                                  - -779This                                  1 2780Is some random781multiline content782 783 784"@ },785            @{ variation = "middle"; obj = [pscustomobject] @{A=1;Name="This`nIs some random`nmultiline content";B=2}; expectedTable = @"786 787A Name                                  B788- ----                                  -7891 This                                  2790  Is some random791  multiline content792 793 794"@ }795        ) {796            param($obj, $expectedTable)797            $output = $obj | Format-Table -Wrap | Out-String798            $output.Replace("`r","").Replace(" ",".").Replace("`n","^") | Should -BeExactly $expectedTable.Replace("`r","").Replace(" ",".").Replace("`n","^")799        }800 801        It "Should not return null when the Console width is equal to 0" {802            [system.management.automation.internal.internaltesthooks]::SetTestHook('SetConsoleWidthToZero', $true)803            try804            {805                # Fill the console window with the string, so that it reaches its max width.806                # Check if the max width is equal to default value (120), to test test hook set.807                $testObject = @{ test = '1' * 200}808                Format-Table -InputObject $testObject | Out-String -Stream | ForEach-Object{$_.length} | Sort-Object -Bottom 1 | Should -Be 120809            }810            finally {811                [system.management.automation.internal.internaltesthooks]::SetTestHook('SetConsoleWidthToZero', $false)812            }813        }814 815        It "-RepeatHeader should output the header at every screen full" -Skip:$noConsole {816            $numHeaders = 4817            $numObjects = [Console]::WindowHeight * $numHeaders818            $out = 1..$numObjects | ForEach-Object { @{foo=$_} } | Format-Table -RepeatHeader | Out-String819            $lines = $out.Split([System.Environment]::NewLine)820            ($lines | Select-String "Name\s*Value").Count | Should -Be ($numHeaders + 1)821        }822 823        It "-RepeatHeader should output the header at every screen full for custom table" -Skip:$noConsole {824            $numHeaders = 4825            $numObjects = [Console]::WindowHeight * $numHeaders826            $out = 1..$numObjects | ForEach-Object { [pscustomobject]@{foo=$_;bar=$_;hello=$_;world=$_} } | Format-Table -Property hello, world -RepeatHeader | Out-String827            $lines = $out.Split([System.Environment]::NewLine)828            ($lines | Select-String "Hello\s*World").Count | Should -Be ($numHeaders + 1)829        }830 831        It "Should be formatted correctly if width is declared and using center alignment" {832            $expectedTable = @"833 834   one835   ---836    1837 838 839"@840            $output = [pscustomobject] @{ one = 1 } | Format-Table @{ l='one'; e='one'; width=10; alignment='center' } | Out-String841            $output.Replace("`r","").Replace(" ",".").Replace("`n","^") | Should -BeExactly $expectedTable.Replace("`r","").Replace(" ",".").Replace("`n","^")842        }843 844        It "Should be formatted correctly with double byte wide chars" {845            $obj = [pscustomobject]@{846                "哇" = "62";847                "dbda" = "KM";848                "消息" = "千"849            }850 851            $expected = @"852 853哇 dbda 消息854-- ---- ----85562 KM   千856 857 858"@859 860            $actual = $obj | Format-Table | Out-String861            ($actual.Replace("`r`n", "`n")) | Should -BeExactly ($expected.Replace("`r`n", "`n"))862        }863 864        It 'Table should format floats, doubles, and decimals with number of decimals from current culture' {865            $o = [PSCustomObject]@{866                double = [double]1234.56789867                float = [float]9876.54321868                decimal = [decimal]4567.123456789869            }870 871            $table = $o | Format-Table | Out-String872 873            $line = foreach ($line in $table.split([System.Environment]::NewLine)) { if ($line -match '^1234') { $line } }874            $line | Should -Not -BeNullOrEmpty875            $expectedDecimals = (Get-Culture).NumberFormat.NumberDecimalDigits876 877            foreach ($num in $line.split(' ', [System.StringSplitOptions]::RemoveEmptyEntries)) {878                $numDecimals = $num.length - $num.indexOf((Get-Culture).NumberFormat.NumberDecimalSeparator) - 1879                $numDecimals | Should -Be $expectedDecimals -Because $num880            }881        }882 883        It 'Works for empty column header label' {884            $ps1xml = @'885    <Configuration>886        <ViewDefinitions>887            <View>888                <Name>Test.Header.Empty</Name>889                <ViewSelectedBy>890                    <TypeName>Test.Format</TypeName>891                </ViewSelectedBy>892                <TableControl>893                    <TableHeaders>894                        <TableColumnHeader>895                            <Label></Label>896                            <Width>4</Width>897                        </TableColumnHeader>898                    </TableHeaders>899                    <TableRowEntries>900                        <TableRowEntry>901                            <TableColumnItems>902                                <TableColumnItem>903                                    <PropertyName>Prop</PropertyName>904                                </TableColumnItem>905                            </TableColumnItems>906                        </TableRowEntry>907                    </TableRowEntries>908                </TableControl>909            </View>910        </ViewDefinitions>911    </Configuration>912'@913 914            $ps1xmlPath = Join-Path -Path $TestDrive -ChildPath 'empty.format.ps1xml'915            Set-Content -Path $ps1xmlPath -Value $ps1xml916            $object = [pscustomobject]@{Prop = '123'}917            # run in own runspace so not affect global sessionstate918            $ps = [powershell]::Create()919            $ps.AddScript( {920                param($ps1xmlPath, $object)921                Update-FormatData -AppendPath $ps1xmlPath922                $object.PSObject.TypeNames.Insert(0, 'Test.Format')923                $object | Format-Table | Out-String924            } ).AddArgument($ps1xmlPath).AddArgument($object) | Out-Null925            $output = $ps.Invoke()926            $expected = @"927Prop----123928"@929            $output.Replace("`n","").Replace("`r","") | Should -BeExactly $expected930        }931    }932 933Describe 'Table color tests' -Tag 'CI' {934    BeforeAll {935        $originalRendering = $PSStyle.OutputRendering936        $PSStyle.OutputRendering = 'Ansi'937    }938 939    AfterAll {940        $PSStyle.OutputRendering = $originalRendering941    }942 943    It 'Table header should use TableHeader' {944        $expected = @(945        ""946        "$($PSStyle.Formatting.TableHeader)foo$($PSStyle.Reset)"947        "$($PSStyle.Formatting.TableHeader)---$($PSStyle.Reset)"948        "  1"949        ""950        )951 952        $actual = [pscustomobject]@{foo = 1} | Format-Table | Out-String -Stream953 954        $actual | Should -BeExactly $expected955    }956 957    Context 'ExcludeProperty parameter' {958        It 'Should exclude specified properties' {959            $obj = [pscustomobject]@{ Name = 'Test'; Age = 30; City = 'Seattle' }960            $result = $obj | Format-Table -ExcludeProperty Age | Out-String961            $result | Should -Match 'Name'962            $result | Should -Match 'City'963            $result | Should -Not -Match 'Age'964        }965 966        It 'Should work with wildcard patterns' {967            $obj = [pscustomobject]@{ Prop1 = 1; Prop2 = 2; Other = 3 }968            $result = $obj | Format-Table -ExcludeProperty Prop* | Out-String969            $result | Should -Match 'Other'970            $result | Should -Not -Match 'Prop1'971            $result | Should -Not -Match 'Prop2'972        }973 974        It 'Should work without Property parameter (implies -Property *)' {975            $obj = [pscustomobject]@{ A = 1; B = 2; C = 3 }976            $result = $obj | Format-Table -ExcludeProperty B | Out-String977            $result | Should -Match 'A'978            $result | Should -Match 'C'979            $result | Should -Not -Match 'B'980        }981 982        It 'Should work with Property parameter' {983            $obj = [pscustomobject]@{ Name = 'Test'; Age = 30; City = 'Seattle'; Country = 'USA' }984            $result = $obj | Format-Table -Property Name, Age, City, Country -ExcludeProperty Age | Out-String985            $result | Should -Match 'Name'986            $result | Should -Match 'City'987            $result | Should -Match 'Country'988            $result | Should -Not -Match 'Age'989        }990 991        It 'Should handle multiple excluded properties' {992            $obj = [pscustomobject]@{ A = 1; B = 2; C = 3; D = 4 }993            $result = $obj | Format-Table -ExcludeProperty B, D | Out-String994            $result | Should -Match 'A'995            $result | Should -Match 'C'996            $result | Should -Not -Match 'B'997            $result | Should -Not -Match 'D'998        }999    }1000}1001