Skip to content

Commit

Permalink
Merge pull request #21 from trackd/prerelease
Browse files Browse the repository at this point in the history
  • Loading branch information
ShaunLawrie authored Jan 21, 2024
2 parents 8f9f1ad + e819d50 commit 62bfe1b
Show file tree
Hide file tree
Showing 21 changed files with 789 additions and 194 deletions.
18 changes: 9 additions & 9 deletions .github/workflows/build-test-publish.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
name: Publish to PSGallery
env:
PSGALLERY_API_KEY: ${{ secrets.PSGALLERY_API_KEY }}
PSGALLERY_API_KEY: ${{ secrets.PSGALLERY_API_KEY }}
on:
push:
branches:
- main
- prerelease
- main
- prerelease

permissions:
contents: write
Expand All @@ -26,7 +26,7 @@ jobs:
$ErrorActionPreference = "Stop"
& .\PwshSpectreConsole\Build.ps1
$env:PSModulePath = @($env:PSModulePath, ".\PwshSpectreConsole\") -join ":"
Invoke-Pester -CI
Invoke-Pester -CI -ExcludeTag "ExcludeCI"
$version = Get-Module PwshSpectreConsole -ListAvailable | Sort-Object -Property Version -Descending | Select-Object -First 1 -ExpandProperty Version
if($null -eq $version) { throw "Failed to load version" }
$onlineVersion = Find-Module -Name PwshSpectreConsole -RequiredVersion $version -ErrorAction SilentlyContinue
Expand All @@ -46,7 +46,7 @@ jobs:
Import-Module .\PwshSpectreConsole\PwshSpectreConsole.psd1 -Force
Publish-Module -Name PwshSpectreConsole -Exclude "Build.ps1" -NugetApiKey $env:PSGALLERY_API_KEY
gh release create "v$newVersion" --target main --generate-notes
publish-prerelease-to-psgallery:
name: Publish Prerelease
runs-on: ubuntu-latest
Expand All @@ -62,11 +62,11 @@ jobs:
$ErrorActionPreference = "Stop"
& ./PwshSpectreConsole/Build.ps1
$env:PSModulePath = @($env:PSModulePath, ".\PwshSpectreConsole\") -join ":"
Invoke-Pester -CI
Invoke-Pester -CI -ExcludeTag "ExcludeCI"
$version = Get-Module PwshSpectreConsole -ListAvailable | Sort-Object -Property Version -Descending | Select-Object -First 1 -ExpandProperty Version
if($null -eq $version) { throw "Failed to load version" }
$onlineVersions = Find-Module -Name PwshSpectreConsole -AllowPrerelease -AllVersions
$latestStableVersion = $onlineVersions | Where-Object { $_.Version -notlike "*prerelease*" } | Sort-Object -Property Version -Descending | Select-Object -First 1 -ExpandProperty Version
$latestStableVersion = [version]$latestStableVersion
$latestPrereleaseVersion = $onlineVersions | Where-Object { $_.Version -like "*prerelease*" } | Sort-Object -Property Version -Descending | Select-Object -First 1 -ExpandProperty Version
Expand All @@ -79,7 +79,7 @@ jobs:
# Prerelease will always be at least one minor version above the latest published stable version so when it's merged to main the minor version will get bumped
# To bump a major version the manifest would be edited manually to vnext.0.0 before merging to main
$newVersion = [version]::new($latestStableVersion.Major, $latestStableVersion.Minor + 1, 0)
if($newVersion -eq $oldVersion) {
Write-Host "Version is not being bumped in prerelease"
} else {
Expand All @@ -100,4 +100,4 @@ jobs:
Publish-Module -Name PwshSpectreConsole -Exclude "Build.ps1" -NugetApiKey $env:PSGALLERY_API_KEY -AllowPrerelease
# Create a gh release for it
gh release create "v$newVersion-$newPrereleaseTag" --target prerelease --generate-notes --prerelease
gh release create "v$newVersion-$newPrereleaseTag" --target prerelease --generate-notes --prerelease
5 changes: 3 additions & 2 deletions .github/workflows/unit-test-only.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ jobs:
$ErrorActionPreference = "Stop"
& .\PwshSpectreConsole\Build.ps1
$env:PSModulePath = @($env:PSModulePath, ".\PwshSpectreConsole\") -join ":"
Invoke-Pester -CI
$PSVersionTable | Out-Host
Get-Module Pester -ListAvailable | Out-Host
Invoke-Pester -CI -ExcludeTag "ExcludeCI"
104 changes: 99 additions & 5 deletions PwshSpectreConsole.Tests/TestHelpers.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ function Get-RandomColor {
}

function Get-RandomList {
param (
param(
[int] $MinItems = 2,
[int] $MaxItems = 10,
[scriptblock] $Generator = {
Expand Down Expand Up @@ -75,7 +75,7 @@ function Get-RandomChartItem {
}

function Get-RandomTree {
param (
param(
[hashtable] $Root,
[int] $MinChildren = 1,
[int] $MaxChildren = 3,
Expand Down Expand Up @@ -105,7 +105,7 @@ function Get-RandomTree {
$newTree = Get-RandomTree -Root $newChild -MaxChildren $MaxChildren -MaxDepth $MaxDepth -CurrentDepth $CurrentDepth
$Root.Children += $newTree
}

return $Root
}

Expand All @@ -114,8 +114,102 @@ function Get-RandomBool {
}

function Get-RandomChoice {
param (
param(
[string[]] $Choices
)
return $Choices[(Get-Random -Minimum 0 -Maximum $Choices.Count)]
}
}

function Get-SpectreRenderable {
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()
}
}

function Get-AnsiEscapeSequence {
<#
could be useful for debugging
#>
param(
[Parameter(Mandatory, ValueFromPipeline)]
[String] $String
)
process {
$Escaped = $String.EnumerateRunes() | ForEach-Object {
if ($_.Value -le 0x1f) {
[Text.Rune]::new($_.Value + 0x2400)
} else {
$_
}
} | Join-String
[PSCustomObject]@{
Escaped = $Escaped
Original = $String
Clean = [System.Management.Automation.Host.PSHostUserInterface]::GetOutputString($String, $false)
}
}
}

function Get-PSStyleRandom {
param(
[Switch] $Foreground,
[Switch] $Background,
[Switch] $Decoration,
[Switch] $RGBForeground,
[Switch] $RGBBackground
)
$Style = Switch ($PSBoundParameters.Keys) {
'Foreground' {
$fg = ($PSStyle.Foreground | Get-Member -MemberType Property | Get-Random).Name
$PSStyle.Foreground.$fg
}
'Background' {
$bg = ($PSStyle.Background | Get-Member -MemberType Property | Get-Random).Name
$PSStyle.Background.$bg
}
'Decoration' {
$deco = ($PSStyle | Get-Member -MemberType Property | Where-Object { $_.Definition -match '^string' -And $_.Name -notmatch 'off$|Reset' } | Get-Random).Name
$PSStyle.$deco
}
'RGBForeground' {
$r = Get-Random -min 0 -max 255
$g = Get-Random -min 0 -max 255
$b = Get-Random -min 0 -max 255
$PSStyle.Foreground.FromRgb($r, $g, $b)
}
'RGBBackground' {
$r = Get-Random -min 0 -max 255
$g = Get-Random -min 0 -max 255
$b = Get-Random -min 0 -max 255
$PSStyle.Background.FromRgb($r, $g, $b)
}
}
return $Style | Join-String
}
Function Get-SpectreColorSample {
$spectreColors = [Spectre.Console.Color] | Get-Member -Static -Type Properties | Select-Object -ExpandProperty Name
foreach ($c in $spectreColors) {
$color = [Spectre.Console.Color]::$c
$renderable = [Spectre.Console.Text]::new("Hello, $c", [Spectre.Console.Style]::new($color))
$SpectreString = Get-SpectreRenderable $renderable
[PSCustomObject]@{
Color = $c
String = $SpectreString
# Object = $color
# Debug = Get-AnsiEscapeSequence $SpectreString
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
Remove-Module PwshSpectreConsole -Force -ErrorAction SilentlyContinue
Import-Module "$PSScriptRoot\..\..\PwshSpectreConsole\PwshSpectreConsole.psd1" -Force
Import-Module "$PSScriptRoot\..\TestHelpers.psm1" -Force

Describe "ConvertTo-SpectreDecoration" {
InModuleScope "PwshSpectreConsole" {
It "Test PSStyle Decorations" {
$PSStyleColor = Get-PSStyleRandom -Decoration
$reset = $PSStyle.Reset
$string = 'Hello, world!, hello universe!'
$sample = "{0}{1}{2}" -f $PSStyleColor, $string, $PSStyle.Reset
$test = Get-SpectreRenderable (ConvertTo-SpectreDecoration $sample)
$test | Should -Be $sample
}
It "Test PSStyle Foreground RGB Colors" -Tag "ExcludeCI" {
# testing something
$PSStyleColor = Get-PSStyleRandom -RGBForeground
$reset = $PSStyle.Reset
$string = 'Hello, world!, hello universe!'
$sample = "{0}{1}{2}" -f $PSStyleColor, $string, $PSStyle.Reset
$test = Get-SpectreRenderable (ConvertTo-SpectreDecoration $sample)
$test | Should -Be $sample
}
It "Test PSStyle Background RGB Colors" -Tag "ExcludeCI" {
$PSStyleColor = Get-PSStyleRandom -RGBBackground
$reset = $PSStyle.Reset
$string = 'Hello, world!, hello universe!'
$sample = "{0}{1}{2}" -f $PSStyleColor, $string, $PSStyle.Reset
$test = Get-SpectreRenderable (ConvertTo-SpectreDecoration $sample)
$test | Should -Be $sample
}
It "Test Spectre Colors" {
# this might work because the colors are generated from CI so shouldnt get us codes we cant render.
$sample = Get-SpectreColorSample
foreach ($item in $sample) {
$test = Get-SpectreRenderable (ConvertTo-SpectreDecoration $item.String)
$test | Should -Be $item.String
}
}
}
}
126 changes: 109 additions & 17 deletions PwshSpectreConsole.Tests/formatting/Format-SpectreTable.tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,14 @@ Describe "Format-SpectreTable" {
InModuleScope "PwshSpectreConsole" {
BeforeEach {
$testData = $null
$testBorder = "None" #Get-RandomBoxBorder
$testBorder = Get-RandomBoxBorder
$testColor = Get-RandomColor

Mock Write-AnsiConsole {
if($RenderableObject -isnot [Spectre.Console.Table]) {
throw "Found $($RenderableObject.GetType().Name), expected [Spectre.Console.Table]"
}
$borderType = ($testBorder -eq "None") ? "NoTableBorder" : $testBorder
if($RenderableObject.Border.GetType().Name -notlike "*$borderType*") {
throw "Found $($RenderableObject.Border.GetType().Name), expected border like *$borderType*"
}
if($RenderableObject.BorderStyle.Foreground.ToMarkup() -ne $testColor) {
throw "Found $($RenderableObject.BorderStyle.Foreground.ToMarkup()), expected $testColor"
}
if($RenderableObject.Rows.Count -ne $testData.Count) {
throw "Found $($RenderableObject.Rows.Count), expected $($testData.Count)"
}
Write-Debug "Input data was $($RenderableObject.Rows.Count) rows, $($RenderableObject.Columns.Count) columns, border $($RenderableObject.BorderStyle.Foreground.ToMarkup()), borderstyle, $($RenderableObject.BorderStyle.GetType().Name)"
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
}
}

Expand All @@ -33,5 +23,107 @@ Describe "Format-SpectreTable" {
Assert-MockCalled -CommandName "Write-AnsiConsole" -Times 1 -Exactly
Should -InvokeVerifiable
}

It "Should create a table when default display members for a command are required and input is piped" {
$testData = Get-ChildItem "$PSScriptRoot"
$testData | Format-SpectreTable -Border $testBorder -Color $testColor
Assert-MockCalled -CommandName "Write-AnsiConsole" -Times 1 -Exactly
Should -InvokeVerifiable
}

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) {
# 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")
}
}

It "Should not throw and should return null when input does not have format data" {
{
$defaultDisplayMembers = [hashtable]@{
"Hello" = "World"
} | Get-DefaultDisplayMembers
$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"
$result = ConvertTo-SpectreDecoration -String $ansiString
$result.Length | Should -Be $rawString.Length
}

It "Should be able to format PSStyle strings" {
$rawString = ""
$ansiString = ""
$PSStyle | Get-Member -MemberType Property | Where-Object { $_.Definition -match '^string' -And $_.Name -notmatch 'off$|Reset' } | ForEach-Object {
$name = $_.Name
$rawString += "$name "
$ansiString += "$($PSStyle.$name)$name "
}
$ansiString += "$($PSStyle.Reset)"
$result = ConvertTo-SpectreDecoration -String $ansiString
$result.Length | Should -Be $rawString.Length
}

It "Should be able to format strings with spectre markup when opted in" {
$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"
$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"
$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"
$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"
}
$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
}

It "Should be able to create a new table row without spectre markup by default" {
$entryItem = [pscustomobject]@{
"Markup" = "[red]Markup[/]"
"Also" = "Hello"
}
$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
}
}
}
}
Loading

0 comments on commit 62bfe1b

Please sign in to comment.