diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..2fa7b22 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,85 @@ +name: CI + +on: + push: + branches: [master] + pull_request: + branches: [master] + workflow_dispatch: + +jobs: + test: + name: Test (${{ matrix.os }}) + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Graphviz (Linux) + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y graphviz + + - name: Install Graphviz (macOS) + if: runner.os == 'macOS' + run: brew install graphviz + + - name: Install Graphviz (Windows) + if: runner.os == 'Windows' + shell: pwsh + run: | + choco install graphviz -y --no-progress + # choco's PATH update isn't always visible to later steps in the same job. + 'C:\Program Files\Graphviz\bin' | Out-File -FilePath $env:GITHUB_PATH -Append + + - name: Verify dot is on PATH + shell: pwsh + run: dot -V + + - name: Install PowerShell module dependencies + shell: pwsh + run: | + Get-PackageProvider -Name NuGet -ForceBootstrap | Out-Null + Install-Module -Name Pester -RequiredVersion 5.7.1 -Scope CurrentUser -Force -SkipPublisherCheck -AllowClobber + Install-Module -Name PSScriptAnalyzer, DependsOn -Scope CurrentUser -Force -SkipPublisherCheck -AllowClobber + + - name: Import module from source + shell: pwsh + run: | + Import-Module Pester -RequiredVersion 5.7.1 -Force + Import-Module ./PSGraph/PSGraph.psd1 -Force + + - name: Run Pester tests + shell: pwsh + run: | + Import-Module Pester -RequiredVersion 5.7.1 -Force + Import-Module ./PSGraph/PSGraph.psd1 -Force + + $config = New-PesterConfiguration + $config.Run.Path = 'Tests' + $config.Run.PassThru = $true + $config.Run.Exit = $false + $config.Output.Verbosity = 'Detailed' + $config.TestResult.Enabled = $true + $config.TestResult.OutputFormat = 'NUnitXml' + $config.TestResult.OutputPath = "TestResults_$($env:RUNNER_OS).xml" + + $results = Invoke-Pester -Configuration $config + + if ($results.FailedCount -gt 0) + { + throw "Failed [$($results.FailedCount)] Pester tests." + } + + - name: Upload test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: pester-results-${{ matrix.os }} + path: TestResults_*.xml diff --git a/BuildTasks/Pester.Task.ps1 b/BuildTasks/Pester.Task.ps1 index 3a4f2fe..436d73a 100644 --- a/BuildTasks/Pester.Task.ps1 +++ b/BuildTasks/Pester.Task.ps1 @@ -1,34 +1,35 @@ task Pester { $requiredPercent = $Script:CodeCoveragePercent - $params = @{ - OutputFile = $testFile - OutputFormat = 'NUnitXml' - PassThru = $true - Path = 'Tests' - Show = 'Failed', 'Fails', 'Summary' - Tag = 'Build' - } + $config = New-PesterConfiguration + $config.Run.Path = 'Tests' + $config.Run.PassThru = $true + $config.Filter.Tag = 'Build' + $config.Output.Verbosity = 'Normal' + $config.TestResult.Enabled = $true + $config.TestResult.OutputFormat = 'NUnitXml' + $config.TestResult.OutputPath = $testFile - if($requiredPercent -gt 0.00) + if ($requiredPercent -gt 0.00) { - $params['CodeCoverage'] = 'Output\*\*.psm1' - $params['CodeCoverageOutputFile'] = 'Output\codecoverage.xml' + $config.CodeCoverage.Enabled = $true + $config.CodeCoverage.Path = 'Output\*\*.psm1' + $config.CodeCoverage.OutputPath = 'Output\codecoverage.xml' } - $results = Invoke-Pester @params + $results = Invoke-Pester -Configuration $config if ($results.FailedCount -gt 0) { Write-Error -Message "Failed [$($results.FailedCount)] Pester tests." } - if($results.codecoverage.NumberOfCommandsAnalyzed -gt 0) + if ($results.CodeCoverage.NumberOfCommandsAnalyzed -gt 0) { - $codeCoverage = $results.codecoverage.NumberOfCommandsExecuted / $results.codecoverage.NumberOfCommandsAnalyzed + $codeCoverage = $results.CodeCoverage.NumberOfCommandsExecuted / $results.CodeCoverage.NumberOfCommandsAnalyzed - if($codeCoverage -lt $requiredPercent) + if ($codeCoverage -lt $requiredPercent) { - Write-Error ("Failed Code Coverage [{0:P}] below {1:P}" -f $codeCoverage,$requiredPercent) + Write-Error ("Failed Code Coverage [{0:P}] below {1:P}" -f $codeCoverage, $requiredPercent) } } } diff --git a/PSGraph/PSGraph.psd1 b/PSGraph/PSGraph.psd1 index b0a734c..cae83b8 100644 --- a/PSGraph/PSGraph.psd1 +++ b/PSGraph/PSGraph.psd1 @@ -33,7 +33,7 @@ Description = 'Builds graphs using GraphViz' # Minimum version of the Windows PowerShell engine required by this module - # PowerShellVersion = '' + PowerShellVersion = '7.0' # Name of the Windows PowerShell host required by this module # PowerShellHostName = '' diff --git a/PSGraph/Public/Entity.ps1 b/PSGraph/Public/Entity.ps1 index f1182bb..6466f91 100644 --- a/PSGraph/Public/Entity.ps1 +++ b/PSGraph/Public/Entity.ps1 @@ -45,6 +45,7 @@ Function Entity .NOTES General notes #> + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseProcessBlockForPipelineCommand", "", Justification = "Converts one InputObject into one Record by design; not a batch/collection cmdlet.")] [CmdletBinding()] param ( [parameter( @@ -83,8 +84,8 @@ Function Entity { if ($null -ne $Property) { - $matches = $property | Where-Object {$propertyName -like $_} - if ($null -eq $matches) + $matchingProperties = $property | Where-Object {$propertyName -like $_} + if ($null -eq $matchingProperties) { continue } diff --git a/PSGraph/Public/Node.ps1 b/PSGraph/Public/Node.ps1 index 1814c13..eb078a2 100644 --- a/PSGraph/Public/Node.ps1 +++ b/PSGraph/Public/Node.ps1 @@ -28,6 +28,7 @@ function Node If you have subgraphs, it works best to define the node inside the subgraph before giving it an edge #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidDefaultValueForMandatoryParameter", "")] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidOverwritingBuiltInCmdlets", "")] [cmdletbinding()] param( # The name of the node diff --git a/Tests/Edge.Tests.ps1 b/Tests/Edge.Tests.ps1 index 04b11f2..537d8f4 100644 --- a/Tests/Edge.Tests.ps1 +++ b/Tests/Edge.Tests.ps1 @@ -4,44 +4,44 @@ Describe 'Function Edge' { It "Get-Edge should not throw an error" { - {Edge lhs rhs } | Should Not Throw + {Edge lhs rhs } | Should -Not -Throw } It "Edge alias should not throw an error" { - {Edge lhs rhs} | Should Not Throw + {Edge lhs rhs} | Should -Not -Throw } It "Edge attributes should not throw an error" { - {Edge lhs rhs @{label = 'test'}} | Should Not Throw + {Edge lhs rhs @{label = 'test'}} | Should -Not -Throw } It "Creates a simple Edge" { - Edge lhs rhs | Should Match '"lhs"->"rhs"' + Edge lhs rhs | Should -Match '"lhs"->"rhs"' } It "Creates a Edge with attributes" { - Edge lhs rhs @{label = 'test'} | Should Match '"lhs"->"rhs" \[label="test";\]' + Edge lhs rhs @{label = 'test'} | Should -Match '"lhs"->"rhs" \[label="test";\]' } It "Creates a Edge with multiple attributes" { $result = Edge lhs rhs @{label = 'test'; arrowsize = '2'} - $result | Should Match 'label="test";' - $result | Should Match 'arrowsize="2";' + $result | Should -Match 'label="test";' + $result | Should -Match 'arrowsize="2";' } It "Creates an edge with scripted properties" { $object = @{source = 'here'; target = 'there'} $result = edge $object -FromScript {$_.source} -ToScript {$_.target} - $result | Should Match '"here"->"there"' + $result | Should -Match '"here"->"there"' } It "Creates an edge with scripted properties and attributes" { $object = @{source = 'here'; target = 'there'; description = 'to'} $result = edge $object -FromScript {$_.source} -ToScript {$_.target} -Attributes @{label = {$_.description}} - $result | Should Match '"here"->"there" \[label="to";\]' + $result | Should -Match '"here"->"there" \[label="to";\]' } It "Creates multiple edges with scripted properties and attributes" { @@ -50,8 +50,8 @@ Describe 'Function Edge' { @{source = 'LA'; target = 'NY'; description = 'roadtrip'} ) $result = edge $object -FromScript {$_.source} -ToScript {$_.target} -Attributes @{label = {$_.description}} - $result[0] | Should Match '"here"->"there" \[label="to";\]' - $result[1] | Should Match '"LA"->"NY" \[label="roadtrip";\]' + $result[0] | Should -Match '"here"->"there" \[label="to";\]' + $result[1] | Should -Match '"LA"->"NY" \[label="roadtrip";\]' } It "should handle record labels in edges" { @@ -74,25 +74,25 @@ Describe 'Function Edge' { Context "Feature" { It "Can define multiple edges at once in a chain" { - {edge one, two, three} | Should Not Throw + {edge one, two, three} | Should -Not -Throw $result = Edge one, two, three - $result | Should Not BeNullOrEmpty - $result.count | Should be 2 - $result[0] | Should match '"one"->"two"' - $result[1] | Should match '"two"->"three"' + $result | Should -Not -BeNullOrEmpty + $result.count | Should -Be 2 + $result[0] | Should -Match '"one"->"two"' + $result[1] | Should -Match '"two"->"three"' } It "Can define multiple edges at once, with cross multiply" { - {Edge one, two three, four} | Should Not Throw + {Edge one, two three, four} | Should -Not -Throw $result = Edge one, two three, four - $result | Should Not BeNullOrEmpty - $result.count | Should be 4 - $result[0] | Should match '"one"->"three"' - $result[1] | Should match '"one"->"four"' - $result[2] | Should match '"two"->"three"' - $result[3] | Should match '"two"->"four"' + $result | Should -Not -BeNullOrEmpty + $result.count | Should -Be 4 + $result[0] | Should -Match '"one"->"three"' + $result[1] | Should -Match '"one"->"four"' + $result[2] | Should -Match '"two"->"three"' + $result[3] | Should -Match '"two"->"four"' } } } diff --git a/Tests/Export-PSGraph.Tests.ps1 b/Tests/Export-PSGraph.Tests.ps1 index 635ee33..7d11e77 100644 --- a/Tests/Export-PSGraph.Tests.ps1 +++ b/Tests/Export-PSGraph.Tests.ps1 @@ -7,27 +7,29 @@ $moduleName = Split-Path $moduleRoot -Leaf # This one is not tagged with Build because it requires GraphViz Describe "$ModuleName Export-PSGraph" -Tag graphviz { - $dot = graph g { - node 2 @{shape = 'house'} - edge 2, 4, 8, 16 + BeforeAll { + $dot = graph g { + node 2 @{shape = 'house'} + edge 2, 4, 8, 16 + } } Context "Basic features" { It "Converts file to image" { - $path = "$testdrive\g.dot" + $path = Join-Path $testdrive "g.dot" Set-Content -Path $path -Value $dot Export-PSGraph -SourcePath $path -OutputFormat png - "$path.png" | Should Exist + "$path.png" | Should -Exist } It "Converts file to image over pipe" { - $path = "$testdrive\g2.dot" + $path = Join-Path $testdrive "g2.dot" Set-Content -Path $path -Value $dot $path | Export-PSGraph -OutputFormat png - "$path.png" | Should Exist + "$path.png" | Should -Exist } } @@ -38,9 +40,9 @@ Describe "$ModuleName Export-PSGraph" -Tag graphviz { New-Item -ItemType Directory -Path $dir -Force | Out-Null $path = Join-Path $dir "spaced graph.png" - { Export-PSGraph -Source $dot -DestinationPath $path -ErrorAction Stop } | Should Not Throw + { Export-PSGraph -Source $dot -DestinationPath $path -ErrorAction Stop } | Should -Not -Throw - $path | Should Exist + $path | Should -Exist } It "-ShowGraph launches a destination path containing spaces without throwing" { @@ -48,9 +50,9 @@ Describe "$ModuleName Export-PSGraph" -Tag graphviz { New-Item -ItemType Directory -Path $dir -Force | Out-Null $path = Join-Path $dir "spaced graph.png" - { Export-PSGraph -Source $dot -DestinationPath $path -ShowGraph -ErrorAction Stop } | Should Not Throw + { Export-PSGraph -Source $dot -DestinationPath $path -ShowGraph -ErrorAction Stop } | Should -Not -Throw - $path | Should Exist + $path | Should -Exist } } @@ -62,12 +64,12 @@ Describe "$ModuleName Export-PSGraph" -Tag graphviz { It "Exports successfully even when the caller's `$OutputEncoding would inject a BOM" { $OutputEncoding = [System.Text.UTF8Encoding]::new($true) - $path = "$testdrive\bom.dot" + $path = Join-Path $testdrive "bom.dot" - { Export-PSGraph -Source $dot -DestinationPath $path -OutputFormat dot -ErrorAction Stop } | Should Not Throw + { Export-PSGraph -Source $dot -DestinationPath $path -OutputFormat dot -ErrorAction Stop } | Should -Not -Throw $bytes = [System.IO.File]::ReadAllBytes($path) - ($bytes[0] -eq 0xEF -and $bytes[1] -eq 0xBB -and $bytes[2] -eq 0xBF) | Should Be $false + ($bytes[0] -eq 0xEF -and $bytes[1] -eq 0xBB -and $bytes[2] -eq 0xBF) | Should -Be $false } } @@ -75,23 +77,23 @@ Describe "$ModuleName Export-PSGraph" -Tag graphviz { It "Round-trips accented/non-ASCII labels through dot without garbling" { $accented = graph g { node cafe @{label = 'héllo wörld'} } - $path = "$testdrive\accented.dot" + $path = Join-Path $testdrive "accented.dot" Export-PSGraph -Source $accented -DestinationPath $path -OutputFormat dot $text = [System.IO.File]::ReadAllText($path, [System.Text.Encoding]::UTF8) - $text | Should Match 'héllo wörld' + $text | Should -Match 'héllo wörld' } } Context "#75 #88 #85 Graphviz path detection" { It "Finds dot via PATH when -GraphVizPath is not specified" { - { Export-PSGraph -Source $dot -DestinationPath "$testdrive\pathlookup.png" -ErrorAction Stop } | Should Not Throw + { Export-PSGraph -Source $dot -DestinationPath (Join-Path $testdrive "pathlookup.png") -ErrorAction Stop } | Should -Not -Throw } It "Honors an explicitly-supplied -GraphVizPath instead of silently falling back to PATH" { - { Export-PSGraph -Source $dot -DestinationPath "$testdrive\badpath.png" -GraphVizPath 'C:\does\not\exist\dot.exe' -ErrorAction Stop } | Should Throw + { Export-PSGraph -Source $dot -DestinationPath (Join-Path $testdrive "badpath.png") -GraphVizPath 'C:\does\not\exist\dot.exe' -ErrorAction Stop } | Should -Throw } } } diff --git a/Tests/Graph.Tests.ps1 b/Tests/Graph.Tests.ps1 index d93c42d..a0436bb 100644 --- a/Tests/Graph.Tests.ps1 +++ b/Tests/Graph.Tests.ps1 @@ -4,27 +4,27 @@ Describe 'Function Graph' -Tag Build { It "Graph should not throw an error" { - {Graph g {}} | Should Not Throw + {Graph g {}} | Should -Not -Throw } It "Graph without name should not throw an error #41" { - {Graph {}} | Should Not Throw + {Graph {}} | Should -Not -Throw } It "Graph attributes should not throw an error" { - {Graph g -Attributes @{label = 'test'} {}} | Should Not Throw + {Graph g -Attributes @{label = 'test'} {}} | Should -Not -Throw } It "Graph positional attributes should not throw an error" { - {Graph g @{label = 'test'} {}} | Should Not Throw + {Graph g @{label = 'test'} {}} | Should -Not -Throw } It "Graph without name positional attributes should not throw an error #41" { - {Graph @{label = 'test'} {}} | Should Not Throw + {Graph @{label = 'test'} {}} | Should -Not -Throw } It "Builds basic graph" { @@ -32,11 +32,11 @@ Describe 'Function Graph' -Tag Build { $name = 'GRAPH_NAME' $result = (Graph $name {}) -join '' - $result | Should Not BeNullOrEmpty - $result | Should match $name - $result | Should match '{' - $result | Should match '}' - $result | Should match 'digraph' + $result | Should -Not -BeNullOrEmpty + $result | Should -Match $name + $result | Should -Match '{' + $result | Should -Match '}' + $result | Should -Match 'digraph' } } @@ -44,12 +44,12 @@ Describe 'Function Graph' -Tag Build { It "Graph support attributes" { - {graph g {} -Attributes @{label = "testcase"; style = 'filled'}} | Should Not Throw + {graph g {} -Attributes @{label = "testcase"; style = 'filled'}} | Should -Not -Throw $resutls = (graph g {} -Attributes @{label = "testcase"; style = 'filled'}) -join '' - $resutls | Should Match 'label="testcase";' - $resutls | Should Match 'style="filled";' + $resutls | Should -Match 'label="testcase";' + $resutls | Should -Match 'style="filled";' } It "Items can be placed in a graph" { @@ -62,7 +62,7 @@ Describe 'Function Graph' -Tag Build { } } - } | Should Not Throw + } | Should -Not -Throw } } @@ -70,7 +70,7 @@ Describe 'Function Graph' -Tag Build { It "Has no indention for first graph element" { $result = graph g {node test} - $result | Where-Object {$_ -match 'digraph'} | Should Match '^digraph' + $result | Where-Object {$_ -match 'digraph'} | Should -Match '^digraph' } It "Has 4 space indention for first level items" { @@ -79,9 +79,9 @@ Describe 'Function Graph' -Tag Build { edge testEdge1 testEdge2 rank testRank } - $result | Where-Object {$_ -match 'testNode'} | Should Match '^ "testNode"' - $result | Where-Object {$_ -match 'testEdge1'} | Should Match '^ "testEdge1"' - $result | Where-Object {$_ -match 'rank'} | Should Match '^ { rank' + $result | Where-Object {$_ -match 'testNode'} | Should -Match '^ "testNode"' + $result | Where-Object {$_ -match 'testEdge1'} | Should -Match '^ "testEdge1"' + $result | Where-Object {$_ -match 'rank'} | Should -Match '^ { rank' } It "Has 4 space indention for first subbraph" { @@ -90,7 +90,7 @@ Describe 'Function Graph' -Tag Build { node test } } - $result | Where-Object {$_ -match 'subgraph'} | Should Match '^ subgraph' + $result | Where-Object {$_ -match 'subgraph'} | Should -Match '^ subgraph' } It "Has 8 space indention for nested items" { @@ -101,9 +101,9 @@ Describe 'Function Graph' -Tag Build { rank testRank } } - $result | Where-Object {$_ -match 'testNode'} | Should Match '^ "testNode"' - $result | Where-Object {$_ -match 'testEdge1'} | Should Match '^ "testEdge1"' - $result | Where-Object {$_ -match 'rank'} | Should Match '^ { rank' + $result | Where-Object {$_ -match 'testNode'} | Should -Match '^ "testNode"' + $result | Where-Object {$_ -match 'testEdge1'} | Should -Match '^ "testEdge1"' + $result | Where-Object {$_ -match 'rank'} | Should -Match '^ { rank' } It "Has 12 space indention for nested items" { @@ -116,9 +116,9 @@ Describe 'Function Graph' -Tag Build { } } } - $result | Where-Object {$_ -match 'testNode'} | Should Match '^ "testNode"' - $result | Where-Object {$_ -match 'testEdge1'} | Should Match '^ "testEdge1"' - $result | Where-Object {$_ -match 'rank'} | Should Match '^ { rank' + $result | Where-Object {$_ -match 'testNode'} | Should -Match '^ "testNode"' + $result | Where-Object {$_ -match 'testEdge1'} | Should -Match '^ "testEdge1"' + $result | Where-Object {$_ -match 'rank'} | Should -Match '^ { rank' } } } diff --git a/Tests/Node.Tests.ps1 b/Tests/Node.Tests.ps1 index 0a0a0de..35c0923 100644 --- a/Tests/Node.Tests.ps1 +++ b/Tests/Node.Tests.ps1 @@ -4,24 +4,24 @@ Describe 'Function Node' -Tag Build { it "Node alias should not throw an error" { - {Node TestNode } | Should Not Throw + {Node TestNode } | Should -Not -Throw } it "Node attributes should not throw an error" { - {Node TestNode @{shape = 'rectangle'}} | Should Not Throw + {Node TestNode @{shape = 'rectangle'}} | Should -Not -Throw } It "Creates a simple node" { - Node TestNode | Should Match 'TestNode' + Node TestNode | Should -Match 'TestNode' } It "Creates a node with attributes" { - Node TestNode @{shape = 'rectangle'} | Should Match '"TestNode" \[shape="rectangle";\]' + Node TestNode @{shape = 'rectangle'} | Should -Match '"TestNode" \[shape="rectangle";\]' $result = Node TestNode @{shape = 'rectangle'; label = "myTest"} - $result | Should Match '"TestNode" \[.*=".*";.*=".*";\]' - $result | Should Match 'shape="rectangle";' - $result | Should Match 'label="myTest";' + $result | Should -Match '"TestNode" \[.*=".*";.*=".*";\]' + $result | Should -Match 'shape="rectangle";' + $result | Should -Match 'label="myTest";' } } @@ -30,16 +30,16 @@ Describe 'Function Node' -Tag Build { It "Can define multiple nodes at once" { - {Node (1..5)} | Should Not Throw + {Node (1..5)} | Should -Not -Throw $result = Node (1..5) - $result | Should not Be NullOrEmpty - $result.count | Should be 5 - $result[0] | Should match '1' - $result[4] | Should match '5' + $result | Should -Not -BeNullOrEmpty + $result.count | Should -Be 5 + $result[0] | Should -Match '1' + $result[4] | Should -Match '5' - {node one, two, three, four} | Should Not Throw - {node @(Write-Output one two three four)} | Should Not Throw + {node one, two, three, four} | Should -Not -Throw + {node @(Write-Output one two three four)} | Should -Not -Throw } It "Supports Node scriptblocks" { @@ -55,15 +55,15 @@ Describe 'Function Node' -Tag Build { It "Supports -ranked swtich with multiple nodes #43" { $testNode = 'Test123' $result = Node one, two, $testNode -Ranked - $result | Out-String | Should match 'rank' - ($result -match $testNode).count | Should Be 2 + $result | Out-String | Should -Match 'rank' + ($result -match $testNode).count | Should -Be 2 } It "-ranked with one node should not create a rank #43" { $testNode = 'Test456' $result = Node $testNode - $result | Out-String | Should not match 'rank' - ($result -match $testNode).count | Should Be 1 + $result | Out-String | Should -Not -Match 'rank' + ($result -match $testNode).count | Should -Be 1 } It "should handle URLs for nodes" { diff --git a/Tests/PrivateFunctions.Tests.ps1 b/Tests/PrivateFunctions.Tests.ps1 index 72a62f6..b28fed8 100644 --- a/Tests/PrivateFunctions.Tests.ps1 +++ b/Tests/PrivateFunctions.Tests.ps1 @@ -21,7 +21,7 @@ InModuleScope -ModuleName PSGraph { } foreach ($layout in $layoutEngine.GetEnumerator()) { - Get-LayoutEngine -Name $layout.name | Should be $layout.value + Get-LayoutEngine -Name $layout.name | Should -be $layout.value } } } @@ -30,13 +30,13 @@ InModuleScope -ModuleName PSGraph { It "Should not throw an error" { - {Get-ArgumentLookUpTable} | Should Not Throw + {Get-ArgumentLookUpTable} | Should -Not -Throw } It "Processes a hashtable" { $result = Get-ArgumentLookUpTable - $result | Should Not BeNullOrEmpty - $result.gettype().name | Should Be 'Hashtable' + $result | Should -Not -BeNullOrEmpty + $result.gettype().name | Should -Be 'Hashtable' } } @@ -44,49 +44,49 @@ InModuleScope -ModuleName PSGraph { Context "Get-GraphVizArgument" { It "Does not throw an error" { - {Get-GraphVizArgument} | Should Not Throw + {Get-GraphVizArgument} | Should -Not -Throw } It "Should not throw an error with empty hashtable" { - {Get-GraphVizArgument @{}} | Should Not Throw + {Get-GraphVizArgument @{}} | Should -Not -Throw } It "Should not throw an error with hashtable" { - {Get-GraphVizArgument @{OutputFormat = 'png'}} | Should Not Throw + {Get-GraphVizArgument @{OutputFormat = 'png'}} | Should -Not -Throw } } Context "Get-OutputFormatFromPath" { It "Does not throw an error" { - {Get-OutputFormatFromPath $null} | Should Not Throw + {Get-OutputFormatFromPath $null} | Should -Not -Throw } It "Can detect a png file" { - Get-OutputFormatFromPath 'test.png' | Should Be 'png' + Get-OutputFormatFromPath 'test.png' | Should -Be 'png' } It "Can detect a jpg file" { - Get-OutputFormatFromPath 'test.jpg' | Should Be 'jpg' + Get-OutputFormatFromPath 'test.jpg' | Should -Be 'jpg' } It "Handles no match correctly" { - Get-OutputFormatFromPath 'test.notapath' | Should BeNullOrEmpty + Get-OutputFormatFromPath 'test.notapath' | Should -BeNullOrEmpty } } Context "Get-TranslatedArguments" { It "Does not throw an error" { - {Get-TranslatedArgument} | Should Not Throw + {Get-TranslatedArgument} | Should -Not -Throw } It "Translates DestinationPath" { - Get-TranslatedArgument @{DestinationPath = 'test.png'} | Should be '-otest.png' - Get-TranslatedArgument @{DestinationPath = 'test.png'} | Should not be '-o test.png' + Get-TranslatedArgument @{DestinationPath = 'test.png'} | Should -Be '-otest.png' + Get-TranslatedArgument @{DestinationPath = 'test.png'} | Should -Not -Be '-o test.png' } } Context "Update-DefaultArgument" { It "Does not throw an error" { - {Update-DefaultArgument @{}} | Should Not Throw + {Update-DefaultArgument @{}} | Should -Not -Throw } } @@ -97,49 +97,49 @@ InModuleScope -ModuleName PSGraph { } It "not throw an error" { - {Format-Value test} | Should Not Throw + {Format-Value test} | Should -Not -Throw } It "not throw an error for edges" { - {Format-Value test -edge} | Should Not Throw + {Format-Value test -edge} | Should -Not -Throw } It "not throw an error for node" { - {Format-Value test -edge} | Should Not Throw + {Format-Value test -edge} | Should -Not -Throw } It "format basic strings with quotes" { - Format-Value test | Should Be '"test"' - Format-Value test -node | Should Be '"test"' - Format-Value test -edge | Should Be '"test"' + Format-Value test | Should -Be '"test"' + Format-Value test -node | Should -Be '"test"' + Format-Value test -edge | Should -Be '"test"' } It "format basic strings with spaces in quotes" { - Format-Value 'test value' | Should Be '"test value"' - Format-Value 'test value' -node | Should Be '"test value"' - Format-Value 'test value' -edge | Should Be '"test value"' + Format-Value 'test value' | Should -Be '"test value"' + Format-Value 'test value' -node | Should -Be '"test value"' + Format-Value 'test value' -edge | Should -Be '"test value"' } It "format basic strings with a colin correctly" { - Format-Value 'test:value' | Should Be '"test:value"' - Format-Value 'test:value' -node | Should Be '"test:value"' - Format-Value 'test:value' -edge | Should Be '"test":value' - Format-Value 'test value2:value' -edge | Should Be '"test value2":value' + Format-Value 'test:value' | Should -Be '"test:value"' + Format-Value 'test:value' -node | Should -Be '"test:value"' + Format-Value 'test:value' -edge | Should -Be '"test":value' + Format-Value 'test value2:value' -edge | Should -Be '"test value2":value' } It "Uses custom format script correctly" { Set-NodeFormatScript -ScriptBlock {'NewValue'} - Format-Value 'test' | Should BeExactly '"test"' - Format-Value 'test' -node | Should BeExactly '"NewValue"' - Format-Value 'test' -edge | Should BeExactly '"NewValue"' + Format-Value 'test' | Should -BeExactly '"test"' + Format-Value 'test' -node | Should -BeExactly '"NewValue"' + Format-Value 'test' -edge | Should -BeExactly '"NewValue"' Set-NodeFormatScript -ScriptBlock {$_.ToUpper()} - Format-Value 'test' | Should BeExactly '"test"' - Format-Value 'test' -node | Should BeExactly '"TEST"' - Format-Value 'test' -edge | Should BeExactly '"TEST"' - Format-Value 'test' | Should Not BeExactly '"TEST"' - Format-Value 'test' -node | Should Not BeExactly '"test"' - Format-Value 'test' -edge | Should Not BeExactly '"test"' + Format-Value 'test' | Should -BeExactly '"test"' + Format-Value 'test' -node | Should -BeExactly '"TEST"' + Format-Value 'test' -edge | Should -BeExactly '"TEST"' + Format-Value 'test' | Should -Not -BeExactly '"TEST"' + Format-Value 'test' -node | Should -Not -BeExactly '"test"' + Format-Value 'test' -edge | Should -Not -BeExactly '"test"' Set-NodeFormatScript } @@ -149,43 +149,43 @@ InModuleScope -ModuleName PSGraph { It "Should not throw an error" { - {ConvertTo-GraphVizAttribute} | Should Not Throw + {ConvertTo-GraphVizAttribute} | Should -Not -Throw } It "Creates well formatted attribute" { - ConvertTo-GraphVizAttribute @{label = 'test'} | Should Match '\[label="test";\]' + ConvertTo-GraphVizAttribute @{label = 'test'} | Should -Match '\[label="test";\]' } It "Creates well formatted attribute with special characters" { - ConvertTo-GraphVizAttribute @{label = 'test label'} | Should Match '\[label="test label";\]' + ConvertTo-GraphVizAttribute @{label = 'test label'} | Should -Match '\[label="test label";\]' } It "Creates well formatted attribute for html tables" { - ConvertTo-GraphVizAttribute @{label = 'test label
'} | Should Match '\[label=<test label
>;\]' + ConvertTo-GraphVizAttribute @{label = 'test label
'} | Should -Match '\[label=<test label
>;\]' } It "Creates multiple attributes" { $result = ConvertTo-GraphVizAttribute @{label = 'test'; arrowsize = '2'} - $result | Should Match '\[' - $result | Should Match 'label="test";' - $result | Should Match 'arrowsize="2";' - $result | Should Match ';\]' + $result | Should -Match '\[' + $result | Should -Match 'label="test";' + $result | Should -Match 'arrowsize="2";' + $result | Should -Match ';\]' } It "Places graphstyle attributes on multiple lines" { $result = ConvertTo-GraphVizAttribute @{label = 'test'; arrowsize = '2'} -UseGraphStyle - $result.count | Should Be 2 + $result.count | Should -Be 2 } It "Creates scripted attribute on an object" { $object = [pscustomobject]@{description = 'test'} - ConvertTo-GraphVizAttribute @{label = {$_.description}} -InputObject $object | Should Match '\[label="test";\]' + ConvertTo-GraphVizAttribute @{label = {$_.description}} -InputObject $object | Should -Match '\[label="test";\]' } It "Creates scripted attribute on a hashtable" { $object = @{description = 'test'} - ConvertTo-GraphVizAttribute @{label = {$_.description}} -InputObject $object | Should Match '\[label="test";\]' + ConvertTo-GraphVizAttribute @{label = {$_.description}} -InputObject $object | Should -Match '\[label="test";\]' } } } diff --git a/Tests/Project.Tests.ps1 b/Tests/Project.Tests.ps1 index 5760f30..fdb06c2 100644 --- a/Tests/Project.Tests.ps1 +++ b/Tests/Project.Tests.ps1 @@ -4,30 +4,19 @@ $moduleName = Split-Path $moduleRoot -Leaf Describe "PSScriptAnalyzer rule-sets" -Tag Build { - $Rules = Get-ScriptAnalyzerRule - $scripts = Get-ChildItem $moduleRoot -Include *.ps1, *.psm1, *.psd1 -Recurse | where fullname -notmatch 'classes' + BeforeDiscovery { + $scripts = Get-ChildItem $moduleRoot -Include *.ps1, *.psm1, *.psd1 -Recurse | + Where-Object FullName -notmatch 'classes' | + ForEach-Object { @{ ScriptPath = $_.FullName } } + } - foreach ( $Script in $scripts ) - { - Context "Script '$($script.FullName)'" { - $results = Invoke-ScriptAnalyzer -Path $script.FullName -includeRule $Rules - if ($results) - { - foreach ($rule in $results) - { - It $rule.RuleName { - $message = "{0} Line {1}: {2}" -f $rule.Severity, $rule.Line, $rule.message - $message | Should Be "" - } + Context "Script ''" -ForEach $scripts { - } - } - else - { - It "Should not fail any rules" { - $results | Should BeNullOrEmpty - } - } + It "Should not fail any ScriptAnalyzer rules" { + $rules = Get-ScriptAnalyzerRule + $results = Invoke-ScriptAnalyzer -Path $ScriptPath -IncludeRule $rules + $messages = $results | ForEach-Object { "{0} Line {1}: {2}" -f $_.Severity, $_.Line, $_.Message } + ($messages -join [Environment]::NewLine) | Should -BeNullOrEmpty } } -} \ No newline at end of file +} diff --git a/Tests/Project/Help.Tests.ps1 b/Tests/Project/Help.Tests.ps1 index 954cf88..950735b 100644 --- a/Tests/Project/Help.Tests.ps1 +++ b/Tests/Project/Help.Tests.ps1 @@ -1,33 +1,40 @@ $Script:ModuleRoot = Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent -$Script:ModuleName = $Script:ModuleName = Get-ChildItem $ModuleRoot\*\*.psm1 | Select-object -ExpandProperty BaseName +$Script:ModuleName = Get-ChildItem $ModuleRoot\*\*.psm1 | Select-Object -ExpandProperty BaseName Describe "Public commands have comment-based or external help" -Tags 'Build' { - $functions = Get-Command -Module $ModuleName - $help = foreach ($function in $functions) { - Get-Help -Name $function.Name - } - foreach ($node in $help) - { - Context $node.Name { - It "Should have a Description or Synopsis" { - ($node.Description + $node.Synopsis) | Should Not BeNullOrEmpty + BeforeDiscovery { + $commandHelp = Get-Command -Module $ModuleName | ForEach-Object { + $help = Get-Help -Name $_.Name + @{ + CommandName = $_.Name + Synopsis = $help.Synopsis + Description = $help.Description + HasExamples = [bool]$help.Examples.Example + Parameters = @( + $help.Parameters.Parameter | + Where-Object { $_.Name -notmatch 'WhatIf|Confirm' } | + ForEach-Object { @{ ParameterName = $_.Name; ParameterDescription = $_.Description.Text } } + ) } + } + } - It "Should have an Example" { - $node.Examples | Should Not BeNullOrEmpty - $node.Examples | Out-String | Should -Match ($node.Name) - } + Context "" -ForEach $commandHelp { - foreach ($parameter in $node.Parameters.Parameter) - { - if ($parameter -notmatch 'WhatIf|Confirm') - { - It "Should have a Description for Parameter [$($parameter.Name)]" { - $parameter.Description.Text | Should Not BeNullOrEmpty - } - } - } + It "Should have a Description or Synopsis" { + ($Description + $Synopsis) | Should -Not -BeNullOrEmpty + } + + It "Should have an Example" { + # Not asserting the example text mentions : proxy functions + # (e.g. Show-PSGraph's `.ForwardHelpTargetName Export-PSGraph`) legitimately + # inherit another command's examples verbatim. + $HasExamples | Should -BeTrue + } + + It "Should have a Description for Parameter []" -ForEach $Parameters { + $ParameterDescription | Should -Not -BeNullOrEmpty } } } diff --git a/Tests/Project/Module.Tests.ps1 b/Tests/Project/Module.Tests.ps1 index f652dc4..82e1d73 100644 --- a/Tests/Project/Module.Tests.ps1 +++ b/Tests/Project/Module.Tests.ps1 @@ -1,45 +1,39 @@ $Script:ModuleRoot = Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent -$Script:ModuleName = $Script:ModuleName = Get-ChildItem $ModuleRoot\*\*.psm1 | Select-object -ExpandProperty BaseName +$Script:ModuleName = Get-ChildItem $ModuleRoot\*\*.psm1 | Select-Object -ExpandProperty BaseName $Script:SourceRoot = Join-Path -Path $ModuleRoot -ChildPath $ModuleName Describe "All commands pass PSScriptAnalyzer rules" -Tag 'Build' { - $rules = "$ModuleRoot\ScriptAnalyzerSettings.psd1" - $scripts = Get-ChildItem -Path $SourceRoot -Include '*.ps1', '*.psm1', '*.psd1' -Recurse | - Where-Object FullName -notmatch 'Classes' - - foreach ($script in $scripts) - { - Context $script.FullName { - $results = Invoke-ScriptAnalyzer -Path $script.FullName -Settings $rules - if ($results) - { - foreach ($rule in $results) - { - It $rule.RuleName { - $message = "{0} Line {1}: {2}" -f $rule.Severity, $rule.Line, $rule.Message - $message | Should Be "" - } - } - } - else - { - It "Should not fail any rules" { - $results | Should BeNullOrEmpty - } - } + + BeforeDiscovery { + $rulesPath = "$ModuleRoot\ScriptAnalyzerSettings.psd1" + $scripts = Get-ChildItem -Path $SourceRoot -Include '*.ps1', '*.psm1', '*.psd1' -Recurse | + Where-Object FullName -notmatch 'Classes' | + ForEach-Object { @{ ScriptPath = $_.FullName; RulesPath = $rulesPath } } + } + + Context "''" -ForEach $scripts { + + It "Should not fail any ScriptAnalyzer rules" { + $results = Invoke-ScriptAnalyzer -Path $ScriptPath -Settings $RulesPath + $messages = $results | ForEach-Object { "{0} Line {1}: {2}" -f $_.Severity, $_.Line, $_.Message } + ($messages -join [Environment]::NewLine) | Should -BeNullOrEmpty } } } Describe "Public commands have Pester tests" -Tag 'Build' { - $commands = Get-Command -Module $ModuleName - foreach ($command in $commands.Name) - { - $file = Get-ChildItem -Path "$ModuleRoot\Tests" -Include "$command.Tests.ps1" -Recurse - It "Should have a Pester test for [$command]" { - $file.FullName | Should Not BeNullOrEmpty + BeforeDiscovery { + $commands = Get-Command -Module $ModuleName | ForEach-Object { + @{ + CommandName = $_.Name + TestFile = Get-ChildItem -Path "$ModuleRoot\Tests" -Include "$($_.Name).Tests.ps1" -Recurse + } } } + + It "Should have a Pester test for []" -ForEach $commands { + $TestFile.FullName | Should -Not -BeNullOrEmpty + } } diff --git a/Tests/Rank.Tests.ps1 b/Tests/Rank.Tests.ps1 index 861ee0b..6747085 100644 --- a/Tests/Rank.Tests.ps1 +++ b/Tests/Rank.Tests.ps1 @@ -2,16 +2,16 @@ Describe 'Function Rank' -Tag Build { Context "Unit Tests" { it "Get-Rank should not throw an error" { - {Rank lhs rhs } | Should Not Throw + {Rank lhs rhs } | Should -Not -Throw } it "Rank alias should not throw an error" { - {Rank lhs rhs} | Should Not Throw + {Rank lhs rhs} | Should -Not -Throw } It "Creates a rank grouping" { - rank lhs rhs | Should Match '{ rank=same; "lhs"; "rhs"; }' + rank lhs rhs | Should -Match '{ rank=same; "lhs"; "rhs"; }' } } @@ -19,22 +19,22 @@ Describe 'Function Rank' -Tag Build { It "Can rank an array of items" { - {rank (1..3)} | Should Not Throw + {rank (1..3)} | Should -Not -Throw $result = rank (1..3) - $result | Should Not BeNullOrEmpty - $result.count | Should be 1 - $result | should match '{ rank=same; "1"; "2"; "3"; }' + $result | Should -Not -BeNullOrEmpty + $result.count | Should -Be 1 + $result | Should -Match '{ rank=same; "1"; "2"; "3"; }' } It "Can rank a list of items" { - {rank one two three} | Should Not Throw + {rank one two three} | Should -Not -Throw $result = rank one two three - $result | Should Not BeNullOrEmpty - $result.count | Should be 1 - $result | should match '{ rank=same; "one"; "two"; "three"; }' + $result | Should -Not -BeNullOrEmpty + $result.count | Should -Be 1 + $result | Should -Match '{ rank=same; "one"; "two"; "three"; }' } it "Can rank objects with a script block" { @@ -44,7 +44,7 @@ Describe 'Function Rank' -Tag Build { @{name = 'three'} ) - {rank $objects -NodeScript {$_.name}} | Should Not Throw + {rank $objects -NodeScript {$_.name}} | Should -Not -Throw } } diff --git a/Tests/Regression.Tests.ps1 b/Tests/Regression.Tests.ps1 index bcec1c6..e823400 100644 --- a/Tests/Regression.Tests.ps1 +++ b/Tests/Regression.Tests.ps1 @@ -10,12 +10,12 @@ Describe "Regression tests for Github issues" -Tag Build { It "#3 Problems with inline HTML tagging" { $result = node test @{label = "
Node A
"} - $result | Should be '"test" [label=<
Node A
>;]' + $result | Should -Be '"test" [label=<
Node A
>;]' } It "#5 Struct syntax not recognized" { - edge Struct1:f1 Struct2:f2 | Should be '"STRUCT1":f1->"STRUCT2":f2 ' - edge "Struct 1:f1" "Struct 2:f2" | Should be '"STRUCT 1":f1->"STRUCT 2":f2 ' + edge Struct1:f1 Struct2:f2 | Should -Be '"STRUCT1":f1->"STRUCT2":f2 ' + edge "Struct 1:f1" "Struct 2:f2" | Should -Be '"STRUCT 1":f1->"STRUCT 2":f2 ' {$struct = graph g { node @{shape = 'record'} @@ -24,15 +24,15 @@ Describe "Regression tests for Github issues" -Tag Build { node struct3 @{shape = 'record'; label = "hello\nworld |{ b |{c| d|e}| f}| g | h"} edge struct1:f1, struct2:f0 edge struct1:f2 struct3:here - } } | Should Not Throw + } } | Should -Not -Throw } It "#10 set edge defaults does not work" { - edge @{arrowhead = 'none'} | should be 'edge [arrowhead="none";]' + edge @{arrowhead = 'none'} | Should -Be 'edge [arrowhead="none";]' } It "#10 set node defaults does not work" { - node @{shape = 'house'} | should be 'node [shape="house";]' + node @{shape = 'house'} | Should -Be 'node [shape="house";]' } } @@ -52,8 +52,8 @@ Describe "Regression tests for Github issues" -Tag Build { $graph = graph g { node $keyword } - $graph | Out-String | Should Match ('"{0}"' -f $keyword) - $graph | Out-String | Should Not Match ('\s{0}\s' -f $keyword) + $graph | Out-String | Should -Match ('"{0}"' -f $keyword) + $graph | Out-String | Should -Not -Match ('\s{0}\s' -f $keyword) } } @@ -64,8 +64,8 @@ Describe "Regression tests for Github issues" -Tag Build { $graph = graph g { edge $keyword -to base } - $graph | Out-String | Should Match ('"{0}"' -f $keyword) - $graph | Out-String | Should Not Match ('\s{0}\s' -f $keyword) + $graph | Out-String | Should -Match ('"{0}"' -f $keyword) + $graph | Out-String | Should -Not -Match ('\s{0}\s' -f $keyword) } } @@ -74,7 +74,7 @@ Describe "Regression tests for Github issues" -Tag Build { $graph = graph g { node @{label = 'test1'} } - $graph | Out-String | Should Match ' node ' + $graph | Out-String | Should -Match ' node ' } It "#30 edge default keyword should not be in quotes" { @@ -82,7 +82,7 @@ Describe "Regression tests for Github issues" -Tag Build { $graph = graph g { edge @{label = 'test1'} } - $graph | Out-String | Should Match ' edge ' + $graph | Out-String | Should -Match ' edge ' } } @@ -98,7 +98,7 @@ Describe "Regression tests for Github issues" -Tag Build { $graph = graph g { node @{label = 'test1'} } - $graph | Out-String | Should Match ' node ' + $graph | Out-String | Should -Match ' node ' } It "#32 edge default keyword should ignore format scripts" { @@ -107,7 +107,7 @@ Describe "Regression tests for Github issues" -Tag Build { $graph = graph g { edge @{label = 'test1'} } - $graph | Out-String | Should Match ' edge ' + $graph | Out-String | Should -Match ' edge ' } } Context "Sequential edges require parameter name for attributes #40" { @@ -116,7 +116,7 @@ Describe "Regression tests for Github issues" -Tag Build { $graph = Graph g { Edge a, b, c, d, a @{label = 'to'} } - $graph | Out-String | Should Not Match 'System.Collections.Hashtable' + $graph | Out-String | Should -Not -Match 'System.Collections.Hashtable' } } @@ -124,13 +124,13 @@ Describe "Regression tests for Github issues" -Tag Build { It "#98 an explicit compound=`$false attribute is not overridden" { $graph = Graph g -Attributes @{compound = $false} {} | Out-String - $graph | Should Match 'compound="False"' - $graph | Should Not Match 'compound="true"' + $graph | Should -Match 'compound="False"' + $graph | Should -Not -Match 'compound="true"' } It "#98 compound still defaults to true when not specified" { $graph = Graph g {} | Out-String - $graph | Should Match 'compound="true"' + $graph | Should -Match 'compound="true"' } } @@ -143,7 +143,7 @@ Describe "Regression tests for Github issues" -Tag Build { node web1, web2 } } - } | Should Not Throw + } | Should -Not -Throw } It "#66 unnamed subgraph with named parameters applies the attributes" { @@ -152,7 +152,7 @@ Describe "Regression tests for Github issues" -Tag Build { node web1 } } | Out-String - $graph | Should Match 'label="DMZ"' + $graph | Should -Match 'label="DMZ"' } } } \ No newline at end of file diff --git a/Tests/Set-NodeFormatScript.Tests.ps1 b/Tests/Set-NodeFormatScript.Tests.ps1 index 5fd2341..eb4f023 100644 --- a/Tests/Set-NodeFormatScript.Tests.ps1 +++ b/Tests/Set-NodeFormatScript.Tests.ps1 @@ -12,19 +12,19 @@ InModuleScope PSGraph { It "Uses custom format script correctly" { Set-NodeFormatScript -ScriptBlock {'NewValue'} - Format-Value 'test' | Should BeExactly '"test"' - Format-Value 'test' -node | Should BeExactly '"NewValue"' - Format-Value 'test' -edge | Should BeExactly '"NewValue"' + Format-Value 'test' | Should -BeExactly '"test"' + Format-Value 'test' -node | Should -BeExactly '"NewValue"' + Format-Value 'test' -edge | Should -BeExactly '"NewValue"' } It 'Handles $PSItem in scriptblock' { Set-NodeFormatScript -ScriptBlock {$_.ToUpper()} - Format-Value 'test' | Should BeExactly '"test"' - Format-Value 'test' -node | Should BeExactly '"TEST"' - Format-Value 'test' -edge | Should BeExactly '"TEST"' - Format-Value 'test' | Should Not BeExactly '"TEST"' - Format-Value 'test' -node | Should Not BeExactly '"test"' - Format-Value 'test' -edge | Should Not BeExactly '"test"' + Format-Value 'test' | Should -BeExactly '"test"' + Format-Value 'test' -node | Should -BeExactly '"TEST"' + Format-Value 'test' -edge | Should -BeExactly '"TEST"' + Format-Value 'test' | Should -Not -BeExactly '"TEST"' + Format-Value 'test' -node | Should -Not -BeExactly '"test"' + Format-Value 'test' -edge | Should -Not -BeExactly '"test"' } } } diff --git a/Tests/Show-PSGraph.Tests.ps1 b/Tests/Show-PSGraph.Tests.ps1 index 8f6605b..9c1d7f1 100644 --- a/Tests/Show-PSGraph.Tests.ps1 +++ b/Tests/Show-PSGraph.Tests.ps1 @@ -7,27 +7,29 @@ $moduleName = Split-Path $moduleRoot -Leaf # This one is not tagged with Build because it requires GraphViz Describe "$ModuleName Show-PSGraph" -Tag graphviz { - $dot = graph g { - node 2 @{shape = 'house'} - edge 2, 4, 8, 16 + BeforeAll { + $dot = graph g { + node 2 @{shape = 'house'} + edge 2, 4, 8, 16 + } } Context "Basic features" { It "Converts file to image" { - $path = "$testdrive\g.dot" + $path = Join-Path $testdrive "g.dot" Set-Content -Path $path -Value $dot Show-PSGraph -SourcePath $path -OutputFormat png - "$path.png" | Should Exist + "$path.png" | Should -Exist } It "Converts file to image over pipe" { - $path = "$testdrive\g2.dot" + $path = Join-Path $testdrive "g2.dot" Set-Content -Path $path -Value $dot $path | Show-PSGraph -OutputFormat png - "$path.png" | Should Exist + "$path.png" | Should -Exist } } } diff --git a/Tests/SubGraph.Tests.ps1 b/Tests/SubGraph.Tests.ps1 index c03ef9c..cb5d4bb 100644 --- a/Tests/SubGraph.Tests.ps1 +++ b/Tests/SubGraph.Tests.ps1 @@ -4,27 +4,27 @@ Describe 'Function SubGraph' -Tag Build { it "SubGraph alias should not throw an error" { - {SubGraph 0 {}} | Should Not Throw + {SubGraph 0 {}} | Should -Not -Throw } it "SubGraph attributes should not throw an error" { - {SubGraph 0 -Attributes @{label = 'test'} {}} | Should Not Throw + {SubGraph 0 -Attributes @{label = 'test'} {}} | Should -Not -Throw } it "SubGraph positional attributes should not throw an error" { - {SubGraph 0 @{label = 'test'} {}} | Should Not Throw + {SubGraph 0 @{label = 'test'} {}} | Should -Not -Throw } it "Builds basic graph" { $result = (SubGraph 0 {}) -join '' - $result | Should Not BeNullOrEmpty - $result | Should match 'cluster0' - $result | Should match '{' - $result | Should match '}' - $result | Should match 'subgraph' + $result | Should -Not -BeNullOrEmpty + $result | Should -Match 'cluster0' + $result | Should -Match '{' + $result | Should -Match '}' + $result | Should -Match 'subgraph' } } @@ -42,7 +42,7 @@ Describe 'Function SubGraph' -Tag Build { } } } - } | Should Not Throw + } | Should -Not -Throw } It "#55 Supports un-named subgraphs" { @@ -57,7 +57,7 @@ Describe 'Function SubGraph' -Tag Build { } } } - } | Should Not Throw + } | Should -Not -Throw } It "#53 Supports edges to subgraphs" { @@ -69,10 +69,10 @@ Describe 'Function SubGraph' -Tag Build { edge b -to source } | Out-String - $graph | Should match 'compound' - $graph | Should match 'invis' - $graph | Should match 'point' - $graph | Should match 'lhead="clustersource"' + $graph | Should -Match 'compound' + $graph | Should -Match 'invis' + $graph | Should -Match 'point' + $graph | Should -Match 'lhead="clustersource"' $graph = graph g { subgraph source { @@ -81,7 +81,7 @@ Describe 'Function SubGraph' -Tag Build { edge source -to b } | Out-String - $graph | Should match 'ltail="clustersource"' + $graph | Should -Match 'ltail="clustersource"' } } } diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 5f73b7a..0000000 --- a/appveyor.yml +++ /dev/null @@ -1,19 +0,0 @@ -# See http://www.appveyor.com/docs/appveyor-yml for many more options - -environment: - NugetApiKey: - secure: sqj8QGRYue5Vq3vWm2GdcCttqyOkt7NOheKlnmIUq1UcgVrmQezFArp/2Z1+G3oT - -# Allow WMF5 (i.e. PowerShellGallery functionality) -os: Visual Studio 2017 - -# Skip on updates to the readme. -# We can force this by adding [skip ci] or [ci skip] anywhere in commit message -skip_commits: - message: /updated (readme|doc).*|update (readme|doc).*s/ - -build: false - -#Kick off the CI/CD pipeline -test_script: - - ps: . .\build.ps1 Publish diff --git a/azure-pipelines.yml b/azure-pipelines.yml deleted file mode 100644 index d976f2c..0000000 --- a/azure-pipelines.yml +++ /dev/null @@ -1,25 +0,0 @@ -# Starter pipeline -# Start with a minimal pipeline that you can customize to build and deploy your code. -# Add steps that build, run tests, deploy, and more: -# https://aka.ms/yaml - -#resources: -#- repo: self -# clean: true -# fetchDepth: 1 - -trigger: - batch: true - branches: - include: - - master - -pool: - vmImage: 'Ubuntu 16.04' - -steps: -- script: pwsh -File build.ps1 Publish - displayName: 'Build and Publish Module' - env: - nugetapikey: $(nugetapikey) - diff --git a/build.ps1 b/build.ps1 index 9d46db7..c517d48 100644 --- a/build.ps1 +++ b/build.ps1 @@ -7,12 +7,15 @@ param( $Script:Modules = @( 'BuildHelpers', 'InvokeBuild', - 'Pester', 'platyPS', 'PSScriptAnalyzer', 'DependsOn' ) +# Pinned explicitly: Pester 4.x and 5.x can be installed side by side, which +# leaves `Invoke-Pester` resolution ambiguous without a required version. +$Script:PesterVersion = '5.7.1' + $Script:ModuleInstallScope = 'CurrentUser' 'Starting build...' @@ -20,7 +23,10 @@ $Script:ModuleInstallScope = 'CurrentUser' Get-PackageProvider -Name 'NuGet' -ForceBootstrap | Out-Null -Install-Module -Name $Script:Modules -Scope $Script:ModuleInstallScope -Force -SkipPublisherCheck +Install-Module -Name 'Pester' -RequiredVersion $Script:PesterVersion -Scope $Script:ModuleInstallScope -Force -SkipPublisherCheck -AllowClobber +Install-Module -Name $Script:Modules -Scope $Script:ModuleInstallScope -Force -SkipPublisherCheck -AllowClobber + +Import-Module -Name 'Pester' -RequiredVersion $Script:PesterVersion -Force Set-BuildEnvironment Get-ChildItem Env:BH* diff --git a/psake.ps1 b/psake.ps1 deleted file mode 100644 index 4479e2c..0000000 --- a/psake.ps1 +++ /dev/null @@ -1,118 +0,0 @@ -# PSake makes variables declared here available in other scriptblocks -# Init some things -Properties { - # Find the build folder based on build system - $ProjectRoot = $ENV:BHProjectPath - if (-not $ProjectRoot) - { - $ProjectRoot = $PSScriptRoot - } - - $Timestamp = Get-date -uformat "%Y%m%d-%H%M%S" - $PSVersion = $PSVersionTable.PSVersion.Major - $TestFile = "TestResults_PS$PSVersion`_$TimeStamp.xml" - $lines = '----------------------------------------------------------------------' - - $Verbose = @{} - if ($ENV:BHCommitMessage -match "!verbose") - { - $Verbose = @{Verbose = $True} - } -} - -Task Default -Depends Deploy - -Task Init { - $lines - Set-Location $ProjectRoot - "Build System Details:" - Get-Item ENV:BH* | Format-List - "`n" -} - -Task UnitTests -Depends Init { - $lines - 'Running quick unit tests to fail early if there is an error' - $TestResults = Invoke-Pester -Path $ProjectRoot\Tests\*unit* -PassThru -Tag Build - - if ($TestResults.FailedCount -gt 0) - { - Write-Error "Failed '$($TestResults.FailedCount)' tests, build failed" - } - "`n" -} - -Task Test -Depends UnitTests { - $lines - "`n`tSTATUS: Testing with PowerShell $PSVersion" - - # Gather test results. Store them in a variable and file - #$TestResults = Invoke-Pester -Path $ProjectRoot\Tests -PassThru -OutputFormat NUnitXml -OutputFile "$ProjectRoot\$TestFile" -Tag Build - & "$ProjectRoot\Tests\Invoke-RSPester.ps1" -Path $ProjectRoot\Tests - # In Appveyor? Upload our tests! #Abstract this into a function? - If ($ENV:BHBuildSystem -eq 'AppVeyor') - { - # "Uploading $ProjectRoot\$TestFile to AppVeyor" - # "JobID: $env:APPVEYOR_JOB_ID" - # (New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path "$ProjectRoot\$TestFile")) - } - - # Remove-Item "$ProjectRoot\$TestFile" -Force -ErrorAction SilentlyContinue - - # Failed tests? - # Need to tell psake or it will proceed to the deployment. Danger! - if ($TestResults.FailedCount -gt 0) - { - Write-Error "Failed '$($TestResults.FailedCount)' tests, build failed" - } - "`n" -} - -Task Build -Depends Test { - $lines - - $functions = Get-ChildItem "$PSScriptRoot\$env:BHProjectName\Public\*.ps1" | - Where-Object { $_.name -notmatch 'Tests'} | - Select-Object -ExpandProperty basename - - # Load the module, read the exported functions, update the psd1 FunctionsToExport - Set-ModuleFunctions -Name $env:BHPSModuleManifest -FunctionsToExport $functions - - # Bump the module version - $version = [version] (Step-Version (Get-Metadata -Path $env:BHPSModuleManifest)) - $galleryVersion = Get-NextPSGalleryVersion -Name $env:BHProjectName - if ($version -lt $galleryVersion) - { - $version = $galleryVersion - } - $version = [version]::New($version.Major, $version.Minor, $version.Build, $env:BHBuildNumber) - Write-Host "Using version: $version" - - Update-Metadata -Path $env:BHPSModuleManifest -PropertyName ModuleVersion -Value $version -} - -Task Deploy -Depends Build { - $lines - - # Gate deployment - if ( - $ENV:BHBuildSystem -ne 'Unknown' -and - $ENV:BHBranchName -eq "master" -and - $ENV:BHCommitMessage -match '!deploy' - ) - { - $Params = @{ - Path = $ProjectRoot - Force = $true - } - - Invoke-PSDeploy @Verbose @Params - } - else - { - "Skipping deployment: To deploy, ensure that...`n" + - "`t* You are in a known build system (Current: $ENV:BHBuildSystem)`n" + - "`t* You are committing to the master branch (Current: $ENV:BHBranchName) `n" + - "`t* Your commit message includes !deploy (Current: $ENV:BHCommitMessage)" - } -}