PowerShell/test/powershell/Modules/Microsoft.PowerShell.Utility/Format-Custom.Tests.ps1

447 lines
11 KiB
PowerShell

# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
Describe "Format-Custom" -Tags "CI" {
Context "Check Format-Custom aliases" {
It "Should have the same output between the alias and the unaliased function" {
$nonaliased = Get-FormatData | Format-Custom
$aliased = Get-FormatData | fc
$($nonaliased | Out-String).CompareTo($($aliased | Out-String)) | Should -Be 0
}
}
Context "Check specific flags on Format-Custom" {
It "Should be able to specify the depth in output" {
$getprocesspester = Get-FormatData | Format-Custom -Depth 1
($getprocesspester).Count | Should -BeGreaterThan 0
}
It "Should be able to use the Property flag to select properties" {
Get-Command | Format-Custom -Property "Name" | Should -Not -Match "Source"
}
}
}
Describe "Format-Custom DRT basic functionality" -Tags "CI" {
Add-Type -TypeDefinition @"
public abstract class NamedItem
{
public string name;
}
public abstract class MyContainerBase : NamedItem
{
public System.Collections.Generic.List<NamedItem> children = new System.Collections.Generic.List<NamedItem> ();
}
public sealed class MyLeaf1 : NamedItem
{
public int val1 = 0;
}
public sealed class MyLeaf2 : NamedItem
{
public int val2 = 0;
}
public sealed class MyContainer1 : MyContainerBase
{
public string data1;
}
public sealed class MyContainer2 : MyContainerBase
{
public string data2;
}
"@
It "Format-Custom with subobject should work" {
$expectResult1 = "this is the name"
$expectResult2 = "this is the name of the sub object"
$testObject = @{}
$testObject.name = $expectResult1
$testObject.subObjectValue = @{}
$testObject.subObjectValue.name = $expectResult2
$testObject.subObjectValue.array = (0..63)
$testObject.subObjectValue.stringarray = @("one","two")
$result = $testObject | Format-Custom | Out-String
$result | Should -Match $expectResult1
$result | Should -Match $expectResult2
$result | Should -Match "one"
$result | Should -Match "two"
}
It "Format-Custom with Tree Object should work" {
$expectedResult=@"
class MyContainer1
{
data1 = data 1
children =
[
class MyLeaf1
{
val1 = 10
name = leaf 1
}
class MyLeaf2
{
val2 = 20
name = leaf 2
}
]
name = container 1
}
class MyContainer2
{
data2 = data 2
children =
[
class MyLeaf1
{
val1 = 10
name = leaf 1
}
class MyLeaf2
{
val2 = 20
name = leaf 2
}
]
name = container 2
}
class MyContainer2
{
data2 = data 2 deep
children =
[
class MyContainer1
{
data1 = cx data
children =
[
class MyLeaf1
{
val1 = 10
name = leaf 1
}
class MyLeaf2
{
val2 = 20
name = leaf 2
}
]
name = cx
}
]
name = container 2 deep
}
class MyContainer1
{
data1 = cx data
children =
[
class MyLeaf1
{
val1 = 10
name = leaf 1
}
class MyLeaf2
{
val2 = 20
name = leaf 2
}
]
name = cx
}
"@
$leaf1 = New-Object MyLeaf1
$leaf1.name = "leaf 1"
$leaf1.val1 = 10
$leaf2 = New-Object MyLeaf2
$leaf2.name = "leaf 2"
$leaf2.val2 = 20
$c1 = New-Object MyContainer1
$c1.name = "container 1"
$c1.data1 = "data 1"
$c1.children.Add($leaf1)
$c1.children.Add($leaf2)
$c2 = New-Object MyContainer2
$c2.name = "container 2"
$c2.data2 = "data 2"
$c2.children.Add($leaf1)
$c2.children.Add($leaf2)
$cDeep = New-Object MyContainer2
$cDeep.name = "container 2 deep"
$cDeep.data2 = "data 2 deep"
$cx= New-Object MyContainer1
$cx.name = "cx"
$cx.data1 = "cx data"
$cx.children.Add($leaf1)
$cx.children.Add($leaf2)
$cDeep.children.Add($cx)
$objectList = @($c1,$c2,$cDeep,$cx)
$result = $objectList | Format-Custom | Out-String
$result = $result -replace "[{} `n\r]",""
$expectedResult = $expectedResult -replace "[{} `n\r]",""
$result | Should -Be $expectedResult
}
It "Format-Custom with Empty Data Tree Object should work" {
$expectedResult=@"
class MyContainer1
{
data1 =
children =
name =
}
"@
$c= New-Object MyContainer1
$c.name = $null
$c.data1 = $null
$c.children = $null
$objectList = @($c)
$result = $objectList | Format-Custom | Out-String
$result = $result -replace "[{} `n\r]",""
$expectedResult = $expectedResult -replace "[{} `n\r]",""
$result | Should -Be $expectedResult
}
It "Format-Custom with Back Pointers Tree Object should work" {
$expectedResult=@"
class MyContainer1
{
data1 =
children =
[
class MyContainer1
{
data1 =
children =
[
class MyContainer1
{
data1 =
children =
[
MyContainer1
]
name = ROOT
}
]
name = ROOT
}
]
name = ROOT
}
"@
$root= New-Object MyContainer1
$root.name = "ROOT"
$root.children.Add($root)
$objectList = @($root)
$result = $objectList | Format-Custom | Out-String
$result = $result -replace "[{} `n\r]",""
$expectedResult = $expectedResult -replace "[{} `n\r]",""
$result | Should -Be $expectedResult
}
It "Format-Custom with Leaf Only Data should work" {
$expectedResult=@"
class MyLeaf1
{
val1 = 10
name = leaf 1
}
class MyLeaf2
{
val2 = 20
name = leaf 2
}
"@
$leaf1 = New-Object MyLeaf1
$leaf1.name = "leaf 1"
$leaf1.val1 = 10
$leaf2 = New-Object MyLeaf2
$leaf2.name = "leaf 2"
$leaf2.val2 = 20
$objectList = @($leaf1,$leaf2)
$result = $objectList | Format-Custom | Out-String
$result = $result -replace "[{} `n\r]",""
$expectedResult = $expectedResult -replace "[{} `n\r]",""
$result | Should -Be $expectedResult
}
It "Format-Custom should not lost data" {
# See https://github.com/PowerShell/PowerShell/pull/11342 for more information
$data = (Get-Help Out-Null).Examples
$formattedData = $data | Format-Custom | Out-String
$formattedData | Should -BeLike "*$($data.Example.title)*"
$formattedData | Should -BeLike "*$($data.Example.code)*"
$formattedData | Should -BeLike "*$($data.Example.remarks.Text)*"
}
}
Describe "Format-Custom with expression based EntrySelectedBy in a CustomControl" -Tags "CI" {
BeforeAll {
$formatFilePath = Join-Path $TestDrive 'UpdateFormatDataTests.format.ps1xml'
$xmlContent = @'
<?xml version="1.0" encoding="UTF-8" ?>
<Configuration>
<Controls>
<Control>
<Name>MyTestControl</Name>
<CustomControl>
<CustomEntries>
<CustomEntry>
<EntrySelectedBy>
<SelectionCondition>
<TypeName>MyTestObject</TypeName>
<ScriptBlock>$_.Name -eq 'SelectScriptBlock'</ScriptBlock>
</SelectionCondition>
</EntrySelectedBy>
<CustomItem>
<Text>Entry selected by ScriptBlock</Text>
</CustomItem>
</CustomEntry>
<CustomEntry>
<EntrySelectedBy>
<SelectionCondition>
<TypeName>MyTestObject</TypeName>
<PropertyName>SelectProperty</PropertyName>
</SelectionCondition>
</EntrySelectedBy>
<CustomItem>
<Text>Entry selected by property</Text>
</CustomItem>
</CustomEntry>
<CustomEntry>
<CustomItem>
<Text>Default was picked</Text>
</CustomItem>
</CustomEntry>
</CustomEntries>
</CustomControl>
</Control>
</Controls>
<ViewDefinitions>
<View>
<Name>DefaultView</Name>
<ViewSelectedBy>
<TypeName>MyTestObject</TypeName>
</ViewSelectedBy>
<GroupBy>
<PropertyName>Name</PropertyName>
<CustomControlName>MyTestControl</CustomControlName>
</GroupBy>
<TableControl>
<TableHeaders>
<TableColumnHeader />
</TableHeaders>
<TableRowEntries>
<TableRowEntry>
<TableColumnItems>
<TableColumnItem>
<PropertyName>Name</PropertyName>
</TableColumnItem>
</TableColumnItems>
</TableRowEntry>
</TableRowEntries>
</TableControl>
</View>
</ViewDefinitions>
</Configuration>
'@
Set-Content -Path $formatFilePath -Value $xmlContent
$ps = [powershell]::Create()
$iss = [initialsessionstate]::CreateDefault2()
$iss.Formats.Add($formatFilePath)
$rs = [runspacefactory]::CreateRunspace($iss)
$rs.Open()
$ps.Runspace = $rs
}
AfterAll {
$rs.Close()
$ps.Dispose()
}
It 'Property expression binding should be able to access the current object' {
$script = {
[PSCustomObject]@{
PSTypeName = 'MyTestObject'
SelectProperty = $true
Name = 'testing'
}
}
$null = $ps.AddScript($script).AddCommand('Out-String')
$ps.Streams.Error.Clear()
$expectedOutput = @'
Entry selected by property
Name
----
testing
'@ -replace '\r?\n', "^"
$ps.Invoke() -replace '\r?\n', "^" | Should -BeExactly $expectedOutput
$ps.Streams.Error | Should -BeNullOrEmpty
}
It 'ScriptBlock expression binding should be able to access the current object' {
$script = {
[PSCustomObject]@{
PSTypeName = 'MyTestObject'
SelectProperty = $false
Name = 'SelectScriptBlock'
}
}
$null = $ps.AddScript($script).AddCommand('Out-String')
$ps.Streams.Error.Clear()
$expectedOutput = @'
Entry selected by ScriptBlock
Name
----
SelectScriptBlock
'@ -replace '\r?\n', "^"
$ps.Invoke() -replace '\r?\n', "^" | Should -BeExactly $expectedOutput
$ps.Streams.Error | Should -BeNullOrEmpty
}
}