Skip to content

Commit

Permalink
Merge pull request #27 from trackd/FormatTableVersion
Browse files Browse the repository at this point in the history
Updates to Format-SpectreTable and Format-SpectreJson
  • Loading branch information
ShaunLawrie authored Feb 16, 2024
2 parents 85fa7dd + e68afe5 commit 5cde2c4
Show file tree
Hide file tree
Showing 14 changed files with 550 additions and 345 deletions.
41 changes: 31 additions & 10 deletions PwshSpectreConsole.Tests/TestHelpers.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ using namespace Spectre.Console

function Get-RandomColor {
$type = 1 # Get-Random -Minimum 0 -Maximum 2
switch($type) {
switch ($type) {
0 {
$colors = [Spectre.Console.Color] | Get-Member -Static -Type Properties | Select-Object -ExpandProperty Name
return $colors[$(Get-Random -Minimum 0 -Maximum $colors.Count)]
}
1 {
$hex = @()
for($i = 0; $i -lt 3; $i++) {
for ($i = 0; $i -lt 3; $i++) {
$value = Get-Random -Minimum 0 -Maximum 255
$hex += [byte]$value
}
Expand All @@ -28,7 +28,7 @@ function Get-RandomList {
)
$items = @()
$count = Get-Random -Minimum $MinItems -Maximum $MaxItems
for($i = 0; $i -lt $count; $i++) {
for ($i = 0; $i -lt $count; $i++) {
$items += $Generator.Invoke()
}
return $items
Expand All @@ -39,7 +39,7 @@ function Get-RandomString {
$length = Get-Random -Minimum 10 -Maximum 20
$chars = [char[]]([char]'a'..[char]'z' + [char]'A'..[char]'Z' + [char]'0'..[char]'9')
$string = ""
for($i = 0; $i -lt $length; $i++) {
for ($i = 0; $i -lt $length; $i++) {
$string += $chars[$(Get-Random -Minimum 0 -Maximum $chars.Count)]
}
return $string
Expand Down Expand Up @@ -83,23 +83,23 @@ function Get-RandomTree {
[int] $CurrentDepth = 0
)

if($CurrentDepth -gt $MaxDepth) {
if ($CurrentDepth -gt $MaxDepth) {
return $Root
}

$CurrentDepth++

if($null -eq $Root) {
if ($null -eq $Root) {
$Root = @{
Label = Get-RandomString
Label = Get-RandomString
Children = @()
}
}

$children = Get-Random -Minimum $MinChildren -Maximum $MaxChildren
for($i = 0; $i -lt $children; $i++) {
for ($i = 0; $i -lt $children; $i++) {
$newChild = @{
Label = Get-RandomString
Label = Get-RandomString
Children = @()
}
$newTree = Get-RandomTree -Root $newChild -MaxChildren $MaxChildren -MaxDepth $MaxDepth -CurrentDepth $CurrentDepth
Expand Down Expand Up @@ -151,7 +151,8 @@ function Get-AnsiEscapeSequence {
$Escaped = $String.EnumerateRunes() | ForEach-Object {
if ($_.Value -le 0x1f) {
[Text.Rune]::new($_.Value + 0x2400)
} else {
}
else {
$_
}
} | Join-String
Expand All @@ -162,6 +163,11 @@ function Get-AnsiEscapeSequence {
}
}
}
function StripAnsi {
process {
[System.Management.Automation.Host.PSHostUserInterface]::GetOutputString($_, $false)
}
}

function Get-PSStyleRandom {
param(
Expand Down Expand Up @@ -213,3 +219,18 @@ Function Get-SpectreColorSample {
}
}
}
function Get-SpectreTableRowData {
param(
[int]$Count = 5,
[Switch]$Markup
)
if ($null -eq $count) {
$count = 5
}
1..$Count | ForEach-Object {
if ($Markup) {
return '[{0}] {1} [/]' -f (Get-RandomColor), (Get-RandomString)
}
Get-RandomString
}
}
53 changes: 23 additions & 30 deletions PwshSpectreConsole.Tests/formatting/Format-SpectreTable.tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ Describe "Format-SpectreTable" {

Mock Write-AnsiConsole -Verifiable -ParameterFilter {
$RenderableObject -is [Spectre.Console.Table] `
-and ($testBorder -eq "None" -or $RenderableObject.Border.GetType().Name -like "*$testBorder*") `
-and $RenderableObject.BorderStyle.Foreground.ToMarkup() -eq $testColor `
-and $RenderableObject.Rows.Count -eq $testData.Count
-and ($testBorder -eq "None" -or $RenderableObject.Border.GetType().Name -like "*$testBorder*") `
-and $RenderableObject.BorderStyle.Foreground.ToMarkup() -eq $testColor `
-and $RenderableObject.Rows.Count -eq $testData.Count
}
}

Expand All @@ -33,29 +33,30 @@ Describe "Format-SpectreTable" {

It "Should be able to retrieve default display members for command output with format data" {
$testData = Get-ChildItem "$PSScriptRoot"
$defaultDisplayMembers = $testData | Get-DefaultDisplayMembers
if($IsLinux -or $IsMacOS) {
$defaultDisplayMembers = $testData | Format-Table | Get-TableHeader
if ($IsLinux -or $IsMacOS) {
# Expected @('UnixMode', 'User', 'Group', 'LastWrite…', 'Size', 'Name'), but got @('UnixMode', 'User', 'Group', 'LastWriteTime', 'Size', 'Name').
# i have no idea whats truncating LastWriteTime
# $defaultDisplayMembers.Properties.GetEnumerator().Name | Should -Be @("UnixMode", "User", "Group", "LastWriteTime", "Size", "Name")
$defaultDisplayMembers.Properties.GetEnumerator().Name | Should -Match 'UnixMode|User|Group|LastWrite|Size|Name'
} else {
$defaultDisplayMembers.Properties.GetEnumerator().Name | Should -Be @("Mode", "LastWriteTime", "Length", "Name")
$defaultDisplayMembers.keys | Should -Match 'UnixMode|User|Group|LastWrite|Size|Name'
}
else {
$defaultDisplayMembers.keys | Should -Be @("Mode", "LastWriteTime", "Length", "Name")
}
}

It "Should not throw and should return null when input does not have format data" {
{
$defaultDisplayMembers = [hashtable]@{
"Hello" = "World"
} | Get-DefaultDisplayMembers
} | Get-TableHeader
$defaultDisplayMembers | Should -Be $null
} | Should -Not -Throw
}

It "Should be able to format ansi strings" {
$rawString = "hello world"
$ansiString = "`e[31mhello `e[46mworld`e[0m"
$rawString = "hello world"
$ansiString = "`e[31mhello `e[46mworld`e[0m"
$result = ConvertTo-SpectreDecoration -String $ansiString
$result.Length | Should -Be $rawString.Length
}
Expand All @@ -74,56 +75,48 @@ Describe "Format-SpectreTable" {
}

It "Should be able to format strings with spectre markup when opted in" {
$rawString = "hello spectremarkup world"
$ansiString = "hello [red]spectremarkup[/] world"
$rawString = "hello spectremarkup world"
$ansiString = "hello [red]spectremarkup[/] world"
$result = ConvertTo-SpectreDecoration -String $ansiString -AllowMarkup
$result.Length | Should -Be $rawString.Length
}

It "Should leave spectre markup alone by default" {
$ansiString = "hello [red]spectremarkup[/] world"
$ansiString = "hello [red]spectremarkup[/] world"
$result = ConvertTo-SpectreDecoration -String $ansiString
$result.Length | Should -Be $ansiString.Length
}

It "Should be able to create a new table cell with spectre markup" {
$rawString = "hello spectremarkup world"
$ansiString = "hello [red]spectremarkup[/] world"
$rawString = "hello spectremarkup world"
$ansiString = "hello [red]spectremarkup[/] world"
$result = New-TableCell -String $ansiString -AllowMarkup
$result | Should -BeOfType [Spectre.Console.Markup]
$result.Length | Should -Be $rawString.Length
}

It "Should be able to create a new table cell without spectre markup by default" {
$ansiString = "hello [red]spectremarkup[/] world"
$ansiString = "hello [red]spectremarkup[/] world"
$result = New-TableCell -String $ansiString
$result | Should -BeOfType [Spectre.Console.Text]
$result.Length | Should -Be $ansiString.Length
}

It "Should be able to create a new table row with spectre markup" {
$rawString = "Markup"
$entryItem = [pscustomobject]@{
"Markup" = "[red]Markup[/]"
"Also" = "Hello"
}
$entryitem = Get-SpectreTableRowData -Markup
$result = New-TableRow -Entry $entryItem -AllowMarkup
$result -is [array] | Should -Be $true
$result[0] | Should -BeOfType [Spectre.Console.Markup]
$result[0].Length | Should -Be $rawString.Length
$result.Count | Should -Be ($entryItem.PSObject.Properties | Measure-Object).Count
$result.Count | Should -Be $entryitem.Count
}

It "Should be able to create a new table row without spectre markup by default" {
$entryItem = [pscustomobject]@{
"Markup" = "[red]Markup[/]"
"Also" = "Hello"
}
$entryitem = Get-SpectreTableRowData -Markup
$result = New-TableRow -Entry $entryItem
$result -is [array] | Should -Be $true
$result[0] | Should -BeOfType [Spectre.Console.Text]
$result[0].Length | Should -Be $entryItem.Markup.Length
$result.Count | Should -Be ($entryItem.PSObject.Properties | Measure-Object).Count
$result[0].Length | Should -Be $entryItem[0].Length
$result.Count | Should -Be $entryitem.Count
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
Remove-Module PwshSpectreConsole -Force -ErrorAction SilentlyContinue
Import-Module "$PSScriptRoot\..\..\PwshSpectreConsole\PwshSpectreConsole.psd1" -Force
Import-Module "$PSScriptRoot\..\TestHelpers.psm1" -Force

Describe "Format-SpectreJson" {
InModuleScope "PwshSpectreConsole" {
BeforeEach {
$testData = $null
$testBorder = 'Markdown'
$testColor = Get-RandomColor
Mock Write-AnsiConsole {
param(
[Parameter(Mandatory)]
[Spectre.Console.Rendering.Renderable] $RenderableObject
)
try {
$writer = [System.IO.StringWriter]::new()
$output = [Spectre.Console.AnsiConsoleOutput]::new($writer)
$settings = [Spectre.Console.AnsiConsoleSettings]::new()
$settings.Out = $output
$console = [Spectre.Console.AnsiConsole]::Create($settings)
$console.Write($RenderableObject)
$writer.ToString()
}
finally {
$writer.Dispose()
}
}
}
It "Simple scalar array test" {
{
$numbers = Get-Random -Minimum 30 -Maximum 50
$json = 1..$numbers | Format-SpectreJson -Border None
($json.trim() -split "\r?\n").count | Should -Be ($numbers + 2) # 10 items + 2 braces
} | Should -Not -Throw
}
It "Simple String test" {
{
$numbers = Get-Random -Minimum 30 -Maximum 50
$json = 1..$numbers | ConvertTo-Json | Format-SpectreJson -Border None
($json.trim() -split "\r?\n").count | Should -Be ($numbers + 2) # 10 items + 2 braces
} | Should -Not -Throw
}
It "Should take json string input" {
$data = @(
[pscustomobject]@{Name = "John"; Age = 25; City = "New York" },
[pscustomobject]@{Name = "Jane"; Age = $null; City = "Los Angeles" }
)
$roundtrip = $data | ConvertTo-Json | Format-SpectreJson -Border None | StripAnsi | ConvertFrom-Json
(Compare-Object -ReferenceObject $data -DifferenceObject $roundtrip -Property Name, Age, City -CaseSensitive -IncludeEqual).SideIndicator | Should -Be @('==','==')
}
It "Should roundtrip json string input" {
$ht = @{}
Get-RandomList -MinItems 30 -MaxItems 50 | ForEach-Object {
$ht[$_] = Get-RandomString
}
$data = [pscustomobject]$ht
$roundtrip = $data | ConvertTo-Json | Format-SpectreJson -Border None | StripAnsi | ConvertFrom-Json
$roundtrip.psobject.properties.name | Should -Be $data.psobject.properties.name
$roundtrip.psobject.properties.value | Should -Be $data.psobject.properties.value
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,26 +27,48 @@ Describe "Format-SpectreTable" {
}
}
}
It "Should create a table when default display members for a command are required" {
It "Should create a table and display results properly" {
$testData = Get-ChildItem "$PSScriptRoot"
$verification = Get-DefaultDisplayMembers $testData
$verification = $testdata | Format-Table | Get-TableHeader
$testResult = Format-SpectreTable -Data $testData -Border $testBorder -Color $testColor
$command = Get-Command "Select-Object"
$rows = $testResult -split "\r?\n" | Select-Object -Skip 1 | Select-Object -SkipLast 2
$rows = $testResult -split "\r?\n" | Select-Object -Skip 1 -SkipLast 2
$header = $rows[0]
$properties = $header -split '\|' | Get-AnsiEscapeSequence | ForEach-Object {
if (-Not [String]::IsNullOrWhiteSpace($_.Clean)) {
$_.Clean -replace '\s+'
$properties = $header -split '\|' | StripAnsi | ForEach-Object {
if (-Not [String]::IsNullOrWhiteSpace($_)) {
$_.Trim()
}
}
if ($IsLinux -or $IsMacOS) {
$verification.Properties.keys | Should -Match 'UnixMode|User|Group|LastWrite|Size|Name'
$verification.keys | Should -Match 'UnixMode|User|Group|LastWrite|Size|Name'
}
else {
$verification.Properties.keys | Should -Be $properties
$verification.keys | Should -Be $properties
}
Assert-MockCalled -CommandName "Write-AnsiConsole" -Times 1 -Exactly
Should -InvokeVerifiable
}
It "Should create a table and display ICollection results properly" {
$testData = 1 | Group-Object
$testResult = Format-SpectreTable -Data $testData -Border Markdown -HideHeaders -Property Group
$clean = $testResult -replace '\s+|\|'
$clean | StripAnsi | Should -Be '{1}'
Assert-MockCalled -CommandName "Write-AnsiConsole" -Times 1 -Exactly
Should -InvokeVerifiable
}
It "Should be able to use calculated properties" {
$Data = Get-Process -Id $pid
$Format = $data | Format-SpectreTable ProcessName, @{Label="TotalRunningTime"; Expression={(Get-Date) - $_.StartTime}} -Border Markdown
$obj = $Format -split "\r?\n" | Select-Object -Skip 1 -SkipLast 2
$deconstructed = $obj -split '\|' | StripAnsi | ForEach-Object {
if (-Not [String]::IsNullOrEmpty($_)) {
$_.Trim()
}
}
$deconstructed[0] | Should -Be 'ProcessName'
$deconstructed[1] | Should -Be 'TotalRunningTime'
$deconstructed[4] | Should -Be 'pwsh'
Assert-MockCalled -CommandName "Write-AnsiConsole" -Times 1 -Exactly
Should -InvokeVerifiable
}
}
}
Loading

0 comments on commit 5cde2c4

Please sign in to comment.